diff --git a/init.lua b/init.lua index 9b4655a..7044ec5 100644 --- a/init.lua +++ b/init.lua @@ -8,7 +8,6 @@ _cartographer = { CHUNK_SIZE = 16, biome_lookup = {}, - marker_count = 0, marker_lookup = {}, maps = minetest.deserialize(mod_storage:get_string("maps")) or {}, next_map_id = mod_storage:get_int("next_map_id"), diff --git a/items.lua b/items.lua index 935dece..1cad510 100644 --- a/items.lua +++ b/items.lua @@ -6,17 +6,21 @@ local player_maps = {}; -- player_x: The X position (in world coordinates) -- player_z: The Z position (in world coordinates) -- player_name: The name of the player to show to -local function show_map_id_formspec(id, player_x, player_z, player_name) +-- (Optional) marker_page: The current page that the marker editor is on +local function show_map_id_formspec(id, player_x, player_z, player_name, marker_page) cartographer.fill_local(id, player_x, player_z); - player_maps[player_name] = id; + player_maps[player_name] = { + id = id, + page = marker_page or 1, + }; local map = cartographer.get_map(id); player_x, player_z = cartographer.to_map_coordinates(map, player_x, player_z) local formspec = cartographer.get_map_formspec_map(data, map, player_x, player_z); - if _cartographer.marker_count > 0 then - formspec = formspec .. string.format("style_type[button,image_button;noclip=true;border=true] container[%f,0.5]", map.w * 0.25) -- TODO: Don't assume map.w * 0.25 - .. _cartographer.generate_marker_formspec(cartographer.get_marker(map, player_x, player_z), map.detail, cartographer.skin.marker_bg, cartographer.skin.marker_button) + if #_cartographer.marker_lookup > 0 then + formspec = formspec .. string.format("style_type[button,image_button,label;noclip=true] container[%f,0.5]", map.w * 0.25) -- TODO: Don't assume map.w * 0.25 + .. _cartographer.generate_marker_formspec(cartographer.get_marker(map, player_x, player_z), map.detail, marker_page or 1, cartographer.skin.marker_bg, cartographer.skin.marker_button) .. "container_end[]"; end minetest.show_formspec(player_name, "cartographer:map", formspec); @@ -67,20 +71,25 @@ end -- fields: A table containing the input minetest.register_on_player_receive_fields(function(player, name, fields) if name == "cartographer:map" then - local map = cartographer.get_map(player_maps[player:get_player_name()]); + local data = player_maps[player:get_player_name()]; + + local map = cartographer.get_map(data.id); if not map then return; end for k,v in pairs(fields) do local marker = k:match("marker%-(.+)"); - minetest.chat_send_all(k .. ": " .. tostring(marker)); + local pos = player:get_pos(); if marker or k == "clear_marker" then - local pos = player:get_pos(); local player_x, player_z = cartographer.to_map_coordinates(map, pos.x, pos.z); cartographer.set_marker(map, player_x, player_z, marker); - show_map_id_formspec(player_maps[player:get_player_name()], pos.x, pos.z, player:get_player_name()); + show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page); + elseif k == "prev_button" then + show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page - 1); + elseif k == "next_button" then + show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page + 1); elseif k == "quit" then player_maps[player:get_player_name()] = nil; end diff --git a/map_api.lua b/map_api.lua index 5ed2afa..26afb0c 100644 --- a/map_api.lua +++ b/map_api.lua @@ -162,30 +162,48 @@ local function format_marker_id(id) return id:gsub(":", "_"); end +-- Find the marker data for a given id +-- id: The id to search for +-- +-- Returns the marker data, or nil if not found +function cartographer.get_marker_data(id) + if not id then + return nil; + end + + id = format_marker_id(id); + for _,marker in pairs(_cartographer.marker_lookup) do + if marker.id == id then + return marker; + end + end + + return nil; +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 --- --- Returns the final id that the marker was registered under function cartographer.register_marker(id, name, textures) if not id then return nil; end id = format_marker_id(id); - if not _cartographer.marker_lookup[id] then - _cartographer.marker_count = _cartographer.marker_count + 1; + local existing_marker = cartographer.get_marker_data(id); + if existing_marker then + existing_marker.name = name; + existing_marker.textures = textures; + else + _cartographer.marker_lookup[#_cartographer.marker_lookup+1] = { + id = id, + name = name, + textures = textures, + }; end - - _cartographer.marker_lookup[id] = { - name = name, - textures = textures, - }; - - return id; end function cartographer.is_filled(map, x, z) @@ -222,7 +240,7 @@ function cartographer.get_marker_texture(id, detail) end id = format_marker_id(id); - local marker = _cartographer.marker_lookup[id]; + local marker = cartographer.get_marker_data(id); if marker then return marker.textures[math.min(detail, #marker.textures)]; diff --git a/marker_formspec.lua b/marker_formspec.lua index 975143a..b0c1910 100644 --- a/marker_formspec.lua +++ b/marker_formspec.lua @@ -2,11 +2,12 @@ -- selected_id: The id of the currently selected marker, or nil if no marker is -- selected -- detail: The map's detail level +-- page: The current page -- bg: A 9-slice background skin table -- button: A button skin table -- -- Returns a formspec string for use in containers -function _cartographer.generate_marker_formspec(selected_id, detail, bg, button) +function _cartographer.generate_marker_formspec(selected_id, detail, page, bg, button) local fs = string.format("background9[0,0;3.25,3.875;%s.png;false;%s]", bg.texture, tostring(bg.radius)) .. string.format("style_type[button,image_button;border=false;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png;bgimg_middle=%s;textcolor=%s]", button.texture, button.hovered_texture, button.pressed_texture, tostring(button.radius), button.font_color) .. "button[0.125,0.125;1.125,0.5;clear_marker;Erase]"; @@ -14,16 +15,24 @@ function _cartographer.generate_marker_formspec(selected_id, detail, bg, button) fs = fs .. string.format("style[marker-%s;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png]", selected_id, button.selected_texture, button.selected_texture, button.selected_texture); end - -- TODO: Support pagination if _cartographer.marker_count is too high - local i = 0; - for id in pairs(_cartographer.marker_lookup) do + local starting_id = ((page - 1) * 20) + 1; + for i = starting_id,math.min(#_cartographer.marker_lookup,starting_id + 19),1 do + local marker = _cartographer.marker_lookup[i]; fs = fs .. string.format("image_button[%f,%f;0.5,0.5;%s.png;marker-%s;]", - i % 5 * 0.625 + 0.125, - math.floor(i / 5) * 0.625 + 0.75, - cartographer.get_marker_texture(id, detail), - id); - - i = i + 1; + (i - starting_id) % 5 * 0.625 + 0.125, + math.floor((i - starting_id) / 5) * 0.625 + 0.75, + marker.textures[math.min(detail, #marker.textures)], + marker.id); end + + if page > 1 then + fs = fs .. "button[0.125,3.25;0.5,0.5;prev_button;<]"; + end + + if starting_id + 19 < #_cartographer.marker_lookup then + fs = fs .. "button[2.625,3.25;0.5,0.5;next_button;>]"; + end + + fs = fs .. string.format("label[1.375,3.5;%d / %d]", page, math.ceil(#_cartographer.marker_lookup / 20)); return fs; end