2020-12-05 20:03:01 -08:00
-- FORMSPECS
2020-12-06 20:10:41 -08:00
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 " )
2020-12-27 14:37:12 -08:00
local black = minetest.get_color_escape_sequence ( " #111111 " )
2020-12-06 20:10:41 -08:00
2020-12-05 20:03:01 -08:00
-- Guidebook formspec (with or without default)
function adv_core . guide_formspec ( name )
--Display Guide (scrollable formspec)
2020-12-06 20:10:41 -08:00
local formspec = {
" formspec_version[3] " ,
2020-12-20 20:30:29 -08:00
" size[9,11.5] " ,
2020-12-06 20:10:41 -08:00
" position[0.5,0.5] " ,
" anchor[0.5,0.5] " ,
" no_prepend[] " ,
" bgcolor[#EAD994FF;both;#00000080] " ,
2020-12-20 20:30:29 -08:00
" box[1.12,0.2;6.8,1.2;#00000030] " ,
" image[1.2,0.3;6.6,1;title.png] " ,
2020-12-22 17:55:03 -08:00
" hypertext[0.3,1.5;8.4,9.5;play; " ,
2020-12-20 20:30:29 -08:00
" <global halign=center color=#000 size=12 font=Regular> " ,
" ----------- Adventure Core is a discovery mod! ----------- \n " ,
2020-12-22 17:55:03 -08:00
" <global halign=center> " ,
2020-12-20 20:30:29 -08:00
" 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 " ,
2020-12-22 17:55:03 -08:00
" 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
2020-12-20 20:30:29 -08:00
" When you hear it, an element has just spawned near you! \n " ,
2020-12-22 17:55:03 -08:00
" 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 " ,
2020-12-20 20:30:29 -08:00
" 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
2020-12-22 18:13:22 -08:00
table.insert ( formspec , " craft a 'pouch'. \n " )
2020-12-20 20:30:29 -08:00
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 , " ] " )
2020-12-06 20:10:41 -08:00
return table.concat ( formspec , " " )
2020-12-05 20:03:01 -08:00
end
-- Pouch Formspec
function adv_core . pouch_formspec ( name )
-- Display Pouch
2020-12-06 20:10:41 -08:00
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 , " " )
2020-12-05 20:03:01 -08:00
end
-- Store Formspec, with search functionality
function adv_core . store_formspec ( name , page , search , selected )
2020-12-06 10:57:53 -08:00
--how to sort:
--https://stackoverflow.com/questions/17436947/how-to-iterate-through-table-in-lua
2020-12-20 20:30:29 -08:00
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
2020-12-07 20:41:27 -08:00
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
2020-12-27 14:37:12 -08:00
" 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 , " ] " ,
2020-12-07 20:41:27 -08:00
--Search Bar
2020-12-20 20:30:29 -08:00
" field[9.0,10;5,0.6;search;; " , search , " ] " ,
" field_close_on_enter[search;false] " ,
2020-12-16 18:53:26 -08:00
" 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
2020-12-20 20:30:29 -08:00
--hypertext element is set based on if search is used
" field[0,0;0,0;page;; " , page , " ] " ,
2020-12-22 17:55:03 -08:00
" field[0,0;0,0;selected;; " , selected , " ] " ,
2020-12-20 20:30:29 -08:00
" 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;] " ,
2020-12-16 18:53:26 -08:00
}
2020-12-20 20:30:29 -08:00
--Rows and Columns of Items
if num_objects > 0 then
2020-12-16 18:53:26 -08:00
local matched = { }
local unmatched = { }
if search ~= nil and search ~= " " then
--Separate
for object in pairs ( objectTable ) do
2020-12-20 20:30:29 -08:00
if string.find ( object , search ) ~= nil then
2020-12-16 18:53:26 -08:00
matched [ # matched + 1 ] = object
end
end
--Sort A-Z
table.sort ( matched ) ;
2020-12-20 20:30:29 -08:00
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 ] = " ; "
2020-12-22 17:55:03 -08:00
formspec [ # formspec + 1 ] = " get_item_ " .. adv_core.escape_for_formspec ( matched [ i ] )
2020-12-20 20:30:29 -08:00
formspec [ # formspec + 1 ] = " ;] "
formspec [ # formspec + 1 ] = " tooltip[ "
2020-12-22 17:55:03 -08:00
formspec [ # formspec + 1 ] = " get_item_ " .. adv_core.escape_for_formspec ( matched [ i ] )
2020-12-20 20:30:29 -08:00
formspec [ # formspec + 1 ] = " ; "
formspec [ # formspec + 1 ] = matched [ i ]
formspec [ # formspec + 1 ] = " ;#000;#FFF] "
2020-12-16 18:53:26 -08:00
end
else --Display Normally
2020-12-20 20:30:29 -08:00
--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
2020-12-16 18:53:26 -08:00
for object in pairs ( objectTable ) do
unmatched [ # unmatched + 1 ] = object
end
table.sort ( unmatched ) ;
2020-12-20 20:30:29 -08:00
--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
2020-12-16 18:53:26 -08:00
--Display Normal
2020-12-20 20:30:29 -08:00
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 ] = " ; "
2020-12-22 17:55:03 -08:00
formspec [ # formspec + 1 ] = " get_item_ " .. adv_core.escape_for_formspec ( unmatched [ i ] )
2020-12-20 20:30:29 -08:00
formspec [ # formspec + 1 ] = " ;] "
formspec [ # formspec + 1 ] = " tooltip[ "
2020-12-22 17:55:03 -08:00
formspec [ # formspec + 1 ] = " get_item_ " .. adv_core.escape_for_formspec ( unmatched [ i ] )
2020-12-20 20:30:29 -08:00
formspec [ # formspec + 1 ] = " ; "
formspec [ # formspec + 1 ] = unmatched [ i ]
formspec [ # formspec + 1 ] = " ;#000;#FFF] "
2020-12-16 18:53:26 -08:00
end
2020-12-20 20:30:29 -08:00
end
2020-12-16 18:53:26 -08:00
end
2020-12-20 20:30:29 -08:00
2020-12-16 18:53:26 -08:00
--Selected Item Display
2020-12-20 20:30:29 -08:00
if selected ~= nil and selected ~= " " then
--show item
2020-12-27 14:37:12 -08:00
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; "
2020-12-20 20:30:29 -08:00
formspec [ # formspec + 1 ] = selected
formspec [ # formspec + 1 ] = " ;;] "
--Show Costs
2020-12-27 14:37:12 -08:00
formspec [ # formspec + 1 ] = " hypertext[1.5,6.8;7,1;;<global halign=left size=16 font=regular color=#000> Fire: "
2020-12-20 20:30:29 -08:00
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 ] = " ] "
2020-12-16 18:53:26 -08:00
--Show "Create" button
2020-12-20 20:30:29 -08:00
if adv_core.player_can_afford_object ( name , selected ) then
2020-12-27 14:37:12 -08:00
formspec [ # formspec + 1 ] = " button[3,7.8;2,1.5;create;Create] "
2020-12-20 20:30:29 -08:00
else
2020-12-27 14:37:12 -08:00
formspec [ # formspec + 1 ] = " button[2,7.8;4,1.5;;Can't Afford] "
formspec [ # formspec + 1 ] = " box[2,7.8;4,1.5;#8008] "
2020-12-20 20:30:29 -08:00
end
2020-12-16 18:53:26 -08:00
end
2020-12-07 14:03:33 -08:00
-- 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.
2020-12-07 20:41:27 -08:00
return table.concat ( formspec , " " )
2020-12-05 20:03:01 -08:00
end
2020-12-22 17:55:03 -08:00
--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
2020-12-27 14:37:12 -08:00
minetest.sound_play ( " adv_core_success " , { to_player = player_name , gain = 0.3 } )
2020-12-22 17:55:03 -08:00
return true
end
2020-12-06 20:10:41 -08:00
-- formspec callbacks
2020-12-05 20:03:01 -08:00
minetest.register_on_player_receive_fields ( function ( player , formname , fields )
2020-12-06 20:10:41 -08:00
if formname ~= " adventure_core:store " and formname ~= " adventure_core:guidebook " then
2020-12-05 20:03:01 -08:00
return
end
2020-12-06 20:10:41 -08:00
if formname == " adventure_core:guidebook " then
2020-12-22 17:55:03 -08:00
local name = player : get_player_name ( )
2020-12-06 20:10:41 -08:00
if fields.play then
minetest.sound_play ( " adv_core_spawn_sound " , { to_player = name , gain = 0.8 } )
end
2020-12-20 20:30:29 -08:00
elseif formname == " adventure_core:store " then
if fields.quit then
return
end
2020-12-22 17:55:03 -08:00
--setup defaults/hidden fields
local name = player : get_player_name ( )
2020-12-20 20:30:29 -08:00
local search = fields.search or " "
2020-12-22 17:55:03 -08:00
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
2020-12-20 20:30:29 -08:00
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
2020-12-22 17:55:03 -08:00
for k , v in pairs ( fields ) do
if k : match ( " get_item_ " ) then
current_item = get_item ( k )
end
end
2020-12-20 20:30:29 -08:00
if fields.key_enter_field == " search " then
2020-12-22 17:55:03 -08:00
minetest.show_formspec ( name , " adventure_core:store " , adv_core.store_formspec ( name , page , search , current_item ) )
2020-12-20 20:30:29 -08:00
end
2020-12-22 17:55:03 -08:00
minetest.show_formspec ( name , " adventure_core:store " , adv_core.store_formspec ( name , page , search , current_item ) )
2020-12-06 20:10:41 -08:00
end
2020-12-22 17:55:03 -08:00
end )