diff --git a/mods/mappointer/depends.txt b/mods/mappointer/depends.txt new file mode 100644 index 0000000..ae7337f --- /dev/null +++ b/mods/mappointer/depends.txt @@ -0,0 +1,2 @@ +default +signs_lib diff --git a/mods/mappointer/init.lua b/mods/mappointer/init.lua new file mode 100644 index 0000000..a27af7f --- /dev/null +++ b/mods/mappointer/init.lua @@ -0,0 +1,233 @@ +mappointer = {} +mappointer.points = {} +mappointer.count = 1 +local S = signs_lib.gettext +local MAX_INPUT_CHARS = 400 +local function trim_input(text) + return text:sub(1, math.min(MAX_INPUT_CHARS, text:len())) +end +local function make_infotext(text) + text = trim_input(text) + local lines = signs_lib.split_lines_and_words(text) or {} + local lines2 = { } + for _, line in ipairs(lines) do + table.insert(lines2, (table.concat(line, " "):gsub("#[0-9a-fA-F#^]", function (s) + return s:sub(2):find("[#^]") and s:sub(2) or "" + end))) + end + return table.concat(lines2, "\n") +end + +function mappointer.update_sign(pos, fields) + local meta = minetest.get_meta(pos) + + -- legacy udpate + if meta:get_string("formspec") ~= "" then + meta:set_string("formspec", "") + end + + local text = fields and fields.text or meta:get_string("text") + local poiType = fields and fields.poiType or meta:get_string("poiType") + text = trim_input(text) + + local owner = meta:get_string("owner") + local ownstr = "" + if owner ~= "" then ownstr = S("Locked sign, owned by @1\n", owner) end + + meta:set_string("text", text) + meta:set_string("infotext", ownstr..make_infotext(text).." ") + + local glow = meta:get_string("glow") + signs_lib.set_obj_text(pos, text, glow) + local found = false + for i, poi in pairs(mappointer.points) do + if poi['pos']['x'] == pos.x and + poi['pos']['y'] == pos.y and + poi['pos']['z'] == pos.z then + found = true + poi.text = text + poi.type = poiType + end + end + if found == false then + table.insert(mappointer.points, {pos=pos, text=text, type=poiType}) + end + mappointer.save_data() +end + +function mappointer.get_sign_formspec(pos, nodename) + + local meta = minetest.get_meta(pos) + local txt = meta:get_string("text") + local state = meta:get_int("unifont") == 1 and "on" or "off" + + local formspec = { + "size[6,4.8]", + "background[-0.5,-0.5;7,5;signs_lib_sign_bg.png]", + "image[0.1,3;7,1;signs_lib_sign_color_palette.png]", + "textarea[0.15,-0.2;6.3,2.8;text;;" .. minetest.formspec_escape(txt) .. "]", + "dropdown[0.1,2.2;6.1,0;poiType;Building,Travelnet,Point of Interest,Other;1]", + "button_exit[3.7,4.2;2,1;ok;" .. S("Write") .. "]", + "label[0.3,4;Unicode font]", + "image_button[0.6,4.3;1,0.6;signs_lib_switch_" .. state .. ".png;uni_" + .. state .. ";;;false;signs_lib_switch_interm.png]", + } + + if minetest.registered_nodes[nodename].allow_widefont then + state = meta:get_int("widefont") == 1 and "on" or "off" + formspec[#formspec+1] = "label[2.1,4;Wide font]" + formspec[#formspec+1] = "image_button[2.3,4.3;1,0.6;signs_lib_switch_" .. state .. ".png;wide_" + .. state .. ";;;false;signs_lib_switch_interm.png]" + end + + return table.concat(formspec, "") +end + +function mappointer.rightclick_sign(pos, node, player, itemstack, pointed_thing) + + if not player or not signs_lib.can_modify(pos, player) then return end + + player:get_meta():set_string("signslib:pos", minetest.pos_to_string(pos)) + minetest.log("test open formspec") + minetest.show_formspec(player:get_player_name(), "mappointer:poi", mappointer.get_sign_formspec(pos, node.name)) + minetest.log("test close formspec") +end + +mappointer.save_data = function() + local data = minetest.write_json(mappointer.points); + local path = minetest.get_worldpath().."/mod_poi.data"; + + local file = io.open( path, "w" ); + if( file ) then + file:write( data ); + file:close(); + else + print("[Mod mappointer] Error: Savefile '"..tostring( path ).."' could not be written."); + end +end + +mappointer.restore_data = function() + local path = minetest.get_worldpath().."/mod_poi.data"; + local file = io.open( path, "r" ); + if(file) then + local data = file:read("*all"); + mappointer.points = minetest.parse_json(data); + file:close(); + if mappointer.points == nil then mappointer.points = {} end + for _ in pairs(mappointer.points) do mappointer.count = mappointer.count + 1 end + else + print("[Mod mappointer] Error: Read file '"..tostring( path ).."': not found."); + end +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname ~= "mappointer:poi" then return end + + local pos_string = player:get_meta():get_string("signslib:pos") + local pos = minetest.string_to_pos(pos_string) + local playername = player:get_player_name() + + if fields.text and fields.ok then + minetest.log("action", S("@1 wrote \"@2\" to sign at @3 of type @4", + (playername or ""), + fields.text:gsub('\\', '\\\\'):gsub("\n", "\\n"), + pos_string, + fields.poiType + )) + mappointer.update_sign(pos, fields) + elseif fields.wide_on or fields.wide_off or fields.uni_on or fields.uni_off then + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local change_wide + local change_uni + + if fields.wide_on and meta:get_int("widefont") == 1 then + meta:set_int("widefont", 0) + change_wide = true + elseif fields.wide_off and meta:get_int("widefont") == 0 then + meta:set_int("widefont", 1) + change_wide = true + end + if fields.uni_on and meta:get_int("unifont") == 1 then + meta:set_int("unifont", 0) + change_uni = true + elseif fields.uni_off and meta:get_int("unifont") == 0 then + meta:set_int("unifont", 1) + change_uni = true + end + + if change_wide then + minetest.log("action", S("@1 flipped the wide-font switch to \"@2\" at @3", + (playername or ""), + (fields.wide_on and "off" or "on"), + minetest.pos_to_string(pos) + )) + mappointer.update_sign(pos, fields) + minetest.show_formspec(playername, "mappointer:poi", mappointer.get_sign_formspec(pos, node.name)) + end + if change_uni then + minetest.log("action", S("@1 flipped the unicode-font switch to \"@2\" at @3", + (playername or ""), + (fields.uni_on and "off" or "on"), + minetest.pos_to_string(pos) + )) + mappointer.update_sign(pos, fields) + minetest.show_formspec(playername, "mappointer:poi", mappointer.get_sign_formspec(pos, node.name)) + end + end +end) + +function mappointer.destruct_sign(pos) + local meta = minetest.get_meta(pos) + local glow = meta:get_string("glow") + if glow ~= "" and not minetest.is_creative_enabled("") then + local num = tonumber(glow) + minetest.add_item(pos, ItemStack(signs_lib.glow_item .. " " .. num)) + end + signs_lib.delete_objects(pos) + for i, poi in pairs(mappointer.points) do + minetest.log("about to remove "..i) + if poi['pos']['x'] == pos.x and + poi['pos']['y'] == pos.y and + poi['pos']['z'] == pos.z then + minetest.log("removed poi") + table.remove(mappointer.points, i) + end + end + mappointer.save_data() +end + +signs_lib.register_sign("mappointer:point_of_interest", { + description = "Sign for POI", + inventory_image = "signs_lib_sign_wall_steel_inv.png", + tiles = { + "signs_lib_sign_wall_steel.png", + "signs_lib_sign_wall_steel_edges.png", + nil, -- not set, so it'll use the standard pole mount texture + nil, -- not set, so it'll use the standard hanging chains texture + "default_steel_block.png" -- for the yard sign's stick + }, + groups = signs_lib.standard_steel_groups, + sounds = signs_lib.standard_steel_sign_sounds, + locked = true, + entity_info = "standard", + allow_hanging = true, + allow_widefont = true, + allow_onpole = true, + allow_onpole_horizontal = true, + allow_yard = true, + use_texture_alpha = "clip", + on_punch = mappointer.update_sign, + on_rightclick = mappointer.rightclick_sign, + on_destruct = mappointer.destruct_sign, +}) + +minetest.register_craft({ + output = 'mappointer:point_of_interest', + recipe = { + {'default:sign_wall_steel', 'default:book'}, + } +}) + +mappointer.restore_data()