forked from DFHack/dfhack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsyndrome-util.lua
More file actions
185 lines (173 loc) · 5.24 KB
/
Copy pathsyndrome-util.lua
File metadata and controls
185 lines (173 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
--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.active_creature_interaction_effectst: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