Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Micro AIs: simplify unit variable handling functions
The main reason for doing this, besides simplifying the code, is to avoid using the WML table dump __cfg, which is slow. This includes a change of the format in which the variables are stored, but since these are internal Micro AI utility functions, that does not matter. (cherry-picked from commit 133568e)
- Loading branch information
Showing
1 changed file
with
30 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,50 @@ | ||
-- This set of functions provides a consistent way of storing Micro AI | ||
-- variables in units. They need to be stored inside a [micro_ai] tag in a | ||
-- unit's [variables] tag together with an ai_id= key, so that they can be | ||
-- removed when the Micro AI gets deleted. Otherwise subsequent Micro AIs used | ||
-- in the same scenario (or using the same units in later scenarios) might work | ||
-- incorrectly or not at all. | ||
-- Note that, with this method, there can only ever be one of these tags for each | ||
-- ai_ca in each unit (but of course several when there are several Micro AIs | ||
-- with different ai_CA values affecting the same unit) | ||
-- For the time being, we only allow key=value style variables. | ||
-- variables in units. Individual variables are stored inside a table with a | ||
-- name specific to the MAI ('micro_ai-' .. ai_id). This table is removed when | ||
-- the Micro AI is deleted in order to ensure that subsequent Micro AIs used | ||
-- in the same scenario (or using the same units in later scenarios) work | ||
-- correctly. | ||
-- Note that, with this method, there can only ever be one of these tables for each | ||
-- ai_id in each unit, but several tables are created for the same unit when there | ||
-- are several Micro AIs with different ai_id values. | ||
-- For the time being, we do not allow sub-tables. This is done because these | ||
-- unit variables are required to be persistent across save-load cycles and | ||
-- therefore need to be in WML table format. This could be extended to allow | ||
-- sub-tables in WML format, but there is no need for that at this time. | ||
|
||
local micro_ai_unit_variables = {} | ||
|
||
function micro_ai_unit_variables.modify_mai_unit_variables(unit, ai_id, action, vars_table) | ||
-- Modify [unit][variables][micro_ai] tags | ||
-- @ai_id (string): the id of the Micro AI | ||
-- @action (string): "delete", "set" or "insert" | ||
-- @vars_table: table of key=value pairs with the variables to be set or inserted (not needed for @action="delete") | ||
|
||
local variables = unit.variables.__cfg | ||
|
||
-- Always delete the respective [variables][micro_ai] tag, if it exists | ||
local existing_table | ||
for i,mai in ipairs(variables) do | ||
if (mai[1] == "micro_ai") and (mai[2].ai_id == ai_id) then | ||
existing_table = mai[2] | ||
table.remove(variables, i) | ||
break | ||
end | ||
end | ||
|
||
-- Then replace it, if the "set" action is selected | ||
-- or add the new keys to it, overwriting old ones with the same name, if action == "insert" | ||
if (action == "set") or (action == "insert") then | ||
local tag = { "micro_ai" } | ||
|
||
if (not existing_table) or (action == "set") then | ||
tag[2] = vars_table | ||
tag[2].ai_id = ai_id | ||
else | ||
for k,v in pairs(vars_table) do existing_table[k] = v end | ||
tag[2] = existing_table | ||
end | ||
|
||
table.insert(variables, tag) | ||
end | ||
|
||
-- All of this so far was only on the table dump -> apply to unit | ||
unit.variables.__cfg = variables | ||
end | ||
|
||
function micro_ai_unit_variables.delete_mai_unit_variables(unit, ai_id) | ||
micro_ai_unit_variables.modify_mai_unit_variables(unit, ai_id, "delete") | ||
unit.variables['micro_ai_' .. ai_id] = nil | ||
end | ||
|
||
function micro_ai_unit_variables.insert_mai_unit_variables(unit, ai_id, vars_table) | ||
micro_ai_unit_variables.modify_mai_unit_variables(unit, ai_id, "insert", vars_table) | ||
local mai_var = unit.variables['micro_ai_' .. ai_id] or {} | ||
-- Restrict to top-level named fields | ||
for k,v in pairs(vars_table) do mai_var[k] = v end | ||
unit.variables['micro_ai_' .. ai_id] = mai_var | ||
end | ||
|
||
function micro_ai_unit_variables.set_mai_unit_variables(unit, ai_id, vars_table) | ||
micro_ai_unit_variables.modify_mai_unit_variables(unit, ai_id, "set", vars_table) | ||
local mai_var = {} | ||
-- Restrict to top-level named fields | ||
for k,v in pairs(vars_table) do mai_var[k] = v end | ||
unit.variables['micro_ai_' .. ai_id] = mai_var | ||
end | ||
|
||
function micro_ai_unit_variables.get_mai_unit_variables(unit, ai_id, key) | ||
-- Get the content of [unit][variables][micro_ai] tag for the given @ai_id | ||
-- Get the content of [unit][variables]['micro_ai_' .. ai_id] tag | ||
-- Return value: | ||
-- - If tag is found: value of key if @key parameter is given, otherwise | ||
-- table of key=value pairs (including the ai_id key) | ||
-- - If no such tag is found: nil (if @key is set), otherwise empty table | ||
-- - If tag is found: value of key if @key parameter is given, otherwise entire table | ||
-- - If no such tag is found: nil if @key is given, otherwise empty table | ||
|
||
for mai in wml.child_range(unit.variables.__cfg, "micro_ai") do | ||
if (mai.ai_id == ai_id) then | ||
if key then | ||
return mai[key] | ||
else | ||
return mai | ||
end | ||
end | ||
end | ||
local mai_var = unit.variables['micro_ai_' .. ai_id] or {} | ||
|
||
-- If we got here, no corresponding tag was found | ||
-- Return empty table; or nil if @key was set | ||
if (not key) then return {} end | ||
if key then | ||
return mai_var[key] | ||
else | ||
return mai_var | ||
end | ||
end | ||
|
||
return micro_ai_unit_variables |