33
44class TrackerEvent (object ):
55 def __init__ (self , frames ):
6+ #: The frame of the game this event was applied
67 self .frame = frames
78
89 def __str__ (self ):
10+ """ Dumps the event data to a json string. """
911 return json .dumps (self .__dict__ )
1012
1113 def load_context (self , replay ):
@@ -21,6 +23,9 @@ def __init__(self, frames, data):
2123 #: Id of the player the stats are for
2224 self .pid = data [0 ]
2325
26+ #: The Player object that these stats apply to
27+ self .player = None
28+
2429 #: An ordered list of all the available stats
2530 self .stats = data [1 ]
2631
@@ -142,6 +147,9 @@ def __init__(self, frames, data):
142147 #: The unique id of the unit being born
143148 self .unit_id = self .unit_id_index << 16 | self .unit_id_recycle
144149
150+ #: The unit object that was born
151+ self .unit = None
152+
145153 #: The unit type name of the unit being born
146154 self .unit_type_name = data [2 ]
147155
@@ -151,6 +159,12 @@ def __init__(self, frames, data):
151159 #: The id of the player that pays upkeep for this unit.
152160 self .upkeep_pid = data [4 ]
153161
162+ #: The player object that pays upkeep for this one. 0 means neutral unit
163+ self .unit_upkeeper = None
164+
165+ #: The player object that controls this unit. 0 means neutral unit
166+ self .unit_controller = None
167+
154168 #: The x coordinate of the location
155169 self .x = data [5 ]
156170
@@ -168,14 +182,18 @@ def load_context(self, replay):
168182 self .unit_upkeeper = replay .player [self .upkeep_pid ]
169183
170184 if self .unit_id in replay .objects :
185+ # This can happen because game events are done first
171186 self .unit = replay .objects [self .unit_id ]
172187 else :
173188 # TODO: How to tell if something is hallucination?
174189 self .unit = replay .datapack .create_unit (self .unit_id , self .unit_type_name , 0 , self .frame )
175- self .unit .location = self .location
176190 replay .objects [self .unit_id ] = self .unit
177191 replay .active_units [self .unit_id_index ] = self .unit
178192
193+ self .unit .location = self .location
194+ self .unit .birth = self .frame
195+ self .unit .owner = self .unit_upkeeper
196+
179197
180198class UnitDiedEvent (TrackerEvent ):
181199 name = 'UnitDiedEvent'
@@ -192,9 +210,15 @@ def __init__(self, frames, data):
192210 #: The unique id of the unit being killed
193211 self .unit_id = self .unit_id_index << 16 | self .unit_id_recycle
194212
213+ #: The unit object that died
214+ self .unit = None
215+
195216 #: The id of the player that killed this unit. None when not available.
196217 self .killer_pid = data [2 ]
197218
219+ #: The player object of the that killed the unit. Not always available.
220+ self .killer = None
221+
198222 #: The x coordinate of the location
199223 self .x = data [3 ]
200224
@@ -207,12 +231,11 @@ def __init__(self, frames, data):
207231 def load_context (self , replay ):
208232 if self .unit_id in replay .objects :
209233 self .unit = replay .objects [self .unit_id ]
234+ self .unit .death = self .frame
210235 self .unit .location = self .location
211236 del replay .active_units [self .unit_id_index ]
212237 else :
213- # Create a new unit, but we don't have a type name map yet!
214238 print "Unit died before it was born!"
215- self .unit = None
216239
217240 if self .killer_pid : # This field isn't always available
218241 self .killer = replay .player [self .killer_pid ]
@@ -233,26 +256,33 @@ def __init__(self, frames, data):
233256 #: The unique id of the unit changing ownership
234257 self .unit_id = self .unit_id_index << 16 | self .unit_id_recycle
235258
259+ #: The unit object that is affected by this event
260+ self .unit = None
261+
236262 #: The new id of the player that controls this unit.
237263 self .control_pid = data [2 ]
238264
239265 #: The new id of the player that pays upkeep for this unit.
240266 self .upkeep_pid = data [3 ]
241267
268+ #: The player object that pays upkeep for this one. 0 means neutral unit
269+ self .unit_upkeeper = None
270+
271+ #: The player object that controls this unit. 0 means neutral unit
272+ self .unit_controller = None
242273
243274 def load_context (self , replay ):
244- if self .control_pid : # 0 means neutral unit
275+ if self .control_pid :
245276 self .unit_controller = replay .player [self .control_pid ]
246277
247- if self .upkeep_pid : # 0 means neutral unit
278+ if self .upkeep_pid :
248279 self .unit_upkeeper = replay .player [self .upkeep_pid ]
249280
250281 if self .unit_id in replay .objects :
251282 self .unit = replay .objects [self .unit_id ]
283+ self .unit .owner = self .unit_upkeeper
252284 else :
253- # Create a new unit, but we don't have a type name map yet!
254285 print "Unit owner changed before it was born!"
255- self .unit = None
256286
257287
258288class UnitTypeChangeEvent (TrackerEvent ):
@@ -270,6 +300,9 @@ def __init__(self, frames, data):
270300 #: The unique id of the unit changing type
271301 self .unit_id = self .unit_id_index << 16 | self .unit_id_recycle
272302
303+ #: The unit object that was changed
304+ self .unit = None
305+
273306 #: The the new unit type name
274307 self .unit_type_name = data [2 ]
275308
@@ -279,7 +312,6 @@ def load_context(self, replay):
279312 replay .datapack .change_type (self .unit , self .unit_type_name , self .frame )
280313 else :
281314 print "Unit type changed before it was born!"
282- self .unit = None
283315
284316
285317class UpgradeCompleteEvent (TrackerEvent ):
@@ -291,6 +323,9 @@ def __init__(self, frames, data):
291323 #: The player that completed the upgrade
292324 self .pid = data [0 ]
293325
326+ #: The Player object that completed the upgrade
327+ self .player = None
328+
294329 #: The name of the upgrade
295330 self .upgrade_type_name = data [1 ]
296331
@@ -319,6 +354,9 @@ def __init__(self, frames, data):
319354 #: The unique id of the stated unit
320355 self .unit_id = self .unit_id_index << 16 | self .unit_id_recycle
321356
357+ #: The unit object that was started (e.g. started to warp in)
358+ self .unit = None
359+
322360 #: The the new unit type name
323361 self .unit_type_name = data [2 ]
324362
@@ -328,6 +366,12 @@ def __init__(self, frames, data):
328366 #: The id of the player that pays upkeep for this unit.
329367 self .upkeep_pid = data [4 ]
330368
369+ #: The player object that pays upkeep for this one. 0 means neutral unit
370+ self .unit_upkeeper = None
371+
372+ #: The player object that controls this unit. 0 means neutral unit
373+ self .unit_controller = None
374+
331375 #: The x coordinate of the location
332376 self .x = data [5 ]
333377
@@ -345,14 +389,17 @@ def load_context(self, replay):
345389 self .unit_upkeeper = replay .player [self .upkeep_pid ]
346390
347391 if self .unit_id in replay .objects :
392+ # This can happen because game events are done first
348393 self .unit = replay .objects [self .unit_id ]
349394 else :
350395 # TODO: How to tell if something is hallucination?
351396 self .unit = replay .datapack .create_unit (self .unit_id , self .unit_type_name , 0 , self .frame )
352397 replay .objects [self .unit_id ] = self .unit
353398 replay .active_units [self .unit_id_index ] = self .unit
354399
400+ self .unit .owner = self .unit_upkeeper
355401 self .unit .location = self .location
402+ self .unit .birth = self .frame
356403
357404
358405class UnitDoneEvent (TrackerEvent ):
@@ -370,12 +417,14 @@ def __init__(self, frames, data):
370417 #: The unique id of the finished unit
371418 self .unit_id = self .unit_id_index << 16 | self .unit_id_recycle
372419
420+ #: The unit object that was finished
421+ self .unit = None
422+
373423 def load_context (self , replay ):
374424 if self .unit_id in replay .objects :
375425 self .unit = replay .objects [self .unit_id ]
376426 else :
377427 print "Unit done before it was started!"
378- self .unit = None
379428
380429
381430class UnitPositionsEvent (TrackerEvent ):
@@ -384,30 +433,24 @@ class UnitPositionsEvent(TrackerEvent):
384433 def __init__ (self , frames , data ):
385434 super (UnitPositionsEvent , self ).__init__ (frames )
386435
387- #: ???
436+ #: The starting unit index point.
388437 self .first_unit_index = data [0 ]
389438
390- #: ???
439+ #: An ordered list of unit/point data interpreted as below.
391440 self .items = data [1 ]
392441
393-
442+ #: A list of units that had their position updated by this event
394443 self .units = list ()
395444
445+ #: A list of (unit_index, (x,y)) derived from the first_unit_index and items
396446 self .positions = list ()
447+
397448 unit_index = self .first_unit_index
398449 for i in range (0 , len (self .items ), 3 ):
399450 unit_index += self .items [i ]
400451 x = self .items [i + 1 ]* 4
401452 y = self .items [i + 2 ]* 4
402453 self .positions .append ((unit_index , (x ,y )))
403- """ We need to be able to find units without the recycle id, can't do this yet!
404- unitTagIndex = event['m_firstUnitIndex']
405- for i in xrange(len(event['m_items']) / 3):
406- unitTagIndex += event['m_items'][i * 3 + 0]
407- x = event['m_items'][i * 3 + 1] * 4
408- y = event['m_items'][i * 3 + 2] * 4
409- # the unit with unitTagIndex is now at coordinate (x, y)
410- """
411454
412455 def load_context (self , replay ):
413456 for unit_index , (x ,y ) in self .positions :
0 commit comments