186 lines
5.2 KiB
Lua
186 lines
5.2 KiB
Lua
--lua/syndrome-util.lua
|
|
--author expwnent
|
|
--some utilities for adding syndromes to units
|
|
|
|
local _ENV = mkmodule("syndrome-util")
|
|
local utils = require("utils")
|
|
|
|
function findUnitSyndrome(unit,syn_id)
|
|
for index,syndrome in ipairs(unit.syndromes.active) do
|
|
if syndrome['type'] == syn_id then
|
|
return syndrome
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
--usage: syndromeUtil.ResetPolicy.DoNothing, syndromeUtil.ResetPolicy.ResetDuration, etc
|
|
ResetPolicy = ResetPolicy or utils.invert({
|
|
"DoNothing",
|
|
"ResetDuration",
|
|
"AddDuration",
|
|
"NewInstance"
|
|
})
|
|
|
|
function eraseSyndromeData(unit,syndromeId,oldestFirst)
|
|
for i = (oldestFirst and 0) or #unit.body.wounds-1,(oldestFirst and #unit.body.wounds-1) or 0,(oldestFirst and 1) or -1 do
|
|
if unit.body.wounds[i].syndrome_id == syndromeId then
|
|
unit.body.wounds:erase(i)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
function eraseSyndrome(unit,syndromeId,oldestFirst)
|
|
local i1
|
|
local iN
|
|
local d
|
|
if oldestFirst then
|
|
i1 = 0
|
|
iN = #unit.syndromes.active-1
|
|
d = 1
|
|
else
|
|
i1 = #unit.syndromes.active-1
|
|
iN = 0
|
|
d = -1
|
|
end
|
|
local syndromes = unit.syndromes.active
|
|
for i=i1,iN,d do
|
|
if syndromes[i]['type'] == syndromeId then
|
|
eraseSyndromeData(unit,syndromeId,oldestFirst)
|
|
syndromes:erase(i)
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function eraseSyndromeClassHelper(unit,synclass)
|
|
for i,unitSyndrome in ipairs(unit.syndromes.active) do
|
|
local syndrome = df.syndrome.find(unitSyndrome.type)
|
|
for _,class in ipairs(syndrome.syn_class) do
|
|
if class.value == synclass then
|
|
eraseSyndromeData(unit,syndrome.id)
|
|
unit.syndromes.active:erase(i)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function eraseSyndromeClass(unit,synclass)
|
|
local count=0
|
|
while eraseSyndromeClassHelper(unit,synclass) do
|
|
count = count+1
|
|
end
|
|
return count
|
|
end
|
|
|
|
function eraseSyndromes(unit,syndromeId)
|
|
local count=0
|
|
while eraseSyndrome(unit,syndromeId,true) do
|
|
count = count+1
|
|
end
|
|
return count
|
|
end
|
|
|
|
--target is a df.unit, syndrome is a df.syndrome, resetPolicy is one of syndromeUtil.ResetPolicy
|
|
--if the target has an instance of the syndrome already, the reset policy takes effect
|
|
--returns true if the unit did not have the syndrome before calling and false otherwise
|
|
function infectWithSyndrome(target,syndrome,resetPolicy)
|
|
local oldSyndrome = findUnitSyndrome(target,syndrome.id)
|
|
if oldSyndrome == nil or resetPolicy == nil or resetPolicy == ResetPolicy.NewInstance then
|
|
local unitSyndrome = df.unit_syndrome:new()
|
|
unitSyndrome.type = syndrome.id
|
|
unitSyndrome.year = df.global.cur_year
|
|
unitSyndrome.year_time = df.global.cur_year_tick
|
|
unitSyndrome.ticks = 0
|
|
unitSyndrome.wound_id = -1
|
|
for k,v in ipairs(syndrome.ce) do
|
|
local symptom = df.unit_syndrome.T_symptoms:new()
|
|
symptom.quantity = 0
|
|
symptom.delay = 0
|
|
symptom.ticks = 0
|
|
symptom.flags.active = true
|
|
unitSyndrome.symptoms:insert("#",symptom)
|
|
end
|
|
target.syndromes.active:insert("#",unitSyndrome)
|
|
elseif resetPolicy == ResetPolicy.DoNothing then
|
|
elseif resetPolicy == ResetPolicy.ResetDuration then
|
|
for k,symptom in ipairs(oldSyndrome.symptoms) do
|
|
symptom.ticks = 0
|
|
end
|
|
oldSyndrome.ticks = 0
|
|
elseif resetPolicy == ResetPolicy.AddDuration then
|
|
for k,symptom in ipairs(oldSyndrome.symptoms) do
|
|
--really it's syndrome.ce[k].end, but lua doesn't like that because keywords
|
|
if syndrome.ce[k]["end"] ~= -1 then
|
|
symptom.ticks = symptom.ticks - syndrome.ce[k]["end"]
|
|
end
|
|
end
|
|
else qerror("Bad reset policy: " .. resetPolicy)
|
|
end
|
|
return (oldSyndrome == nil)
|
|
end
|
|
|
|
function isValidTarget(unit,syndrome)
|
|
--mostly copied from itemsyndrome, which is based on autoSyndrome
|
|
if
|
|
#syndrome.syn_affected_class==0
|
|
and #syndrome.syn_affected_creature==0
|
|
and #syndrome.syn_affected_caste==0
|
|
and #syndrome.syn_immune_class==0
|
|
and #syndrome.syn_immune_creature==0
|
|
and #syndrome.syn_immune_caste==0
|
|
then
|
|
return true
|
|
end
|
|
local affected = false
|
|
local unitRaws = df.creature_raw.find(unit.race)
|
|
local casteRaws = unitRaws.caste[unit.caste]
|
|
local unitRaceName = unitRaws.creature_id
|
|
local unitCasteName = casteRaws.caste_id
|
|
local unitClasses = casteRaws.creature_class
|
|
for _,unitClass in ipairs(unitClasses) do
|
|
for _,syndromeClass in ipairs(syndrome.syn_affected_class) do
|
|
if unitClass.value==syndromeClass.value then
|
|
affected = true
|
|
end
|
|
end
|
|
end
|
|
for caste,creature in ipairs(syndrome.syn_affected_creature) do
|
|
local affectedCreature = creature.value
|
|
local affectedCaste = syndrome.syn_affected_caste[caste].value
|
|
if affectedCreature == unitRaceName and (affectedCaste == unitCasteName or affectedCaste == "ALL") then
|
|
affected = true
|
|
end
|
|
end
|
|
for _,unitClass in ipairs(unitClasses) do
|
|
for _,syndromeClass in ipairs(syndrome.syn_immune_class) do
|
|
if unitClass.value == syndromeClass.value then
|
|
affected = false
|
|
end
|
|
end
|
|
end
|
|
for caste,creature in ipairs(syndrome.syn_immune_creature) do
|
|
local immuneCreature = creature.value
|
|
local immuneCaste = syndrome.syn_immune_caste[caste].value
|
|
if immuneCreature == unitRaceName and (immuneCaste == unitCasteName or immuneCaste == "ALL") then
|
|
affected = false
|
|
end
|
|
end
|
|
return affected
|
|
end
|
|
|
|
function infectWithSyndromeIfValidTarget(target,syndrome,resetPolicy)
|
|
if isValidTarget(target,syndrome) then
|
|
infectWithSyndrome(target,syndrome,resetPolicy)
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
return _ENV
|