random_snippets/map_loaded_chunks.lua

191 lines
5.1 KiB
Lua

if not whosit then
print("define `whosit` global first")
--return
end
whosit = whosit or {} -- this will become snippet's "global" if not defined as a real one
local chunk_map = whosit.chunk_map or {}
whosit.chunk_map = chunk_map
local jobs = chunk_map.jobs or {}
chunk_map.jobs = jobs
local FORMNAME = "whosit:chunk_map"
chunk_map._contexts = chunk_map._contexts or {}
local function get_context(player_name, create_new)
local context = chunk_map._contexts[player_name] or (create_new and {})
if context then
chunk_map._contexts[player_name] = context
context.player_name = player_name
end
return context
end
local function round_to_mapblock(pos)
return vector.apply(pos/16, math.floor) * 16
end
local function is_pos_emerged(pos)
core.load_area(pos,pos)
local node = core.get_node(pos)
if node and node.name ~= 'ignore' then
return true
end
return false
end
chunk_map.show_map = function(playername, pos)
if type(playername) ~= "string" or (not vector.check(pos)) then
return
end
local context = get_context(playername, true)
context.pos = pos or context.pos
if not pos then
return
end
local map_display_width = 11
local map_display_height = 10
local map_display_cell_size = 0.5
local formspec = [[
formspec_version[6]
size[16,10]
box[0.1,0.1;13.0,10.0;grey]
button[13.9,0.8;0.8,0.8;north;N]
button[14.8,1.7;0.8,0.8;east;E]
button[13.9,2.6;0.8,0.8;south;S]
button[13,1.7;0.8,0.8;west;W]
button[12.9,0.7;0.8,0.8;down;D]
button[14.9,0.7;0.8,0.8;up;U]
box[0.2,0.2;0.5,0.5;yellow]
]]
local cells = {}
local template = string.format("box[%%s,%%s;%s,%s;%%s]", map_display_cell_size, map_display_cell_size)
local center = pos
local map_display_width_blocks = map_display_width/map_display_cell_size
local map_display_height_blocks = map_display_height/map_display_cell_size
local top_left_x = pos.x - (map_display_width_blocks*16/2)
local top_left_z = pos.z - (map_display_height_blocks*16/2)
local query_pos = vector.new(top_left_x, pos.y, top_left_z)
for idx_x = 0, map_display_width_blocks do
for idx_z = 0, map_display_height_blocks do
local emerged = is_pos_emerged(query_pos)
table.insert(cells, string.format(template,
idx_x * map_display_cell_size,
idx_z * map_display_cell_size,
emerged and "blue" or "white"))
query_pos.z = query_pos.z + 16
end
query_pos.x = query_pos.x + 16
end
table.insert(cells, string.format("label[13.1,4;%s]", dump(pos)))
core.show_formspec(playername, FORMNAME, formspec .. table.concat(cells,''))
end
chunk_map.map_on_player_receive_fields = function(playername, formname, fields)
if formname ~= FORMNAME then
return
end
local context = get_context(playername, false)
if not context or not context.pos then
return
end
if fields.quit then
return
end
local pos = context.pos
if fields.north then
pos.z = pos.z + 16
elseif fields.south then
pos.z = pos.z - 16
elseif fields.east then
pos.x = pos.x + 16
elseif fields.west then
pos.x = pos.x - 16
elseif fields.up then
-- FIXME use 16 here
pos.y = pos.y + 1
elseif fields.down then
-- FIXME use 16 here
pos.y = pos.y - 1
end
chunk_map.show_map(playername, pos)
end
chunk_map.step_jobs = function(dtime)
--print(dtime)
local jobs = chunk_map.jobs
for i=#jobs,1,-1 do
local job = jobs[i]
if job.coro and coroutine.status(job.coro) == "supended" then
coroutine.resume(job.coro)
else
print(string.format("job %s done", job))
jobs[i] = nil
end
end
end
chunk_map.cmd_show_map = function(playername, params)
local params = params:split(" ")
local x,y,z = table.unpack(params)
x,y,z = tonumber(x), tonumber(y), tonumber(z)
local pos
if (type(x) == "number" and type(y) == "number" and type(z) == "number") then
pos = vector.new(x,y,z)
else
local context = get_context(playername)
pos = context and context.pos
end
if not pos then
return false, "please provide x y z"
end
chunk_map.show_map(playername, pos)
end
if not chunk_map.callbacks_registered then
core.register_on_player_receive_fields(
chunk_map.map_on_player_receive_fields
)
core.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
chunk_map._contexts[player_name] = nil
end)
-- core.register_globalstep(function(dtime)
-- chunk_map.step_jobs(dtime)
-- end)
core.register_chatcommand("whosit_chunk_map",
{
func = chunk_map.cmd_show_map,
}
)
chunk_map.callbacks_registered = true
end