-- FORMSPECS local red = minetest.get_color_escape_sequence("red") local blue = minetest.get_color_escape_sequence("blue") local green = minetest.get_color_escape_sequence("green") local yellow = minetest.get_color_escape_sequence("yellow") local black = minetest.get_color_escape_sequence("#111111") -- Guidebook formspec (with or without default) function adv_core.guide_formspec(name) --Display Guide (scrollable formspec) local formspec = { "formspec_version[3]", "size[9,11.5]", "position[0.5,0.5]", "anchor[0.5,0.5]", "no_prepend[]", "bgcolor[#EAD994FF;both;#00000080]", "box[1.12,0.2;6.8,1.2;#00000030]", "image[1.2,0.3;6.6,1;title.png]", "hypertext[0.3,1.5;8.4,9.5;play;", "", " ----------- Adventure Core is a discovery mod! ----------- \n", "", "You are encourged to search far and wide in search of the\n", "Four Elements: ", "\n", "These elements are found more commonly the futher you wander,\n", "dig, and climb from spawn, and you must be ready for: -Clickme\n", --This sound "When you hear it, an element has just spawned near you!\n", "Look for something like the image on the right glowing and floating above the terrain.\n", "Click/Punch to capture it, and you have collected a piece of element!\n", "To view how much you have collected ", } --optional display based on settings, very handy if adv_core.setting("enable_chat_commands",true) then table.insert(formspec, "type '/pouch' in chat, or\n") end table.insert(formspec, "craft a 'pouch'.\n") table.insert(formspec, "\n There is also a Adventure shop!\n") if adv_core.setting("enable_adventure_shop",true) then if adv_core.setting("enable_chat_commands",true) then table.insert(formspec, "You can craft this shop, or use the '/shop' command.\n") else table.insert(formspec, "You can craft this shop and place it in the world.\n") end else if adv_core.setting("enable_chat_commands",true) then table.insert(formspec, "You can use the '/shop' command to access it.\n") else table.insert(formspec, "You will have to search the map for these special places.\n") end end table.insert(formspec, "There, you can buy unique objects and items.\n\n") if(minetest.get_modpath("default")) ~= nil and adv_core.setting("enable_spawn_biome", true) then table.insert(formspec, "Hint: Elements will spawn according to what biome you are in.\n\n") end table.insert(formspec, "------------- Happy Adventuring! -------------") table.insert(formspec, "]") return table.concat(formspec, "") end -- Pouch Formspec function adv_core.pouch_formspec(name) -- Display Pouch local pouch = adv_core.load_pouch(name) local formspec = { "formspec_version[3]", "size[6,6]", "position[0.5,0.6]", "anchor[0.5,0.5]", "no_prepend[]", "bgcolor[#00000000;both;#00000080]", "background[0,0;6,6;pouch.png]", "image[0.8,0.4;2,2;fire.png]", "label[1.4,2.5;", red, "Fire: " , pouch.fire , "]", "image[3.14,0.4;2,2;water.png]", "label[3.67,2.5;", blue, "Water: ", pouch.water, "]", "image[0.8,2.9;2,2;earth.png]", "label[1.3,5;", green, "Earth: ", pouch.earth, "]", "image[3.11,2.9;2,2;air.png]", "label[3.82,5;", yellow,"Air: " , pouch.air , "]", } return table.concat(formspec, "") end -- Store Formspec, with search functionality function adv_core.store_formspec(name, page, search, selected) --how to sort: --https://stackoverflow.com/questions/17436947/how-to-iterate-through-table-in-lua page = tonumber(page) search = tostring(search) selected = tostring(selected) local objectTable = adv_core.objectTable local num_objects = adv_core.num_objects local num_pages = math.floor(num_objects / 64)+1 local pouch = adv_core.load_pouch(name) if page > num_pages then page = num_pages end local formspec = { "formspec_version[3]", "size[16,12]", "position[0.5,0.5]", "anchor[0.5,0.5]", "no_prepend[]", --background "bgcolor[#866f4c;both;#00000080]", "box[0.2,0.2;15.6,11.6;#dec29cFF]", --pouch "box[0.3,2.4;0.7,6.6;#564222FF]", "image[0.42,2.6;0.4,0.4;pouch.png]", "image[0.38,3.2;0.5,0.5;fire.png]", "image[0.38,4.6;0.5,0.5;water.png]", "image[0.38,6.0;0.5,0.5;earth.png]", "image[0.38,7.4;0.5,0.5;air.png]", "hypertext[0.38,3.9;1.5,1;; ", pouch.fire, "]", "hypertext[0.38,5.3;1.5,1;; ", pouch.water, "]", "hypertext[0.38,6.8;1.5,1;; ", pouch.earth, "]", "hypertext[0.38,8.1;1.5,1;; ", pouch.air, "]", --Search Bar "field[9.0,10;5,0.6;search;;",search,"]", "field_close_on_enter[search;false]", "image_button[14.1,10;0.6,0.6;search.png;do_search;]", "image_button[14.8,10;0.6,0.6;clear.png;reset_search;]", --Paging --hypertext element is set based on if search is used "field[0,0;0,0;page;;",page,"]", "field[0,0;0,0;selected;;",selected,"]", "image_button[11.3,0.5;0.6,0.6;prev.png;previous_page;]", "image_button[12.3,0.5;0.6,0.6;next.png;next_page;]", } --Rows and Columns of Items if num_objects > 0 then local matched = {} local unmatched = {} if search ~= nil and search ~= "" then --Separate for object in pairs(objectTable) do if string.find(object, search) ~= nil then matched[#matched+1] = object end end --Sort A-Z table.sort(matched); num_pages = math.floor(#matched/64+1) if page > num_pages then page = num_pages end --add hypertext element: formspec[#formspec+1] = "hypertext[8,1.1;8,1;; Page " formspec[#formspec+1] = page formspec[#formspec+1] = " of " formspec[#formspec+1] = num_pages formspec[#formspec+1] = "]" for i = (page-1)*64+1, math.min(page*64,#matched) do local index = i - (page-1)*64-1 --index is for finding row-column local row = math.floor(index / 8) local column = index - row*8 formspec[#formspec+1] = "item_image_button[" formspec[#formspec+1] = column*0.95+8.1 formspec[#formspec+1] = "," formspec[#formspec+1] = row*0.95+2 formspec[#formspec+1] = ";0.9,0.9;" formspec[#formspec+1] = matched[i] formspec[#formspec+1] = ";" formspec[#formspec+1] = "get_item_"..adv_core.escape_for_formspec(matched[i]) formspec[#formspec+1] = ";]" formspec[#formspec+1] = "tooltip[" formspec[#formspec+1] = "get_item_"..adv_core.escape_for_formspec(matched[i]) formspec[#formspec+1] = ";" formspec[#formspec+1] = matched[i] formspec[#formspec+1] = ";#000;#FFF]" end else --Display Normally --Show number of pages formspec[#formspec+1] = "hypertext[8,1.1;8,1;; Page " formspec[#formspec+1] = page formspec[#formspec+1] = " of " formspec[#formspec+1] = num_pages formspec[#formspec+1] = "]" --sort A-Z for object in pairs(objectTable) do unmatched[#unmatched+1] = object end table.sort(unmatched); --Display current page for i = (page-1)*64+1, math.min(page*64,#unmatched) do local index = i - (page-1)*64-1 --index is for finding row-column --minetest.chat_send_all(index) local row = math.floor(index / 8) local column = index - row*8 --Display Normal formspec[#formspec+1] = "item_image_button[" formspec[#formspec+1] = column*0.95+8.1 formspec[#formspec+1] = "," formspec[#formspec+1] = row*0.95+2 formspec[#formspec+1] = ";0.9,0.9;" formspec[#formspec+1] = unmatched[i] formspec[#formspec+1] = ";" formspec[#formspec+1] = "get_item_".. adv_core.escape_for_formspec(unmatched[i]) formspec[#formspec+1] = ";]" formspec[#formspec+1] = "tooltip[" formspec[#formspec+1] = "get_item_".. adv_core.escape_for_formspec(unmatched[i]) formspec[#formspec+1] = ";" formspec[#formspec+1] = unmatched[i] formspec[#formspec+1] = ";#000;#FFF]" end end end --Selected Item Display if selected ~= nil and selected ~= "" then --show item formspec[#formspec+1] = "hypertext[1.5,1.8;5,1;;" formspec[#formspec+1] = minetest.registered_nodes[selected].description or selected formspec[#formspec+1] = "]" formspec[#formspec+1] = "item_image_button[2,2.8;4,4;" formspec[#formspec+1] = selected formspec[#formspec+1] = ";;]" --Show Costs formspec[#formspec+1] = "hypertext[1.5,6.8;7,1;; Fire: " formspec[#formspec+1] = objectTable[selected].fire formspec[#formspec+1] = " Water: " formspec[#formspec+1] = objectTable[selected].water formspec[#formspec+1] = " Earth: " formspec[#formspec+1] = objectTable[selected].earth formspec[#formspec+1] = " Air: " formspec[#formspec+1] = objectTable[selected].air formspec[#formspec+1] = "]" --Show "Create" button if adv_core.player_can_afford_object(name, selected) then formspec[#formspec+1] = "button[3,7.8;2,1.5;create;Create]" else formspec[#formspec+1] = "button[2,7.8;4,1.5;;Can't Afford]" formspec[#formspec+1] = "box[2,7.8;4,1.5;#8008]" end end -- Number of pages is always the same, search function will separate them into -- a group of matched and the rest in unmatched. -- Then it will display *both* sets in alphabetical order, matching first. -- Matching are displayed with a light-blue background box around them. return table.concat(formspec, "") end --For pattern matching local function get_item(str) local lstr = string.sub(str,10) --remove any extraneous characters return adv_core.remove_formspec_escapes(lstr) --remove "get_item_" end -- for give command local function give(player_name, item) local itemstack = ItemStack(item) if itemstack:is_empty() then return false elseif (not itemstack:is_known()) or (itemstack:get_name() == "unknown") then return false -- "Cannot give an unknown item" -- Forbid giving 'ignore' due to unwanted side effects elseif itemstack:get_name() == "ignore" then return false -- "Giving 'ignore' is not allowed" end local playerref = minetest.get_player_by_name(player_name) --Give to Player local leftover = playerref:get_inventory():add_item("main", itemstack) if not leftover:is_empty() then return false end --take from player local object = adv_core.objectTable[item] adv_core.take_from_player(player_name, object.fire, object.water, object.earth, object.air, false) --play successful sound minetest.sound_play("adv_core_success", { to_player = player_name, gain = 0.3 }) return true end -- formspec callbacks minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= "adventure_core:store" and formname ~= "adventure_core:guidebook" then return end if formname == "adventure_core:guidebook" then local name = player:get_player_name() if fields.play then minetest.sound_play("adv_core_spawn_sound", {to_player = name, gain=0.8}) end elseif formname == "adventure_core:store" then if fields.quit then return end --setup defaults/hidden fields local name = player:get_player_name() local search = fields.search or "" local page = fields.page or 1 local current_item = fields.selected or "" --Process "purchases" before changing the selected item if fields.create then if adv_core.player_can_afford_object(name, current_item) then if give(name, current_item) then else minetest.chat_send_player(name, minetest.colorize(#C11, "AdventureCoreShop: Unable to create that item")) end end end if fields.reset_search then search = "" elseif fields.next_page then page = page+1 elseif fields.previous_page then page = page-1 page = math.max(1, page) end for k, v in pairs(fields) do if k:match("get_item_") then current_item = get_item(k) end end if fields.key_enter_field == "search" then minetest.show_formspec(name, "adventure_core:store", adv_core.store_formspec(name, page, search, current_item)) end minetest.show_formspec(name, "adventure_core:store", adv_core.store_formspec(name, page, search, current_item)) end end)