forked from Sokomine/yl_speak_up
yl_speak_up.execute_all_relevant_effects
This commit is contained in:
parent
7cfad9586a
commit
d3d90134ee
@ -155,6 +155,65 @@ yl_speak_up.show_effect = function(r)
|
||||
end
|
||||
|
||||
|
||||
-- called by yl_speak_up.input_talk(..); -- TODO
|
||||
-- This function is called *after* the player has clicked on an option
|
||||
-- and *after* any actions (i.e. trade) have been completed either
|
||||
-- successfully (=action_was_succesful is true) or not.
|
||||
-- Unlike the preconditions, the effects are executed in ordered form,
|
||||
-- ordered by their r_id.
|
||||
-- Returns the new target dialog that is to be displayed next. This will
|
||||
-- usually be the one with the r_type "dialog" - unless r_type "on_failure"
|
||||
-- was encountered after an unsuccessful action *or* right after an
|
||||
-- effect that returned false.
|
||||
-- Note: In edit mode, effects will *not* be executed.
|
||||
yl_speak_up.execute_all_relevant_effects = function(player, effects, o_id, action_was_successful)
|
||||
local target_dialog = ""
|
||||
if(not(effects)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "No effects given.")
|
||||
-- no effects? Then...return to the start dialog
|
||||
return ""
|
||||
end
|
||||
local pname = player:get_player_name()
|
||||
local n_id = yl_speak_up.speak_to[pname].n_id
|
||||
local edit_mode = (yl_speak_up.edit_mode[pname] == n_id)
|
||||
if(not(edit_mode)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Executing effects.")
|
||||
else
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Not executing effects because in edit mode.")
|
||||
end
|
||||
local last_result = action_was_successful
|
||||
-- Important: the list of effects is *sorted* here. The order remains constant!
|
||||
local sorted_key_list = yl_speak_up.sort_keys(effects)
|
||||
for i, k in ipairs(sorted_key_list) do
|
||||
local r = effects[ k ]
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "..executing "..
|
||||
tostring(r.r_id)..": "..yl_speak_up.show_effect(r))
|
||||
-- do not execute effects in edit mode
|
||||
if(not(edit_mode)) then
|
||||
local res = yl_speak_up.execute_effect(player, n_id, o_id, r)
|
||||
if(not(res)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id)..
|
||||
" -> Effect failed to execute.")
|
||||
end
|
||||
end
|
||||
-- "dialog" gives us the normal target_dialog
|
||||
if(r.r_type and r.r_type == "dialog") then
|
||||
target_dialog = r.r_value
|
||||
-- "on_failure" gives an alternate target dialog if the action
|
||||
-- or last effect failed
|
||||
elseif(r.r_type and r.r_type == "on_failure" and r.r_value and not(last_result)) then
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Aborted executing effects at "..
|
||||
tostring(r.r_id)..". New target dialog: "..tostring(r.r_value)..".")
|
||||
-- we also stop execution here
|
||||
return r.r_value
|
||||
end
|
||||
end
|
||||
-- all preconditions are true
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Finished executing effects.")
|
||||
return target_dialog
|
||||
end
|
||||
|
||||
|
||||
-- executes an effect/result r for the player and npc n_id;
|
||||
-- returns true on success (relevant for on_failure)
|
||||
-- TODO: in edit mode, nothing gets executed except perhaps dialog
|
||||
@ -165,8 +224,9 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
|
||||
elseif(r.r_type == "auto" or r.r_type == "trade") then
|
||||
-- these effects don't do anything
|
||||
return true
|
||||
elseif(r.r_type == "dialog") then
|
||||
-- TODO: how to handle target dialog?
|
||||
elseif(r.r_type == "dialog"
|
||||
or r.r_type == "on_failure") then
|
||||
-- this needs to be handled in the calling function
|
||||
return true
|
||||
elseif(r.r_type == "function") then
|
||||
-- this can only be set and edited with the staff
|
||||
@ -338,9 +398,6 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r)
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, tostring(r_id).." "..
|
||||
"Great: Crafting is possible!")
|
||||
return true
|
||||
-- "go to other dialog if the action (i.e. trade) failed", -- 5
|
||||
elseif(r.r_type == "on_failure") then
|
||||
-- TODO: implement effect on_failure
|
||||
-- "send a chat message to all players", -- 6
|
||||
elseif(r.r_type == "chat_all") then
|
||||
local pname = player:get_player_name()
|
||||
|
110
functions.lua
110
functions.lua
@ -2510,103 +2510,14 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
|
||||
local d_option = n_dialog.d_options[o]
|
||||
|
||||
-- which dialog do we have to show next? default: keep this one
|
||||
local target_dialog = d_id
|
||||
-- which dialog do we have to show next?
|
||||
-- determine that by executing the effects
|
||||
local target_dialog = yl_speak_up.execute_all_relevant_effects(
|
||||
player, d_option.o_results, o, true) --action_was_successful) --TODO
|
||||
|
||||
-- Let's do something if results exist
|
||||
if d_option.o_results ~= nil then
|
||||
for k, v in pairs(d_option.o_results) do
|
||||
-- in edit_mode, only the switching to the next dialog is executed (we want to edit,
|
||||
-- not solve quests, get/take items, teleport...)
|
||||
if not(edit_mode) and v.r_type == "give_item" then
|
||||
local item = ItemStack(v.r_value)
|
||||
|
||||
if minetest.registered_items[item:get_name()] ~= nil then
|
||||
local r = player:get_inventory():add_item("main", item)
|
||||
else
|
||||
say("Item not found!")
|
||||
end
|
||||
end
|
||||
if not(edit_mode) and v.r_type == "take_item" then
|
||||
local item = ItemStack(v.r_value)
|
||||
|
||||
if minetest.registered_items[item:get_name()] ~= nil then
|
||||
local r = player:get_inventory():remove_item("main", item)
|
||||
else
|
||||
say("Item not found!")
|
||||
end
|
||||
end
|
||||
if not(edit_mode) and v.r_type == "move" then
|
||||
local target_pos = nil
|
||||
local target_pos_valid = false
|
||||
|
||||
--pos like (100,20,400)
|
||||
if minetest.string_to_pos(v.r_value) then
|
||||
target_pos = minetest.string_to_pos(v.r_value)
|
||||
target_pos_valid = true
|
||||
end
|
||||
|
||||
--pos like 100,20,400
|
||||
local maybe = string.split(v.r_value, ",")
|
||||
if not target_pos_valid and maybe and tonumber(maybe[1]) and tonumber(maybe[2]) and tonumber(maybe[3]) and maybe[4] == nil and
|
||||
tonumber(maybe[1]) <= 32000 and tonumber(maybe[1]) >= -32000 and
|
||||
tonumber(maybe[2]) <= 32000 and tonumber(maybe[2]) >= -32000 and
|
||||
tonumber(maybe[3]) <= 32000 and tonumber(maybe[3]) >= -32000 then
|
||||
target_pos = {x=maybe[1],y=maybe[2],z=maybe[3]}
|
||||
target_pos_valid = true
|
||||
end
|
||||
|
||||
--pos like {x=100,y=20,z=400}
|
||||
if not target_pos_valid and string.sub(v.r_value,1,1) == "{" and string.sub(v.r_value,-1,-1) == "}" then
|
||||
local might_be_pos = minetest.deserialize("return " .. v.r_value)
|
||||
if tonumber(might_be_pos.x) and tonumber(might_be_pos.x) <= 32000 and tonumber(might_be_pos.x) >= -32000 and
|
||||
tonumber(might_be_pos.y) and tonumber(might_be_pos.y) <= 32000 and tonumber(might_be_pos.y) >= -32000 and
|
||||
tonumber(might_be_pos.z) and tonumber(might_be_pos.z) <= 32000 and tonumber(might_be_pos.z) >= -32000 then
|
||||
target_pos = might_be_pos
|
||||
target_pos_valid = true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if target_pos_valid == true then
|
||||
player:set_pos(target_pos)
|
||||
if vector.distance(player:get_pos(),target_pos) >= 2 then
|
||||
say("Something went wrong! Player wasn't moved properly.")
|
||||
end
|
||||
end
|
||||
|
||||
-- Debug
|
||||
if target_pos_valid == false then
|
||||
local obj = yl_speak_up.speak_to[pname].obj
|
||||
local n_id = yl_speak_up.speak_to[pname].n_id
|
||||
local npc = get_number_from_id(n_id)
|
||||
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 move player "..pname.." because the content of "..v.r_id.." is wrong:"..dump(v.r_value))
|
||||
else
|
||||
minetest.log("error","[MOD] yl_speak_up: NPC with unknown ID or without proper object could not move player "..dump(pname).." because the content of "..v.r_id.." is wrong:"..dump(v.r_value))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
if not(edit_mode) and v.r_type == "function" then
|
||||
yl_speak_up.eval_and_execute_function(player, v, "r_")
|
||||
|
||||
end
|
||||
if v.r_type == "dialog" then
|
||||
if dialog.n_dialogs[v.r_value] ~= nil then
|
||||
target_dialog = v.r_value
|
||||
else
|
||||
say("This dialog does not exist")
|
||||
end
|
||||
end
|
||||
if v.r_type == "auto" then
|
||||
say("auto forward")
|
||||
end
|
||||
end -- end of loop over d_option.o_results
|
||||
|
||||
-- if there is a trade associated with this dialog and option, show that trade now
|
||||
local trade_id = tostring(d_id).." "..tostring(o)
|
||||
if(dialog.trades and dialog.trades[ trade_id ]) then
|
||||
-- if there is a trade associated with this dialog and option, show that trade now
|
||||
local trade_id = tostring(d_id).." "..tostring(o)
|
||||
if(dialog.trades and dialog.trades[ trade_id ]) then
|
||||
-- remember which option was selected
|
||||
yl_speak_up.speak_to[pname].o_id = o
|
||||
-- which dialog shall be shown in case of a successful trade?
|
||||
@ -2614,14 +2525,13 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
-- show the trade dialog
|
||||
yl_speak_up.show_fs(player, "trade_simple", trade_id)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- else switch to the target dialog as stated in results/effects
|
||||
if(target_dialog ~= d_id) then
|
||||
-- else switch to the target dialog as stated in results/effects
|
||||
if(target_dialog ~= d_id) then
|
||||
-- if there are any changes done: ask first and don't switch to the new dialog yet
|
||||
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, target_dialog)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user