Skip to content

Commit

Permalink
add semaphore for temporary status updates
Browse files Browse the repository at this point in the history
  • Loading branch information
white-haired-uncle authored May 13, 2024
1 parent a26b9ee commit 2067008
Showing 1 changed file with 93 additions and 0 deletions.
93 changes: 93 additions & 0 deletions lua/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1112,3 +1112,96 @@ function wesnoth.wml_actions.set_wrath_intensity(cfg)
end
wesnoth.units.to_map(unit)
end

-- [unit_status_semaphore]
--
-- first call with action=incr will save original value and set status
-- last call with action=decr (count=0) will restore original value
--
-- unit.variables.statuses.foo.original_value, where foo is a status like 'unhealable' - stores original value to restore when all custom actions are done messing with this status
-- unit.variables.statuses.foo.count - counts the number of custom actions that currently need this status set
function wesnoth.wml_actions.unit_status_semaphore(cfg)
local debug = cfg.debug or false
if debug and not debug then print("shut up luacheck") end
local unit_id = cfg.id or wml.error("[unit_status_semaphore]: missing required id=")
local status = cfg.status or wml.error("[unit_status_semaphore]: missing required status=")
local action = cfg.action or wml.error("[unit_status_semaphore]: missing required action=")

local unit = wesnoth.units.get(unit_id).__cfg
local vars = wml.get_child(unit, "variables")
local statuses = wml.get_child(vars, "statuses")
local current = {}
local had_current = false
if statuses ~= nil then
current = wml.get_child(statuses, status)
if current == nil then
current = {}
else
had_current = true
end
end
if action == "clear" then -- just clear, do not reset to original value
if statuses ~= nil then
if status == "all" then
wml.remove_child(vars, "statuses")
else
wml.remove_child(statuses, status)
if #statuses == 0 then wml.remove_child(vars, "statuses") end
end
end
elseif action == "reset" then -- clear and reset to original value
if statuses == nil then
wml.error("[unit_status_semaphore]: reset failed to find any original values")
else
if status == "all" then
for s in wml.child_range(vars, "statuses") do
wml.get_child(unit, "status")[s] = current.original_value
wml.remove_child(statuses, s)
end
else
if current == nil then
wml.error(string.format("[unit_status_semaphore]: reset failed to find original value for %s",status))
else
wml.get_child(unit, "status")[status] = current.original_value
wml.remove_child(statuses, status)
end
end
if #statuses == 0 then wml.remove_child(vars, "statuses") end
end
elseif action == "get_count" then
local variable = cfg.variable or wml.error("[unit_status_semaphore]: get_count requires variable=")
wml.variables[variable] = current.count
elseif action == "get_original" then
local variable = cfg.variable or wml.error("[unit_status_semaphore]: get_original requires variable=")
wml.variables[variable] = current.original_value
elseif action == "incr" then
if current == nil or current.count == nil or current.count == 0 then
current.count = 1
current.original_value = wml.get_child(unit, "status")[status]
wml.get_child(unit, "status")[status] = true
else
current.count = current.count + 1
end
if statuses == nil then
statuses = {}
table.insert(statuses, { status, current } )
table.insert(vars, { "statuses", statuses } )
else
if not had_current then table.insert(statuses, { status, current } ) end
end
elseif action == "decr" then
if statuses == nil or current == nil or current.count == nil or current.count == 0 then
wml.error("[unit_status_semaphore]: Cannot decrement nil/0 value")
else
current.count = current.count - 1
if current.count == 0 then
wml.get_child(unit, "status")[status] = current.original_value
wml.remove_child(statuses, status)
if #statuses == 0 then wml.remove_child(vars, "statuses") end
end
end
else
wml.error(string.format("[unit_status_semaphore]: Unknown action: %s", action))
end
wesnoth.units.to_map(unit)
end

0 comments on commit 2067008

Please sign in to comment.