mirror of
https://gitea.your-land.de/Sokomine/yl_speak_up.git
synced 2025-06-25 00:28:03 +02:00
added yl_speak_up.execute_next_action and general action handling
This commit is contained in:
parent
2290f9d463
commit
9ed4cfc92d
@ -119,13 +119,100 @@ yl_speak_up.show_action = function(a)
|
||||
end
|
||||
|
||||
|
||||
yl_speak_up.execute_all_actions = function(player, actions, o_id)
|
||||
-- TODO: implement execute_all_actions
|
||||
-- actions - in contrast to preconditions and effects - may take time
|
||||
-- because the player usually gets presented a formspec and needs to
|
||||
-- react to that; thus, we can't just execute all actions simultaneously
|
||||
yl_speak_up.execute_next_action = function(player, a_id, result_of_a_id)
|
||||
local pname = player:get_player_name()
|
||||
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 dialog = yl_speak_up.speak_to[pname].dialog
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Last action: "..tostring(a_id).." returned "..
|
||||
tostring(result_of_a_id)..".")
|
||||
local actions = {}
|
||||
local effects = {}
|
||||
local sorted_key_list = {}
|
||||
if(dialog
|
||||
and dialog.n_dialogs
|
||||
and dialog.n_dialogs[d_id]
|
||||
and dialog.n_dialogs[d_id].d_options
|
||||
and dialog.n_dialogs[d_id].d_options[o_id]
|
||||
and dialog.n_dialogs[d_id].d_options[o_id].actions) then
|
||||
-- get the actual actions
|
||||
actions = dialog.n_dialogs[d_id].d_options[o_id].actions
|
||||
-- needed later on when all actions are executed
|
||||
effects = dialog.n_dialogs[d_id].d_options[o_id].o_results
|
||||
-- sort the actions so that we can execute them always in the
|
||||
-- same order
|
||||
sorted_key_list = yl_speak_up.sort_keys(actions)
|
||||
local nr = 0
|
||||
if(a_id) then
|
||||
nr = table.indexof(sorted_key_list, a_id)
|
||||
-- did the action fail?
|
||||
if(nr > -1 and not(result_of_a_id)) then
|
||||
local this_action = actions[ sorted_key_list[ nr ]]
|
||||
-- if there is an on_failure target dialog: go there
|
||||
if(this_action.a_on_failure) then
|
||||
-- set the current action to nil
|
||||
yl_speak_up.speak_to[pname].a_id = nil
|
||||
-- no option of the new dialog has been selected yet
|
||||
yl_speak_up.speak_to[pname].o_id = nil
|
||||
-- show the new dialog
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Action "..
|
||||
tostring(a_id).." failed. Switching to dialog "..
|
||||
tostring(this_action.a_on_failure)..".")
|
||||
yl_speak_up.show_fs(player, "talk", {n_id = n_id,
|
||||
d_id = this_action.a_on_failure})
|
||||
return
|
||||
else
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Action "..
|
||||
tostring(a_id).." failed, but no a_on_failure target "..
|
||||
"dialog defined. Continuing execution.")
|
||||
end
|
||||
end
|
||||
end
|
||||
-- get the next entry
|
||||
if(nr > -1 and nr < #sorted_key_list and sorted_key_list[nr + 1]) then
|
||||
local next_action = actions[ sorted_key_list[ nr + 1 ]]
|
||||
-- store which action we are currently executing
|
||||
yl_speak_up.speak_to[pname].a_id = next_action.a_id
|
||||
-- execute the next action
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Executing next action "..
|
||||
tostring(next_action.a_id)..".")
|
||||
yl_speak_up.execute_action(player, n_id, o_id, next_action)
|
||||
-- the player needs time to react
|
||||
return
|
||||
end
|
||||
end
|
||||
-- when all actions are executed:
|
||||
-- set the current action to nil
|
||||
yl_speak_up.speak_to[pname].a_id = nil
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "All actions have been executed successfully. "..
|
||||
"Doing effects/results now.")
|
||||
-- execute all effects/results
|
||||
local target_dialog = yl_speak_up.execute_all_relevant_effects(player, effects, o_id, true)
|
||||
-- the function above returns a target dialog; show that to the player
|
||||
yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = target_dialog})
|
||||
end
|
||||
|
||||
|
||||
yl_speak_up.execute_action = function(player, n_id, o_id, r)
|
||||
-- TODO: implement execute_action. boils down to showing formspecs
|
||||
yl_speak_up.execute_action = function(player, n_id, o_id, a)
|
||||
if(not(a.a_type) or a.a_type == "" or a.a_type == "none") then
|
||||
-- no action - nothing to do
|
||||
return true
|
||||
elseif(a.a_type == "trade") then
|
||||
yl_speak_up.show_fs(player, "trade_simple", a.a_value)
|
||||
return
|
||||
elseif(a.a_type == "npc_gives") then
|
||||
-- TODO implement npc_gives action
|
||||
elseif(a.a_type == "npc_wants") then
|
||||
-- TODO implement npc_wants action
|
||||
elseif(a.a_type == "text_input") then
|
||||
-- TODO implement text_input action
|
||||
elseif(a.a_type == "custom") then
|
||||
-- TODO implement custom action
|
||||
end
|
||||
-- fallback: unkown type
|
||||
return false
|
||||
end
|
||||
|
@ -2450,6 +2450,26 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
|
||||
local dialog = yl_speak_up.speak_to[pname].dialog
|
||||
|
||||
-- we may soon need actions and o_results from the selected_option
|
||||
local selected_option = {}
|
||||
if(d_id and o and dialog
|
||||
and dialog.n_dialogs
|
||||
and dialog.n_dialogs[d_id]
|
||||
and dialog.n_dialogs[d_id].d_options
|
||||
and dialog.n_dialogs[d_id].d_options[o]) then
|
||||
selected_option = dialog.n_dialogs[d_id].d_options[o]
|
||||
end
|
||||
|
||||
if(not(edit_mode)) then
|
||||
-- abort if the option does not exist
|
||||
if(not(selected_option)) then
|
||||
return
|
||||
end
|
||||
yl_speak_up.speak_to[pname].o_id = o
|
||||
-- start with executing the first action
|
||||
yl_speak_up.execute_next_action(player, nil, true)
|
||||
return
|
||||
end
|
||||
|
||||
-- all three buttons (pre(C)onditions, (Ef)fects, edit option) lead to the same new formspec
|
||||
if( edit_mode ) then
|
||||
@ -2468,15 +2488,25 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- in edit mode: another dialog was selected
|
||||
if ( o == "" and edit_mode) then
|
||||
-- in edit mode: has another dialog been selected?
|
||||
-- if nothing better can be found: keep the old dialog
|
||||
local show_dialog = d_id
|
||||
-- an option button was selected;
|
||||
-- since we do not execute actions and effects in edit mode, we need to find out the
|
||||
-- right target dialog manually (and assume all went correct)
|
||||
if( o ~= "" ) then
|
||||
-- find out the normal target dialog of this option
|
||||
if(selected_option and selected_option.o_results) then
|
||||
for k, v in pairs(selected_option.o_results) do
|
||||
if(v and v.r_type == "dialog") then
|
||||
show_dialog = v.v_value
|
||||
end
|
||||
end
|
||||
end
|
||||
-- dropdown menu was used; provided the dialog exists (and it's not the "New dialog" option)
|
||||
-- (if a new dialog was added using the "+" button, fields.d_id gets set accordingly)
|
||||
if(fields.d_id and fields.d_id ~= show_dialog and dialog.n_dialogs[fields.d_id]) then
|
||||
elseif(fields.d_id and fields.d_id ~= show_dialog and dialog.n_dialogs[fields.d_id]) then
|
||||
show_dialog = fields.d_id
|
||||
-- in edit mode: prev_dialog_../next_dialog_.. was selected
|
||||
else
|
||||
@ -2498,42 +2528,9 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
-- no option was selected - so we need to end this here
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local n_dialog = dialog.n_dialogs[d_id]
|
||||
|
||||
-- if there are no options, there can be no results either
|
||||
if(not(n_dialog) or not(n_dialog.d_options)) then
|
||||
return
|
||||
end
|
||||
|
||||
local d_option = n_dialog.d_options[o]
|
||||
|
||||
-- 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
|
||||
|
||||
-- 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?
|
||||
yl_speak_up.speak_to[pname].target_d_id = target_dialog
|
||||
-- show the trade dialog
|
||||
yl_speak_up.show_fs(player, "trade_simple", trade_id)
|
||||
return
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
||||
|
||||
-- Make the NPC talk
|
||||
|
||||
function yl_speak_up.config(clicker, npc)
|
||||
|
@ -140,30 +140,16 @@ yl_speak_up.input_do_trade_simple = function(player, formname, fields)
|
||||
|
||||
-- go back to the main dialog
|
||||
if(fields.abort_trade_simple or fields.quit or fields.finished_trading) then
|
||||
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 target_dialog = d_id
|
||||
-- if at least one successful trade has happened: show the target dialog
|
||||
-- (else show the current dialog again)
|
||||
if(trade and trade.trade_done > 0 and yl_speak_up.speak_to[pname].target_d_id) then
|
||||
target_dialog = yl_speak_up.speak_to[pname].target_d_id
|
||||
end
|
||||
-- was the action a success?
|
||||
local success = not(not(trade and trade.trade_done and trade.trade_done > 0))
|
||||
local a_id = trade.a_id
|
||||
yl_speak_up.debug_msg(player, n_id, o_id, "Ending trade.")
|
||||
-- done trading
|
||||
yl_speak_up.speak_to[pname].target_d_id = nil
|
||||
yl_speak_up.speak_to[pname].trade_id = nil
|
||||
|
||||
-- if in edit mode: go back to the edit options dialog
|
||||
if(yl_speak_up.edit_mode[pname] == n_id and n_id and o_id) then
|
||||
-- go to the edit options dialog
|
||||
yl_speak_up.show_fs(player, "edit_option_dialog",
|
||||
{n_id = n_id, d_id = d_id, o_id = o_id})
|
||||
return
|
||||
-- show either the current or the target dialog
|
||||
elseif(target_dialog) then
|
||||
yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = target_dialog})
|
||||
return
|
||||
end
|
||||
-- execute the next action
|
||||
yl_speak_up.execute_next_action(player, a_id, success)
|
||||
return
|
||||
end
|
||||
|
||||
-- show this formspec again
|
||||
@ -564,6 +550,8 @@ yl_speak_up.get_fs_trade_simple = function(player, trade_id)
|
||||
trade.edit_trade = true
|
||||
end
|
||||
yl_speak_up.trade[pname] = trade
|
||||
-- store which action we are working at
|
||||
trade.a_id = yl_speak_up.speak_to[pname].a_id
|
||||
else
|
||||
trade_id = yl_speak_up.speak_to[pname].trade_id
|
||||
trade.trade_id = trade_id
|
||||
|
Loading…
Reference in New Issue
Block a user