cartographer/map_api.lua

191 lines
6.2 KiB
Lua

function cartographer.create_map(x, z, w, h, filled, detail, scale)
local id = _cartographer.next_map_id;
local map = {
id = id,
x = x,
z = z,
w = w,
h = h,
detail = detail,
scale = scale,
fill = {},
markers = {},
};
_cartographer.maps[id] = map;
if filled then
cartographer.fill(map, x, z, w, h);
end
_cartographer.next_map_id = _cartographer.next_map_id + 1;
return id;
end
function cartographer.get_map(id)
return _cartographer.maps[id];
end
function cartographer.resize_map(id, w, h)
local map = cartographer.get_map(id);
if map ~= nil and w >= map.w and h >= map.h then
map.w = w;
map.h = h;
end
end
function cartographer.fill(map, x, z, w, h)
if map == nil then
return;
end
for i = math.max(x, map.x),math.min(x + w - 1, map.x + map.w),1 do
for j = math.max(z, map.z),math.min(z + h - 1, map.z + map.h),1 do
map.fill[(i - map.x) + ((j - map.z) * map.w)] = map.detail;
end
end
end
function cartographer.set_marker(map, x, z, marker)
if map == nil or x < map.x or x > map.x + map.w or z < map.z or z > map.z + map.h then
return;
end
if not map.markers[x] then
map.markers[x] = {
[z] = marker,
};
else
map.markers[x][z] = marker;
end
end
function cartographer.get_marker(map, x, z)
if map == nil or x < map.x or x > map.x + map.w or z < map.z or z > map.z + map.h or not map.markers[x] then
return nil;
end
return map.markers[x][z];
end
function cartographer.fill_local(id, x, z)
local map = cartographer.get_map(id);
if map ~= nil and x >= map.x - 2 and x <= map.x + map.w + 1 and z >= map.z - 2 and z <= map.z + map.h + 1 then
-- minetest.chat_send_all("[" .. tostring(x) .. ", " .. tostring(z) .. "] - [" .. tostring(map.x - 2) .. ", " .. tostring(map.z - 2) .. "], [" .. tostring(map.x + map.w + 1) .. ", " .. tostring(map.z + map.h + 1) .. "]");
cartographer.fill(map, x - 2, z - 2, 5, 5);
end
end
local timer = 0;
minetest.register_globalstep(function(dt)
timer = timer - dt;
if timer < 0 then
timer = timer + 5;
-- Fill in all player-held maps
for _,p in ipairs(minetest.get_connected_players()) do
local inventory = p:get_inventory();
local pos = p:get_pos();
if pos.y > -10 then
for i = 1,inventory:get_size("main") do
local stack = inventory:get_stack("main", i);
if stack:get_name() == "cartographer:map" then
local player_x = tochunk(pos.x);
local player_y = tochunk(pos.z);
cartographer.fill_local(stack:get_meta():get_int("cartographer:map_id"), player_x, player_y);
end
end
for i = -2,2 do
for j = -2,2 do
local adjusted_pos = {
x = tochunk(pos.x + fromchunk(i)),
y = tochunk(pos.y),
z = tochunk(pos.z + fromchunk(j)),
}
cartographer.queue_region(adjusted_pos);
end
end
end
end
for i = 1,10 do
cartographer.scan_regions();
end
end
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
-- Register a marker with textures to display
-- id: A string containing the id of the marker
-- name: A string containing the displayedname of the marker
-- 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
function cartographer.register_marker(id, name, textures)
if not _cartographer.marker_lookup then
_cartographer.marker_count = _cartographer.marker_count + 1;
end
_cartographer.marker_lookup[id] = {
name = name,
textures = textures,
};
end
function cartographer.is_filled(map, x, z)
if map == nil then
return false;
end
-- 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
-- Get the texture name (minus extension) for the given marker and detail level.
-- id: A string containing the marker id
-- detail: The detail level
-- Returns a string with a texture name, or nil if no matching marker was found.
function cartographer.get_marker_texture(id, detail)
local marker = _cartographer.marker_lookup[id];
if marker then
return marker.textures[math.min(detail, #marker.textures)];
end
return nil;
end