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
|
||||
cartographer = {
|
||||
biome_lookup = {},
|
||||
biome_heights = {},
|
||||
scan_queue = {},
|
||||
};
|
||||
_cartographer = {
|
||||
CHUNK_SIZE = 16,
|
||||
|
||||
biome_lookup = {},
|
||||
maps = minetest.deserialize(mod_storage:get_string("maps")) or {},
|
||||
next_map_id = mod_storage:get_int("next_map_id"),
|
||||
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)
|
||||
|
||||
function cartographer.register_biome(name, texture, height)
|
||||
cartographer.biome_lookup[name] = texture;
|
||||
|
||||
if height ~= nil and height ~= 0 then
|
||||
cartographer.biome_heights[name] = height;
|
||||
end
|
||||
-- Register a biome with textures to display
|
||||
-- name: A string containing the biome name
|
||||
-- textures: A table of texture names.
|
||||
-- These should correspond with detail levels,
|
||||
-- any detail level past the length of the table will return the last texture
|
||||
-- (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
|
||||
|
||||
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)]));
|
||||
return map.fill[(x - map.x) + ((z - map.z) * map.w)] ~= nil;
|
||||
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
|
||||
str = str..tile:format(fx, fy, scale, scale, "cartographer_unknown_biome." .. tostring(get_variant(random)) .. ".png")
|
||||
else
|
||||
local name = minetest.get_biome_name(column[j]);
|
||||
local biome = cartographer.biome_lookup[name];
|
||||
local height = cartographer.biome_heights[name] or 0;
|
||||
local name = minetest.get_biome_name(column[j].biome);
|
||||
local height = column[j].height;
|
||||
local biome = cartographer.get_biome_texture(name, math.floor(height + 0.5), detail);
|
||||
|
||||
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")
|
||||
else
|
||||
if height > 0 then
|
||||
str = str..tile:format(fx, fy, scale, scale, "cartographer_cliff.png")
|
||||
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
|
||||
|
||||
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
|
||||
-- str = str..marker:format(fx, fy - (height * 0.025), scale, scale, "dicon.png")
|
||||
-- elseif i == spawn_x and j == spawn_y then
|
||||
|
|
|
@ -62,16 +62,28 @@ cartographer.register_biome("Wasteland", {
|
|||
cartographer.register_biome("Grassland Ocean", {
|
||||
"cartographer_simple_water",
|
||||
"cartographer_colored_water",
|
||||
});
|
||||
}, nil, 0);
|
||||
cartographer.register_biome("Grassland Ocean", {
|
||||
"cartographer_simple_land",
|
||||
"cartographer_colored_sand",
|
||||
}, 0);
|
||||
cartographer.register_biome("Gravel Beach", {
|
||||
"cartographer_simple_land",
|
||||
"cartographer_colored_sand",
|
||||
"cartographer_gravel",
|
||||
});
|
||||
}, 0);
|
||||
cartographer.register_biome("Gravel Beach", {
|
||||
"cartographer_simple_water",
|
||||
"cartographer_colored_water",
|
||||
}, nil, 0);
|
||||
cartographer.register_biome("Savanna Ocean", {
|
||||
"cartographer_simple_water",
|
||||
"cartographer_colored_water",
|
||||
});
|
||||
}, nil, 0);
|
||||
cartographer.register_biome("Savanna Ocean", {
|
||||
"cartographer_simple_land",
|
||||
"cartographer_colored_sand",
|
||||
}, 0);
|
||||
|
||||
-- Materials
|
||||
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 function register_mapchunk(x, y, biome)
|
||||
local function register_mapchunk(x, y, biome, height)
|
||||
if not data.generated[x] then
|
||||
data.generated[x] = {
|
||||
[y] = biome,
|
||||
[y] = {
|
||||
biome = biome,
|
||||
height = height,
|
||||
}
|
||||
};
|
||||
elseif not data.generated[x][y] then
|
||||
data.generated[x][y] = biome;
|
||||
data.generated[x][y] = {
|
||||
biome = biome,
|
||||
height = height,
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -15,6 +21,7 @@ local function get_mapgen_biome(min, max, mmin, mmax)
|
|||
local DEFAULT = minetest.get_biome_id("default");
|
||||
|
||||
local biomes = minetest.get_mapgen_object("biomemap");
|
||||
local heights = minetest.get_mapgen_object("heightmap");
|
||||
|
||||
local xx = max.x - min.x;
|
||||
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 scan_biomes = {};
|
||||
local scan_heights = {};
|
||||
|
||||
for i = startx,startx + xx,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
|
||||
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
|
||||
|
@ -48,7 +57,12 @@ local function get_mapgen_biome(min, max, mmin, mmax)
|
|||
end
|
||||
end
|
||||
|
||||
return biome;
|
||||
local avg_height = 0;
|
||||
if high > 0 then
|
||||
avg_height = scan_heights[biome] / high;
|
||||
end
|
||||
|
||||
return biome, avg_height;
|
||||
end
|
||||
|
||||
local function get_biome(min, max)
|
||||
|
@ -61,6 +75,7 @@ local function get_biome(min, max)
|
|||
local zz = max.z - min.z;
|
||||
|
||||
local scan_biomes = {};
|
||||
local scan_heights = {};
|
||||
|
||||
for i = min.x,max.x,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;
|
||||
if node == "air" or node == WATER_SOURCE then
|
||||
scan_biomes[b] = (scan_biomes[b] or 0) + 1;
|
||||
scan_heights[b] = (scan_heights[b] or 0) + j;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -88,7 +104,12 @@ local function get_biome(min, max)
|
|||
end
|
||||
end
|
||||
|
||||
return biome;
|
||||
local avg_height = 0;
|
||||
if high > 0 then
|
||||
avg_height = scan_heights[biome] / high;
|
||||
end
|
||||
|
||||
return biome, avg_height;
|
||||
end
|
||||
|
||||
local function on_generated(min, max, blockseed)
|
||||
|
@ -110,9 +131,9 @@ local function on_generated(min, max, blockseed)
|
|||
y = max.y,
|
||||
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
|
||||
register_mapchunk(i, j, biome)
|
||||
register_mapchunk(i, j, biome, height)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user