export to ink: support for variables (to a degree) and precondtions (to a degree)
This commit is contained in:
parent
1c89bd7dcf
commit
13de73ecde
@ -1,7 +1,6 @@
|
||||
-- helper functions for export_to_ink_language:
|
||||
|
||||
-- TODO: include effect setting variables to values (problem: diffrent characters allowed)
|
||||
-- TODO: include preconditions/conditions regarding setting variables
|
||||
|
||||
|
||||
-- this table will hold the functions for exporting to ink so that we don't fill that namespace too much
|
||||
@ -58,18 +57,35 @@ end
|
||||
-- displayed instead (in yl_speak_up) and before (in ink) shwoing the target dialog text;
|
||||
-- also, the divert_to target dialog may need to be rewritten
|
||||
yl_speak_up.export_to_ink.print_choice = function(lines, choice_text, n_id, start_dialog,
|
||||
alternate_text, divert_to, only_once, label)
|
||||
-- don't repeat the text of the choice in the output when running ink
|
||||
alternate_text, divert_to, only_once, label,
|
||||
precondition_list, effect_list)
|
||||
-- usually, options/answers/choices can be selected multiple times;
|
||||
-- we support the default ink way of "*" as well (but only until the player stops talking,
|
||||
-- not persistently stored)
|
||||
if(not(only_once)) then
|
||||
table.insert(lines, "\n+ ")
|
||||
else
|
||||
table.insert(lines, "\n* ")
|
||||
end
|
||||
-- helps to regcognize what has been changed how when importing again
|
||||
if(label and label ~= "") then
|
||||
table.insert(lines, "(")
|
||||
table.insert(lines, tostring(label))
|
||||
table.insert(lines, ") ")
|
||||
end
|
||||
-- are there any preconditions which can be handled by ink? most can not as they can
|
||||
-- only be determined ingame (i.e. state of a block); even the value of variables may
|
||||
-- have been changed externally
|
||||
if(precondition_list and #precondition_list > 0) then
|
||||
for _, p_text in ipairs(precondition_list) do
|
||||
if(p_text ~= "") then
|
||||
table.insert(lines, "{ ")
|
||||
table.insert(lines, p_text)
|
||||
table.insert(lines, " } ")
|
||||
end
|
||||
end
|
||||
end
|
||||
-- don't repeat the text of the choice in the output when running ink
|
||||
table.insert(lines, "[")
|
||||
table.insert(lines, choice_text)
|
||||
table.insert(lines, "]")
|
||||
@ -85,6 +101,16 @@ yl_speak_up.export_to_ink.print_choice = function(lines, choice_text, n_id, star
|
||||
-- write the divert into a new line as well
|
||||
table.insert(lines, "\n ")
|
||||
end
|
||||
-- setting a variable to a value is something we can model in ink as well
|
||||
if(effect_list and #effect_list > 0) then
|
||||
for _, e_text in ipairs(effect_list) do
|
||||
table.insert(lines, "\n ~ ")
|
||||
table.insert(lines, e_text)
|
||||
end
|
||||
-- the divert needs to be put into a new line
|
||||
table.insert(lines, "\n")
|
||||
end
|
||||
-- actually go to the dialog this option leads to
|
||||
table.insert(lines, " -> ")
|
||||
if(not(start_dialog) or start_dialog == "") then
|
||||
start_dialog = "d_1"
|
||||
@ -182,6 +208,117 @@ yl_speak_up.export_to_ink.print_effect_knot = function(lines, n_id, d_id, o_id,
|
||||
end
|
||||
|
||||
|
||||
-- which variables are used by this NPC?
|
||||
yl_speak_up.export_to_ink.print_variables_used = function(lines, dialog, n_id, pname)
|
||||
if(not(dialog) or not(dialog.n_dialogs)) then
|
||||
return
|
||||
end
|
||||
local vars_used = {}
|
||||
for d_id, d_data in pairs(dialog.n_dialogs or {}) do
|
||||
for o_id, o_data in pairs(d_data.d_options or {}) do
|
||||
-- variables may be used in preconditions
|
||||
for p_id, p in pairs(o_data.o_prerequisites or {}) do
|
||||
-- we are checking the state of a variable
|
||||
if(p and p.p_type and p.p_type == "state") then
|
||||
-- store as key in order to avoid duplicates
|
||||
vars_used[ p.p_variable ] = true
|
||||
-- properties are comparable to variables
|
||||
elseif(p and p.p_type and p.p_type == "property") then
|
||||
vars_used[ "property "..p.p_value ] = true
|
||||
end
|
||||
end
|
||||
for r_id, r in pairs(o_data.o_results or {}) do
|
||||
if(r and r.r_type and r.r_type == "state") then
|
||||
vars_used[ r.r_variable ] = true
|
||||
elseif(r and r.r_type and r.r_type == "property") then
|
||||
vars_used[ "property "..r.r_value ] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(lines, "\n")
|
||||
-- we stored as key/value in order to avoid duplicates
|
||||
for var_name, _ in pairs(vars_used) do
|
||||
-- replace blanks with an underscore in an attempt to turn it into a legal var name
|
||||
-- (this is not really sufficient as var names in yl_speak_up are just strings,
|
||||
-- while the ink language expects sane var names like other lanugages)
|
||||
-- TODO: this is not necessarily a legitimate var name!
|
||||
local parts = string.split(var_name, " ")
|
||||
table.remove(parts, 1)
|
||||
local v_name = table.concat(parts, "_")
|
||||
-- stor it for later use
|
||||
vars_used[var_name] = v_name
|
||||
-- add the variable as a variable to INK
|
||||
table.insert(lines, "\nVAR ")
|
||||
table.insert(lines, v_name)
|
||||
table.insert(lines, " = NONE") -- start with undefined/nil (we don't know the stored value)
|
||||
end
|
||||
table.insert(lines, "\n")
|
||||
return vars_used
|
||||
end
|
||||
|
||||
|
||||
-- which preconditions and effects can be modelled in ink?
|
||||
--
|
||||
-- in singleplayer adventures, properties can be relevant as well;
|
||||
-- in multiplayer, other players may affect the state of the property
|
||||
--
|
||||
-- *some* functions may be relevant here:
|
||||
-- (but not for variables)
|
||||
-- * compare a variable with a variable
|
||||
-- * counted dialog option visits
|
||||
-- * counted option visits
|
||||
--
|
||||
-- types "true" and "false" can be relevant later on
|
||||
|
||||
-- small helper function
|
||||
local var_with_operator = function(liste, var_name, op, var_cmp_value, vars_used)
|
||||
-- visits are not stored as variables in ink
|
||||
if(not(vars_used[var_name])) then
|
||||
vars_used[var_name] = var_name
|
||||
end
|
||||
if(op == "~=") then
|
||||
op = "!="
|
||||
end
|
||||
if(op=="==" or op=="!=" or op==">=" or op==">" or op=="<=" or op==">") then
|
||||
table.insert(liste, tostring(vars_used[var_name]).." ".. op.." "..tostring(var_cmp_value))
|
||||
elseif(op=="not") then
|
||||
table.insert(liste, "not "..tostring(vars_used[var_name]))
|
||||
elseif(op=="is_set") then
|
||||
table.insert(liste, tostring(vars_used[var_name]))
|
||||
elseif(op=="is_unset") then
|
||||
table.insert(liste, tostring(vars_used[var_name]).." == NONE")
|
||||
end
|
||||
-- the following values for op cannot really be checked here and are not printed:
|
||||
-- "more_than_x_seconds_ago","less_than_x_seconds_ago",
|
||||
-- "quest_step_done", "quest_step_not_done"
|
||||
end
|
||||
|
||||
yl_speak_up.export_to_ink.translate_precondition_list = function(dialog, preconditions, vars_used, n_id)
|
||||
-- collect preconditions that may work in ink
|
||||
local liste = {}
|
||||
-- variables may be used in preconditions
|
||||
for p_id, p in pairs(preconditions or {}) do
|
||||
if(p and p.p_type and p.p_type == "state") then
|
||||
-- state changes of variables may mostly work in ink as well
|
||||
var_with_operator(liste, p.p_variable, p.p_operator, p.p_var_cmp_value, vars_used)
|
||||
elseif(p and p.p_type and p.p_type == "property") then
|
||||
-- same with properties
|
||||
var_with_operator(liste, p.p_value, p.p_operator, p.p_var_cmp_value, vars_used)
|
||||
elseif(p and p.p_type and p.p_type == "evaluate" and p.p_value == "counted_visits_to_option") then
|
||||
-- simulate the visit counter that ink has in yl_speak_up
|
||||
local tmp_var_name = n_id.."_"..p.p_param1.."_"..p.p_param2
|
||||
var_with_operator(liste, tmp_var_name, p.p_operator, p.p_var_cmp_value, vars_used)
|
||||
elseif(p and p.p_type and p.p_type == "true") then
|
||||
table.insert(liste, p.p_type)
|
||||
elseif(p and p.p_type and p.p_type == "false") then
|
||||
table.insert(liste, p.p_type)
|
||||
end
|
||||
end
|
||||
return liste
|
||||
end
|
||||
|
||||
|
||||
yl_speak_up.export_to_ink_language = function(dialog, n_id)
|
||||
local start_dialog = yl_speak_up.get_start_dialog_id(dialog)
|
||||
if(not(start_dialog)) then
|
||||
@ -194,6 +331,9 @@ yl_speak_up.export_to_ink_language = function(dialog, n_id)
|
||||
"\nWhat do you wish to do?",
|
||||
"\n+ Talk to ", tostring(dialog.n_npc), " -> ", tostring(n_id).."_"..tostring(start_dialog),
|
||||
"\n+ End -> END"}
|
||||
|
||||
local vars_used = ink_export.print_variables_used(tmp, dialog, n_id, pname)
|
||||
|
||||
local sorted_d_list = yl_speak_up.sort_keys(dialog.n_dialogs or {}, true)
|
||||
for i, d_id in ipairs(sorted_d_list) do
|
||||
-- store the knots for actions and effects here:
|
||||
@ -265,13 +405,18 @@ yl_speak_up.export_to_ink_language = function(dialog, n_id)
|
||||
alternate_text_on_success = ""
|
||||
end
|
||||
|
||||
-- which preconditions can be translated to ink?
|
||||
local p_list = ink_export.translate_precondition_list(dialog, o_data.o_prerequisites,
|
||||
vars_used, n_id)
|
||||
local e_list = {} --TODO
|
||||
|
||||
-- what remains is to print the option/choice itself
|
||||
ink_export.print_choice(tmp,
|
||||
-- TODO: deal with when_prerequisites_not_met
|
||||
o_data.o_text_when_prerequisites_met, n_id, start_dialog,
|
||||
alternate_text_on_success, target_dialog,
|
||||
o_data.o_visit_only_once,
|
||||
o_id)
|
||||
o_id, p_list, e_list)
|
||||
end -- dealt with the option
|
||||
table.insert(tmp, "\n")
|
||||
-- add way to end talking to the NPC
|
||||
|
Loading…
Reference in New Issue
Block a user