338 lines
14 KiB
Lua
338 lines
14 KiB
Lua
-- 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;",
|
|
"<global halign=center color=#000 size=12 font=Regular>",
|
|
" ----------- Adventure Core is a discovery mod! ----------- \n",
|
|
"<global halign=center>",
|
|
"You are encourged to search far and wide in search of the\n",
|
|
"Four Elements: <style color=#F00> Fire </style><style color=#00F>Water </style>",
|
|
"<style color=#0F0>Earth </style><style color=#FF0>Air </style>\n",
|
|
"These elements are found more commonly the futher you wander,\n",
|
|
"dig, and climb from spawn, and you must be ready for: <action name=play><style color=#000 size=18>(This Sound)</style></action>-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.<img name=fire.png float=right width=32 height=32>\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, "<global halign=center>\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;;<global halign=left size=16 font=regular color=#F00> ", pouch.fire, "]",
|
|
"hypertext[0.38,5.3;1.5,1;;<global halign=left size=16 font=regular color=#00F> ", pouch.water, "]",
|
|
"hypertext[0.38,6.8;1.5,1;;<global halign=left size=16 font=regular color=#0F0> ", pouch.earth, "]",
|
|
"hypertext[0.38,8.1;1.5,1;;<global halign=left size=16 font=regular color=#FF0> ", 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;;<global halign=center size=20 font=normal color=#000> 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;;<global halign=center size=20 font=normal color=#000> 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;;<global halign=center size=18 color=#000>"
|
|
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;;<global halign=left size=16 font=regular color=#000> 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)
|