Skip to content

Commit 53e5678

Browse files
committed
Add killer logic to ContextLoader, refine the API.
1 parent 4b45b62 commit 53e5678

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed

sc2reader/data/__init__.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,24 @@ def __init__(self, unit_id):
5353
#: Specifically, it is the frame that the :class:`~sc2reader.events.tracker.UnitDiedEvent` is received.
5454
self.died_at = None
5555

56+
#: Deprecated, see :attr:`self.killing_player`
57+
self.killed_by = None
58+
5659
#: A reference to the player that killed this unit. Only available for 2.0.8+ replays.
5760
#: This value is not set if the killer is unknown or not relevant (morphed into a
5861
#: different unit or used to create a building, etc)
59-
self.killed_by = None
62+
self.killing_player = None
63+
64+
#: A reference to the unit that killed this unit. Only available for 2.1+ replays.
65+
#: This value is not set if the killer is unknown or not relevant (morphed into a
66+
#: different unit or used to create a building, etc). If the killing unit dies before
67+
#: the killed unit dies, a bug may cause the killing unit to be None. This can occur
68+
#: due because of projectile speeds.
69+
self.killing_unit = None
70+
71+
#: A list of units that this unit has killed. Only available for 2.1+ replays.
72+
#: The unit only gets credit for the kills that it gets the final blow on.
73+
self.killed_units = list()
6074

6175
#: The unique in-game id for this unit. The id can sometimes be zero because
6276
#: TargetUnitCommandEvents will create a new unit with id zero when a unit

sc2reader/engine/plugins/context.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,21 @@ def handleUnitDiedEvent(self, event, replay):
146146
else:
147147
self.logger.error("Unit {0} died at {1} [{2}] before it was born!".format(event.unit_id, Length(seconds=event.second), event.frame))
148148

149-
if event.killer_pid in replay.player:
150-
event.killer = replay.player[event.killer_pid]
149+
if event.killing_player_id in replay.player:
150+
event.killing_player = event.killer = replay.player[event.killing_player_id]
151151
if event.unit:
152-
event.unit.killed_by = event.killer
153-
event.killer.killed_units.append(event.unit)
154-
elif event.killer_pid:
155-
self.logger.error("Unknown killer pid {0} at {1} [{2}]".format(event.killer_pid, Length(seconds=event.second), event.frame))
152+
event.unit.killing_player = event.unit.killed_by = event.killing_player
153+
event.killing_player.killed_units.append(event.unit)
154+
elif event.killing_player_id:
155+
self.logger.error("Unknown killing player id {0} at {1} [{2}]".format(event.killing_player_id, Length(seconds=event.second), event.frame))
156+
157+
if event.killing_unit_id in replay.objects:
158+
event.killing_unit = replay.objects[event.killing_unit_id]
159+
if event.unit:
160+
event.unit.killing_unit = event.killing_unit
161+
event.killing_unit.killed_units.append(event.unit)
162+
elif event.killing_unit_id:
163+
self.logger.error("Unknown killing unit id {0} at {1} [{2}]".format(event.killing_unit_id, Length(seconds=event.second), event.frame))
156164

157165
def handleUnitOwnerChangeEvent(self, event, replay):
158166
self.load_tracker_controller(event, replay)

sc2reader/events/tracker.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,18 @@ def __init__(self, frames, data, build):
313313
#: The unit object that died
314314
self.unit = None
315315

316-
#: The id of the player that killed this unit. None when not available.
316+
#: Deprecated, see :attr:`killing_player_id`
317317
self.killer_pid = data[2]
318318

319-
#: The player object of the that killed the unit. Not always available.
319+
#: Deprecated, see :attr:`killing_player`
320320
self.killer = None
321321

322+
#: The id of the player that killed this unit. None when not available.
323+
self.killing_player_id = data[2]
324+
325+
#: The player object of the that killed the unit. Not always available.
326+
self.killing_player = None
327+
322328
#: The x coordinate of the center of the dying unit's footprint. Only 4 point resolution
323329
#: prior to Starcraft Patch 2.1.
324330
self.x = data[3]
@@ -331,24 +337,27 @@ def __init__(self, frames, data, build):
331337
self.location = (self.x, self.y)
332338

333339
#: The index portion of the killing unit's id. Available for build 27950+
334-
self.killer_unit_index = None
340+
self.killing_unit_index = None
335341

336342
#: The recycle portion of the killing unit's id. Available for build 27950+
337-
self.killer_unit_recycle = None
343+
self.killing_unit_recycle = None
338344

339345
#: The unique id of the unit doing the killing. Available for build 27950+
340-
self.killer_unit_id = None
346+
self.killing_unit_id = None
347+
348+
#: A reference to the :class:`Unit` that killed this :class:`Unit`
349+
self.killing_unit = None
341350

342351
if build < 27950:
343352
self.x = self.x * 4
344353
self.y = self.y * 4
345354
self.location = (self.x, self.y)
346355
else:
347356
# Starcraft patch 2.1 introduced killer unit indexes
348-
self.killer_unit_index = data[5]
349-
self.killer_unit_recycle = data[6]
350-
if self.killer_unit_index:
351-
self.killer_unit_id = self.killer_unit_index << 18 | self.killer_unit_recycle
357+
self.killing_unit_index = data[5]
358+
self.killing_unit_recycle = data[6]
359+
if self.killing_unit_index:
360+
self.killing_unit_id = self.killing_unit_index << 18 | self.killing_unit_recycle
352361

353362
def __str__(self):
354363
return self._str_prefix() + "{0: >15} - Unit died {1}.".format(self.unit.owner, self.unit)

0 commit comments

Comments
 (0)