10
10
11
11
@loggable
12
12
class GameEvent (Event ):
13
+ """
14
+ This is the base class for all game events. The attributes below are universally available.
15
+ """
13
16
name = 'GameEvent'
14
17
15
18
def __init__ (self , frame , pid ):
19
+ #: The id of the player generating the event. This is 16 for global non-player events.
20
+ #: Prior to Heart of the Swarm this was the player id. Since HotS it is
21
+ #: now the user id (uid), we still call it pid for backwards compatibility.
16
22
self .pid = pid
23
+
24
+ #: A reference to the :class:`~sc2reader.objects.Player` object representing
25
+ #: this player in the replay. Not available for global events (:attr:`pid` = 16)
26
+ self .player = None
27
+
28
+ #: The frame of the game that this event was recorded at. 16 frames per game second.
17
29
self .frame = frame
30
+
31
+ #: The second of the game that this event was recorded at. 16 frames per game second.
18
32
self .second = frame >> 4
33
+
34
+ #: A flag indicating if it is a local or global event.
19
35
self .is_local = (pid != 16 )
20
36
21
37
def _str_prefix (self ):
@@ -27,20 +43,34 @@ def __str__(self):
27
43
28
44
29
45
class GameStartEvent (GameEvent ):
46
+ """
47
+ Recorded when the game starts and the frames start to roll. This is a global non-player
48
+ event.
49
+ """
50
+
30
51
name = 'GameStartEvent'
31
52
32
53
def __init__ (self , frame , pid , data ):
33
54
super (GameStartEvent , self ).__init__ (frame , pid )
34
55
35
56
36
57
class PlayerLeaveEvent (GameEvent ):
58
+ """
59
+ Recorded when a player leaves the game.
60
+ """
61
+
37
62
name = 'PlayerLeaveEvent'
38
63
39
64
def __init__ (self , frame , pid , data ):
40
65
super (PlayerLeaveEvent , self ).__init__ (frame , pid )
41
66
42
67
43
68
class UserOptionsEvent (GameEvent ):
69
+ """
70
+ This event is recorded for each player at the very beginning of the game before the
71
+ :class:`GameStartEvent`.
72
+ """
73
+
44
74
name = 'UserOptionsEvent'
45
75
46
76
def __init__ (self , frame , pid , data ):
@@ -94,7 +124,18 @@ class PlayerActionEvent(GameEvent):
94
124
95
125
@loggable
96
126
class AbilityEvent (PlayerActionEvent ):
127
+ """
128
+ Ability events are generated when ever a player in the game issues a command
129
+ to a unit or group of units. They are split into three subclasses of ability,
130
+ each with their own set of associated data. The attributes listed below are
131
+ shared across all ability event types.
132
+
133
+ See :class:`LocationAbilityEvent`, :class:`TargetAbilityEvent`, and :class:`SelfAbilityEvent`
134
+ for individual details.
135
+ """
136
+
97
137
name = 'AbilityEvent'
138
+
98
139
is_player_action = True
99
140
100
141
def __init__ (self , frame , pid , data ):
@@ -157,47 +198,8 @@ def __init__(self, frame, pid, data):
157
198
#: The type of ability, one of: None (no target), TargetPoint, TargetUnit, or Data
158
199
self .ability_type = data ['data' ][0 ]
159
200
160
- ability_type_data = data ['data' ][1 ]
161
-
162
- if self .ability_type == 'TargetUnit' :
163
- #: Flags set on the target unit. Available for TargetUnit type events
164
- self .target_flags = ability_type_data .get ('flags' , None )
165
-
166
- #: Timer?? Available for TargetUnit type events.
167
- self .target_timer = ability_type_data .get ('timer' , None )
168
-
169
- #: Unique id of the target unit. Available for TargetUnit type events.
170
- self .target_unit_id = ability_type_data .get ('unit_tag' , None )
171
-
172
- #: A reference to the targetted unit
173
- self .target_unit = None
174
-
175
- #: Current integer type id of the target unit. Available for TargetUnit type events.
176
- self .target_unit_type = ability_type_data .get ('unit_link' , None )
177
-
178
- #: Integer player id of the controlling player. Available for TargetUnit type events starting in 19595.
179
- #: When the targetted unit is under fog of war this id is zero.
180
- self .control_player_id = ability_type_data .get ('control_player_id' , None )
181
-
182
- #: Integer player id of the player paying upkeep. Available for TargetUnit type events.
183
- self .upkeep_player_id = ability_type_data .get ('upkeep_player_id' , None )
184
-
185
- if self .ability_type in ('TargetPoint' , 'TargetUnit' ):
186
- #: The x coordinate of the target. Available for TargetPoint and TargetUnit type events.
187
- self .x = ability_type_data ['point' ].get ('x' , 0 )/ 4096.0
188
-
189
- #: The y coordinate of the target. Available for TargetPoint and TargetUnit type events.
190
- self .y = ability_type_data ['point' ].get ('y' , 0 )/ 4096.0
191
-
192
- #: The z coordinate of the target. Available for TargetPoint and TargetUnit type events.
193
- self .z = ability_type_data ['point' ].get ('z' , 0 )
194
-
195
- #: The location of the target. Available for TargetPoint and TargetUnit type events
196
- self .location = (self .x , self .y , self .z )
197
-
198
- if self .ability_type == 'Data' :
199
- #: Other target data. Available for Data type events.
200
- self .target_data = ability_type_data .get ('data' , None )
201
+ #: The raw data associated with this ability type
202
+ self .ability_type_data = data ['data' ][1 ]
201
203
202
204
#: Other unit id??
203
205
self .other_unit_id = data ['other_unit_tag' ]
@@ -224,19 +226,118 @@ def __str__(self):
224
226
225
227
226
228
class LocationAbilityEvent (AbilityEvent ):
229
+ """
230
+ Extends :class:`AbilityEvent`
231
+
232
+ This event is recorded when ever a player issues a command that targets a location
233
+ and NOT a unit. Commands like Psistorm, Attack Move, Fungal Growth, and EMP fall
234
+ under this category.
235
+
236
+ Note that like all AbilityEvents, the event will be recorded regardless
237
+ of whether or not the command was successful.
238
+ """
239
+
227
240
name = 'LocationAbilityEvent'
228
241
242
+ def __init__ (self , frame , pid , data ):
243
+ super (LocationAbilityEvent , self ).__init__ (frame , pid , data )
244
+
245
+ #: The x coordinate of the target. Available for TargetPoint and TargetUnit type events.
246
+ self .x = self .ability_type_data ['point' ].get ('x' , 0 )/ 4096.0
247
+
248
+ #: The y coordinate of the target. Available for TargetPoint and TargetUnit type events.
249
+ self .y = self .ability_type_data ['point' ].get ('y' , 0 )/ 4096.0
250
+
251
+ #: The z coordinate of the target. Available for TargetPoint and TargetUnit type events.
252
+ self .z = self .ability_type_data ['point' ].get ('z' , 0 )
253
+
254
+ #: The location of the target. Available for TargetPoint and TargetUnit type events
255
+ self .location = (self .x , self .y , self .z )
256
+
229
257
230
258
class TargetAbilityEvent (AbilityEvent ):
259
+ """
260
+ Extends :class:`AbilityEvent`
261
+
262
+ TargetAbilityEvents are recorded when ever a player issues a command that targets a unit.
263
+ The location of the target unit at the time of the command is also recorded. Commands like
264
+ Chronoboost, Transfuse, and Snipe fall under this category.
265
+
266
+ Note that all AbilityEvents are recorded regardless of whether or not the command was successful.
267
+ """
268
+
231
269
name = 'TargetAbilityEvent'
232
270
271
+ def __init__ (self , frame , pid , data ):
272
+ super (TargetAbilityEvent , self ).__init__ (frame , pid , data )
273
+
274
+ #: Flags set on the target unit. Available for TargetUnit type events
275
+ self .target_flags = self .ability_type_data .get ('flags' , None )
276
+
277
+ #: Timer?? Available for TargetUnit type events.
278
+ self .target_timer = self .ability_type_data .get ('timer' , None )
279
+
280
+ #: Unique id of the target unit. Available for TargetUnit type events.
281
+ self .target_unit_id = self .ability_type_data .get ('unit_tag' , None )
282
+
283
+ #: A reference to the targetted unit
284
+ self .target_unit = None
285
+
286
+ #: Current integer type id of the target unit. Available for TargetUnit type events.
287
+ self .target_unit_type = self .ability_type_data .get ('unit_link' , None )
288
+
289
+ #: Integer player id of the controlling player. Available for TargetUnit type events starting in 19595.
290
+ #: When the targetted unit is under fog of war this id is zero.
291
+ self .control_player_id = self .ability_type_data .get ('control_player_id' , None )
292
+
293
+ #: Integer player id of the player paying upkeep. Available for TargetUnit type events.
294
+ self .upkeep_player_id = self .ability_type_data .get ('upkeep_player_id' , None )
295
+
296
+ #: The x coordinate of the target. Available for TargetPoint and TargetUnit type events.
297
+ self .x = self .ability_type_data ['point' ].get ('x' , 0 )/ 4096.0
298
+
299
+ #: The y coordinate of the target. Available for TargetPoint and TargetUnit type events.
300
+ self .y = self .ability_type_data ['point' ].get ('y' , 0 )/ 4096.0
301
+
302
+ #: The z coordinate of the target. Available for TargetPoint and TargetUnit type events.
303
+ self .z = self .ability_type_data ['point' ].get ('z' , 0 )
304
+
305
+ #: The location of the target. Available for TargetPoint and TargetUnit type events
306
+ self .location = (self .x , self .y , self .z )
307
+
233
308
234
309
class SelfAbilityEvent (AbilityEvent ):
310
+ """
311
+ Extends :class:`AbilityEvent`
312
+
313
+ SelfAbilityEvents are recorded when ever a player issues a command that has no target. Commands
314
+ like Burrow, SeigeMode, Train XYZ, and Stop fall under this category.
315
+
316
+ Note that all AbilityEvents are recorded regardless of whether or not the command was successful.
317
+ """
318
+
235
319
name = 'SelfAbilityEvent'
236
320
321
+ def __init__ (self , frame , pid , data ):
322
+ super (SelfAbilityEvent , self ).__init__ (frame , pid , data )
323
+
324
+ #: Other target data. Available for Data type events.
325
+ self .target_data = self .ability_type_data .get ('data' , None )
326
+
237
327
238
328
@loggable
239
329
class SelectionEvent (PlayerActionEvent ):
330
+ """
331
+ Selection events are generated when ever the active selection of the
332
+ player is updated. Unlike other game events, these events can also be
333
+ generated by non-player actions like unit deaths or transformations.
334
+
335
+ Starting in Starcraft 2.0.0, selection events targetting control group
336
+ buffers are also generated when control group selections are modified
337
+ by non-player actions. When a player action updates a control group
338
+ a :class:`HotkeyEvent` is generated.
339
+ """
340
+
240
341
name = 'SelectionEvent'
241
342
is_player_action = True
242
343
@@ -300,6 +401,22 @@ def create_control_group_event(frame, pid, data):
300
401
301
402
@loggable
302
403
class HotkeyEvent (PlayerActionEvent ):
404
+ """
405
+ Hotkey events are recorded when ever a player action modifies a control
406
+ group. I know that calling control group events hotkey events doesn't make
407
+ sense but for backwards compatibility I haven't changed it yet. Sorry.
408
+
409
+ There are three kinds of hotkey events, generated by each of the possible
410
+ player actions:
411
+
412
+ * :class:`SetToHotkeyEvent` - Recorded when a user sets a control group (ctrl+#).
413
+ * :class:`GetFromHotkeyEvent` - Recorded when a user retrieves a control group (#).
414
+ * :class:`AddToHotkeyEvent` - Recorded when a user adds to a control group (shift+ctrl+#)
415
+
416
+ All three events have the same set of data (shown below) but are interpretted differently.
417
+ See the class entry for details.
418
+ """
419
+
303
420
name = 'HotkeyEvent'
304
421
is_player_action = True
305
422
@@ -326,19 +443,46 @@ def __init__(self, frame, pid, data):
326
443
327
444
328
445
class SetToHotkeyEvent (HotkeyEvent ):
446
+ """
447
+ Extends :class:`HotkeyEvent`
448
+
449
+ This event does a straight forward replace of the current control group contents
450
+ with the player's current selection. This event doesn't have masks set.
451
+ """
452
+
329
453
name = 'SetToHotkeyEvent'
330
454
331
455
332
456
class AddToHotkeyEvent (HotkeyEvent ):
457
+ """
458
+ Extends :class:`HotkeyEvent`
459
+
460
+ This event adds the current selection to the control group.
461
+ """
462
+
333
463
name = 'AddToHotkeyEvent'
334
464
335
465
336
466
class GetFromHotkeyEvent (HotkeyEvent ):
467
+ """
468
+ Extends :class:`HotkeyEvent`
469
+ This event replaces the current selection with the contents of the control group.
470
+ The mask data is used to limit that selection to units that are currently selectable.
471
+ You might have 1 medivac and 8 marines on the control group but if the 8 marines are
472
+ inside the medivac they cannot be part of your selection.
473
+ """
474
+
337
475
name = 'GetFromHotkeyEvent'
338
476
339
477
340
478
@loggable
341
479
class CameraEvent (GameEvent ):
480
+ """
481
+ Camera events are generated when ever the player camera moves, zooms, or rotates.
482
+ It does not matter why the camera changed, this event simply records the current
483
+ state of the camera after changing.
484
+ """
485
+
342
486
name = 'CameraEvent'
343
487
344
488
def __init__ (self , frame , pid , data ):
0 commit comments