2021-06-08 23:56:55 +02:00
2022-01-04 01:30:33 +01:00
-- helper function; get a formspec with the inventory of the player (for selecting items)
yl_speak_up.fs_your_inventory_select_item = function ( pname , data )
return " label[0.2,4.2;Name of the item(stack):] " ..
" field[4.0,4.0;16.0,0.6;inv_stack_name;; " .. ( data.inv_stack_name or " " ) .. " ] " ..
" tooltip[inv_stack_name;Enter name of the block and amount. \n " ..
" Example: \" default:apple 3 \" for three apples, \n " ..
" \" farming:bread \" for a bread.] " ..
" label[0.2,5.7;Or put the item in here \n and click on \" Update \" :] " ..
" button[5.5,5.5;1.5,0.9;store_item_name;Update] " ..
" list[detached:yl_speak_up_player_ " .. pname .. " ;npc_wants;4.0,5.5;1,1;] " ..
" label[8,4.9;Your inventory:] " ..
" list[current_player;main;8,5.3;8,4;] "
end
2021-12-26 02:35:18 +01:00
-- helper function: get the names of the inventory lists of the node at position
-- pos on the map and return the index of search_for_list_name in that index
yl_speak_up.get_node_inv_lists = function ( pos , search_for_list_name )
if ( not ( pos ) ) then
return { inv_lists = { " - no inventory - " } , index = " 1 " }
end
local meta = minetest.get_meta ( pos )
if ( not ( meta ) ) then
return { inv_lists = { " - no inventory - " } , index = " 1 " }
end
local inv_lists = { }
2021-12-27 21:12:05 +01:00
local index = - 1
2021-12-26 02:35:18 +01:00
local inv = meta : get_inventory ( )
table.insert ( inv_lists , minetest.formspec_escape ( " - please select - " ) )
for k , v in pairs ( inv : get_lists ( ) ) do
table.insert ( inv_lists , k )
if ( search_for_list_name == k ) then
index = # inv_lists
end
end
return { inv_lists = inv_lists , index = tostring ( index ) }
end
2021-06-10 18:06:21 +02:00
-- evaluate those preconditions of type "function" (set by the staff)
-- and execute those effects/results of type "function" (set by the staff)
-- WARNING: This is extremly powerful!
-- The code is taken out of the function
-- calculate_displayable_options(..)
-- (written by AliasAlreadyTaken).
-- It requires the npc_master priv to add or edit this prereq.
-- The function is called by
-- * yl_speak_up.eval_precondition and
-- * yl_speak_up.eval_effect.
yl_speak_up.eval_and_execute_function = function ( player , x_v , id_prefix )
local pname = player : get_player_name ( )
--minetest.chat_send_all("this is in a single prereq or effect: "..dump(x_v))
local x_id = x_v [ id_prefix .. " id " ]
if x_v [ id_prefix .. " type " ] ~= " function " then
return true
end
local code = x_v [ id_prefix .. " value " ]
if code : byte ( 1 ) == 27 then
local obj = yl_speak_up.speak_to [ pname ] . obj
local n_id = yl_speak_up.speak_to [ pname ] . n_id
2021-06-21 18:22:37 +02:00
local npc = yl_speak_up.get_number_from_id ( n_id )
2021-06-10 18:06:21 +02:00
if obj : get_luaentity ( ) and tonumber ( npc ) then
minetest.log ( " error " , " [MOD] yl_speak_up: NPC with ID n_ " .. npc .. " at position " .. minetest.pos_to_string ( obj : get_pos ( ) , 0 ) .. " could not compile the content of " .. x_id .. " : " .. dump ( code ) .. " because of illegal bytecode for player " .. pname )
else
minetest.log ( " error " , " [MOD] yl_speak_up: NPC with ID unknown could not compile the content of " .. x_id .. " : " .. dump ( code ) .. " for player unknown because of illegal bytecode " )
end
end
local param = " playername "
if ( id_prefix == " r_ " ) then
param = " player "
end
local f , msg = loadstring ( " return function( " .. param .. " ) " .. code .. " end " )
if not f then
local obj = yl_speak_up.speak_to [ pname ] . obj
local n_id = yl_speak_up.speak_to [ pname ] . n_id
2021-06-21 18:22:37 +02:00
local npc = yl_speak_up.get_number_from_id ( n_id )
2021-06-10 18:06:21 +02:00
if obj : get_luaentity ( ) and tonumber ( npc ) then
minetest.log ( " error " , " [MOD] yl_speak_up: NPC with ID n_ " .. npc .. " at position " .. minetest.pos_to_string ( obj : get_pos ( ) , 0 ) .. " could not compile the content of " .. x_id .. " : " .. dump ( code ) .. " for player " .. pname )
else
minetest.log ( " error " , " [MOD] yl_speak_up: NPC with ID unknown could not compile the content of " .. x_id .. " : " .. dump ( code ) .. " for player unknown " )
end
else
local func = f ( )
local ok , ret = pcall ( func , pname )
if not ok then
local obj = yl_speak_up.speak_to [ pname ] . obj
local n_id = yl_speak_up.speak_to [ pname ] . n_id
2021-06-21 18:22:37 +02:00
local npc = yl_speak_up.get_number_from_id ( n_id )
2021-06-10 18:06:21 +02:00
if obj : get_luaentity ( ) and tonumber ( npc ) then
minetest.log ( " error " , " [MOD] yl_speak_up: NPC with ID n_ " .. npc .. " at position " .. minetest.pos_to_string ( obj : get_pos ( ) , 0 ) .. " could not execute the content of " .. x_id .. " : " .. dump ( code ) .. " for player " .. pname )
else
minetest.log ( " error " , " [MOD] yl_speak_up: NPC with ID unknown could not execute the content of " .. x_id .. " : " .. dump ( code ) .. " for player unknown " )
end
end
if type ( ret ) == " boolean " then
return ret
end
end
-- fallback
return false
end
2021-06-09 21:49:29 +02:00
2021-07-02 18:58:37 +02:00
-- helper function for yl_speak_up.input_fs_edit_option_related
yl_speak_up.delete_element_p_or_a_or_e = function (
player , pname , n_id , d_id , o_id , x_id , id_prefix ,
element_list_name , element_desc , formspec_input_to )
-- does the dialog we want to modify exist?
local dialog = yl_speak_up.speak_to [ pname ] . dialog
if ( not ( dialog and dialog.n_dialogs
and x_id
and dialog.n_dialogs [ d_id ]
and dialog.n_dialogs [ d_id ] . d_options
and dialog.n_dialogs [ d_id ] . d_options [ o_id ] ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;The dialog that is supposed to contain the \n " ..
" element that you want to delete does not exist.] " ..
" button[1.5,1.5;2,0.9;back_from_cannot_be_edited;Back] " } )
return
end
local old_elem = dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] [ x_id ]
if ( id_prefix == " r_ " and old_elem and old_elem.r_type == " dialog " ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Effects of the type \" dialog \" cannot be deleted. \n " ..
" Use the edit options or dialog menu to change the target dialog.] " ..
" button[1.5,1.5;2,0.9;back_from_cannot_be_edited;Back] " } )
return
end
-- actually delete the element
dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] [ x_id ] = nil
-- record this as a change, but do not save do disk yet
table.insert ( yl_speak_up.npc_was_changed [ n_id ] ,
" Dialog " .. tostring ( d_id ) .. " : " .. element_desc .. " " .. tostring ( x_id ) ..
" deleted for option " .. tostring ( o_id ) .. " . " )
-- TODO: when trying to save: save to disk as well?
-- show the new/changed element
-- go back to the edit option dialog (after all we just deleted the prerequirement)
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[6,2] " ..
" label[0.2,0.5; " .. element_desc .. " \" " ..
minetest.formspec_escape ( tostring ( x_id ) ) ..
" \" has been deleted.] " ..
" button[1.5,1.5;2,0.9;back_from_delete_element;Back] " } )
return
end
2021-07-02 20:58:35 +02:00
-- helper function for yl_speak_up.input_fs_edit_option_related
yl_speak_up.save_element_p_or_a_or_e = function (
player , pname , n_id , d_id , o_id , x_id , id_prefix , tmp_data_cache ,
element_list_name , element_desc , max_entries_allowed ,
values_what , values_operator , values_block , values_trade , values_inv ,
formspec_input_to , data , fields )
-- for creating the new prerequirement; normal elements: p_type, p_value, p_id
local v = { }
-- determine p_type
v [ id_prefix .. " type " ] = values_what [ data.what ]
2021-09-03 21:14:47 +02:00
-- so that we don't have to compare number values of data.what
local what_type = values_what [ data.what ]
2021-07-02 20:58:35 +02:00
local dialog = yl_speak_up.speak_to [ pname ] . dialog
if ( not ( dialog ) or not ( dialog.n_dialogs )
or not ( dialog.n_dialogs [ d_id ] )
or not ( dialog.n_dialogs [ d_id ] . d_options )
or not ( dialog.n_dialogs [ d_id ] . d_options [ o_id ] ) ) then
-- this really should not happen during the normal course of operation
-- (only if the player sends forged formspec data or a bug occoured)
minetest.chat_send_player ( pname , " Dialog or option does not exist. " )
return
end
local elements = dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ]
if ( not ( elements ) ) then
dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] = { }
elements = dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ]
x_id = " new "
end
-- set x_id appropriately
if ( not ( x_id ) or x_id == " new " ) then
x_id = id_prefix .. yl_speak_up.find_next_id ( elements )
end
v [ id_prefix .. " id " ] = x_id
-- if needed: show a message after successful save so that the player can take
-- his items back from the trade_inv slots
local show_save_msg = nil
local sorted_key_list = yl_speak_up.sort_keys ( elements )
if ( x_id == " new " and # sorted_key_list >= max_entries_allowed ) then
-- this really should not happen during the normal course of operation
-- (only if the player sends forged formspec data or a bug occoured)
minetest.chat_send_player ( pname , " Maximum number of allowed entries exceeded. " )
return
end
-- "an internal state (i.e. of a quest)", -- 2
2021-09-03 21:14:47 +02:00
if ( what_type == " state " and id_prefix ~= " a_ " ) then
2021-07-02 20:58:35 +02:00
v [ id_prefix .. " value " ] = " expression "
v [ id_prefix .. " operator " ] = values_operator [ data.operator ]
v [ id_prefix .. " var_cmp_value " ] = ( data.var_cmp_value or " " )
2022-01-17 03:07:45 +01:00
-- if it is a custom server function,then do not preifx it with $ playername
if ( id_prefix == " p_ " ) then
local idx = table.indexof ( yl_speak_up.custom_server_functions . precondition_descriptions ,
data.variable_name )
if ( idx > - 1 ) then
v [ id_prefix .. " variable " ] = data.variable_name
else
v [ id_prefix .. " variable " ] = yl_speak_up.add_pname_to_var ( data.variable_name , pname )
end
else
v [ id_prefix .. " variable " ] = yl_speak_up.add_pname_to_var ( data.variable_name , pname )
end
2021-07-02 20:58:35 +02:00
2022-06-19 02:49:25 +02:00
-- "the value of a property of the NPC (for generic NPC)"
elseif ( what_type == " property " and id_prefix ~= " a_ " ) then
v [ id_prefix .. " value " ] = ( data.property or " " )
v [ id_prefix .. " operator " ] = values_operator [ data.operator ]
v [ id_prefix .. " var_cmp_value " ] = ( data.var_cmp_value or " " )
-- "something that has to be calculated or evaluated (=call a function)"
elseif ( what_type == " evaluate " and id_prefix ~= " a_ " ) then
2022-06-27 00:00:08 +02:00
v [ id_prefix .. " value " ] = ( data.function_name or " " )
2022-06-19 02:49:25 +02:00
v [ id_prefix .. " operator " ] = values_operator [ data.operator ]
v [ id_prefix .. " var_cmp_value " ] = ( data.var_cmp_value or " " )
-- transfer the parameters
for i = 1 , 9 do
v [ id_prefix .. " param " .. str ( i ) ] = ( data [ " param " .. str ( i ) ] or " " )
end
2021-07-02 20:58:35 +02:00
-- "a block somewhere", -- 3
2021-09-03 21:14:47 +02:00
elseif ( what_type == " block " and id_prefix ~= " a_ " ) then
2021-07-02 20:58:35 +02:00
v [ id_prefix .. " value " ] = values_block [ data.block ]
if ( not ( data.block_pos ) or not ( data.node_data ) or not ( data.node_data . name ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Please select a block first!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
-- for "node_is_air", there is no need to store node name and parameter
if ( v [ id_prefix .. " value " ]
and ( v [ id_prefix .. " value " ] == " node_is_like "
or v [ id_prefix .. " value " ] == " node_is_diffrent_from " )
or v [ id_prefix .. " value " ] == " place "
or v [ id_prefix .. " value " ] == " dig "
or v [ id_prefix .. " value " ] == " punch "
or v [ id_prefix .. " value " ] == " right-click " ) then
v [ id_prefix .. " node " ] = data.node_data . name
v [ id_prefix .. " param2 " ] = data.node_data . param2
end
-- preconditions can be applied to all blocks; effects may be more limited
if ( id_prefix == " r_ "
and yl_speak_up.check_blacklisted ( v [ id_prefix .. " value " ] ,
-- we don't know yet which node will be there later on
data.node_data . name , data.node_data . name ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Blocks of type \" " ..
tostring ( data.node_data . name ) .. " \" do not allow \n " ..
" interaction of type \" " .. tostring ( v [ id_prefix .. " value " ] ) ..
" \" for NPC.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
-- we also need to store the position of the node
v [ id_prefix .. " pos " ] = { x = data.block_pos . x , y = data.block_pos . y , z = data.block_pos . z }
-- "I can't punch it. The block is as the block *above* the one I punched.",
if ( id_prefix == " p_ " and data.block == 5 ) then
v.p_pos . y = v.p_pos . y + 1
end
-- "a trade", -- 4
-- (only for preconditions; not for effects)
2021-09-03 21:14:47 +02:00
elseif ( what_type == " trade " and id_prefix == " p_ " ) then
2021-07-02 20:58:35 +02:00
-- this depends on the trade associated with that option; therefore,
-- it does not need any more parameters (they come dynamicly from the
-- trade)
v.p_value = values_trade [ data.trade ]
-- "the inventory of the player", -- 5
-- "the inventory of the NPC", -- 6
2021-12-26 02:35:18 +01:00
-- "the inventory of a block somewhere", -- 7
2021-07-02 20:58:35 +02:00
-- (only for preconditions; not for effects)
2021-12-26 22:43:06 +01:00
elseif ( ( id_prefix == " p_ "
and ( what_type == " player_inv " or what_type == " npc_inv " or what_type == " block_inv " ) )
or ( id_prefix == " r_ "
and ( what_type == " put_into_block_inv " or what_type == " take_from_block_inv " ) ) ) then
-- changing the inventory of a block? we need to set p_value to something
if ( id_prefix == " r_ " ) then
-- just to be sure something is stored there...
v.r_value = data.inv_stack_name
-- for easier access in the formspec
v.r_itemstack = data.inv_stack_name
-- store in p_value what we want to check regarding the inv (contains/contains not/empty/..)
else
v.p_value = values_inv [ data.inv ]
end
2021-07-02 20:58:35 +02:00
if ( v.p_value and v.p_value ~= " inv_is_empty " ) then
2021-07-02 21:25:41 +02:00
if ( not ( data.inv_stack_name ) or data.inv_stack_name == " " ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Please provide the name of the " ..
" \n item you want to check for!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
2021-07-02 20:58:35 +02:00
-- we have checked this value earlier on
2021-12-26 22:43:06 +01:00
v [ id_prefix .. " itemstack " ] = data.inv_stack_name
2021-07-02 20:58:35 +02:00
end
2021-12-26 02:35:18 +01:00
if ( not ( data.inv_list_name ) or data.inv_list_name == " " ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Please provide the name of the " ..
" \n inventory you want to access!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
-- the name of the inventory list we want to access
2021-12-26 22:43:06 +01:00
v [ id_prefix .. " inv_list_name " ] = data.inv_list_name
2021-12-26 02:35:18 +01:00
-- the inventory of a block
2021-12-26 22:43:06 +01:00
if ( what_type == " block_inv "
or what_type == " put_into_block_inv "
or what_type == " take_from_block_inv " ) then
2021-12-26 02:35:18 +01:00
if ( not ( data.block_pos ) or not ( data.node_data ) or not ( data.node_data . name ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Please select a block first!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
-- we also need to store the position of the node
v [ id_prefix .. " pos " ] = { x = data.block_pos . x , y = data.block_pos . y , z = data.block_pos . z }
end
2021-12-26 18:50:04 +01:00
-- "give item (created out of thin air) to player (requires npc_master priv)", -- 9
-- "take item from player and destroy it (requires npc_master priv)", -- 10
2021-09-03 21:14:47 +02:00
elseif ( id_prefix == " r_ " and ( what_type == " give_item " or what_type == " take_item " ) ) then
2021-07-02 20:58:35 +02:00
if ( not ( data.inv_stack_name ) or data.inv_stack_name == " " ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Please provide the name of the " ..
" \n item you want to give or take!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
if ( not ( minetest.check_player_privs ( player , { npc_master = true } ) ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Error: You need the \" npc_master \" priv " ..
" in order to set this effect.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ " r_value " ] = data.inv_stack_name
2021-12-26 18:50:04 +01:00
-- "move the player to a given position (requires npc_master priv)", -- 11
2021-09-03 21:14:47 +02:00
elseif ( what_type == " move " and id_prefix == " r_ " ) then
2021-07-02 20:58:35 +02:00
if ( not ( data.move_to_x ) or not ( data.move_to_y ) or not ( data.move_to_z ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Error: Please provide valid coordinates " ..
" x, y and z!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
if ( not ( minetest.check_player_privs ( player , { npc_master = true } ) ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Error: You need the \" npc_master \" priv " ..
" in order to set this effect.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ " r_value " ] = minetest.pos_to_string (
{ x = data.move_to_x , y = data.move_to_y , z = data.move_to_z } )
2021-12-26 18:50:04 +01:00
-- effect "execute Lua code (requires npc_master priv)", -- precondition: 8; effect: 12
2021-09-03 21:14:47 +02:00
elseif ( ( what_type == " function " and id_prefix == " p_ " )
or ( what_type == " function " and id_prefix == " r_ " ) ) then
2021-07-02 20:58:35 +02:00
if ( not ( data.lua_code ) or data.lua_code == " " ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Error: Please enter the Lua code you want " ..
" to execute!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
if ( not ( minetest.check_player_privs ( player , { npc_master = true } ) ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Error: You need the \" npc_master \" priv " ..
" in order to set this.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ id_prefix .. " value " ] = data.lua_code
2021-12-26 18:50:04 +01:00
-- "NPC crafts something", -- 6
2021-07-02 20:58:35 +02:00
-- (only for effects; not for preconditions)
2021-09-03 21:14:47 +02:00
elseif ( what_type == " craft " and id_prefix == " r_ " ) then
2021-07-02 20:58:35 +02:00
local player_inv = player : get_inventory ( )
if ( player_inv : get_stack ( " craftpreview " , 1 ) : is_empty ( ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: Please prepare your craft grid first! " ..
" \n Your NPC needs to know what to craft.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
-- store the craft result (Note: the craft result may change in the future
-- if the server changes its craft result, making this craft invalid)
v [ " r_value " ] = player_inv : get_stack ( " craftpreview " , 1 ) : to_string ( )
v [ " r_craft_grid " ] = { }
for i = 1 , 9 do
-- store all the indigrents of the craft grid
table.insert ( v [ " r_craft_grid " ] ,
player_inv : get_stack ( " craft " , i ) : to_string ( ) )
end
2021-12-26 18:50:04 +01:00
-- "go to other dialog if the *previous* effect failed", -- 7
2021-07-02 20:58:35 +02:00
-- (only for effects; not for preconditions)
2021-09-03 21:14:47 +02:00
elseif ( what_type == " on_failure " and id_prefix == " r_ " ) then
2021-07-02 20:58:35 +02:00
v [ " r_value " ] = data.on_failure
2021-12-26 18:50:04 +01:00
-- "send a chat message to all players", -- 8
2021-07-02 20:58:35 +02:00
-- (only for effects; not for preconditions)
2021-09-03 21:14:47 +02:00
elseif ( what_type == " chat_all " and id_prefix == " r_ " ) then
2021-07-02 20:58:35 +02:00
data.chat_msg_text = fields.chat_msg_text
-- allow saving only if the placeholders are all present
-- (reason for requiring them: players and server owners ought to
-- be able to see who is responsible for a message)
if ( not ( string.find ( data.chat_msg_text , " %$NPC_NAME%$ " ) )
or not ( string.find ( data.chat_msg_text , " %$PLAYER_NAME%$ " ) )
or not ( string.find ( data.chat_msg_text , " %$OWNER_NAME%$ " ) ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Error: Your chat message needs to contain " ..
" the following \n placeholders: $NPC_NAME$, " ..
" $PLAYER_NAME$ and $OWNER_NAME$. \n That way, other " ..
" players will know who sent the message.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ " r_value " ] = data.chat_msg_text
-- "Normal trade - one item(stack) for another item(stack).", -- 3
-- (only for actions)
2021-09-03 21:14:47 +02:00
elseif ( what_type == " trade " and id_prefix == " a_ " ) then
2021-07-02 20:58:35 +02:00
-- remember which option was selected
yl_speak_up.speak_to [ pname ] . o_id = o_id
-- do not switch target dialog (we are in edit mode)
yl_speak_up.speak_to [ pname ] . target_d_id = nil
-- just to make sure that the trade_id is properly set...
if ( not ( data.trade_id ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Error: Missing trade ID.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
-- the button is called store_trade_simple instead of save_element in
-- the trade simple function(s); we want to store a trade
fields.store_trade_simple = true
local res = yl_speak_up.input_add_trade_simple ( player , " " , fields )
-- the above function sets:
-- dialog.trades[ trade_id ] = {pay={ps},buy={bs}, d_id = d_id, o_id = o_id}
-- store the trade as an action:
local dialog = yl_speak_up.speak_to [ pname ] . dialog
if ( res and dialog.trades and dialog.trades [ data.trade_id ] ) then
v [ " a_value " ] = data.trade_id
v [ " a_pay " ] = dialog.trades [ data.trade_id ] . pay
v [ " a_buy " ] = dialog.trades [ data.trade_id ] . buy
v [ " a_on_failure " ] = " "
if ( data.action_failure_dialog ) then
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
v [ " a_on_failure " ] = sorted_dialog_list [ data.action_failure_dialog ]
end
end
-- "The NPC gives something to the player (i.e. a quest item).", -- 4
-- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5
-- (only for actions)
2022-01-04 04:52:24 +01:00
elseif ( ( ( what_type == " npc_gives " or what_type == " npc_wants " ) and id_prefix == " a_ " )
or ( what_type == " player_offered_item " and id_prefix == " p_ " ) ) then
2021-09-03 21:14:47 +02:00
local trade_inv_list = what_type
2022-01-04 04:52:24 +01:00
if ( id_prefix == " p_ " ) then
trade_inv_list = " npc_wants "
end
2021-07-02 20:58:35 +02:00
local trade_inv = minetest.get_inventory ( { type = " detached " , name = " yl_speak_up_player_ " .. pname } )
if ( not ( trade_inv ) or trade_inv : is_empty ( trade_inv_list ) ) then
2022-01-04 04:52:24 +01:00
local what = " give to "
if ( id_prefix == " p_ " ) then
what = " accept from "
end
2021-07-02 20:58:35 +02:00
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Please insert an item first! Your NPC " ..
2022-01-04 04:52:24 +01:00
" needs \n to know what it shall " .. what .. " the player.] " ..
2021-07-02 20:58:35 +02:00
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ " a_on_failure " ] = " "
if ( data.action_failure_dialog ) then
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
v [ " a_on_failure " ] = sorted_dialog_list [ data.action_failure_dialog ]
end
-- change the node in the slot
local stack = trade_inv : get_stack ( trade_inv_list , 1 )
if ( not ( stack ) or not ( minetest.registered_items [ stack : get_name ( ) ] ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;This item is unkown. Please use only known " ..
" items.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
-- is this particular item blacklisted on this server?
2022-01-04 04:52:24 +01:00
-- this is only relevant for actions, not for preconditions
if ( id_prefix ~= " p_ " and yl_speak_up.blacklist_action_quest_item [ stack : get_name ( ) ] ) then
2021-07-02 20:58:35 +02:00
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Sorry. This item is blacklisted on this " ..
" server. \n You can't use it as a quest item.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
local meta = stack : get_meta ( )
-- what does the NPC want to give?
2022-01-04 04:52:24 +01:00
v [ id_prefix .. " value " ] = stack : get_name ( ) .. " " .. stack : get_count ( )
2021-07-02 20:58:35 +02:00
-- for displaying as a background image
2022-01-04 04:52:24 +01:00
data.item_string = v [ id_prefix .. " value " ]
if ( what_type == " npc_wants " or what_type == " player_offered_item " ) then
2021-07-02 20:58:35 +02:00
-- try to reconstruct $PLAYER_NAME$ (may not always work)
local item_was_for = meta : get_string ( " yl_speak_up:quest_item_for " )
local new_desc = meta : get_string ( " description " )
if ( item_was_for and item_was_for ~= " " ) then
new_desc = string.gsub ( new_desc , item_was_for , " $PLAYER_NAME$ " )
end
data.item_desc = new_desc
end
-- set new description if there is one set (optional)
if ( data.item_desc
and data.item_desc ~= " "
and data.item_desc ~= " - none set - " ) then
2021-09-03 21:14:47 +02:00
if ( what_type == " npc_gives " ) then
2021-07-02 20:58:35 +02:00
meta : set_string ( " description " , data.item_desc )
end
2022-01-04 04:52:24 +01:00
v [ id_prefix .. " item_desc " ] = data.item_desc
2021-07-02 20:58:35 +02:00
end
2022-01-04 04:52:24 +01:00
if ( what_type == " npc_wants " or what_type == " player_offers_item " ) then
2021-07-02 20:58:35 +02:00
data.item_quest_id = meta : get_string ( " yl_speak_up:quest_id " )
end
-- set special ID (optional)
if ( data.item_quest_id
and data.item_quest_id ~= " "
and data.item_quest_id ~= " - no item set - " ) then
2021-09-03 21:14:47 +02:00
if ( what_type == " npc_gives " ) then
2021-07-02 20:58:35 +02:00
-- which player got this quest item?
meta : set_string ( " yl_speak_up:quest_item_for " , pname )
-- include the NPC id so that we know which NPC gave it
meta : set_string ( " yl_speak_up:quest_item_from " , tostring ( n_id ) )
-- extend quest_id by NPC id so that it becomes more uniq
meta : set_string ( " yl_speak_up:quest_id " ,
tostring ( n_id ) .. " " .. tostring ( data.item_quest_id ) )
end
2022-01-04 04:52:24 +01:00
v [ id_prefix .. " item_quest_id " ] = data.item_quest_id
2021-07-02 20:58:35 +02:00
end
2021-09-03 21:14:47 +02:00
if ( v [ " a_item_quest_id " ] and not ( v [ " a_item_desc " ] ) and what_type == " npc_gives " ) then
2021-07-02 20:58:35 +02:00
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;You can't set a special quest ID without " ..
" also changing \n the description. The player would be " ..
" unable to tell \n the quest item and normal items " ..
" apartapart.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
2022-01-04 23:01:16 +01:00
if ( data.item_group and data.item_group ~= " "
and data.item_group ~= " - no, just this one item - " ) then
2022-01-04 04:52:24 +01:00
v [ " p_item_group " ] = data.item_group
end
2022-01-05 01:01:23 +01:00
v [ " p_item_stack_size " ] = data.item_stack_size
v [ " p_match_stack_size " ] = data.match_stack_size
2021-07-02 20:58:35 +02:00
local player_inv = player : get_inventory ( )
if ( not ( player_inv : room_for_item ( " main " , stack ) ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;You have no room in your inventory for " ..
" the example \n item. Please make room so that it can be " ..
" given back to you!] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
player_inv : add_item ( " main " , stack )
trade_inv : remove_item ( trade_inv_list , stack )
-- just send a message that the save was successful and give the player time to
-- take his items back
show_save_msg = " size[9,2.5] " ..
" label[0.2,0.5;The information was saved successfully. \n " ..
" The item has been returned to your inventory.] " ..
2021-07-03 21:59:13 +02:00
" button[1.5,2.0;2,0.9;back_from_saving;Back] "
2021-07-02 20:58:35 +02:00
-- "The player has to manually enter a password or passphrase or some other text.", -- 6
2021-09-03 21:14:47 +02:00
elseif ( what_type == " text_input " and id_prefix == " a_ " ) then
2021-07-02 20:58:35 +02:00
if ( not ( data.quest_question ) ) then
data.quest_question = " Your answer: "
end
v [ " a_question " ] = data.quest_question
-- the player setting this up needs to provide the correct answer
if ( not ( data.quest_answer ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Error: Please provide the correct answer! \n " ..
" The answer the player gives is checked against this.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ " a_value " ] = data.quest_answer
if ( not ( data.action_failure_dialog ) ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Error: Please provide a target dialog if " ..
" the player gives the wrong answer.] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
v [ " a_on_failure " ] = sorted_dialog_list [ data.action_failure_dialog ]
2022-01-06 02:41:04 +01:00
elseif ( what_type == " deal_with_offered_item " and id_prefix == " r_ " ) then
if ( not ( data.select_deal_with_offered_item ) or data.select_deal_with_offered_item < 2 ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2.5] " ..
" label[0.2,0.5;Error: Please select what the NPC shall do!] " ..
" button[1.5,2.0;2,0.9;back_from_error_msg;Back] " } )
return
end
v [ " r_value " ] = yl_speak_up.dropdown_values_deal_with_offered_item [ data.select_deal_with_offered_item ]
2021-07-02 20:58:35 +02:00
-- "Call custom functions that are supposed to be overridden by the server.", --
2021-12-26 18:50:04 +01:00
-- precondition: 9; action: 7; effect: 13
2021-09-03 21:14:47 +02:00
elseif ( ( id_prefix == " a_ " and what_type == " custom " )
or ( id_prefix == " p_ " and what_type == " custom " )
or ( id_prefix == " r_ " and what_type == " custom " ) ) then
2021-07-02 20:58:35 +02:00
v [ id_prefix .. " value " ] = data.custom_param
if ( id_prefix == " a_ " ) then
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
v [ " a_on_failure " ] = sorted_dialog_list [ data.action_failure_dialog ]
end
2021-07-12 00:22:49 +02:00
2021-09-03 21:14:47 +02:00
-- "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 10
-- precondition: 10
elseif ( what_type == " other " and id_prefix == " p_ " ) then
2021-07-12 00:22:49 +02:00
if ( data.other_o_id and data.other_o_id ~= " -select- " ) then
v [ " p_value " ] = data.other_o_id
end
if ( data.fulfilled and data.fulfilled ~= " -select- " ) then
v [ " p_fulfilled " ] = data.fulfilled
end
2022-05-06 17:29:28 +02:00
elseif ( what_type == " true " ) then
v [ " p_value " ] = true -- doesn't matter here - just *some* value
elseif ( what_type == " false " ) then
v [ " p_value " ] = true -- doesn't matter here - just *some* value
2021-07-02 20:58:35 +02:00
end
v [ " alternate_text " ] = data.alternate_text
-- only save if something was actually selected
if ( v [ id_prefix .. " value " ] ) then
if ( not ( dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] ) ) then
dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] = { }
end
-- store the change in the dialog
dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] [ x_id ] = v
-- clear up data
yl_speak_up.speak_to [ pname ] [ id_prefix .. " id " ] = nil
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] = nil
-- record this as a change, but do not save do disk yet
2021-07-25 21:55:14 +02:00
table.insert ( yl_speak_up.npc_was_changed [ n_id ] ,
2021-07-02 20:58:35 +02:00
" Dialog " .. tostring ( d_id ) .. " : " .. element_desc .. " " .. tostring ( x_id ) ..
" added/changed for option " .. tostring ( o_id ) .. " . " )
if ( show_save_msg ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = show_save_msg } )
return
end
-- TODO: when trying to save: save to disk as well?
-- show the new/changed precondition
yl_speak_up.show_fs ( player , formspec_input_to , x_id )
return
else
-- make sure the player is informed that saving failed
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: There is no \" " .. tostring ( id_prefix ) ..
" value \" set. \n " ..
" \n Could not save.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
end
2021-06-08 23:56:55 +02:00
-- These two functions
-- * yl_speak_up.input_fs_edit_option_related and
-- * yl_speak_up.get_fs_edit_option_related
-- are very similar for preconditions and effects. Therefore they're called here
-- with a lot of parameters. fs_edit_preconditions.lua and fs_edit_effects.lua
-- contain only wrappers.
yl_speak_up.input_fs_edit_option_related = function ( player , formname , fields ,
id_prefix , element_list_name , max_entries_allowed ,
element_desc , tmp_data_cache ,
text_ask_for_punching ,
values_what , values_operator , values_block , values_trade , values_inv ,
check_what , check_operator , check_block , check_trade , check_inv ,
get_sorted_player_var_list_function ,
formspec_input_to
)
if ( not ( player ) ) then
return
end
local pname = player : get_player_name ( )
-- what are we talking about?
local n_id = yl_speak_up.speak_to [ pname ] . n_id
local d_id = yl_speak_up.speak_to [ pname ] . d_id
local o_id = yl_speak_up.speak_to [ pname ] . o_id
local x_id = yl_speak_up.speak_to [ pname ] [ id_prefix .. " id " ]
-- this only works in edit mode
if ( not ( n_id ) or yl_speak_up.edit_mode [ pname ] ~= n_id ) then
return
end
2021-07-08 23:33:27 +02:00
if ( fields.back_from_cannot_be_edited
or fields.back_from_show_var_usage ) then
2021-06-27 17:43:14 +02:00
yl_speak_up.show_fs ( player , formspec_input_to , x_id )
return
end
2022-01-04 01:24:42 +01:00
-- clear editing cache tmp_data_cache for all other types
if ( id_prefix ~= " p_ " ) then
yl_speak_up.speak_to [ pname ] [ " tmp_prereq " ] = nil
end
if ( id_prefix ~= " a_ " ) then
yl_speak_up.speak_to [ pname ] [ " tmp_action " ] = nil
end
if ( id_prefix ~= " r_ " ) then
yl_speak_up.speak_to [ pname ] [ " tmp_effect " ] = nil
end
2021-07-02 18:58:37 +02:00
-- delete precondition, action or effect
2021-06-08 23:56:55 +02:00
if ( fields.delete_element ) then
2021-07-02 18:58:37 +02:00
yl_speak_up.delete_element_p_or_a_or_e ( player , pname , n_id , d_id , o_id , x_id , id_prefix ,
element_list_name , element_desc , formspec_input_to )
return
2021-06-08 23:56:55 +02:00
end
if ( fields.select_block_pos ) then
minetest.chat_send_player ( pname , text_ask_for_punching )
-- this formspec expects the block punch:
yl_speak_up.speak_to [ pname ] . expect_block_punch = formspec_input_to
return
end
-- field inputs: those do not trigger a sending of the formspec on their own
2021-09-03 21:29:37 +02:00
local was_changed = false
-- are we talking about an inventory?
-- (inventory only applies to preconditions; not effects)
local data = yl_speak_up.speak_to [ pname ] [ tmp_data_cache ]
2021-09-03 21:14:47 +02:00
local what_type = " "
if ( data and data.what and values_what [ data.what ] ) then
what_type = values_what [ data.what ]
end
2021-06-21 20:43:13 +02:00
if ( ( ( fields.inv_stack_name and fields.inv_stack_name ~= " " )
or ( fields.store_item_name and fields.store_item_name ~= " " ) )
2021-06-28 18:24:07 +02:00
and data and data.what
2021-12-26 22:43:06 +01:00
and ( ( id_prefix == " p_ "
and ( what_type == " player_inv " or what_type == " npc_inv " or what_type == " block_inv " ) )
2021-12-26 18:50:04 +01:00
-- "give item (created out of thin air) to player (requires npc_master priv)", -- 9
-- "take item from player and destroy it (requires npc_master priv)", -- 10
2021-12-26 22:43:06 +01:00
or ( id_prefix == " r_ "
and ( what_type == " give_item " or what_type == " take_item "
or what_type == " put_into_block_inv " or what_type == " take_from_block_inv " ) ) ) ) then
2021-06-21 20:43:13 +02:00
local wanted = " "
local wanted_name = " "
if ( not ( fields.store_item_name ) ) then
local parts = fields.inv_stack_name : split ( " " )
local size = 1
if ( parts and # parts > 1 ) then
size = tonumber ( parts [ 2 ] )
if ( not ( size ) or size < 1 ) then
size = 1
end
end
wanted = parts [ 1 ] .. " " .. tostring ( size )
wanted_name = parts [ 1 ]
else
local trade_inv = minetest.get_inventory ( { type = " detached " ,
name = " yl_speak_up_player_ " .. pname } )
if ( not ( trade_inv ) or trade_inv : is_empty ( " npc_wants " , 1 ) ) then
-- show error message
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.0;Please put an item(stack) into the slot " ..
" next to the \n \" Store \" button first!] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
2021-06-08 23:56:55 +02:00
end
2021-06-21 20:43:13 +02:00
local stack = trade_inv : get_stack ( " npc_wants " , 1 )
wanted = stack : get_name ( ) .. " " .. stack : get_count ( )
wanted_name = stack : get_name ( )
2021-06-08 23:56:55 +02:00
end
-- does the item exist?
2021-06-21 20:43:13 +02:00
if ( minetest.registered_items [ wanted_name ] ) then
data.inv_stack_name = wanted
fields.inv_stack_name = wanted
2021-06-08 23:56:55 +02:00
else
-- show error message
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[8,2] " ..
" label[0.2,0.5;Error: \" " ..
2021-06-21 20:43:13 +02:00
minetest.formspec_escape ( wanted ) ..
2021-06-08 23:56:55 +02:00
" \" is not a valid item(stack).] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
end
2022-01-06 02:41:04 +01:00
elseif ( fields.select_deal_with_offered_item and fields.select_deal_with_offered_item ~= " " ) then
data.select_deal_with_offered_item = table.indexof (
yl_speak_up.dropdown_list_deal_with_offered_item ,
fields.select_deal_with_offered_item )
2022-01-05 01:01:23 +01:00
elseif ( fields.select_accept_group and fields.select_accept_group ~= " "
2022-01-04 04:00:08 +01:00
and data and data.what and what_type == " player_offered_item " and id_prefix == " p_ " ) then
data.item_group = fields.select_accept_group
2022-01-05 01:01:23 +01:00
elseif ( fields.select_match_stack_size and fields.select_match_stack_size ~= " "
and data and data.what and what_type == " player_offered_item " and id_prefix == " p_ " ) then
data.match_stack_size = fields.select_match_stack_size : split ( " " ) [ 1 ]
2021-06-08 23:56:55 +02:00
-- comparison value for a variable (same for both preconditions and effects)
2022-06-19 02:49:25 +02:00
-- (also used for checking return values of functions and property values)
2021-06-08 23:56:55 +02:00
elseif ( fields.var_cmp_value
2022-06-19 02:49:25 +02:00
and data and data.what and id_prefix ~= " a_ "
and ( what_type == " state " or what_type == " property " or what_type == " evaluate " ) ) then
2021-06-08 23:56:55 +02:00
data.var_cmp_value = fields.var_cmp_value
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-10 17:46:09 +02:00
-- text for a chat message
elseif ( fields.chat_msg_text
2021-09-03 21:14:47 +02:00
and data and data.what and what_type == " chat_all " and id_prefix == " r_ " ) then
2021-06-10 17:46:09 +02:00
data.chat_msg_text = fields.chat_msg_text
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-14 23:44:28 +02:00
2021-06-16 02:59:10 +02:00
elseif ( fields.custom_param
and fields.custom_param ~= " - Insert a text that is passed on to your function here - "
2021-06-19 23:42:05 +02:00
and fields.custom_param ~= " "
2021-06-29 00:15:36 +02:00
and data and data.what
2021-09-03 21:14:47 +02:00
and ( ( id_prefix == " a_ " and what_type == " custom " )
or ( id_prefix == " p_ " and what_type == " custom " )
or ( id_prefix == " r_ " and what_type == " custom " ) ) ) then
2021-06-16 02:59:10 +02:00
data.custom_param = fields.custom_param
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-16 02:59:10 +02:00
2021-06-14 23:44:28 +02:00
elseif ( fields.action_item_quest_id
and fields.action_item_quest_id ~= " "
and fields.action_item_quest_id ~= " - none set - "
2021-09-03 21:14:47 +02:00
and data and data.what and what_type == " npc_gives " and id_prefix == " a_ " ) then
2021-06-14 23:44:28 +02:00
data.item_quest_id = fields.action_item_quest_id
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-14 23:44:28 +02:00
end
-- action_item_quest_id and action_item_desc can be set at the same time
if ( fields.action_item_desc
and fields.action_item_desc ~= " "
and fields.action_item_desc ~= " - no item set - "
2021-09-03 21:14:47 +02:00
and data and data.what and what_type == " npc_gives " and id_prefix == " a_ " ) then
2021-06-14 23:44:28 +02:00
-- TODO: check if it diffrent from the default one of the stack
data.item_desc = fields.action_item_desc
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-08 23:56:55 +02:00
end
2021-06-15 19:40:56 +02:00
if ( fields.quest_question
2021-06-19 23:42:05 +02:00
and fields.quest_question ~= " "
2021-09-03 21:14:47 +02:00
and data and data.what and what_type == " text_input " and id_prefix == " a_ " ) then
2021-06-15 19:40:56 +02:00
data.quest_question = fields.quest_question
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-15 19:40:56 +02:00
end
-- quest question and answer can be given with the same press of the save button
if ( fields.quest_answer
and fields.quest_answer ~= " - Insert the correct answer here - "
2021-06-19 23:42:05 +02:00
and fields.quest_answer ~= " "
2021-09-03 21:14:47 +02:00
and data and data.what and what_type == " text_input " and id_prefix == " a_ " ) then
2021-06-15 19:40:56 +02:00
data.quest_answer = fields.quest_answer
2021-06-21 19:38:25 +02:00
was_changed = true
2021-06-15 19:40:56 +02:00
end
2021-06-08 23:56:55 +02:00
2021-12-26 18:50:04 +01:00
-- "move the player to a given position (requires npc_master priv)", -- 11
2021-06-28 23:05:23 +02:00
if ( fields.move_to_x or fields.move_to_y or fields.move_to_z ) then
local dimension = { " x " , " y " , " z " }
for i , dim in ipairs ( dimension ) do
local text = fields [ " move_to_ " .. dim ]
if ( text and text ~= " " ) then
local val = tonumber ( text )
if ( not ( val ) or val < - 32000 or val > 32000 ) then
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
formspec = " size[9,2] " ..
" label[0.2,0.5;Error: The coordinate values have " ..
" be in the range of -32000..32000.] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
else
data [ " move_to_ " .. dim ] = val
end
end
end
end
2021-06-28 23:35:45 +02:00
-- lua code
if ( fields.lua_code ) then
data.lua_code = fields.lua_code
end
2021-06-28 23:05:23 +02:00
2021-06-08 23:56:55 +02:00
-- the save button was pressed
if ( fields.save_element and data and data.what and values_what [ data.what ] ) then
2021-07-02 20:58:35 +02:00
local v = yl_speak_up.save_element_p_or_a_or_e (
player , pname , n_id , d_id , o_id , x_id , id_prefix , tmp_data_cache ,
element_list_name , element_desc , max_entries_allowed ,
values_what , values_operator , values_block , values_trade , values_inv ,
formspec_input_to , data , fields )
return
2021-06-08 23:56:55 +02:00
end
2021-07-02 20:58:35 +02:00
2021-06-08 23:56:55 +02:00
-- selections in a dropdown menu (they trigger sending the formspec)
-- select a general direction/type first
2021-06-21 19:38:25 +02:00
-- but *not* when enter was pressed (enter sends them all)
2021-06-21 20:43:13 +02:00
if ( fields.select_what and not ( fields.key_enter ) and not ( fields.store_item_name ) ) then
2021-06-08 23:56:55 +02:00
local nr = table.indexof ( check_what , fields.select_what )
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] = { what = nr }
2021-06-21 19:38:25 +02:00
end
2021-06-08 23:56:55 +02:00
-- select a subtype for the "a trade" selection
2021-06-21 19:38:25 +02:00
if ( fields.select_trade ) then
2021-06-08 23:56:55 +02:00
local nr = table.indexof ( check_trade , fields.select_trade )
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . trade = nr
2021-06-21 19:38:25 +02:00
end
2021-06-08 23:56:55 +02:00
-- select a subtype for the inventory selection (player or NPC)
2021-06-21 19:38:25 +02:00
if ( fields.select_inv ) then
2021-06-08 23:56:55 +02:00
local nr = table.indexof ( check_inv , fields.select_inv )
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . inv = nr
2021-06-21 19:38:25 +02:00
end
2021-06-08 23:56:55 +02:00
-- select data regarding a block
2021-06-21 19:38:25 +02:00
if ( fields.select_block ) then
2021-06-08 23:56:55 +02:00
local nr = table.indexof ( check_block , fields.select_block )
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . block = nr
2021-06-21 19:38:25 +02:00
end
2021-12-26 02:35:18 +01:00
-- select data regarding the inventory list of a block
if ( fields.inv_list_name and fields.inv_list_name ~= " " ) then
local tmp = yl_speak_up.get_node_inv_lists (
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . block_pos ,
fields.inv_list_name )
-- if that inventory list really exists in that block: all ok
if ( tmp and tmp.index ~= " " and tmp.index ~= " 1 " ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . inv_list_name = fields.inv_list_name
end
end
2021-06-08 23:56:55 +02:00
-- select data regarding a variable
2021-06-21 19:38:25 +02:00
if ( fields.select_variable ) then
2021-06-08 23:56:55 +02:00
-- get the list of available variables (with the same elements
-- and the same sort order as when the dropdown was displayed)
local var_list = get_sorted_player_var_list_function ( pname )
2021-07-03 21:25:38 +02:00
yl_speak_up.strip_pname_from_varlist ( var_list , pname )
2021-06-08 23:56:55 +02:00
local nr = table.indexof ( var_list , fields.select_variable )
if ( nr ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . variable = nr
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . variable_name = var_list [ nr ]
end
2021-06-21 19:38:25 +02:00
end
2021-06-08 23:56:55 +02:00
-- select data regarding an operator
2021-06-21 19:38:25 +02:00
if ( fields.select_operator ) then
2021-06-08 23:56:55 +02:00
local nr = table.indexof ( check_operator , fields.select_operator )
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . operator = nr
2021-06-21 19:38:25 +02:00
end
2022-06-19 02:49:25 +02:00
-- "the value of a property of the NPC (for generic NPC)"
if ( fields.property and fields.property ~= " " ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . property = fields.property
end
-- "something that has to be calculated or evaluated (=call a function)"
2022-06-27 00:00:08 +02:00
if ( fields.select_function_name and fields.select_function_name ~= " " ) then
for k , v in pairs ( yl_speak_up [ " custom_functions_ " .. id_prefix ] ) do
if ( v [ " description " ] == fields.select_function_name ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . function_name = k
end
end
end
-- "something that has to be calculated or evaluated (=call a function)"
2022-06-19 02:49:25 +02:00
if ( fields.evaluate and fields.evaluate ~= " " ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . evaluate = fields.evaluate
end
for i = 1 , 9 do
local s = " param " .. tostring ( i )
if ( fields [ s ] and fields [ s ] ~= " " ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] [ s ] = fields [ s ]
end
end
2021-07-12 00:22:49 +02:00
-- another dialog option is true or false
-- Note: "-select-" can be choosen here as well
if ( fields.select_other_o_id and fields.select_other_o_id ~= " " ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . other_o_id = fields.select_other_o_id
end
-- Note: "-select-" can be choosen here as well
if ( fields.select_fulfilled and fields.select_fulfilled ~= " " ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . fulfilled = fields.select_fulfilled
end
2021-06-21 19:38:25 +02:00
if ( fields.select_on_failure ) then
2021-06-09 21:43:49 +02:00
-- in this case we really want the name of the target dialog
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . on_failure = fields.select_on_failure
2021-06-21 19:38:25 +02:00
end
if ( fields.select_on_action_failure
2021-06-15 19:40:56 +02:00
and data and data.what and id_prefix == " a_ " ) then
2021-06-14 01:12:12 +02:00
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
local nr = table.indexof ( sorted_dialog_list , fields.select_on_action_failure )
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] . action_failure_dialog = nr
end
2021-06-20 23:24:33 +02:00
-- new variables have to be added (and deleted) somewhere after all
if ( fields.manage_variables ) then
-- remember which formspec we are comming from
yl_speak_up.speak_to [ pname ] [ " working_at " ] = formspec_input_to
yl_speak_up.show_fs ( player , " manage_variables " )
return
end
2021-07-02 19:36:50 +02:00
-- handle editing and changing of alternate texts for actions
if ( fields.button_edit_action_on_failure_text_change
or fields.button_edit_effect_on_failure_text_change
2021-07-17 16:23:06 +02:00
or fields.turn_alternate_text_into_new_dialog
2021-07-02 19:36:50 +02:00
or fields.save_dialog_modification ) then
yl_speak_up.handle_edit_actions_alternate_text (
player , pname , n_id , d_id , o_id , x_id , id_prefix ,
formspec_input_to , data , fields , tmp_data_cache )
2021-07-17 16:23:06 +02:00
if ( not ( fields.save_dialog_modification )
and not ( fields.turn_alternate_text_into_new_dialog ) ) then
2021-07-02 19:36:50 +02:00
return
end
was_changed = true
-- we are back from that submenu
elseif ( fields.back_from_edit_dialog_modification ) then
was_changed = true
end
2021-07-08 23:33:27 +02:00
-- show var usage - starting from clicking on a precondition or effect in the
-- edit options menu and viewing the list containing that selected element
if ( fields.show_var_usage and x_id ) then
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local element = dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] [ x_id ]
if ( element and element [ id_prefix .. " variable " ] ) then
2021-07-15 02:07:17 +02:00
local effect_name = " (Ef)fect "
if ( id_prefix == " p_ " ) then
effect_name = " pre(C)ondition "
end
2021-07-08 23:33:27 +02:00
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
2021-07-31 21:55:51 +02:00
formspec = yl_speak_up.fs_get_list_of_usage_of_variable (
2021-07-12 17:52:34 +02:00
element [ id_prefix .. " variable " ] , pname , true ,
2021-07-15 02:07:17 +02:00
" back_from_show_var_usage " ,
" Back to select " .. effect_name .. " " .. tostring ( x_id ) ..
" of option " .. tostring ( o_id ) ..
2021-07-15 04:40:25 +02:00
" of dialog " .. tostring ( d_id ) ,
-- internal variable?
( data and data.variable and data.variable < 3 ) )
2021-07-12 17:52:34 +02:00
} )
2021-07-08 23:33:27 +02:00
return
end
-- show var usuage - but this time from the edit dialog for that precondition or effect
elseif ( fields.show_var_usage_edit_element and x_id ) then
local dialog = yl_speak_up.speak_to [ pname ] . dialog
2021-07-31 19:01:09 +02:00
local element = nil
-- x_id may be "new" and this may be the first element in element_list_name
if ( dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] ) then
element = dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ] [ x_id ]
end
2021-07-15 02:07:17 +02:00
if ( not ( element ) or data.variable_name ) then
element = { }
element [ id_prefix .. " variable " ] = data.variable_name
end
2021-07-08 23:33:27 +02:00
if ( element and element [ id_prefix .. " variable " ] ) then
2021-07-15 02:07:17 +02:00
local effect_name = " (Ef)fect "
if ( id_prefix == " p_ " ) then
effect_name = " pre(C)ondition "
end
2021-07-08 23:33:27 +02:00
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
2021-07-31 21:55:51 +02:00
formspec = yl_speak_up.fs_get_list_of_usage_of_variable (
2021-07-12 17:52:34 +02:00
element [ id_prefix .. " variable " ] , pname , true ,
2021-07-15 02:07:17 +02:00
" back_from_error_msg " ,
" Back to select " .. effect_name .. " " .. tostring ( x_id ) ..
" of option " .. tostring ( o_id ) ..
2021-07-15 04:40:25 +02:00
" of dialog " .. tostring ( d_id ) ,
-- internal variable?
( data and data.variable and data.variable < 3 ) )
2021-07-12 17:52:34 +02:00
} )
2021-07-08 23:33:27 +02:00
return
end
2021-07-15 04:23:06 +02:00
-- allow to delete unused variables
elseif ( fields.delete_unused_variable ) then
2021-07-31 19:01:09 +02:00
-- try to delete the variable (button comes from the show usage of variable formspec)
local text = yl_speak_up.del_quest_variable ( pname , data.variable_name , nil )
2021-07-15 04:23:06 +02:00
yl_speak_up.show_fs ( player , " msg " , {
input_to = " yl_speak_up: " .. formspec_input_to ,
2021-07-31 19:01:09 +02:00
formspec = " size[10,2] " ..
" label[0.2,0.0;Trying to delete variable \" " ..
2021-07-15 04:23:06 +02:00
minetest.formspec_escape ( tostring ( data.variable_name ) ) ..
" \" : \n " .. text .. " ] " ..
" button[1.5,1.5;2,0.9;back_from_error_msg;Back] " } )
return
2021-07-08 23:33:27 +02:00
end
2021-07-02 19:36:50 +02:00
-- the player wants to change/edit a precondition or effect
if ( not ( fields.back )
and ( fields.change_element or fields.select_what or fields.select_trade
or fields.select_inv or fields.select_block
2021-12-26 02:35:18 +01:00
or fields.inv_list_name
2022-01-06 02:41:04 +01:00
or fields.select_deal_with_offered_item
2022-01-04 04:00:08 +01:00
or fields.select_accept_group
2022-01-05 01:01:23 +01:00
or fields.select_match_stack_size
2021-07-02 19:36:50 +02:00
or fields.select_variable or fields.select_operator
or fields.select_on_failure
or fields.select_on_action_failure
or fields.back_from_error_msg
or fields.store_item_name
2021-07-12 00:22:49 +02:00
or fields.select_other_o_id
or fields.select_fulfilled
2022-06-27 00:00:08 +02:00
or fields.select_function_name
2021-07-02 19:36:50 +02:00
or was_changed
or fields.key_enter
or fields.quit
-- return was pressed
or fields.key_enter_field ) ) then
yl_speak_up.show_fs ( player , formspec_input_to )
return
end
-- go back to the edit option dialog
yl_speak_up.show_fs ( player , " edit_option_dialog " ,
{ n_id = n_id , d_id = d_id , o_id = o_id , caller = formspec_input_to } )
end
2021-06-08 23:56:55 +02:00
yl_speak_up.get_fs_edit_option_related = function ( player , table_click_result ,
id_prefix , element_list_name , max_entries_allowed ,
element_desc , tmp_data_cache ,
what_do_you_want_txt ,
2021-06-19 23:42:05 +02:00
values_what , values_operator , values_block , values_trade , values_inv ,
2021-06-08 23:56:55 +02:00
check_what , check_operator , check_block , check_trade , check_inv ,
get_sorted_player_var_list_function ,
show_element_function ,
table_of_name ,
text_variable , text_select_operator , text_select_value ,
text_block_position )
if ( not ( player ) ) then
return " "
end
local pname = player : get_player_name ( )
-- what are we talking about?
local n_id = yl_speak_up.speak_to [ pname ] . n_id
local d_id = yl_speak_up.speak_to [ pname ] . d_id
local o_id = yl_speak_up.speak_to [ pname ] . o_id
local x_id = yl_speak_up.speak_to [ pname ] [ id_prefix .. " id " ]
-- this only works in edit mode
if ( not ( n_id ) or yl_speak_up.edit_mode [ pname ] ~= n_id ) then
return " size[1,1]label[0,0;You cannot edit this NPC.] "
end
local dialog = yl_speak_up.speak_to [ pname ] . dialog
if ( not ( dialog ) or not ( dialog.n_dialogs )
or not ( dialog.n_dialogs [ d_id ] )
or not ( dialog.n_dialogs [ d_id ] . d_options )
or not ( dialog.n_dialogs [ d_id ] . d_options [ o_id ] ) ) then
return " size[4,1]label[0,0;Dialog option does not exist.] "
end
local elements = dialog.n_dialogs [ d_id ] . d_options [ o_id ] [ element_list_name ]
if ( not ( elements ) ) then
elements = { }
end
-- did we arrive here through clicking on an element in the dialog edit options menu?
if ( table_click_result or elements [ table_click_result ] ) then
if ( not ( elements [ table_click_result ] ) ) then
-- which element has the player selected?
local sorted_key_list = yl_speak_up.sort_keys ( elements )
local selected = minetest.explode_table_event ( table_click_result )
-- use "new" if nothing fits
x_id = " new "
if ( ( selected.type == " CHG " or selected.type == " DLC " )
and selected.row <= # sorted_key_list ) then
x_id = sorted_key_list [ selected.row ]
end
if ( x_id == " new " and # sorted_key_list >= max_entries_allowed ) then
return " size[9,1.5] " ..
" label[0.2,0.0;There are only up to " ..
minetest.formspec_escape ( yl_speak_up.max_result_effects ) ..
" " .. element_desc .. " s allowed per dialog option.] " ..
" button[2.0,0.8;1.0,0.9;back;Back] "
end
else
-- allow to directly specify a x_id to show
x_id = table_click_result
end
2021-07-08 23:33:27 +02:00
local show_var_usage = " "
if ( x_id
2021-07-10 17:51:50 +02:00
2021-07-08 23:33:27 +02:00
and elements [ x_id ]
and elements [ x_id ] [ id_prefix .. " type " ]
and elements [ x_id ] [ id_prefix .. " type " ] == " state "
and elements [ x_id ] [ id_prefix .. " variable " ] ) then
show_var_usage = " button[12.0,1.8;6.5,0.9;show_var_usage; " ..
" Show where this variable is used] "
end
2021-06-08 23:56:55 +02:00
-- store which element we are talking about
yl_speak_up.speak_to [ pname ] [ id_prefix .. " id " ] = x_id
2021-06-19 23:42:05 +02:00
-- nothing selected yet
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] = nil
2021-06-08 23:56:55 +02:00
-- display the selected element
if ( x_id ~= " new " ) then
2022-01-16 21:49:52 +01:00
return " size[20,3] " ..
2021-06-08 23:56:55 +02:00
" bgcolor[#00000000;false] " ..
" label[0.2,0.5;Selected " .. element_desc .. " :] " ..
" tablecolumns[text;color,span=1;text;text] " ..
" table[0.2,0.8;19.6,0.7; " .. table_of_name .. " ; " ..
minetest.formspec_escape ( elements [ x_id ] [ id_prefix .. " id " ] ) ..
" ,#FFFF00, " ..
minetest.formspec_escape ( elements [ x_id ] [ id_prefix .. " type " ] ) ..
" , " ..
minetest.formspec_escape (
2021-07-03 21:25:38 +02:00
show_element_function ( elements [ x_id ] , pname ) ) .. " ;0] " ..
2021-06-08 23:56:55 +02:00
" button[2.0,1.8;1.5,0.9;delete_element;Delete] " ..
" button[4.0,1.8;1.5,0.9;change_element;Change] " ..
2021-06-21 18:43:58 +02:00
" button[6.0,1.8;5.5,0.9;back;Back to edit dialog option \" " ..
2021-07-08 23:33:27 +02:00
tostring ( o_id ) .. " \" ] " ..
show_var_usage
2021-06-08 23:56:55 +02:00
end
end
local data = yl_speak_up.speak_to [ pname ] [ tmp_data_cache ]
2021-09-03 21:14:47 +02:00
2021-06-08 23:56:55 +02:00
if ( not ( data ) or not ( data.what ) ) then
data = { what = 1 }
end
-- fallback
if ( not ( x_id ) ) then
x_id = " new "
end
2021-06-19 23:42:05 +02:00
2021-07-02 03:24:45 +02:00
local e = nil
2021-06-19 23:42:05 +02:00
-- does the element exist already? if so: use the existing values as presets for data
-- (so that the element can be edited)
-- does kind of the opposite than the saving of values starting in line 323 of this file
if ( x_id ~= " new " and data.what == 1 and elements [ x_id ] ) then
2021-07-02 03:24:45 +02:00
e = elements [ x_id ]
2021-06-27 17:43:14 +02:00
if ( id_prefix == " r_ " and e [ " r_type " ] == " dialog " ) then
-- dialog effects cannot be edited this way
return " size[9,2] " ..
" label[0.2,0.5;Effects of the type \" dialog \" cannot be edited this way. \n " ..
" Use the edit options or dialog menu to change the target dialog.] " ..
" button[1.5,1.5;2,0.9;back_from_cannot_be_edited;Back] "
end
2021-06-27 17:52:06 +02:00
if ( id_prefix == " p_ " and e [ " p_type " ] == " item " ) then
-- the staff-based item precondition can be translated to an editable
-- inventory precondition which is equal
e [ " p_type " ] = " player_inv "
e [ " p_itemstack " ] = e [ " p_value " ]
e [ " p_value " ] = " inv_contains "
end
2021-06-19 23:42:05 +02:00
data.what = table.indexof ( values_what , e [ id_prefix .. " type " ] )
if ( data.what == - 1 ) then
data.what = 1
2021-07-02 03:24:45 +02:00
2021-06-19 23:42:05 +02:00
-- npc_gives/npc_wants (action)
2021-07-02 03:24:45 +02:00
-- (two seperate functions, but can be handled here together)
2021-06-19 23:42:05 +02:00
elseif ( data.what and id_prefix == " a_ " and ( data.what == 4 or data.what == 5 ) ) then
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
data.action_failure_dialog = math.max ( 1 ,
table.indexof ( sorted_dialog_list , e [ " a_on_failure " ] ) )
2021-06-20 00:36:07 +02:00
-- data.item_string is used to show a background image
2021-06-19 23:42:05 +02:00
data.item_string = e [ " a_value " ] -- stack name and count (as string)
data.item_desc = e [ " a_item_desc " ]
data.item_quest_id = e [ " a_item_quest_id " ]
2022-01-04 04:52:24 +01:00
-- player_offered_item precondition
elseif ( data.what and id_prefix == " p_ " and ( data.what == 8 ) ) then
-- data.item_string is used to show a background image
data.item_string = e [ " p_value " ] -- stack name and count (as string)
data.item_desc = e [ " p_item_desc " ]
data.item_quest_id = e [ " p_item_quest_id " ]
data.item_group = e [ " p_item_group " ]
2022-01-05 01:01:23 +01:00
data.item_stack_size = e [ " p_item_stack_size " ]
data.match_stack_size = e [ " p_match_stack_size " ]
2021-07-02 03:24:45 +02:00
end
2021-07-01 22:33:19 +02:00
if ( e [ " alternate_text " ] ) then
data.alternate_text = e [ " alternate_text " ]
end
2021-06-20 00:58:08 +02:00
-- write that data back
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] = data
2021-06-19 23:42:05 +02:00
end
2021-06-30 01:46:37 +02:00
local save_button = " button[5.0,12.2;1,0.7;save_element;Save] "
2021-06-08 23:56:55 +02:00
local formspec =
2021-06-20 02:18:32 +02:00
" size[20,13] " ..
2021-06-30 04:23:55 +02:00
" label[5,0.5;Edit " .. element_desc .. " \" " .. minetest.formspec_escape ( x_id ) ..
" \" of option \" " .. minetest.formspec_escape ( tostring ( o_id ) ) ..
" \" of dialog \" " .. minetest.formspec_escape ( tostring ( d_id ) ) .. " \" ] " ..
2021-06-08 23:56:55 +02:00
" label[0.2,1.5; " .. what_do_you_want_txt .. " ] " ..
" label[0.2,2.0;Something regarding...] " ..
" dropdown[4.0,1.8;14.0,0.6;select_what; " ..
table.concat ( check_what , " , " ) .. " ; " ..
tostring ( data.what ) .. " ;] " ..
2021-06-30 01:46:37 +02:00
" button[3.0,12.2;1,0.7;back;Abort] "
2021-06-14 01:12:12 +02:00
if ( id_prefix ~= " a_ " ) then
formspec = formspec ..
2021-06-21 20:43:13 +02:00
" label[1,10.5;If you are unsure if your setup of pre(C)onditions and (Ef)fects " ..
2021-06-14 01:12:12 +02:00
" works as intended, \n type \" /npc_talk_debug " .. tostring ( n_id ) .. " \" " ..
" in chat in order to enter debug mode. You can leave it with " ..
" \" /npc_talk_debug off \" .] "
end
2021-06-08 23:56:55 +02:00
2021-07-02 02:33:33 +02:00
2021-07-17 16:23:06 +02:00
if ( data.what ) then
yl_speak_up.speak_to [ pname ] [ tmp_data_cache ] = data
end
2021-09-03 21:14:47 +02:00
local what_type = " "
if ( data and data.what and values_what [ data.what ] ) then
what_type = values_what [ data.what ]
end
2021-06-08 23:56:55 +02:00
-- "an internal state (i.e. of a quest)", -- 2
-- (state is the second offered option in both preconditions and effects list)
2021-09-03 21:14:47 +02:00
if ( data.what and what_type == " state " and id_prefix ~= " a_ " ) then
2021-07-02 03:24:45 +02:00
return yl_speak_up.get_fs_edit_option_p_and_e_state (
2021-07-02 17:00:36 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_variable , text_select_value , text_select_operator ,
values_operator , check_operator , get_sorted_player_var_list_function )
2021-07-02 02:50:56 +02:00
2022-06-19 02:49:25 +02:00
-- "the value of a property of the NPC (for generic NPC)"
2022-06-19 19:32:30 +02:00
elseif ( data.what and what_type == " property " and id_prefix ~= " a_ " ) then
2022-06-19 02:49:25 +02:00
return yl_speak_up.get_fs_edit_option_p_and_e_property (
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_select_operator , values_operator , check_operator )
-- "something that has to be calculated or evaluated (=call a function)"
2022-06-19 19:32:30 +02:00
elseif ( data.what and what_type == " evaluate " and id_prefix ~= " a_ " ) then
2022-06-19 02:49:25 +02:00
return yl_speak_up.get_fs_edit_option_p_and_e_evaluate (
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_select_operator , values_operator , check_operator )
2021-07-02 02:50:56 +02:00
-- "a block somewhere", -- 3
-- (block is the third offered option in both preconditions and effects list)
2021-09-03 21:14:47 +02:00
elseif ( data.what and what_type == " block " and id_prefix ~= " a_ " ) then
2021-07-02 03:24:45 +02:00
return yl_speak_up.get_fs_edit_option_p_and_e_block (
2021-07-02 17:08:51 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_block_position , values_block , check_block )
2021-07-02 02:50:56 +02:00
-- "a trade", -- 4
-- (trade - only for preconditions; effects have something else here)
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " p_ " and what_type == " trade " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_precondition_trade (
2021-07-02 17:14:34 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e ,
values_trade , check_trade )
2021-07-02 02:50:56 +02:00
-- "the inventory of the player", -- 5
-- "the inventory of the NPC", -- 6
2021-12-26 02:35:18 +01:00
-- "the inventory of a block somewhere", -- 7
2021-12-26 22:43:06 +01:00
-- "put item from the NPC's inventory into a chest etc.", -- 4 (effect)
-- "take item from a chest etc. and put it into the NPC's inventory", -- 5 (effect)
2021-07-02 02:50:56 +02:00
-- (inventory - only for preconditions; effects have something else here)
2021-12-26 22:43:06 +01:00
elseif ( ( data.what and id_prefix == " p_ "
and ( what_type == " player_inv " or what_type == " npc_inv " or what_type == " block_inv " ) )
or ( data.what and id_prefix == " r_ "
and ( what_type == " put_into_block_inv " or what_type == " take_from_block_inv " ) ) ) then
2021-12-26 02:35:18 +01:00
-- the inventory of a block needs more input options (in particular block selection)
data.what_type = what_type
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_precondition_inv (
2021-07-02 17:17:33 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e ,
2021-12-26 02:35:18 +01:00
values_inv , check_inv , values_block )
2021-07-02 02:50:56 +02:00
2022-01-06 02:41:04 +01:00
elseif ( data.what and id_prefix == " r_ " and what_type == " deal_with_offered_item " ) then
return yl_speak_up.get_fs_edit_option_effect_deal_with_offered_item (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-12-26 18:50:04 +01:00
-- "give item (created out of thin air) to player (requires npc_master priv)", -- 9
-- "take item from player and destroy it (requires npc_master priv)", -- 10
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " r_ " and ( what_type == " give_item " or what_type == " take_item " ) ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_effect_give_item_or_take_item (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
2021-12-26 18:50:04 +01:00
-- "move the player to a given position (requires npc_master priv)", -- 11
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " r_ " and what_type == " move " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_effect_move (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
2021-12-26 18:50:04 +01:00
-- "execute Lua code (requires npc_master priv)", -- precondition: 8; effect: 12
2021-09-03 21:14:47 +02:00
elseif ( ( data.what and id_prefix == " p_ " and what_type == " function " )
or ( data.what and id_prefix == " r_ " and what_type == " function " ) ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_p_and_e_function (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
2021-12-26 18:50:04 +01:00
-- "NPC crafts something", -- 6
2021-07-02 02:50:56 +02:00
-- (craft - only for effects - not for preconditions)
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " r_ " and what_type == " craft " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_effect_craft (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
-- "go to other dialog if the *previous* effect failed", -- 5
-- (on_failure - only for effects - not for preconditions)
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " r_ " and what_type == " on_failure " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_effect_on_failure (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
2021-12-26 18:50:04 +01:00
-- "send a chat message to all players" -- 8
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " r_ " and what_type == " chat_all " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_effect_chat_all (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
-- "Normal trade - one item(stack) for another item(stack).", -- 3
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " a_ " and what_type == " trade " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_action_trade (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
-- "The NPC gives something to the player (i.e. a quest item).", -- 4
-- (only for actions)
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " a_ " and what_type == " npc_gives " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_action_npc_gives (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
-- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5
-- (only for actions)
2022-01-04 04:00:08 +01:00
-- "an item the player offered/gave to the NPC", (as precondition)
elseif ( data.what and ( ( id_prefix == " a_ " and what_type == " npc_wants " )
or ( id_prefix == " p_ " and what_type == " player_offered_item " ) ) ) then
return yl_speak_up.get_fs_edit_option_action_npc_wants_or_accepts (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
-- "The player has to manually enter a password or passphrase or some other text.", -- 6
-- (only for actions)
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " a_ " and what_type == " text_input " ) then
2021-07-02 02:50:56 +02:00
return yl_speak_up.get_fs_edit_option_action_text_input (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
-- "Call custom functions that are supposed to be overridden by the server.", -- 7
2021-12-26 18:50:04 +01:00
-- precondition: 9; action: 7; effect: 13
2021-07-02 02:50:56 +02:00
elseif ( data.what
2021-09-03 21:14:47 +02:00
and ( ( id_prefix == " a_ " and what_type == " custom " )
or ( id_prefix == " p_ " and what_type == " custom " )
or ( id_prefix == " r_ " and what_type == " custom " ) ) ) then
2021-07-02 03:34:18 +02:00
return yl_speak_up.get_fs_edit_option_all_custom (
2021-07-02 03:24:45 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-12 00:22:49 +02:00
2021-09-03 21:14:47 +02:00
-- "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 10
2021-07-12 00:22:49 +02:00
-- precondition: 9
2021-09-03 21:14:47 +02:00
elseif ( data.what and id_prefix == " p_ " and what_type == " other " ) then
2021-07-12 00:22:49 +02:00
return yl_speak_up.get_fs_other_option_preconditions (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 02:50:56 +02:00
end
2021-07-02 17:48:54 +02:00
-- create a new precondition, action or effect
return formspec .. save_button
2021-07-02 02:50:56 +02:00
end
----------------------------------------------------------------------------
-- begin of formspecs for types of preconditions, actions and effects
2021-07-02 02:33:33 +02:00
2022-06-24 23:26:47 +02:00
-- helper function for "state", "property" and "evaluate";
-- shows dropdown for operator and input field for comparison value var_cmp_value
yl_speak_up.get_fs_operator_based_comparison = function ( data , id_prefix , save_button , e ,
values_operator , check_operator ,
what_is_this , text_what_is_this ,
text_select_operator , text_select_value )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.operator = math.max ( 1 , table.indexof ( values_operator , e [ id_prefix .. " operator " ] ) )
data.var_cmp_value = e [ id_prefix .. " var_cmp_value " ]
end
2022-06-24 23:26:47 +02:00
if ( not ( data [ what_is_this ] ) or data [ what_is_this ] == " " or tostring ( data [ what_is_this ] ) == - 1
or tostring ( data [ what_is_this ] ) == " 0 " ) then
2021-07-02 03:34:18 +02:00
-- not enough selected yet for saving
save_button = " "
elseif ( not ( data.operator ) or data.operator == 1 ) then
data.operator = 1
save_button = " "
end
2021-07-10 17:51:50 +02:00
local field_for_value = " field[11.7,4.8;7.5,0.6;var_cmp_value;; " ..
2021-07-02 03:34:18 +02:00
minetest.formspec_escape ( data.var_cmp_value or " - enter value - " ) .. " ] "
-- do not show value input field for unary operators
-- (unary operators are diffrent for prerequirements and effects)
if ( not ( data.operator )
or ( id_prefix == " p_ " and ( data.operator == 1 or ( data.operator >= 8 and data.operator < 11 ) ) )
-- "unset", "set_to_current_time"
or ( id_prefix == " r_ " and ( data.operator == 3 or data.operator == 4 ) ) ) then
2021-07-10 17:51:50 +02:00
field_for_value = " label[11.7,5.1;- not used for this operator -] "
2021-07-02 03:34:18 +02:00
end
-- the list of available variables needs to be extended with the ones
-- the player has read access to, and the order has to be constant
-- (because dropdown just returns an index)
2022-06-24 23:26:47 +02:00
return " label[0.2,3.3; " .. text_what_is_this .. " ] " ..
" label[0.2,4.3;Name of " .. what_is_this .. " :] " ..
2021-07-02 03:34:18 +02:00
" label[7.0,4.3; " .. text_select_operator .. " ] " ..
2021-07-10 17:51:50 +02:00
" dropdown[7.0,4.8;4.5,0.6;select_operator; " ..
2021-07-02 03:34:18 +02:00
table.concat ( check_operator , " , " ) .. " ; " ..
tostring ( data.operator ) .. " ;] " ..
2021-07-10 17:51:50 +02:00
" label[11.7,4.3; " .. text_select_value .. " ] " ..
2021-07-02 03:34:18 +02:00
field_for_value ..
2022-06-24 23:26:47 +02:00
save_button
end
-- "an internal state (i.e. of a quest)", -- 2
-- (state is the second offered option in both preconditions and effects list)
yl_speak_up.get_fs_edit_option_p_and_e_state = function (
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_variable , text_select_value , text_select_operator ,
values_operator , check_operator , get_sorted_player_var_list_function )
-- the list of available variables needs to be extended with the ones
-- the player has read access to, and the order has to be constant
-- (because dropdown just returns an index)
local var_list = get_sorted_player_var_list_function ( pname )
local var_list_stripped = yl_speak_up.strip_pname_from_varlist ( var_list , pname )
if ( e ) then
data.variable_name = yl_speak_up.strip_pname_from_var ( e [ id_prefix .. " variable " ] , pname )
data.variable = table.indexof ( var_list , e [ id_prefix .. " variable " ] )
end
if ( not ( data.variable ) or data.variable < 1 ) then
data.variable = 0
end
return formspec ..
yl_speak_up.get_fs_operator_based_comparison ( data , id_prefix , save_button , e ,
values_operator , check_operator , " variable " , text_variable ,
text_select_operator , text_select_value ) ..
" dropdown[0.2,4.8;6.5,0.6;select_variable; " ..
" - please select - " .. var_list_stripped .. " ; " ..
tostring ( data.variable + 1 ) .. " ;] " ..
2021-07-02 03:34:18 +02:00
" button[0.2,6.0;4.0,0.6;manage_variables;Manage variables] " ..
2021-07-08 23:33:27 +02:00
" button[4.7,6.0;6.5,0.6;show_var_usage_edit_element;Show where this variable is used] " ..
2021-07-02 03:34:18 +02:00
" hypertext[1.2,7.0;16.0,2.5;some_text;<normal> " ..
" <b>Note:</b> Each variable is player-specific and will be set and " ..
" checked for the player that currently talks to your NPC. \n " ..
" <b>Note:</b> You can set a variable to the current time in an effect. " ..
" After that, use a precondition to check if that variable was set \" more " ..
" than x seconds ago \" or \" less than x seconds ago \" . This can be " ..
" useful for prevending your NPC from handing out the same quest item again " ..
" too quickly (players are inventive and may use your quest item for their " ..
2022-06-24 23:26:47 +02:00
" own needs). \n </normal>] "
2021-07-02 02:33:33 +02:00
end
2021-06-08 23:56:55 +02:00
2021-07-02 02:33:33 +02:00
2022-06-19 02:49:25 +02:00
-- "the value of a property of the NPC (for generic NPC)"
yl_speak_up.get_fs_edit_option_p_and_e_property = function (
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_select_operator , values_operator , check_operator )
if ( e ) then
data.property = e [ id_prefix .. " value " ]
end
local operator_list = { }
for i , v in ipairs ( check_operator ) do
v2 = values_operator [ i ]
if ( v2 ~= " quest_step_done " and v2 ~= " quest_step_not_done "
and v2 ~= " true_for_param " and v2 ~= " false_for_param " ) then
table.insert ( operator_list , v )
end
end
2022-06-19 19:32:30 +02:00
local text_compare_with = " Compare property with this value: "
if ( id_prefix == " r_ " ) then
text_select_operator = " Set property to: "
text_compare_with = " New value: "
end
2022-06-19 02:49:25 +02:00
-- the list of available variables needs to be extended with the ones
return formspec ..
2022-06-24 23:26:47 +02:00
yl_speak_up.get_fs_operator_based_comparison ( data , id_prefix , save_button , e ,
values_operator , operator_list , " property " ,
" The NPC shall have the following property: " ,
text_select_operator , text_compare_with ) ..
2022-06-19 02:49:25 +02:00
" field[1.0,4.8;5.0,0.6;property;; " ..
minetest.formspec_escape ( data.property or " - enter name - " ) .. " ] " ..
" hypertext[1.2,7.0;16.0,2.5;some_text;<normal> " ..
" <b>Note:</b> Properties are useful for NPC that have a generic " ..
" behaviour and may vary their behaviour slightly. \n " ..
2022-06-24 23:26:47 +02:00
" </normal>] "
2022-06-19 02:49:25 +02:00
end
-- "something that has to be calculated or evaluated (=call a function)"
yl_speak_up.get_fs_edit_option_p_and_e_evaluate = function (
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_select_operator , values_operator , check_operator )
2022-06-27 00:00:08 +02:00
local fun_list = { }
for k , v in pairs ( yl_speak_up [ " custom_functions_ " .. id_prefix ] ) do
table.insert ( fun_list , v [ " description " ] or k )
end
table.sort ( fun_list )
local func_selected = 0
2022-06-25 00:56:45 +02:00
local func_data = nil
2022-06-27 00:00:08 +02:00
if ( e ) then
2022-06-25 00:56:45 +02:00
--data.function_name = e[ id_prefix.."value"]
2022-06-27 00:00:08 +02:00
data.function_name = e [ id_prefix .. " value " ]
end
if ( data.function_name ) then
2022-06-25 00:56:45 +02:00
-- TODO: create the dropdown
func_data = yl_speak_up [ " custom_functions_ " .. id_prefix ] [ data.function_name ]
-- add the fields for param1..param9:
if ( func_data ) then
local xoff = 0
for i = 1 , 9 do
if ( i > 5 ) then
xoff = 10
end
local paramn = " param " .. tostring ( i )
local s = func_data [ paramn .. " _text " ]
if ( s ) then
formspec = formspec ..
" label[ " .. ( 0.2 + xoff ) .. " , " .. ( 6.05 + ( ( i - 1 ) % 5 ) * 0.8 ) .. " ; " ..
minetest.formspec_escape ( s ) .. " ] " ..
" field[ " .. ( 4.0 + xoff ) .. " , " .. ( 5.8 + ( ( i - 1 ) % 5 ) * 0.8 ) ..
" ;5.0,0.6;set_ " .. paramn .. " ;; " ..
minetest.formspec_escape (
data [ paramn ] or " - enter value - " ) .. " ] " ..
" tooltip[set_ " .. paramn .. " ; " ..
minetest.formspec_escape (
func_data [ paramn .. " _desc " ] or " ? " ) .. " ] "
end
end
end
2022-06-27 00:00:08 +02:00
func_selected = table.indexof ( fun_list ,
yl_speak_up [ " custom_functions_ " .. id_prefix ] [ data.function_name ] [ " description " ] )
2022-06-24 23:26:47 +02:00
end
local operator_list = { }
for i , v in ipairs ( check_operator ) do
v2 = values_operator [ i ]
if ( v2 ~= " quest_step_done " and v2 ~= " quest_step_not_done "
and v2 ~= " true_for_param " and v2 ~= " false_for_param " ) then
table.insert ( operator_list , v )
end
end
local text_operator_and_comparison = " "
if ( id_prefix ~= " r_ " ) then
text_operator_and_comparison = yl_speak_up.get_fs_operator_based_comparison (
data , id_prefix , save_button , e ,
values_operator , operator_list , " function " ,
" Execute and evaluate the following function: " ,
2022-06-27 00:00:08 +02:00
" Operator for checking result: " , " Compare the return value with this value: " )
2022-06-24 23:26:47 +02:00
end
-- the list of available variables needs to be extended with the ones
return formspec ..
text_operator_and_comparison ..
2022-06-27 00:00:08 +02:00
" dropdown[0.2,4.8;6.5,0.6;select_function_name; " ..
" - please select -, " .. table.concat ( fun_list , " , " ) .. " ; " ..
tostring ( func_selected + 1 ) .. " ;] "
2022-06-25 00:56:45 +02:00
-- "hypertext[1.2,7.0;16.0,2.5;some_text;<normal>"..
-- "<b>Note:</b> Functions are called with parameters which are passed on to them. "..
-- "The function then calculates a result. This can be compared to a given value."..
-- "</normal>]"
2022-06-19 02:49:25 +02:00
end
2021-07-02 17:08:51 +02:00
2021-12-26 02:35:18 +01:00
-- helper function for:
-- yl_speak_up.get_fs_edit_option_p_and_e_block
yl_speak_up.get_block_pos_info = function ( pname , data , id_prefix , e , values_block , ignore_protection )
2021-12-26 22:43:06 +01:00
-- are we more intrested in the inventory of the block or in the block itself?
local looking_at_inventory = false
if ( data and data.what_type
and ( data.what_type == " block_inv "
or data.what_type == " put_into_block_inv "
or data.what_type == " take_from_block_inv " ) ) then
looking_at_inventory = true
end
2021-07-02 17:08:51 +02:00
-- did the player get here through punching a block in the meantime?
local block_pos = yl_speak_up.speak_to [ pname ] . block_punched
yl_speak_up.speak_to [ pname ] . block_punched = nil
2021-12-26 22:43:06 +01:00
if ( e and e [ id_prefix .. " pos " ] ) then
-- if we are not looking for the inventory of a block:
if ( looking_at_inventory ) then
2021-12-26 02:35:18 +01:00
data.block = math.max ( 1 , table.indexof ( values_block , e [ id_prefix .. " value " ] ) )
end
2021-07-02 03:34:18 +02:00
data.node_data = { }
data.node_data . data = e [ id_prefix .. " node " ]
data.node_data . param2 = e [ id_prefix .. " param2 " ]
data.block_pos = { x = e [ id_prefix .. " pos " ] . x ,
y = e [ id_prefix .. " pos " ] . y ,
z = e [ id_prefix .. " pos " ] . z }
-- the block below was punched
if ( id_prefix == " p_ " and data.block == 5 ) then
data.block_pos . y = data.block_pos . y - 1
2021-07-02 03:24:45 +02:00
end
2021-07-02 03:34:18 +02:00
end
local block_pos_str = " - none set - "
local node = { name = " - unknown - " , param2 = " - unkown - " }
if ( not ( block_pos ) and data and data.block_pos ) then
block_pos = data.block_pos
end
local error_is_protected = " "
if ( block_pos ) then
-- store for later usage
data.block_pos = block_pos
local tmp_pos = { x = block_pos.x , y = block_pos.y , z = block_pos.z }
-- "I can't punch it. The block is as the block *above* the one I punched.",
-- (only valid for preconditions; not for effects - because the player and
-- his NPC need to be able to build there)
if ( data.block and id_prefix == " p_ " and data.block == 5 ) then
tmp_pos.y = block_pos.y + 1
2021-06-08 23:56:55 +02:00
end
2021-07-02 03:34:18 +02:00
-- effects (and, likewise, preconditions): the player at least has to be able to
-- build at that position - check that
2021-12-26 02:35:18 +01:00
if ( not ( ignore_protection ) and minetest.is_protected ( tmp_pos , pname ) ) then
2021-07-02 03:34:18 +02:00
error_is_protected = " label[0.2,7.8;Error: " ..
" The position you punched is protected. It cannot be used by " ..
" your NPC for checks or building. Please select a diffrent block!] "
block_pos = nil
data.block_pos = nil
else
block_pos_str = minetest.pos_to_string ( tmp_pos )
node = minetest.get_node_or_nil ( tmp_pos )
if ( not ( node ) ) then
node = { name = " - unknown - " , param2 = " - unkown - " }
2021-06-08 23:56:55 +02:00
end
2021-07-02 03:34:18 +02:00
-- "There shall be air instead of this block.",
-- (only valid for preconditions)
if ( data.block and id_prefix == " p_ " and data.block == 3 ) then
node = { name = " air " , param2 = 0 }
2021-06-08 23:56:55 +02:00
end
2021-07-02 03:34:18 +02:00
-- cache that (in case a sapling grows or someone else changes it)
data.node_data = node
2021-06-08 23:56:55 +02:00
end
2021-07-02 03:34:18 +02:00
end
2021-12-26 02:35:18 +01:00
local show_save_button = true
2021-07-02 03:34:18 +02:00
if ( node.name == " - unknown - " ) then
2021-12-26 02:35:18 +01:00
show_save_button = false
2021-07-02 03:34:18 +02:00
end
2021-12-26 02:35:18 +01:00
-- if we are dealing with the *inventory* of a block, the state of the block is of no intrest here
2021-12-26 22:43:06 +01:00
if ( not ( looking_at_inventory ) and ( not ( data.block ) or data.block == 1 ) ) then
2021-07-02 03:34:18 +02:00
data.block = 1
-- not enough selected yet for saving
2021-12-26 02:35:18 +01:00
show_save_button = false
end
return { block_pos = block_pos , block_pos_str = block_pos_str , node = node ,
error_is_protected = error_is_protected ,
show_save_button = show_save_button }
end
-- "a block somewhere", -- 3
-- (block is the third offered option in both preconditions and effects list)
yl_speak_up.get_fs_edit_option_p_and_e_block = function (
pname , dialog , formspec , data , id_prefix , save_button , e ,
text_block_position , values_block , check_block )
local res = yl_speak_up.get_block_pos_info ( pname , data , id_prefix , e , values_block , false )
if ( not ( res.show_save_button ) ) then
2021-07-02 03:34:18 +02:00
save_button = " "
end
2021-07-02 17:08:51 +02:00
return formspec ..
" label[0.2,3.3; " .. text_block_position .. " ] " ..
2021-07-02 03:34:18 +02:00
" dropdown[4.0,3.5;16.0,0.6;select_block; " ..
table.concat ( check_block , " , " ) .. " ; " ..
tostring ( data.block ) .. " ;] " ..
" label[0.2,4.8;Position of the block:] " ..
2021-12-26 02:35:18 +01:00
" label[4.0,4.8; " .. minetest.formspec_escape ( res.block_pos_str ) .. " ] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,5.8;Name of block:] " ..
2021-12-26 02:35:18 +01:00
" label[4.0,5.8; " .. minetest.formspec_escape ( res.node . name ) .. " ] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,6.8;Orientation (param2):] " ..
2021-12-26 02:35:18 +01:00
" label[4.0,6.8; " .. minetest.formspec_escape ( res.node . param2 ) .. " ] " ..
2021-07-02 03:34:18 +02:00
" button_exit[10.0,5.5;4.0,0.7;select_block_pos;Set position of block] " ..
" tooltip[select_block_pos;Click on this button to select a block. \n " ..
" This menu will close and you will be asked to punch \n " ..
" the block at the position you want to check or change. \n " ..
" After punching it, you will be returned to this menu.] " ..
2021-12-26 02:35:18 +01:00
res.error_is_protected ..
2021-07-02 03:34:18 +02:00
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-08 23:56:55 +02:00
2021-07-02 02:33:33 +02:00
2021-07-02 17:14:34 +02:00
-- "a trade", -- 4
-- (trade - only for preconditions; effects have something else here)
yl_speak_up.get_fs_edit_option_precondition_trade = function (
pname , dialog , formspec , data , id_prefix , save_button , e ,
values_trade , check_trade )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.trade = math.max ( 1 , table.indexof ( values_trade , e [ " p_value " ] ) )
end
if ( not ( data.trade ) or data.trade == 1 ) then
data.trade = 1
-- not enough selected yet for saving
save_button = " "
end
2021-07-02 17:14:34 +02:00
return formspec ..
" label[0.2,3.3;If the action is a trade, the following shall be true:] " ..
2021-07-02 03:34:18 +02:00
" dropdown[4.0,3.5;16.0,0.6;select_trade; " ..
table.concat ( check_trade , " , " ) .. " ; " ..
tostring ( data.trade ) .. " ;] " ..
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-08 23:56:55 +02:00
2021-07-02 02:33:33 +02:00
2021-07-02 17:17:33 +02:00
-- "the inventory of the player", -- 5
-- "the inventory of the NPC", -- 6
2021-12-26 02:35:18 +01:00
-- "the inventory of a block somewhere", -- 7
2021-12-26 22:43:06 +01:00
-- "put item from the NPC's inventory into a chest etc.", -- 4 (effect)
-- "take item from a chest etc. and put it into the NPC's inventory", -- 5 (effect)
2021-07-02 17:17:33 +02:00
-- (inventory - only for preconditions; effects have something else here)
yl_speak_up.get_fs_edit_option_precondition_inv = function (
pname , dialog , formspec , data , id_prefix , save_button , e ,
2021-12-26 02:35:18 +01:00
values_inv , check_inv , values_block )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.inv = math.max ( 1 , table.indexof ( values_inv , e [ " p_value " ] ) )
2021-12-26 22:43:06 +01:00
data.inv_stack_name = e [ id_prefix .. " itemstack " ]
2021-07-02 03:34:18 +02:00
end
2021-12-26 22:43:06 +01:00
if ( id_prefix == " p_ " and ( not ( data.inv ) or data.inv == 1 ) ) then
2021-07-02 03:34:18 +02:00
data.inv = 1
-- not enough selected yet for saving
save_button = " "
end
2021-12-26 02:35:18 +01:00
local block_selection = " "
2021-12-26 22:43:06 +01:00
if ( data and data.what_type
and ( data.what_type == " block_inv "
or data.what_type == " put_into_block_inv "
or data.what_type == " take_from_block_inv " ) ) then
2021-12-26 02:35:18 +01:00
local inv_list_name = " "
if ( e ) then
-- not really relevant here but needed for getting the position
e [ id_prefix .. " value " ] = " node_is_like "
inv_list_name = e [ id_prefix .. " inv_list_name " ]
end
-- positions of nodes in protected areas are allowed for inventory access
local res = yl_speak_up.get_block_pos_info ( pname , data , id_prefix , e , values_block , true )
if ( not ( res.show_save_button ) ) then
save_button = " "
end
-- which inventory lists are available?
local tmp = yl_speak_up.get_node_inv_lists ( res.block_pos , inv_list_name )
block_selection = " " ..
" label[0.2,7.0;Position of the block:] " ..
" label[4.0,7.0; " .. minetest.formspec_escape ( res.block_pos_str ) .. " ] " ..
" label[0.2,7.5;Name of block:] " ..
" label[4.0,7.5; " .. minetest.formspec_escape ( res.node . name ) .. " ] " ..
" label[0.2,8.0;Orientation (param2):] " ..
" label[4.0,8.0; " .. minetest.formspec_escape ( res.node . param2 ) .. " ] " ..
" label[0.2,8.5;Inventory list name:] " ..
" dropdown[4.0,8.2;3.8,0.6;inv_list_name; " ..
table.concat ( tmp.inv_lists , " , " ) .. " ; " ..
tostring ( tmp.index ) .. " ;] " ..
" button_exit[0.2,9.0;4.0,0.7;select_block_pos;Set position of block] " ..
" tooltip[select_block_pos;Click on this button to select a block. \n " ..
" This menu will close and you will be asked to punch \n " ..
" the block at the position you want to check or change. \n " ..
" After punching it, you will be returned to this menu.] "
end
2021-12-26 22:43:06 +01:00
local intro = " "
-- for preconditions: contain/does not contain item, is empty, ..
if ( id_prefix == " p_ " ) then
intro = " label[0.2,3.0;The following shall be true about the inventory:] " ..
" dropdown[4.0,3.2;16.0,0.6;select_inv; " ..
table.concat ( check_inv , " , " ) .. " ; " ..
tostring ( data.inv ) .. " ;] "
-- for results/effects:
elseif ( data.what_type == " put_into_block_inv " ) then
intro = " label[0.2,3.0;The NPC shall put the following item from his inventory " ..
" into the given block's inventory:] "
elseif ( data.what_type == " take_from_block_inv " ) then
intro = " label[0.2,3.0;The NPC shall take the following item from the given block's " ..
" inventory and put it into his own inventory:] "
end
2021-07-02 17:17:33 +02:00
return formspec ..
2021-12-26 22:43:06 +01:00
intro ..
2022-01-04 01:30:33 +01:00
yl_speak_up.fs_your_inventory_select_item ( pname , data ) ..
2021-12-26 02:35:18 +01:00
block_selection ..
2021-07-02 03:34:18 +02:00
save_button
2021-07-02 02:50:56 +02:00
end
2021-06-08 23:56:55 +02:00
2021-07-02 02:33:33 +02:00
2022-01-06 02:41:04 +01:00
-- "an item the player offered to the NPC"
yl_speak_up.get_fs_edit_option_effect_deal_with_offered_item = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
if ( e ) then
data.select_deal_with_offered_item = table.indexof (
yl_speak_up.dropdown_values_deal_with_offered_item ,
e [ " r_value " ] )
end
if ( not ( data ) or not ( data.select_deal_with_offered_item )
or data.select_deal_with_offered_item < 2 ) then
save_button = " "
data.select_deal_with_offered_item = 1
end
return formspec ..
" label[0.2,3.3;The NPC shall:] " ..
" dropdown[4.0,3.0;15.0,0.7;select_deal_with_offered_item; " ..
table.concat ( yl_speak_up.dropdown_list_deal_with_offered_item , " , " ) .. " ; " ..
tostring ( data.select_deal_with_offered_item ) .. " ;] " ..
save_button
end
2021-12-26 18:50:04 +01:00
-- "give item (created out of thin air) to player (requires npc_master priv)", -- 9
-- "take item from player and destroy it (requires npc_master priv)", -- 10
2021-07-02 17:26:18 +02:00
yl_speak_up.get_fs_edit_option_effect_give_item_or_take_item = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.inv_stack_name = e [ " r_value " ] or " "
end
local text = " The following item shall be created out of thin air and added to the " ..
" player's inventory: "
2022-04-17 19:42:42 +02:00
local priv_name = " effect_give_item "
2021-12-26 18:50:04 +01:00
if ( data.what == 10 ) then
2021-07-02 03:34:18 +02:00
text = " The following item shall be removed from the player's inventory and " ..
" be destroyed: "
2022-04-17 19:42:42 +02:00
priv_name = " effect_take_item "
2021-07-02 03:34:18 +02:00
end
2021-07-02 17:26:18 +02:00
return formspec ..
" label[0.2,3.0; " .. text .. " ] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,3.5;Note: You can *save* this effect only if you have the " ..
" \" npc_master \" priv!] " ..
2022-04-17 19:42:42 +02:00
" label[0.2,8.0; " ..
" And in order to be able to execute it, this NPC \n " ..
" needs the \" " .. tostring ( priv_name ) .. " \" priv. \n \t " ..
" Type \" /npc_talk_privs grant " .. tostring ( yl_speak_up.speak_to [ pname ] . n_id ) ..
" " .. tostring ( priv_name ) .. " \" \n in order to grant this.] " ..
2022-01-04 01:30:33 +01:00
yl_speak_up.fs_your_inventory_select_item ( pname , data ) ..
2021-07-02 03:34:18 +02:00
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-28 18:24:07 +02:00
2021-07-02 02:33:33 +02:00
2021-12-26 18:50:04 +01:00
-- "move the player to a given position (requires npc_master priv)", -- 11
2021-07-02 17:29:25 +02:00
yl_speak_up.get_fs_edit_option_effect_move = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
if ( e [ " r_value " ] and type ( e [ " r_value " ] ) == " string " ) then
local pos = minetest.string_to_pos ( e [ " r_value " ] )
if ( pos ) then
data.move_to_x = pos.x
data.move_to_y = pos.y
data.move_to_z = pos.z
2021-07-02 03:24:45 +02:00
end
end
2021-07-02 03:34:18 +02:00
end
2021-07-02 17:29:25 +02:00
return formspec ..
" label[0.2,3.0;Move the player to this position:] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,3.5;Note: You can *save* this effect only if you have the " ..
2022-04-17 19:42:42 +02:00
" \" npc_master \" priv! \n " ..
" And in order to be able to execute it, this NPC needs the \" " ..
" effect_move_player \" priv. \n \t " ..
" Type \" /npc_talk_privs grant " .. tostring ( yl_speak_up.speak_to [ pname ] . n_id ) ..
" effect_move_player \" in order to grant this.] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,5.3;X:] " ..
" label[3.7,5.3;Y:] " ..
" label[7.2,5.3;Z:] " ..
" field[0.7,5.0;2.0,0.6;move_to_x;; " .. ( data.move_to_x or " " ) .. " ] " ..
" field[4.2,5.0;2.0,0.6;move_to_y;; " .. ( data.move_to_y or " " ) .. " ] " ..
" field[7.7,5.0;2.0,0.6;move_to_z;; " .. ( data.move_to_z or " " ) .. " ] " ..
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-28 23:05:23 +02:00
2021-07-02 02:33:33 +02:00
2021-12-26 18:50:04 +01:00
-- "execute Lua code (requires npc_master priv)", -- precondition: 8; effect: 12
2021-07-02 17:30:57 +02:00
yl_speak_up.get_fs_edit_option_p_and_e_function = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
if ( e [ id_prefix .. " value " ] and e [ id_prefix .. " value " ] ~= " " ) then
data.lua_code = e [ id_prefix .. " value " ]
2021-07-02 03:24:45 +02:00
end
2021-07-02 03:34:18 +02:00
end
2022-04-17 19:42:42 +02:00
local priv_name = " precon_exec_lua "
if ( id_prefix == " _r " ) then
priv_name = " effect_exec_lua "
end
2021-07-02 17:30:57 +02:00
return formspec ..
" label[0.2,3.0;Execute the following Lua code (ought to return true or false):] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,3.5;Note: You can *save* this effect only if you have the " ..
2022-04-17 19:42:42 +02:00
" \" npc_master \" priv! \n " ..
" And in order to be able to execute it, this NPC needs the \" " ..
tostring ( priv_name ) .. " \" priv. \n \t " ..
" Type \" /npc_talk_privs grant " .. tostring ( yl_speak_up.speak_to [ pname ] . n_id ) ..
" " .. tostring ( priv_name ) .. " \" in order to grant this.] " ..
" textarea[0.2,5.0;20,4.0;lua_code;; " ..
2021-07-02 03:34:18 +02:00
minetest.formspec_escape ( tostring ( data.lua_code ) ) .. " ] " ..
save_button
2021-07-02 02:50:56 +02:00
end
2021-06-28 23:35:45 +02:00
2021-07-02 02:33:33 +02:00
2021-12-26 18:50:04 +01:00
-- "NPC crafts something", -- 6
2021-07-02 17:33:04 +02:00
-- (craft - only for effects - not for preconditions)
yl_speak_up.get_fs_edit_option_effect_craft = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
-- those items can at least be shown as background images
data.craftresult = e [ " r_value " ]
data.craft_grid = e [ " r_craft_grid " ]
end
local bg_img = " "
if ( data and data.craftresult and data.craft_grid ) then
2022-01-02 20:01:24 +01:00
bg_img = " item_image[5.95,8.70;0.7,0.7; " .. tostring ( data.craftresult ) .. " ] " ..
" image[4.6,8.6;1,1;gui_furnace_arrow_bg.png^[transformR270] "
2021-07-02 03:34:18 +02:00
for i , v in ipairs ( data.craft_grid ) do
if ( v and v ~= " " ) then
bg_img = bg_img .. " item_image[ " ..
tostring ( 1.15 + ( ( i - 1 ) % 3 ) * 1.25 ) .. " , " ..
2022-01-02 20:01:24 +01:00
tostring ( 8.15 + math.floor ( ( i - 1 ) / 3 ) * 0.65 ) ..
2021-07-02 03:34:18 +02:00
" ;0.7,0.7; " .. tostring ( v ) .. " ] "
2021-06-20 00:36:07 +02:00
end
end
2021-07-02 03:34:18 +02:00
end
2021-07-02 17:33:04 +02:00
return formspec ..
" label[8,2.6;Your invnetory:] " ..
2021-07-02 03:34:18 +02:00
" list[current_player;main;8,3;8,4;] " ..
" label[1,3.1;Your craft grid:] " ..
" list[current_player;craft;1,3.5;3,3;] " ..
" list[current_player;craftpreview;5.8,4.75;1,1;] " ..
" image[4.6,4.8;1,1;gui_furnace_arrow_bg.png^[transformR270] " ..
" label[1,8.0;Use your craft grid to show your NPC what to craft " ..
2022-01-02 20:01:24 +01:00
" and how. Click on \" Save \" to save. Currently stored:] " ..
2021-07-02 03:34:18 +02:00
bg_img ..
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-09 21:43:49 +02:00
2021-07-02 02:33:33 +02:00
2021-07-02 17:35:14 +02:00
-- "go to other dialog if the *previous* effect failed", -- 5
-- (on_failure - only for effects - not for preconditions)
yl_speak_up.get_fs_edit_option_effect_on_failure = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.on_failure = e [ " r_value " ]
2021-07-17 16:23:06 +02:00
data.alternate_text = e [ " alternate_text " ]
2021-07-02 03:34:18 +02:00
end
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
local nr = 1
if ( not ( data ) or not ( data.on_failure ) ) then
save_button = " "
else
nr = table.indexof ( sorted_dialog_list , data.on_failure )
end
local on_failure_dialog = " "
if ( dialog and dialog.n_dialogs and dialog.n_dialogs [ data.on_failure ] ) then
on_failure_dialog =
" label[0.2,5.5;This will switch to dialog \" " ..
minetest.formspec_escape ( tostring ( data.on_failure ) ) .. " \" " ..
yl_speak_up.show_colored_dialog_text (
dialog ,
data ,
data.on_failure ,
" 1.2,5.8;18.0,2.0;d_text " ,
" , but with the following *modified* text " ,
" :] " ,
" button_edit_effect_on_failure_text_change " )
end
2021-07-02 17:35:14 +02:00
return formspec ..
" label[0.2,3.3;If the *previous* effect failed,] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,3.8;switch to the following dialog:] " ..
" dropdown[5.0,3.5;6.5,0.6;select_on_failure; " ..
table.concat ( sorted_dialog_list , " , " ) .. " ; " ..
tostring ( nr ) .. " ;] " ..
on_failure_dialog ..
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-10 17:46:09 +02:00
2021-07-02 02:33:33 +02:00
2021-12-26 18:50:04 +01:00
-- "send a chat message to all players" -- 8
2021-07-02 17:36:36 +02:00
yl_speak_up.get_fs_edit_option_effect_chat_all = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.chat_msg_text = e [ " r_value " ]
end
local default_text = " $NPC_NAME$ (owned by $OWNER_NAME$) announces: $PLAYER_NAME$ " ..
" - example; please enter the text - "
2021-07-02 17:36:36 +02:00
return formspec ..
" label[0.2,3.3;Send the following chat message to *all* players:] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,4.1;Message:] " ..
" field[2.0,3.8;16.0,0.6;chat_msg_text;; " ..
minetest.formspec_escape (
data.chat_msg_text
or default_text ) .. " ] " ..
" label[0.2,5.3;Note: Your chat message needs to contain the following placeholders, " ..
" which will be replaced automaticly like in dialog texts: " ..
" \n $NPC_NAME$, $PLAYER_NAME$ and $OWNER_NAME$.] " ..
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-08 23:56:55 +02:00
2021-07-02 02:33:33 +02:00
2021-07-02 17:38:52 +02:00
-- "Normal trade - one item(stack) for another item(stack).", -- 3
yl_speak_up.get_fs_edit_option_action_trade = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.trade_id = e [ " a_value " ]
-- use as background images
if ( dialog and dialog.trades and dialog.trades [ data.trade_id ] ) then
data.pay = dialog.trades [ data.trade_id ] . pay [ 1 ]
data.buy = dialog.trades [ data.trade_id ] . buy [ 1 ]
2021-06-20 00:36:07 +02:00
end
2021-07-02 03:34:18 +02:00
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
data.action_failure_dialog = math.max ( 1 ,
table.indexof ( sorted_dialog_list , e [ " a_on_failure " ] ) )
end
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local d_id = yl_speak_up.speak_to [ pname ] . d_id
local o_id = yl_speak_up.speak_to [ pname ] . o_id
if ( not ( data.trade_id ) ) then
data.trade_id = tostring ( d_id ) .. " " .. tostring ( o_id )
end
-- show the player which trade is stored
local bg_img = " "
if ( data and data.buy and data.pay ) then
bg_img = " item_image[2.15,4.35;0.7,0.7; " .. tostring ( data.buy ) .. " ] " ..
" item_image[5.15,4.35;0.7,0.7; " .. tostring ( data.pay ) .. " ] "
end
yl_speak_up.speak_to [ pname ] . trade_id = data.trade_id
2021-07-02 17:38:52 +02:00
return formspec ..
" label[8,2.6;Your invnetory:] " ..
2021-07-02 03:34:18 +02:00
" list[current_player;main;8,3;8,4;] " ..
" label[0.2,3.1;Configure trade with " .. minetest.formspec_escape ( dialog.n_npc ) .. " :] " ..
" label[0.5,3.8;The customer pays:] " ..
-- show the second slot of the setup inventory in the detached player's inv
" list[detached:yl_speak_up_player_ " .. pname .. " ;setup;2,4.2;1,1;] " ..
" image[3.5,4.2;1,1;gui_furnace_arrow_bg.png^[transformR270] " ..
" label[4.0,3.8; " .. minetest.formspec_escape ( dialog.n_npc or " ? " ) .. " sells:] " ..
-- show the second slot of said inventory
" list[detached:yl_speak_up_player_ " .. pname .. " ;setup;5,4.2;1,1;1] " ..
bg_img ..
yl_speak_up.set_on_action_failure_dialog ( pname , data ,
" The player shall trade at least once. " ) ..
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-16 00:25:18 +02:00
2021-07-02 02:33:33 +02:00
2021-07-02 17:41:13 +02:00
-- "The NPC gives something to the player (i.e. a quest item).", -- 4
-- (only for actions)
yl_speak_up.get_fs_edit_option_action_npc_gives = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
local bg_img = " "
2022-01-02 20:01:24 +01:00
if ( e ) then
data.item_quest_id = data.item_quest_id or e [ " item_quest_id " ]
data.item_desc = data.item_desc or e [ " item_desc " ]
end
if ( data and ( data.item_node_name or data.item_string ) ) then
bg_img = " item_image[1.15,3.65;0.7,0.7; " ..
tostring ( data.item_node_name or data.item_string ) .. " ] "
2021-07-02 03:34:18 +02:00
end
2021-07-02 17:41:13 +02:00
return formspec ..
" label[8,2.6;Your inventory:] " ..
2021-07-02 03:34:18 +02:00
" list[current_player;main;8,3;8,4;] " ..
" label[1,3.1; " .. minetest.formspec_escape ( dialog.n_npc or " ? " ) .. " gives:] " ..
" list[detached:yl_speak_up_player_ " .. pname .. " ;npc_gives;2,3.5;1,1;] " ..
" label[3.2,4.0; " ..
2021-06-20 02:18:32 +02:00
minetest.formspec_escape (
data.item_node_name
or " - no item set - " ) .. " ] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,5.6;Set a description to turn the item into a special \n " ..
" quest item. Set a special ID (short text) so that \n " ..
" the player cannot create a fake item. Click on \n " ..
" \" Save \" to apply the changes. \n " ..
" You can use placeholders like $PLAYER_NAME$ etc.] " ..
" label[0.2,8.3;Special ID to set:] " ..
" field[3.2,8.0;14.5,0.6;action_item_quest_id;; " ..
2021-06-20 02:18:32 +02:00
minetest.formspec_escape (
data.item_quest_id
or " - none set - " ) .. " ] " ..
2021-07-02 03:34:18 +02:00
" tooltip[action_item_quest_id; " ..
" Set this to a text that helps *you* to remember what this \n " ..
" special quest item is for (i.e. \" quest_deliver_augusts_ " ..
" letter \" ). \n " ..
" The ID will be extended with the ID of the NPC and the \n " ..
" name of the player who got this item from the NPC.] " ..
" label[0.2,9.0;Description to set:] " ..
" field[3.2,8.7;14.5,0.6;action_item_desc;; " ..
2021-06-20 02:18:32 +02:00
minetest.formspec_escape (
2021-07-02 03:34:18 +02:00
data.item_desc
or " - no item set - " ) .. " ] " ..
" tooltip[action_item_desc; " ..
" Set this to a text that helps the *player* to remember what \n " ..
" this special quest item is for (i.e. \" Letter from August to \n " ..
" Frederike \" for a piece of paper). \n " ..
" This description is shown in the inventory on mouseover.] " ..
bg_img ..
yl_speak_up.set_on_action_failure_dialog ( pname , data ,
" The player shall take this offered item. " ) ..
save_button
end
2021-07-02 17:42:08 +02:00
-- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5
-- (only for actions)
2022-01-04 04:00:08 +01:00
-- "an item the player offered/gave to the NPC", (as precondition)
yl_speak_up.get_fs_edit_option_action_npc_wants_or_accepts = function (
2021-07-02 17:42:08 +02:00
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
local bg_img = " "
2022-01-04 04:00:08 +01:00
local node_name = " "
2022-01-02 20:01:24 +01:00
if ( e ) then
data.item_quest_id = data.item_quest_id or e [ " item_quest_id " ]
data.item_desc = data.item_desc or e [ " item_desc " ]
2022-01-04 04:00:08 +01:00
data.item_group = data.item_group or e [ " item_group " ]
2022-01-05 01:01:23 +01:00
data.item_stack_size = data.item_stack_size or e [ " item_stack_size " ]
data.match_stack_size = data.match_stack_size or e [ " match_stack_size " ]
2022-01-02 20:01:24 +01:00
end
if ( data and ( data.item_node_name or data.item_string ) ) then
2022-01-04 04:00:08 +01:00
node_name = tostring ( data.item_node_name or data.item_string )
bg_img = " item_image[1.15,3.65;0.7,0.7; " .. node_name .. " ] "
end
2022-01-06 02:41:04 +01:00
local info_text = " "
2022-01-04 04:00:08 +01:00
if ( id_prefix == " p_ " ) then
local group_list = { minetest.formspec_escape ( " - no, just this one item - " ) }
-- get node name without amount
local parts = node_name : split ( " " )
local nr = 1
2022-01-04 04:52:24 +01:00
local count = 1
2022-01-05 01:01:23 +01:00
local amount = tostring ( 1 )
2022-01-04 04:00:08 +01:00
-- prepare group_list
if ( data and parts and minetest.registered_items [ parts [ 1 ] ] ) then
for k , v in pairs ( minetest.registered_items [ parts [ 1 ] ] . groups ) do
table.insert ( group_list , k )
2022-01-04 04:52:24 +01:00
count = count + 1
if ( data.item_group and data.item_group == k ) then
nr = count
end
2022-01-04 04:00:08 +01:00
end
2022-01-05 01:01:23 +01:00
amount = tostring ( parts [ 2 ] )
end
local size_list = { " any amount " , " exactly " .. amount ,
2022-01-05 01:23:42 +01:00
" less than " .. amount , " more than " .. amount , " another amount than " .. amount }
2022-01-05 01:01:23 +01:00
local match_size = 1
for i , list_text in ipairs ( size_list ) do
if ( data.match_stack_size and data.match_stack_size == list_text : split ( " " ) [ 1 ] ) then
match_size = i
end
end
if ( data ) then
data.item_stack_size = amount
2022-01-04 04:00:08 +01:00
end
2022-01-05 01:01:23 +01:00
info_text =
" label[1,2.6;The player offered:] " ..
" label[6.7,3.1;of:] " ..
" dropdown[2,2.8;4.5,0.6;select_match_stack_size; " ..
table.concat ( size_list , " , " ) .. " ; " ..
tostring ( match_size or 1 ) .. " ;] " ..
" label[1,4.8;...and also all other items of the group:] " ..
2022-01-04 04:00:08 +01:00
" dropdown[2,5.1;5.0,0.6;select_accept_group; " ..
table.concat ( group_list , " , " ) .. " ; " .. tostring ( nr ) .. " ;] "
else
2022-01-05 01:01:23 +01:00
info_text =
" label[1,3.1; " .. minetest.formspec_escape ( dialog.n_npc or " ? " ) .. " wants:] " ..
yl_speak_up.set_on_action_failure_dialog ( pname , data ,
2022-01-04 04:00:08 +01:00
" The player shall give the NPC this item. " )
2021-07-02 03:34:18 +02:00
end
2021-07-02 17:42:08 +02:00
return formspec ..
" label[8,2.6;Your inventory:] " ..
2021-07-02 03:34:18 +02:00
" list[current_player;main;8,3;8,4;] " ..
" list[detached:yl_speak_up_player_ " .. pname .. " ;npc_wants;2,3.5;1,1;] " ..
" label[3.2,4.0; " ..
minetest.formspec_escape (
2022-01-04 04:52:24 +01:00
node_name
2021-07-02 03:34:18 +02:00
or " - no item set - " ) .. " ] " ..
" label[0.2,6.1;If you want a special ID and description, create \n " ..
" those via the \" NPC gives something to the player \" \n " ..
" menu option first and insert that item here. Don't \n " ..
" use other placeholders than $PLAYER_NAME$ for this!] " ..
" label[0.2,8.3;Expected special ID:] " ..
" label[4.0,8.3; " ..
minetest.formspec_escape (
data.item_quest_id
or " - none set - " ) .. " ] " ..
" label[0.2,9.0;Expected description:] " ..
" label[4.0,9.0; " ..
minetest.formspec_escape (
data.item_desc
or " - none set - " ) .. " ] " ..
bg_img ..
2022-01-05 01:01:23 +01:00
info_text ..
2021-07-02 03:34:18 +02:00
save_button
2021-07-02 02:33:33 +02:00
end
2021-06-15 19:40:56 +02:00
2021-07-02 02:33:33 +02:00
2021-07-02 17:45:21 +02:00
-- "The player has to manually enter a password or passphrase or some other text.", -- 6
-- (only for actions)
yl_speak_up.get_fs_edit_option_action_text_input = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.quest_question = e [ " a_question " ]
data.quest_answer = e [ " a_value " ]
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
data.action_failure_dialog = math.max ( 1 ,
table.indexof ( sorted_dialog_list , e [ " a_on_failure " ] ) )
end
2021-07-02 17:45:21 +02:00
return formspec ..
" label[0.2,3.3;What to ask the player and which answer to expect:] " ..
2021-07-02 03:34:18 +02:00
" label[0.2,4.0;Question to show:] " ..
" field[4.0,3.8;10.0,0.6;quest_question;; " ..
minetest.formspec_escape (
data.quest_question
or " Your answer: " ) .. " ] " ..
" label[0.2,5.0;Expected answer:] " ..
" field[4.0,4.8;10.0,0.6;quest_answer;; " ..
minetest.formspec_escape (
data.quest_answer
or " - Insert the correct answer here - " ) .. " ] " ..
" tooltip[quest_question; " ..
" This is just a short text that will be shown to remind \n " ..
" the player what he is asked for. Most of the question \n " ..
" ought to be part of the normal dialog of the NPC.] " ..
" tooltip[quest_answer; " ..
" The correct answer will not be shown to the player. \n " ..
" What the player enters will be compared to this \n " ..
" correct value.] " ..
" tooltip[select_on_action_failure; " ..
" If the player gives the wrong answer, you can show him \n " ..
" a diffrent target dialog (i.e. with text \" No, that answer \n " ..
" was wrong, but please try again! \" ). In such a case the \n " ..
" effects/results of the current dialog option are *not* \n " ..
" executed.] " ..
yl_speak_up.set_on_action_failure_dialog ( pname , data ,
" The player shall enter the correct answer. " ) ..
save_button
end
2021-07-02 17:45:21 +02:00
-- "Call custom functions that are supposed to be overridden by the server.", -- 7
2021-12-26 18:50:04 +01:00
-- precondition: 9; action: 7; effect: 13
2021-07-02 17:45:21 +02:00
yl_speak_up.get_fs_edit_option_all_custom = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
2021-07-02 03:34:18 +02:00
if ( e ) then
data.custom_param = e [ id_prefix .. " value " ]
if ( id_prefix == " a_ " ) then
2021-07-02 03:24:45 +02:00
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
data.action_failure_dialog = math.max ( 1 ,
2021-07-02 03:34:18 +02:00
table.indexof ( sorted_dialog_list , e [ " a_on_failure " ] ) )
2021-07-02 03:24:45 +02:00
end
2021-07-02 03:34:18 +02:00
end
formspec = formspec ..
" label[0.2,3.3;Note: Calling a custom function will require direct support " ..
" from the server.] " ..
" label[0.2,4.0;Parameter for custom function:] " ..
" field[6.0,3.7;10.0,0.6;custom_param;; " ..
minetest.formspec_escape (
data.custom_param
or " - Insert a text that is passed on to your function here - " ) .. " ] " ..
" tooltip[custom_param; " ..
" The custom parameter may help whoever implements the \n " ..
" custom function to more easily see what it belongs to. \n " ..
" Dialog and option ID are also passed as parameters.] "
if ( id_prefix == " a_ " ) then
formspec = formspec ..
2021-06-15 19:40:56 +02:00
" tooltip[select_on_action_failure; " ..
" If the player gives the wrong answer, you can show him \n " ..
" a diffrent target dialog (i.e. with text \" No, that answer \n " ..
" was wrong, but please try again! \" ). In such a case the \n " ..
" effects/results of the current dialog option are *not* \n " ..
2021-06-20 02:18:32 +02:00
" executed.] " ..
yl_speak_up.set_on_action_failure_dialog ( pname , data ,
2021-07-02 03:34:18 +02:00
" The player shall click on the right button. " )
else
2021-06-16 02:59:10 +02:00
formspec = formspec ..
2021-07-02 03:34:18 +02:00
" label[0.3,5.0;Note: Your custom function has to return either true " ..
" or false.] "
2021-06-14 01:12:12 +02:00
end
2021-07-02 03:34:18 +02:00
return formspec .. save_button
end
2021-06-20 02:18:32 +02:00
2021-07-12 00:22:49 +02:00
2021-09-03 21:14:47 +02:00
-- "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 10
-- precondition: 10
2021-07-12 00:22:49 +02:00
yl_speak_up.get_fs_other_option_preconditions = function (
pname , dialog , formspec , data , id_prefix , save_button , e )
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local d_id = yl_speak_up.speak_to [ pname ] . d_id
local o_id = yl_speak_up.speak_to [ pname ] . o_id
-- only o_id with a *lower* o_sort value are suitable (else evaluation would become
-- difficult and loops might be created)
local o_id_list = { }
local options = dialog.n_dialogs [ d_id ] . d_options
if ( options ) then
local this_option = options [ o_id ]
if ( not ( this_option ) or not ( this_option.o_sort ) ) then
this_option = { o_sort = 0 }
end
for k , v in pairs ( options ) do
if ( k and v and v.o_sort and v.o_sort < this_option.o_sort ) then
table.insert ( o_id_list , minetest.formspec_escape ( k ) )
end
end
end
if ( e ) then
data.other_o_id = e [ " p_value " ]
data.fulfilled = e [ " p_fulfilled " ]
end
local nr = math.max ( 0 , table.indexof ( o_id_list , data.other_o_id ) )
nr_fulfilled = 1
if ( data.fulfilled == " true " ) then
nr_fulfilled = 2
elseif ( data.fulfilled == " false " ) then
nr_fulfilled = 3
end
if ( nr == 0 or nr_fulfilled == 1 ) then
save_button = " "
end
return formspec ..
" label[0.2,3.3;Note: You can only select dialog options with a *lower* o_sort value " ..
" for this evaluation.] " ..
" label[0.2,4.0;The preconditions of dialog option:] " ..
" dropdown[6.0,3.7;3.0,0.6;select_other_o_id;-select-, " ..
table.concat ( o_id_list , " , " ) .. " ; " ..
tostring ( nr + 1 ) .. " ;] " ..
" label[9.2,4.0;..shall be:] " ..
" dropdown[11,3.7;2.0,0.6;select_fulfilled;-select-,true,false; " ..
tostring ( nr_fulfilled ) .. " ] " ..
" tooltip[select_other_o_id; " ..
" Sometimes you may need the same preconditions for more than \n " ..
" one dialog option - or you may need one dialog option to be \n " ..
" available exactly when another one is *not* available. \n " ..
" This is what you can do here.] " ..
" tooltip[select_fulfilled; " ..
" If you select \" true \" here, then this precondition will be \n " ..
" fulfilled when all the preconditions of the dialog option you \n " ..
" selected here are true as well. \n " ..
" If you select \" false \" , this precondition will only be \n " ..
" fulfilled if the other dialog option you selected here \n " ..
" is not true.] " ..
save_button
end
2021-07-02 02:33:33 +02:00
-- end of formspecs for types of preconditions, actions and effects
----------------------------------------------------------------------------
2021-06-20 02:18:32 +02:00
-- helper function
yl_speak_up.set_on_action_failure_dialog = function ( pname , data , instruction )
local dialog = yl_speak_up.speak_to [ pname ] . dialog
local nr = 1
if ( data and data.action_failure_dialog ) then
nr = data.action_failure_dialog + 1
end
2021-06-30 23:12:39 +02:00
2021-06-20 02:18:32 +02:00
local sorted_dialog_list = yl_speak_up.sort_keys ( dialog.n_dialogs )
local on_failure_dialog =
" label[0.2,9.9; " .. tostring ( instruction ) .. " If he doesn't, go to dialog:] " ..
2021-06-30 23:12:39 +02:00
" dropdown[11.0,9.6;2.7,0.6;select_on_action_failure; " ..
2021-06-20 02:18:32 +02:00
" - current one -, " ..
table.concat ( sorted_dialog_list , " , " ) .. " ; " .. tostring ( nr ) .. " ;] "
if ( nr and nr > 1 ) then
2021-06-30 23:12:39 +02:00
return on_failure_dialog ..
yl_speak_up.show_colored_dialog_text (
dialog ,
data ,
sorted_dialog_list [ nr - 1 ] ,
2021-07-01 17:24:24 +02:00
" 1.2,10.2;18.0,1.8;d_text " ,
2021-06-30 23:12:39 +02:00
" label[13.8,9.9;and show the following *modified* text:] " ,
2021-07-01 17:24:24 +02:00
" " ,
2021-07-01 22:33:19 +02:00
" button_edit_action_on_failure_text_change " )
2021-06-20 02:18:32 +02:00
end
return on_failure_dialog
end