· 8 years ago · Jul 24, 2018, 07:54 PM
1-- werejew
2
3printd = warfare.printd
4
5squads_by_level = {}
6
7-- ocs_power_table[squadID] = power
8-- might want to save this table.
9ocs_power_table = {}
10
11-- table with all of the combat groups.
12-- no longer used.
13combat_groups = {}
14
15function calculate_squad_power(squad)
16 printd(0)
17
18 local power = 0
19 local sim = alife()
20
21 for k in squad:squad_members() do
22 local se_obj = k.object or k.id and sim:object(k.id)
23
24 if (se_obj) then
25 power = power + se_obj:rank()
26 if IsMonster(se_obj) then -- make monster squads exponentially more powerful as their number is bigger
27 power = power * 5
28 end
29 end
30 end
31
32 ocs_power_table[squad.id] = power
33
34 printd(1)
35end
36
37function squad_on_update(squad)
38 printd(0)
39
40 if squad.registered_with_warfare then
41 local sim = alife()
42 local gg = game_graph()
43
44 -- If the squads current level id is nil
45 if not (squad.current_level_id) then
46 -- get the level id and set current_level_id
47 local lvl = gg:vertex(squad.m_game_vertex_id):level_id()
48 squad.current_level_id = lvl
49
50 -- if the level isn't in squads_by_level, create the table for it.
51 if not squads_by_level[lvl] then
52 squads_by_level[lvl] = {}
53 end
54
55 -- add the squads id to the table of squads in that level.
56 squads_by_level[lvl][squad.id] = true
57
58 if (squad:get_squad_community() == "monster") then
59 --printf("adding monster to level: " .. alife():level_name(lvl))
60 end
61
62 if squad.current_target_id then
63 local obj = alife():object(squad.current_target_id)
64
65 if (obj and obj:clsid() == clsid.smart_terrain) then
66
67 -- If not targeting a base or resource, flag squad as a patrol. could get weird for manual control; look into alternative solutions.
68 if (obj.props and obj.props.base < 1 and obj.props.resource < 1) then
69 squad.patrol_squad = true
70 end
71 end
72 end
73 end
74
75 -- if squad isn't online
76 if not squad.online then
77
78 -- if the squad has a combat group and it isn't disbanded, simulate it.
79 if (squad.combat_group and not squad.combat_group.disbanded) then
80 --printf("--- simulating squad " .. squad:name() .. " ---")
81 squad.combat_group:simulate(squad)
82 end
83
84 -- get the last level id, and calculate the current level id
85 local last = squad.current_level_id
86 local lvl = gg:vertex(squad.m_game_vertex_id):level_id()
87
88 squad.current_level_id = lvl
89
90 -- if the last level id isn't the same as the current one, the squad has moved to a new level.
91 if (last ~= lvl) then
92 -- remove the squads id from the previous levels table.
93 if squads_by_level[last] then
94 squads_by_level[last][squad.id] = nil
95 end
96
97 -- if the level isn't in squads_by_level, create the table for it.
98 if (not squads_by_level[lvl]) then
99 squads_by_level[lvl] = {}
100 end
101
102 -- add the squads id to the table of squads in that level.
103 squads_by_level[lvl][squad.id] = true
104 end
105
106 -- get squads faction
107 local f0 = squad:get_squad_community()
108
109 if not (warfare_options.options.simulate_offline_combat_at_smarts or warfare_options.options.disable_offline_combat) then
110 -- if squad is a mutant and enable_mutant_offline_combat is false, do not continue
111 if (f0 ~= "monster" or warfare_options.options.enable_mutant_offline_combat) then
112
113 -- cycle through squads on the squad's current level
114 for i,t in pairs(squads_by_level[lvl]) do
115
116 -- get the sim object for the squad being checked
117 local squad2 = i and sim:object(i)
118
119 -- make sure the object exists, is registered with warfare, and is not online.
120 if (squad2 and squad2.registered_with_warfare and not squad2.online) then
121
122 -- get the squad's faction
123 local f1 = squad2:get_squad_community()
124
125 -- if the squad is a mutant or enable_mutant_offline combat is false or if the two factions aren't enemies, do not continue.
126 if (f1 ~= "monster" or warfare_options.options.enable_mutant_offline_combat) and game_relations.is_factions_enemies(f0, f1) then
127
128 local power1 = ocs_power_table[squad.id]
129 local power2 = ocs_power_table[squad2.id]
130
131 --printf("checking power for " .. squad:name() .. " and " .. squad2:name())
132
133 -- check to make sure the squads have their powers calculated
134 if (power1 and power1 > 0 and power2 and power2 > 0) then
135 local d = squad.position:distance_to_sqr(squad2.position)
136
137 --printf("--- checking distance for level " .. lvl .. " and squads " .. squad:name() .. " and " .. squad2:name())
138
139 -- ridiculously large for testing purposes
140 if (d < (75*75)) then
141 --printf("--- setting combat group for " .. squad:name() .. " and " .. squad2:name())
142 offline_combat_simulator.set_combat_group(squad, squad2)
143 end
144 end
145 end
146 elseif squad2 then
147 --printf("squad2 registered: " .. tostring(squad2.registered_with_warfare) .. " online: " .. tostring(squad2.online))
148 end
149 end
150 end
151 end
152 end
153 end
154
155 printd(1)
156end
157
158-- create or set the combat group for the squads
159function set_combat_group(squad1, squad2)
160 printd(0)
161
162 -- If both squads have a combat group, return.
163 if (squad1.combat_group and squad2.combat_group) then
164 printd(1)
165 return
166 end
167
168 -- If either squad is online, return.
169 if (squad1.online or squad2.online) then
170 printd(2)
171 return
172 end
173
174 -- Make sure squad exists within the simboard, and npc counts are greater than 0
175 if not (SIMBOARD.squads[squad1.id]) or not (SIMBOARD.squads[squad2.id]) or (squad1:npc_count() == 0) or (squad2:npc_count() == 0) then
176 printd(3)
177 return
178 end
179
180 -- If either squad has a combat group, register the one without a combat group to it.
181 if (squad1.combat_group) then
182 squad1.combat_group:register(squad2, squad1.id)
183 printd(4)
184 return
185 elseif (squad2.combat_group) then
186 squad2.combat_group:register(squad1, squad2.id)
187 printd(5)
188 return
189 end
190
191 -- Create a new combat group and register both squads with it.
192 local group = combat_group.combat_group()
193 group:register(squad1, squad2.id)
194 group:register(squad2, squad1.id)
195 --combat_groups[#combat_groups+1] = group
196
197 printd(6)
198end
199
200function get_num_squads_on_level(lvl, faction)
201 if (squads_by_level[lvl]) then
202 local count = 0
203
204 for s,_ in pairs(squads_by_level[lvl]) do
205 local squad = alife():object(s)
206
207 if (squad) then
208 --printf("get_num_squads_on_level -- squad=%s", squad:name())
209
210 if (squad.get_squad_community and squad:get_squad_community() == faction) then
211 count = count + 1
212 end
213 end
214 end
215
216 --printf("return " .. tostring(count))
217
218 return count
219 else
220 --printf("level doesn't exist")
221 end
222
223 return 0
224end
225
226function get_num_active_squads(faction)
227 local num_active = 0
228
229 --printf("num_active: f=%s, active=%s", faction, num_active)
230
231 for i,lvl in pairs(level_targets.active_levels) do
232 num_active = num_active + get_num_active_squads_on_level(lvl, faction)
233 end
234
235
236 return num_active
237end
238
239function get_num_active_squads_on_level(lvl, faction)
240 if (squads_by_level[lvl]) then
241 local count = 0
242
243 for s,_ in pairs(squads_by_level[lvl]) do
244 local squad = alife():object(s)
245
246 if (squad) then
247 --printf("num active squads -- squad=%s action=%s", squad:name(), squad.current_action)
248
249 if (squad.get_squad_community and squad:get_squad_community() == faction and squad.current_action == 0) then
250 count = count + 1
251 end
252 end
253 end
254
255 --printf("return " .. count .. " for " .. faction)
256
257 return count
258 else
259 --printf("level doesn't exist")
260 end
261
262 return 0
263end
264
265function get_num_inactive_squads_on_level(lvl, faction)
266 if (squads_by_level[lvl]) then
267 local count = 0
268
269 for s,_ in pairs(squads_by_level[lvl]) do
270 local squad = alife():object(s)
271
272 if (squad) then
273 --printf("squad=%s", squad:name())
274
275 if (squad.get_squad_community and squad:get_squad_community() == faction and squad.current_action == 1) then
276 count = count + 1
277 end
278 end
279 end
280
281 return count
282 else
283 --printf("level doesn't exist")
284 end
285
286 return 0
287end
288
289function get_num_defense_squads_on_level(lvl, faction)
290 if (squads_by_level[lvl]) then
291 local count = 0
292
293 for s,_ in pairs(squads_by_level[lvl]) do
294 local squad = alife():object(s)
295
296 if (squad) then
297 --printf("squad=%s", squad:name())
298
299 if (squad.get_squad_community and squad:get_squad_community() == faction and squad.current_action == 1) then
300 local target = squad.current_target_id
301 local obj = target and alife():object(target)
302
303 if (obj:clsid() == clsid.smart_terrain) then
304 if (obj.owning_faction == faction and obj.props and (obj.props.base > 0 or obj.props.resource > 0)) then
305 count = count + 1
306 end
307 end
308 end
309 end
310 end
311
312 return count
313 else
314 --printf("level doesn't exist")
315 end
316
317 return 0
318end
319
320function get_num_offense_squads_on_level(lvl, faction)
321 if (squads_by_level[lvl]) then
322 local count = 0
323
324 for s,_ in pairs(squads_by_level[lvl]) do
325 local squad = alife():object(s)
326
327 if (squad) then
328 --printf("squad=%s", squad:name())
329
330 if (squad.get_squad_community and squad:get_squad_community() == faction and squad.current_action == 0) then
331 local target = squad.current_target_id
332 local obj = target and alife():object(target)
333
334 if (obj:clsid() == clsid.smart_terrain) then
335 if (obj.props and (obj.props.base > 0 or obj.props.resource > 0)) then
336 count = count + 1
337 end
338 end
339 end
340 end
341 end
342
343 return count
344 else
345 --printf("level doesn't exist")
346 end
347
348 return 0
349end