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