Fix numerous scan-related bugs
This commit is contained in:
parent
a5ded9bc11
commit
0f706533b6
@ -1,19 +1,21 @@
|
|||||||
local MAXINT = 2147483647;
|
local MAXINT = 2147483647;
|
||||||
|
|
||||||
|
-- /map <detail> -- Displays a regional map around the player
|
||||||
|
-- (Optional)detail: Specifies the map's detail level. Defaults to the highest
|
||||||
|
-- available detail.
|
||||||
minetest.register_chatcommand("map", {
|
minetest.register_chatcommand("map", {
|
||||||
params = "[<detail>]",
|
params = "[<detail>]",
|
||||||
func = function(name, detail)
|
func = function(name, detail)
|
||||||
local player = minetest.get_player_by_name(name);
|
local player = minetest.get_player_by_name(name);
|
||||||
local pos = player:get_pos();
|
local pos = player:get_pos();
|
||||||
|
|
||||||
local player_x = tochunk(pos.x);
|
local player_x, player_z = cartographer.to_map_coordinates(nil, pos.x, pos.z);
|
||||||
local player_y = tochunk(pos.z);
|
|
||||||
|
|
||||||
if detail == "" then
|
if detail == "" then
|
||||||
detail = MAXINT;
|
detail = MAXINT;
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.show_formspec(name, "map", cartographer.get_map_formspec(data, tochunk(pos.x), tochunk(pos.z), 40, 40, detail));
|
minetest.show_formspec(name, "map", cartographer.get_map_formspec(data, player_x, player_z, 40, 40, detail));
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
22
map_api.lua
22
map_api.lua
@ -69,11 +69,17 @@ function cartographer.get_marker(map, x, z)
|
|||||||
return map.markers[x][z];
|
return map.markers[x][z];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Fill in the local area of a map around a position
|
||||||
|
-- id: A map ID
|
||||||
|
-- x: The x position, in world coordinates
|
||||||
|
-- z: The z position, in world coordinates
|
||||||
function cartographer.fill_local(id, x, z)
|
function cartographer.fill_local(id, x, z)
|
||||||
local map = cartographer.get_map(id);
|
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
|
x, z = cartographer.to_map_coordinates(map, x, z);
|
||||||
-- 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) .. "]");
|
|
||||||
|
-- TODO: Adjust size to match map scale
|
||||||
|
if map 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
|
||||||
cartographer.fill(map, x - 2, z - 2, 5, 5);
|
cartographer.fill(map, x - 2, z - 2, 5, 5);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -93,8 +99,8 @@ function cartographer.to_map_coordinates(map, x, z)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local timer = 0;
|
local timer = 0;
|
||||||
|
|
||||||
minetest.register_globalstep(function(dt)
|
minetest.register_globalstep(function(dt)
|
||||||
|
-- TODO: We need a better way to do this. minetest.after maybe?
|
||||||
timer = timer - dt;
|
timer = timer - dt;
|
||||||
if timer < 0 then
|
if timer < 0 then
|
||||||
timer = timer + 5;
|
timer = timer + 5;
|
||||||
@ -108,17 +114,15 @@ minetest.register_globalstep(function(dt)
|
|||||||
local stack = inventory:get_stack("main", i);
|
local stack = inventory:get_stack("main", i);
|
||||||
|
|
||||||
if stack:get_name() == "cartographer:map" then
|
if stack:get_name() == "cartographer:map" then
|
||||||
local player_x = tochunk(pos.x);
|
cartographer.fill_local(stack:get_meta():get_int("cartographer:map_id"), pos.x, pos.y);
|
||||||
local player_y = tochunk(pos.z);
|
|
||||||
cartographer.fill_local(stack:get_meta():get_int("cartographer:map_id"), player_x, player_y);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for i = -2,2 do
|
for i = -2,2 do
|
||||||
for j = -2,2 do
|
for j = -2,2 do
|
||||||
local adjusted_pos = {
|
local adjusted_pos = {
|
||||||
x = tochunk(pos.x + fromchunk(i)),
|
x = pos.x + fromchunk(i),
|
||||||
y = tochunk(pos.y),
|
y = pos.y,
|
||||||
z = tochunk(pos.z + fromchunk(j)),
|
z = pos.z + fromchunk(j),
|
||||||
}
|
}
|
||||||
cartographer.queue_region(adjusted_pos);
|
cartographer.queue_region(adjusted_pos);
|
||||||
end
|
end
|
||||||
|
@ -94,7 +94,7 @@ local function generate_map(data, x, y, w, h, player_x, player_y, detail, map_sc
|
|||||||
end
|
end
|
||||||
|
|
||||||
function cartographer.get_map_formspec(data, x, y, w, h, detail)
|
function cartographer.get_map_formspec(data, x, y, w, h, detail)
|
||||||
return map_formspec_prefix:format(w * scale, h * scale)..generate_map(data, x - (w * 0.5), y - (h * 0.5), w, h, x, y, detail, 4);
|
return map_formspec_prefix:format(w * scale, h * scale)..generate_map(data, x - (w * 0.5), y - (h * 0.5), w, h, x, y, detail, 1);
|
||||||
end
|
end
|
||||||
|
|
||||||
function cartographer.get_map_formspec_map(data, map, x, y)
|
function cartographer.get_map_formspec_map(data, map, x, y)
|
||||||
|
54
scanner.lua
54
scanner.lua
@ -1,6 +1,14 @@
|
|||||||
local CHUNK_SIZE = _cartographer.CHUNK_SIZE;
|
local CHUNK_SIZE = _cartographer.CHUNK_SIZE;
|
||||||
|
|
||||||
local function register_mapchunk(x, y, biome, height)
|
-- Register a new tile in map data
|
||||||
|
-- x: The x position in map coordinates
|
||||||
|
-- y: The y position in map coordinates
|
||||||
|
-- biome: The tile's biome id
|
||||||
|
-- height: The tile's height
|
||||||
|
-- (Optional): manual_scan: Indicates if this was a 'manual' (non-generated)
|
||||||
|
-- scan. Manual scans are overridden by generated
|
||||||
|
-- scans under normal circumstances.
|
||||||
|
local function register_tile(x, y, biome, height, manual_scan)
|
||||||
if not data.generated[x] then
|
if not data.generated[x] then
|
||||||
data.generated[x] = {
|
data.generated[x] = {
|
||||||
[y] = {
|
[y] = {
|
||||||
@ -8,11 +16,17 @@ local function register_mapchunk(x, y, biome, height)
|
|||||||
height = height,
|
height = height,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if manual_scan ~= nil then
|
||||||
|
data.generated[x][y].manual_scan = manual_scan;
|
||||||
|
end
|
||||||
elseif not data.generated[x][y] or data.generated[x][y].height < height then
|
elseif not data.generated[x][y] or data.generated[x][y].height < height then
|
||||||
data.generated[x][y] = {
|
data.generated[x][y] = {
|
||||||
biome = biome,
|
biome = biome,
|
||||||
height = height,
|
height = height,
|
||||||
};
|
};
|
||||||
|
if manual_scan ~= nil or data.generated[x][y].manual_scan then
|
||||||
|
data.generated[x][y].manual_scan = manual_scan;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -133,21 +147,39 @@ local function on_generated(min, max, blockseed)
|
|||||||
};
|
};
|
||||||
local biome, height = 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, height)
|
register_tile(i, j, biome, height)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Is the scan of this position already handled?
|
||||||
|
-- x: The x position, in map coordinates
|
||||||
|
-- y: The y position, in world coordinates
|
||||||
|
-- x: The z position, in map coordinates
|
||||||
|
--
|
||||||
|
-- Returns true if the position is handled by the current map data
|
||||||
|
local function is_scan_handled(x, y, z)
|
||||||
|
if not data.generated[x] then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
local tile = data.generated[x][z];
|
||||||
|
|
||||||
|
return tile and ((not tile.manual_scan and tile.height > 0) or tile.height >= y);
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Queue a tile for manual scanning
|
||||||
|
-- pos: The position as a table, in world coordinates
|
||||||
function cartographer.queue_region(pos)
|
function cartographer.queue_region(pos)
|
||||||
local converted = {
|
local converted = {
|
||||||
x = tochunk(pos.x) * CHUNK_SIZE,
|
x = fromchunk(tochunk(pos.x)),
|
||||||
y = tochunk(pos.y) * CHUNK_SIZE,
|
y = fromchunk(tochunk(pos.y)),
|
||||||
z = tochunk(pos.z) * CHUNK_SIZE,
|
z = fromchunk(tochunk(pos.z)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if data.generated[pos.x] ~= nil and data.generated[pos.x][pos.z] ~= nil then
|
if is_scan_handled(tochunk(pos.x), pos.y, tochunk(pos.z)) then
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -160,6 +192,7 @@ function cartographer.queue_region(pos)
|
|||||||
cartographer.scan_queue[#cartographer.scan_queue + 1] = converted;
|
cartographer.scan_queue[#cartographer.scan_queue + 1] = converted;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Scan the next tile on the queue, and remove it
|
||||||
function cartographer.scan_regions()
|
function cartographer.scan_regions()
|
||||||
local len = #cartographer.scan_queue;
|
local len = #cartographer.scan_queue;
|
||||||
|
|
||||||
@ -167,23 +200,24 @@ function cartographer.scan_regions()
|
|||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
local startpos = cartographer.scan_queue[len];
|
local startpos = cartographer.scan_queue[1];
|
||||||
local endpos = {
|
local endpos = {
|
||||||
x = startpos.x + CHUNK_SIZE,
|
x = startpos.x + CHUNK_SIZE,
|
||||||
y = startpos.y + CHUNK_SIZE,
|
y = startpos.y + CHUNK_SIZE,
|
||||||
z = startpos.z + CHUNK_SIZE,
|
z = startpos.z + CHUNK_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
if data.generated[startpos.x] ~= nil and data.generated[startpos.x][startpos.z] ~= nil then
|
if is_scan_handled(tochunk(startpos.x), startpos.y, tochunk(startpos.z)) then
|
||||||
|
table.remove(cartographer.scan_queue, 1);
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
local biome,height = get_biome(startpos, endpos);
|
local biome,height = get_biome(startpos, endpos);
|
||||||
if biome ~= nil then
|
if biome ~= nil then
|
||||||
register_mapchunk(startpos.x / CHUNK_SIZE, startpos.z / CHUNK_SIZE, biome, height)
|
register_tile(tochunk(startpos.x), tochunk(startpos.z), biome, height, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
cartographer.scan_queue[len] = nil;
|
table.remove(cartographer.scan_queue, 1);
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_generated(on_generated);
|
minetest.register_on_generated(on_generated);
|
||||||
|
Loading…
Reference in New Issue
Block a user