Record heightmap when scanning
- Use heightmap value for more granular biome texture selection
This commit is contained in:
parent
d0f7c58c47
commit
e5371e19ed
3
init.lua
3
init.lua
@ -2,13 +2,12 @@ local mod_storage = minetest.get_mod_storage();
|
|||||||
|
|
||||||
-- The API object
|
-- The API object
|
||||||
cartographer = {
|
cartographer = {
|
||||||
biome_lookup = {},
|
|
||||||
biome_heights = {},
|
|
||||||
scan_queue = {},
|
scan_queue = {},
|
||||||
};
|
};
|
||||||
_cartographer = {
|
_cartographer = {
|
||||||
CHUNK_SIZE = 16,
|
CHUNK_SIZE = 16,
|
||||||
|
|
||||||
|
biome_lookup = {},
|
||||||
maps = minetest.deserialize(mod_storage:get_string("maps")) or {},
|
maps = minetest.deserialize(mod_storage:get_string("maps")) or {},
|
||||||
next_map_id = mod_storage:get_int("next_map_id"),
|
next_map_id = mod_storage:get_int("next_map_id"),
|
||||||
last_deaths = minetest.deserialize(mod_storage:get_string("deaths")) or {},
|
last_deaths = minetest.deserialize(mod_storage:get_string("deaths")) or {},
|
||||||
|
35
map_api.lua
35
map_api.lua
@ -92,12 +92,20 @@ minetest.register_globalstep(function(dt)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function cartographer.register_biome(name, texture, height)
|
-- Register a biome with textures to display
|
||||||
cartographer.biome_lookup[name] = texture;
|
-- name: A string containing the biome name
|
||||||
|
-- textures: A table of texture names.
|
||||||
if height ~= nil and height ~= 0 then
|
-- These should correspond with detail levels,
|
||||||
cartographer.biome_heights[name] = height;
|
-- any detail level past the length of the table will return the last texture
|
||||||
end
|
-- (Optional) min_height: The minimum Y position where this biome data should be used
|
||||||
|
-- (Optional) max_height: The maximum Y position where this biome data should be used
|
||||||
|
function cartographer.register_biome(name, textures, min_height, max_height)
|
||||||
|
_cartographer.biome_lookup[#_cartographer.biome_lookup + 1] = {
|
||||||
|
name = name,
|
||||||
|
textures = textures,
|
||||||
|
min_height = min_height,
|
||||||
|
max_height = max_height,
|
||||||
|
};
|
||||||
end
|
end
|
||||||
|
|
||||||
function cartographer.is_filled(map, x, z)
|
function cartographer.is_filled(map, x, z)
|
||||||
@ -108,3 +116,18 @@ function cartographer.is_filled(map, x, z)
|
|||||||
minetest.chat_send_all(tostring(x).. ", " .. tostring(z) .. "(" .. tostring(x + (z * map.w)) .."): " .. tostring(map.fill[x + (z * map.w)]));
|
minetest.chat_send_all(tostring(x).. ", " .. tostring(z) .. "(" .. tostring(x + (z * map.w)) .."): " .. tostring(map.fill[x + (z * map.w)]));
|
||||||
return map.fill[(x - map.x) + ((z - map.z) * map.w)] ~= nil;
|
return map.fill[(x - map.x) + ((z - map.z) * map.w)] ~= nil;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Get the texture name (minus index/extension) for the given biome, height, and detail level.
|
||||||
|
-- name: A string containing the biome name
|
||||||
|
-- height: A number representing the Y position of the biome
|
||||||
|
-- detail: The detail level
|
||||||
|
-- Returns a string with a texture name, or nil if no matching biome entry was found.
|
||||||
|
function cartographer.get_biome_texture(name, height, detail)
|
||||||
|
for _,biome in ipairs(_cartographer.biome_lookup) do
|
||||||
|
if biome.name == name and (biome.min_height == nil or height >= biome.min_height) and (biome.max_height == nil or height <= biome.max_height) then
|
||||||
|
return biome.textures[math.min(detail, #biome.textures)];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
@ -26,23 +26,23 @@ local function generate_map(data, x, y, w, h, player_x, player_y, spawn_x, spawn
|
|||||||
if column == nil or column[j] == nil or (is_visible and not is_visible(user, i, j)) then
|
if column == nil or column[j] == nil or (is_visible and not is_visible(user, i, j)) then
|
||||||
str = str..tile:format(fx, fy, scale, scale, "cartographer_unknown_biome." .. tostring(get_variant(random)) .. ".png")
|
str = str..tile:format(fx, fy, scale, scale, "cartographer_unknown_biome." .. tostring(get_variant(random)) .. ".png")
|
||||||
else
|
else
|
||||||
local name = minetest.get_biome_name(column[j]);
|
local name = minetest.get_biome_name(column[j].biome);
|
||||||
local biome = cartographer.biome_lookup[name];
|
local height = column[j].height;
|
||||||
local height = cartographer.biome_heights[name] or 0;
|
local biome = cartographer.get_biome_texture(name, math.floor(height + 0.5), detail);
|
||||||
|
|
||||||
if biome == nil then
|
if biome == nil then
|
||||||
minetest.chat_send_all(name);
|
-- minetest.chat_send_all(name);
|
||||||
str = str..tile:format(fx, fy, scale, scale, "cartographer_unknown_biome." .. tostring(get_variant(random)) .. ".png")
|
str = str..tile:format(fx, fy, scale, scale, "cartographer_unknown_biome." .. tostring(get_variant(random)) .. ".png")
|
||||||
else
|
else
|
||||||
if height > 0 then
|
if height > 0 then
|
||||||
str = str..tile:format(fx, fy, scale, scale, "cartographer_cliff.png")
|
str = str..tile:format(fx, fy, scale, scale, "cartographer_cliff.png")
|
||||||
end
|
end
|
||||||
|
|
||||||
str = str..tile:format(fx, fy - (height * 0.025), scale, scale, biome[math.min(detail, #biome)] .. "." .. tostring(get_variant(random)) .. ".png")
|
str = str..tile:format(fx, fy, scale, scale, biome .. "." .. tostring(get_variant(random)) .. ".png")
|
||||||
end
|
end
|
||||||
|
|
||||||
if i == player_x and j == player_y then
|
if i == player_x and j == player_y then
|
||||||
str = str..marker:format(fx, fy - (height * 0.025), scale, scale, "cartographer_player_icon.png", 2, 500)
|
str = str..marker:format(fx, fy, scale, scale, "cartographer_player_icon.png", 2, 500)
|
||||||
-- elseif i == death_x and j == death_y then
|
-- elseif i == death_x and j == death_y then
|
||||||
-- str = str..marker:format(fx, fy - (height * 0.025), scale, scale, "dicon.png")
|
-- str = str..marker:format(fx, fy - (height * 0.025), scale, scale, "dicon.png")
|
||||||
-- elseif i == spawn_x and j == spawn_y then
|
-- elseif i == spawn_x and j == spawn_y then
|
||||||
|
@ -62,16 +62,28 @@ cartographer.register_biome("Wasteland", {
|
|||||||
cartographer.register_biome("Grassland Ocean", {
|
cartographer.register_biome("Grassland Ocean", {
|
||||||
"cartographer_simple_water",
|
"cartographer_simple_water",
|
||||||
"cartographer_colored_water",
|
"cartographer_colored_water",
|
||||||
});
|
}, nil, 0);
|
||||||
|
cartographer.register_biome("Grassland Ocean", {
|
||||||
|
"cartographer_simple_land",
|
||||||
|
"cartographer_colored_sand",
|
||||||
|
}, 0);
|
||||||
cartographer.register_biome("Gravel Beach", {
|
cartographer.register_biome("Gravel Beach", {
|
||||||
"cartographer_simple_land",
|
"cartographer_simple_land",
|
||||||
"cartographer_colored_sand",
|
"cartographer_colored_sand",
|
||||||
"cartographer_gravel",
|
"cartographer_gravel",
|
||||||
});
|
}, 0);
|
||||||
|
cartographer.register_biome("Gravel Beach", {
|
||||||
|
"cartographer_simple_water",
|
||||||
|
"cartographer_colored_water",
|
||||||
|
}, nil, 0);
|
||||||
cartographer.register_biome("Savanna Ocean", {
|
cartographer.register_biome("Savanna Ocean", {
|
||||||
"cartographer_simple_water",
|
"cartographer_simple_water",
|
||||||
"cartographer_colored_water",
|
"cartographer_colored_water",
|
||||||
});
|
}, nil, 0);
|
||||||
|
cartographer.register_biome("Savanna Ocean", {
|
||||||
|
"cartographer_simple_land",
|
||||||
|
"cartographer_colored_sand",
|
||||||
|
}, 0);
|
||||||
|
|
||||||
-- Materials
|
-- Materials
|
||||||
cartographer.register_map_material_name("default:paper", "fiber", 5);
|
cartographer.register_map_material_name("default:paper", "fiber", 5);
|
||||||
|
37
scanner.lua
37
scanner.lua
@ -1,12 +1,18 @@
|
|||||||
local CHUNK_SIZE = _cartographer.CHUNK_SIZE;
|
local CHUNK_SIZE = _cartographer.CHUNK_SIZE;
|
||||||
|
|
||||||
local function register_mapchunk(x, y, biome)
|
local function register_mapchunk(x, y, biome, height)
|
||||||
if not data.generated[x] then
|
if not data.generated[x] then
|
||||||
data.generated[x] = {
|
data.generated[x] = {
|
||||||
[y] = biome,
|
[y] = {
|
||||||
|
biome = biome,
|
||||||
|
height = height,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
elseif not data.generated[x][y] then
|
elseif not data.generated[x][y] then
|
||||||
data.generated[x][y] = biome;
|
data.generated[x][y] = {
|
||||||
|
biome = biome,
|
||||||
|
height = height,
|
||||||
|
};
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -15,6 +21,7 @@ local function get_mapgen_biome(min, max, mmin, mmax)
|
|||||||
local DEFAULT = minetest.get_biome_id("default");
|
local DEFAULT = minetest.get_biome_id("default");
|
||||||
|
|
||||||
local biomes = minetest.get_mapgen_object("biomemap");
|
local biomes = minetest.get_mapgen_object("biomemap");
|
||||||
|
local heights = minetest.get_mapgen_object("heightmap");
|
||||||
|
|
||||||
local xx = max.x - min.x;
|
local xx = max.x - min.x;
|
||||||
local yy = max.y - min.y;
|
local yy = max.y - min.y;
|
||||||
@ -29,12 +36,14 @@ local function get_mapgen_biome(min, max, mmin, mmax)
|
|||||||
local startz = min.z - mmin.z;
|
local startz = min.z - mmin.z;
|
||||||
|
|
||||||
local scan_biomes = {};
|
local scan_biomes = {};
|
||||||
|
local scan_heights = {};
|
||||||
|
|
||||||
for i = startx,startx + xx,1 do
|
for i = startx,startx + xx,1 do
|
||||||
for k = startz,startz + zz,1 do
|
for k = startz,startz + zz,1 do
|
||||||
local b = biomes[i + (k * (xxx + 1))]
|
local b = biomes[i + (k * (xxx + 1))];
|
||||||
if b ~= nil and b ~= UNDERGROUND and b ~= DEFAULT then
|
if b ~= nil and b ~= UNDERGROUND and b ~= DEFAULT then
|
||||||
scan_biomes[b] = (scan_biomes[b] or 0) + 1;
|
scan_biomes[b] = (scan_biomes[b] or 0) + 1;
|
||||||
|
scan_heights[b] = (scan_heights[b] or 0) + heights[i + (k * (xxx + 1))];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -48,7 +57,12 @@ local function get_mapgen_biome(min, max, mmin, mmax)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return biome;
|
local avg_height = 0;
|
||||||
|
if high > 0 then
|
||||||
|
avg_height = scan_heights[biome] / high;
|
||||||
|
end
|
||||||
|
|
||||||
|
return biome, avg_height;
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_biome(min, max)
|
local function get_biome(min, max)
|
||||||
@ -61,6 +75,7 @@ local function get_biome(min, max)
|
|||||||
local zz = max.z - min.z;
|
local zz = max.z - min.z;
|
||||||
|
|
||||||
local scan_biomes = {};
|
local scan_biomes = {};
|
||||||
|
local scan_heights = {};
|
||||||
|
|
||||||
for i = min.x,max.x,1 do
|
for i = min.x,max.x,1 do
|
||||||
for j = min.y,max.y,1 do
|
for j = min.y,max.y,1 do
|
||||||
@ -73,6 +88,7 @@ local function get_biome(min, max)
|
|||||||
node = minetest.get_node(pos).name;
|
node = minetest.get_node(pos).name;
|
||||||
if node == "air" or node == WATER_SOURCE then
|
if node == "air" or node == WATER_SOURCE then
|
||||||
scan_biomes[b] = (scan_biomes[b] or 0) + 1;
|
scan_biomes[b] = (scan_biomes[b] or 0) + 1;
|
||||||
|
scan_heights[b] = (scan_heights[b] or 0) + j;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -88,7 +104,12 @@ local function get_biome(min, max)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return biome;
|
local avg_height = 0;
|
||||||
|
if high > 0 then
|
||||||
|
avg_height = scan_heights[biome] / high;
|
||||||
|
end
|
||||||
|
|
||||||
|
return biome, avg_height;
|
||||||
end
|
end
|
||||||
|
|
||||||
local function on_generated(min, max, blockseed)
|
local function on_generated(min, max, blockseed)
|
||||||
@ -110,9 +131,9 @@ local function on_generated(min, max, blockseed)
|
|||||||
y = max.y,
|
y = max.y,
|
||||||
z = j * CHUNK_SIZE + CHUNK_SIZE,
|
z = j * CHUNK_SIZE + CHUNK_SIZE,
|
||||||
};
|
};
|
||||||
local biome = get_mapgen_biome(sub_min, sub_max, min, max);
|
local biome, height = get_mapgen_biome(sub_min, sub_max, min, max);
|
||||||
if biome ~= nil then
|
if biome ~= nil then
|
||||||
register_mapchunk(i, j, biome)
|
register_mapchunk(i, j, biome, height)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user