2020-06-01 13:59:34 +02:00
|
|
|
-- Arguments
|
|
|
|
-- map_data: The cartographer map data table
|
|
|
|
local map_data = ...;
|
|
|
|
|
|
|
|
-- Constants
|
2020-04-18 02:28:15 +02:00
|
|
|
local TILE_SIZE = 0.25;
|
|
|
|
local TILE_OFFSET = 0.24; -- Slightly smaller than TILE_SIZE. We overlap tiles slightly to minimize seams
|
2020-02-16 18:55:07 +01:00
|
|
|
|
2020-04-18 13:53:32 +02:00
|
|
|
-- NoiseParams table for tile variations
|
|
|
|
local MAP_NOISE = {
|
|
|
|
offset = 0,
|
|
|
|
scale = 1,
|
|
|
|
spread = {x = 2, y = 2, z = 2},
|
2020-06-01 13:31:38 +02:00
|
|
|
seed = tonumber(minetest.get_mapgen_setting("seed")),
|
2020-04-18 13:53:32 +02:00
|
|
|
octaves = 2,
|
|
|
|
persist = 0.63,
|
|
|
|
lacunarity = 2.0,
|
|
|
|
flags = "defaults, absvalue",
|
|
|
|
};
|
|
|
|
|
|
|
|
-- Get the variant of the tile at a given position
|
|
|
|
-- x: The X position of the tile (in map coordinates)
|
|
|
|
-- z: The Z position of the tile (in map coordinates)
|
|
|
|
-- noise: A 2d lookup table of perlin noise. Must contain the position [x + 1][y + 1]
|
|
|
|
--
|
|
|
|
-- Returns a number from 1 to 4
|
|
|
|
local function get_variant(x, z, noise)
|
|
|
|
return math.floor(math.min(noise[x + 1][z + 1] * 3, 3)) + 1;
|
2020-02-16 18:55:07 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
local map_formspec_prefix = [[
|
|
|
|
formspec_version[3]
|
|
|
|
size[%f,%f]
|
|
|
|
real_coordinates[true]
|
|
|
|
style_type[image_button;border=false]
|
|
|
|
]];
|
|
|
|
|
|
|
|
local tile = "image[%f,%f;%f,%f;%s]";
|
2020-06-02 00:22:08 +02:00
|
|
|
local player_marker = "animated_image[%f,%f;%f,%f;;%s;%d;%d]";
|
2020-02-16 18:55:07 +01:00
|
|
|
|
2020-03-29 20:12:10 +02:00
|
|
|
-- Generate formspec markup for an unknown biome tile
|
2020-04-18 02:28:15 +02:00
|
|
|
-- x: The x position of the tile
|
|
|
|
-- y: The y position of the tile
|
2020-04-18 15:15:13 +02:00
|
|
|
-- detail: The detail level
|
2020-04-18 02:28:15 +02:00
|
|
|
-- variant: The tile variant
|
|
|
|
--
|
|
|
|
-- Returns a formspec string
|
2020-04-18 15:15:13 +02:00
|
|
|
local function unknown_biome_tile(x, y, detail, variant)
|
|
|
|
return string.format("image[%f,%f;%f,%f;%s.%s.png]",
|
|
|
|
x, y,
|
|
|
|
TILE_SIZE, TILE_SIZE,
|
|
|
|
cartographer.detail_texture(cartographer.skin.unknown_biome_textures, detail),
|
|
|
|
variant);
|
2020-03-29 20:12:10 +02:00
|
|
|
end
|
|
|
|
|
2020-04-10 13:00:29 +02:00
|
|
|
-- Generate formspec markup for a given map
|
|
|
|
-- x: The X position of the map (in map coordinates)
|
|
|
|
-- y: The Z position of the map (in map coordinates)
|
|
|
|
-- w: The width of the map (in map coordinates)
|
|
|
|
-- h: The height of the map (in map coordinates)
|
|
|
|
-- player_x: The X position of the player marker (in map coordinates)
|
|
|
|
-- player_y: The Y position of the player marker (in map coordinates)
|
|
|
|
-- detail: The detail level
|
|
|
|
-- map_scale: Integer scaling factor for displaying a zoomed-out map
|
2020-04-21 13:29:30 +02:00
|
|
|
-- height_mode: If true, displaces tiles by their height
|
2020-04-10 13:00:29 +02:00
|
|
|
-- (Optional) is_visible: Callback to determine if a tile should be drawn
|
|
|
|
-- (Optional) get_marker: Callback to get the marker for any given tile
|
|
|
|
-- (Optional) user: userdata passed to the is_visible/get_marker callbacks
|
|
|
|
--
|
|
|
|
-- Returns a formspec string
|
2020-06-01 13:59:34 +02:00
|
|
|
local function generate_map(x, y, w, h, player_x, player_y, detail, map_scale, height_mode, is_visible, get_marker, user)
|
2020-02-16 18:55:07 +01:00
|
|
|
local str = "";
|
2020-04-18 13:53:32 +02:00
|
|
|
local noise = PerlinNoiseMap(MAP_NOISE, { x=w + 1, y=h + 1, z=1}):get_2d_map({ x=x, y=y});
|
2020-04-10 13:00:29 +02:00
|
|
|
|
2020-02-16 18:55:07 +01:00
|
|
|
for i = x,x + w,1 do
|
2020-04-18 02:28:15 +02:00
|
|
|
local fx = (i - x) * TILE_OFFSET;
|
2020-06-01 13:59:34 +02:00
|
|
|
local column = map_data.generated[i * map_scale];
|
2020-02-16 18:55:07 +01:00
|
|
|
for j = y + h,y,-1 do
|
2020-04-18 02:28:15 +02:00
|
|
|
local fy = (y + h - j) * TILE_OFFSET;
|
2020-03-07 16:26:24 +01:00
|
|
|
if column == nil or column[j * map_scale] == nil or (is_visible and not is_visible(user, i, j)) then
|
2020-04-18 15:15:13 +02:00
|
|
|
str = str .. unknown_biome_tile(fx, fy, detail, get_variant(i - x, j - y, noise));
|
2020-02-16 18:55:07 +01:00
|
|
|
else
|
2020-03-07 16:26:24 +01:00
|
|
|
local name = minetest.get_biome_name(column[j * map_scale].biome);
|
|
|
|
local height = column[j * map_scale].height;
|
2020-02-17 02:18:47 +01:00
|
|
|
local biome = cartographer.get_biome_texture(name, math.floor(height + 0.5), detail);
|
2020-02-20 01:56:31 +01:00
|
|
|
|
2020-04-10 13:14:47 +02:00
|
|
|
if biome then
|
|
|
|
local depth = math.min(math.max(math.floor(height / 8), -8), 0) * -1
|
2020-04-21 01:33:26 +02:00
|
|
|
height = math.max(math.min(math.floor(height / (math.max(map_scale * 0.5, 1) + 4)), 8), 0)
|
2020-02-16 18:55:07 +01:00
|
|
|
|
2020-04-10 13:14:47 +02:00
|
|
|
local mod = "";
|
2020-02-16 18:55:07 +01:00
|
|
|
if height > 0 then
|
2020-04-10 13:14:47 +02:00
|
|
|
mod = "^[colorize:white:"..tostring(height * 10)
|
|
|
|
height = height * 0.05;
|
|
|
|
|
2020-04-21 13:29:30 +02:00
|
|
|
if height_mode then
|
|
|
|
str = str .. tile:format(fx, fy - height + TILE_OFFSET, TILE_SIZE, height + 0.01, cartographer.detail_texture(cartographer.skin.cliff_textures, detail) .. ".png");
|
|
|
|
else
|
|
|
|
height = 0;
|
|
|
|
end
|
2020-04-10 13:14:47 +02:00
|
|
|
elseif depth > 0 then
|
|
|
|
mod = "^[colorize:#1f1f34:"..tostring(depth * 10)
|
2020-02-16 18:55:07 +01:00
|
|
|
end
|
|
|
|
|
2020-04-18 13:53:32 +02:00
|
|
|
str = str..tile:format(fx, fy - height, TILE_SIZE, TILE_SIZE, biome .. "." .. tostring(get_variant(i - x, j - y, noise)) .. ".png" .. mod)
|
2020-02-16 18:55:07 +01:00
|
|
|
|
2020-04-10 13:14:47 +02:00
|
|
|
if get_marker then
|
|
|
|
local marker = cartographer.get_marker_texture(get_marker(user, i, j), detail);
|
|
|
|
if marker then
|
2020-04-18 02:28:15 +02:00
|
|
|
str = str..tile:format(fx, fy - height, TILE_SIZE, TILE_SIZE, marker .. ".png")
|
2020-04-10 13:14:47 +02:00
|
|
|
end
|
2020-03-17 11:52:15 +01:00
|
|
|
end
|
|
|
|
|
2020-04-10 13:14:47 +02:00
|
|
|
if i == player_x and j == player_y then
|
2020-04-18 15:15:13 +02:00
|
|
|
local player_icon = cartographer.detail_texture(cartographer.skin.player_icons, detail);
|
2020-06-02 00:22:08 +02:00
|
|
|
str = str .. player_marker:format(fx, fy - height,
|
|
|
|
TILE_SIZE, TILE_SIZE,
|
|
|
|
player_icon.texture .. ".png",
|
|
|
|
player_icon.frame_count,
|
|
|
|
player_icon.frame_duration);
|
2020-04-10 13:14:47 +02:00
|
|
|
end
|
|
|
|
else
|
2020-04-18 15:15:13 +02:00
|
|
|
str = str .. unknown_biome_tile(fx, fy, detail, get_variant(i - x, j - y, noise));
|
2020-02-16 18:55:07 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return str;
|
|
|
|
end
|
|
|
|
|
2020-04-18 02:28:15 +02:00
|
|
|
-- Get the formspec for a given map segment
|
|
|
|
-- x: The X position of the map, in map coordinates
|
|
|
|
-- y: The Y position of the map, in map coordinates
|
|
|
|
-- w: The width of the map, in map coordinates
|
|
|
|
-- h: The height of the map, in map coordinates
|
|
|
|
-- detail: The detail level of the map
|
2020-04-21 13:29:30 +02:00
|
|
|
-- scale: Integer scaling factor for displaying a zoomed-out map
|
|
|
|
-- height_mode: If true, displaces tiles by their height
|
2020-04-18 02:28:15 +02:00
|
|
|
--
|
|
|
|
-- Returns a formspec string, the width of the formspec, and the height of the
|
|
|
|
-- formspec
|
2020-06-01 13:59:34 +02:00
|
|
|
function cartographer.get_map_formspec(x, y, w, h, detail, scale, height_mode)
|
2020-04-18 02:28:15 +02:00
|
|
|
local formspec_width = (w + 1) * TILE_OFFSET + 0.01;
|
|
|
|
local formspec_height = (h + 1) * TILE_OFFSET + 0.01;
|
2020-06-01 13:59:34 +02:00
|
|
|
return map_formspec_prefix:format(formspec_width, formspec_height)..generate_map(x - (w * 0.5), y - (h * 0.5), w, h, x, y, detail, scale, height_mode),
|
2020-04-18 02:28:15 +02:00
|
|
|
formspec_width,
|
|
|
|
formspec_height;
|
2020-02-16 18:55:07 +01:00
|
|
|
end
|
|
|
|
|
2020-04-18 02:28:15 +02:00
|
|
|
-- Get the formspec for a given map table
|
|
|
|
-- map: The map to use
|
|
|
|
-- x: The X position of the player marker, in map coordinates
|
|
|
|
-- y: The Y position of the player marker, in map coordinates
|
2020-04-21 13:29:30 +02:00
|
|
|
-- height_mode: If true, displaces tiles by their height
|
2020-04-18 02:28:15 +02:00
|
|
|
--
|
|
|
|
-- Returns a formspec string, the width of the formspec, and the height of the
|
|
|
|
-- formspec
|
2020-06-02 14:01:11 +02:00
|
|
|
function cartographer.get_map_formspec_map(map, x, y, height_mode)
|
2020-04-18 02:28:15 +02:00
|
|
|
local formspec_width = (map.w + 1) * TILE_OFFSET + 0.01;
|
|
|
|
local formspec_height = (map.h + 1) * TILE_OFFSET + 0.01;
|
2020-06-01 13:59:34 +02:00
|
|
|
return map_formspec_prefix:format(formspec_width, formspec_height)..generate_map(map.x, map.z, map.w, map.h, x, y, map.detail, map.scale, height_mode, cartographer.is_filled, cartographer.get_marker, map),
|
2020-04-18 02:28:15 +02:00
|
|
|
formspec_width,
|
|
|
|
formspec_height;
|
2020-02-16 18:55:07 +01:00
|
|
|
end
|