yl_speak_up/fs_edit_effects.lua
2021-06-10 17:46:09 +02:00

184 lines
7.2 KiB
Lua

-- Which diffrent types of effects are available?
-- -> The following fields are part of an effect/result:
-- r_id the ID/key of the effect/result
-- r_type selected from values_what; the staffs allow to use other
-- types like "function" or "give_item" etc. - but that is not
-- supported here (cannot be edited or created; only be shown)
-- r_value used to store the subtype of r_type
--
-- a state/variable:
-- r_variable name of a variable the player has *write* access to;
-- dropdown list with allowed options
-- r_operator selected from values_operator
-- r_var_cmp_value can be set freely by the player (the variable will be
-- set to this value)
--
-- a block in the world:
-- r_pos a position in the world; determined by asking the player
-- to punch the block
-- r_node (follows from r_pos)
-- r_param2 (follows from r_pos)
--
-- a craft receipe:
-- r_value the expected craft result
-- r_craft_grid array containing the stacks in the 9 craft grid fields in string form
--
-- on_failure:
-- r_value alternate target dialog if the action failed
--
-- Unlike in preconditions, trade (the trade action already happened) and
-- inventory actions are not supported as effects.
--
-- some helper lists for creating the formspecs and evaulating
-- the player's answers:
-- general direction of what could make up an effect
local check_what = {
"- please select -",
"an internal state (i.e. of a quest)", -- 2
"a block somewhere", -- 3
"NPC crafts soemthing", -- 4
"go to other dialog if the action (i.e. trade) failed", -- 5
"send a chat message to all players", -- 6
}
-- how to store these as r_type in the precondition:
local values_what = {"", "state", "block", "craft", "on_failure", "chat_all"}
-- unlike in the preconditions, the "I cannot punch it" option is
-- not offered here - because the player (and later the NPC) needs
-- to be able to build at this position
local check_block = {
"- please select -", -- 1
"If there is air: Place a block so that it looks like now.", -- 2
"If there is a block: Dig it.", -- 3
-- TODO: not sure if punching a block (as an npc) is possible without bugs
"Punch the block.", -- 4
-- TODO: not sure if right-clicking a block (as an npc) is possible without bugs
"Right-click the block.", -- 5
}
-- how to store these as p_value (the actual node data gets stored as p_node, p_param2 and p_pos):
local values_block = {"", "place", "dig", "punch", "right-click"}
-- comparison operators for variables
local check_operator = {
"- please select -", -- 1
"set to value:", -- 2
"is no longer needed (unset)", -- 3
}
-- how to store these as r_value (the actual variable is stored in r_variable, and the value in r_new_value):
local values_operator = {"", "set_to", "unset"}
-- get the list of variables the player has *write* access to
yl_speak_up.get_sorted_player_var_list_write_access = function(pname)
local var_list = {}
-- some values - like hour of day or HP of the player - can be read in
-- a precondition but not be modified
-- get the list of variables the player can *write*
local tmp = yl_speak_up.get_quest_variables_with_write_access(pname)
-- sort that list (the dropdown formspec element returns just an index)
table.sort(tmp)
for i, v in ipairs(tmp) do
table.insert(var_list, v)
end
return var_list
end
-- returns a human-readable text as description of the effects
-- (as shown in the edit options dialog and in the edit effect formspec)
yl_speak_up.show_effect = function(r)
if(not(r.r_type) or r.r_type == "") then
return "(nothing): Nothing to do. No effect."
elseif(r.r_type == "give_item") then
return "give_item: Add \""..tostring(r.r_value).."\" to the player's inventory."
elseif(r.r_type == "take_item") then
return "take_item: Take \""..tostring(r.r_value).."\" from the player's inventory."
elseif(r.r_type == "move") then
return "move: Move the player to "..tostring(r.r_value).."."
elseif(r.r_type == "function") then
return "function: execute \""..tostring(r.r_value).."\"."
elseif(r.r_type == "trade") then
return "trade: obsolete (now defined as an action)"
elseif(r.r_type == "dialog") then
return "Switch to dialog \""..tostring(r.r_value).."\"."
elseif(r.r_type == "state") then
if(not(r.r_operator)) then
return "Error: Operator not defined."
elseif(r.r_operator == "set_to") then
return "set VARIABLE[ "..tostring(r.r_variable).." ] to value \""..
tostring(r.r_var_cmp_value).."\""
elseif(r.r_operator == "unset") then
return "discard VARIABLE[ "..tostring(r.r_variable).." ] (unset)"
else
return "ERROR: Wrong operator \""..tostring(r.r_operator).."\" for "..
"VARIABLE[ "..tostring(r.r_variable).." ]"
end
elseif(r.r_type == "block") then
if(not(r.r_pos) or type(r.r_pos) ~= "table"
or not(r.r_pos.x) or not(r.r_pos.y) or not(r.r_pos.z)) then
return "ERROR: r.r_pos is "..minetest.serialize(r.r_pos)
elseif(r.r_value == "place") then
return "Place \""..tostring(r.r_node).."\" with param2: "..tostring(r.r_param2)..
" at "..minetest.pos_to_string(p.p_pos).."."
elseif(r.r_value == "dig") then
return "Dig the block at "..minetest.pos_to_string(r.r_pos).."."
elseif(r.r_value == "punch") then
return "Punch the block at "..minetest.pos_to_string(r.r_pos).."."
elseif(r.r_value == "right-click") then
return "Right-click the block at "..minetest.pos_to_string(r.r_pos).."."
else
return "ERROR: Don't know what to do with the block at "..
minetest.pos_to_string(r.r_pos)..": \""..tostring(r.r_value).."\"?"
end
elseif(r.r_type == "craft") then
if(not(r.r_value) or not(r.r_craft_grid)) then
return "ERROR: Crafting not configured correctly."
end
-- TODO: check here if the craft receipe is broken?
return "Craft \""..tostring(r.r_value).."\" from "..table.concat(r.r_craft_grid, ", ").."."
elseif(r.r_type == "on_failure") then
return "If the action (i.e. trade) failed, go to dialog \""..tostring(r.r_value).. "\"."
elseif(r.r_type == "chat_all") then
return "Send chat message: \""..tostring(r.r_value).."\""
end
-- fallback
return tostring(r.r_value)
end
-- these are only wrapper functions for those in fs_edit_general.lua
yl_speak_up.input_fs_edit_effects = function(player, formname, fields)
return yl_speak_up.input_fs_edit_option_related(player, formname, fields,
"r_", "o_results", yl_speak_up.max_result_effects,
"(Ef)fect", "tmp_result",
"Please punch the block you want to manipulate in your effect!",
values_what, values_operator, values_block, {}, {},
check_what, check_operator, check_block, {}, {},
-- player variables with write access
yl_speak_up.get_sorted_player_var_list_write_access,
"edit_effects"
)
end
yl_speak_up.get_fs_edit_effects = function(player, table_click_result)
return yl_speak_up.get_fs_edit_option_related(player, table_click_result,
"r_", "o_results", yl_speak_up.max_result_effects,
"(Ef)fect", "tmp_result",
"What do you want to change with this effect?",
check_what, check_operator, check_block, {}, {},
-- player variables with write access
yl_speak_up.get_sorted_player_var_list_write_access,
yl_speak_up.show_effect,
"table_of_elements",
"Change the value of the following variable:", "What to do:", "New value:",
"The NPC shall do something to the block at the following position:"
)
end