11from constants import races
22from collections import defaultdict
3- from sc2reader . utils import PersonDict
3+
44from sc2reader .constants import *
5+ from sc2reader .data import GameObject , ABILITIES
6+ from sc2reader .utils import PersonDict ,Selection
7+
58
69class Replay (object ):
710
@@ -38,7 +41,7 @@ def __init__(self, filename, release, frames=0):
3841 self .messages = list ()
3942 self .recorder = None # Player object
4043 self .winner_known = False
41-
44+
4245 # Set in parsers.DetailParser.load, should we hide this?
4346 self .file_time = None # Probably number milliseconds since EPOCH
4447
@@ -49,6 +52,9 @@ def __init__(self, filename, release, frames=0):
4952 self .date = None # Date when the game was played in local time
5053 self .utc_date = None # Date when the game was played in UTC
5154
55+ #from obslib
56+ self .objects = {}
57+
5258class Attribute (object ):
5359
5460 def __init__ (self , data ):
@@ -133,28 +139,63 @@ def __repr__(self):
133139
134140# Actor is a base class for Observer and Player
135141class Person (object ):
136- def __init__ (self , pid , name ):
142+ def __init__ (self , pid , name , replay ):
137143 self .pid = pid
138144 self .name = name
139145 self .is_obs = None
140146 self .messages = list ()
141147 self .events = list ()
142148 self .recorder = False # Actual recorder will be determined using the replay.message.events file
143149
150+ #From obslib
151+ self .selections = {}
152+ self .hotkeys = {}
153+ self .replay = replay
154+
155+ def get_selection (self , number = 10 ):
156+ """ Get selection buffer by number """
157+ if number < 10 :
158+ return self .get_hotkey (number )
159+ else :
160+ selection = self .selections .get (number , Selection ())
161+ self .selections [number ] = selection
162+ return selection
163+
164+ def get_hotkey (self , number ):
165+ """ Get hotkey buffer by number (does not load it) """
166+ hotkey = self .hotkeys .get (number , Selection ())
167+ self .hotkeys [number ] = hotkey
168+ return hotkey
169+
170+ def load_hotkey (self , number , timestamp ):
171+ """ Push hotkey to current selection (10) """
172+ hotkey = self .hotkeys .get (number , Selection ())
173+ self .hotkeys [number ] = hotkey
174+ selection = self .get_selection (10 ) # get user bank
175+ selection .deselect_all (timestamp )
176+ selection .select (hotkey .current (), timestamp )
177+
178+ def army_composition_at (self , frame ):
179+ return [object for object in self .game .objects .values () if object .alive_at (frame ) and object .player == self and issubclass (object .object_types [frame ], Army )]
180+
181+ def production_structures_at (self , frame ):
182+ return [object for object in self .game .objects .values () if object .alive_at (frame ) and object .player == self and issubclass (object .object_types [frame ], Production )]
183+
184+
144185class Observer (Person ):
145- def __init__ (self , pid , name ):
146- super (Observer ,self ).__init__ (pid ,name )
186+ def __init__ (self , pid , name , replay ):
187+ super (Observer ,self ).__init__ (pid , name , replay )
147188 self .is_obs = True
148189
149190class Player (Person ):
150191
151192 url_template = "http://%s.battle.net/sc2/en/profile/%s/%s/%s/"
152193
153- def __init__ (self , pid , data , realm = "us" ):
194+ def __init__ (self , pid , data , replay ):
154195 # TODO: get a map of realm,subregion => region in here
155- super (Player ,self ).__init__ (pid ,data [0 ])
196+ super (Player ,self ).__init__ (pid , data [0 ], replay )
156197 self .is_obs = False
157- self .realm = realm
198+ self .realm = replay . realm
158199 self .uid = data [1 ][4 ]
159200 self .subregion = data [1 ][2 ]
160201 self .url = self .url_template % (self .realm , self .uid , self .subregion , self .name )
@@ -176,10 +217,10 @@ def __init__(self, pid, data, realm="us"):
176217
177218 self .choosen_race = "" # Populated from the replay.attribute.events file
178219 self .color_rgba = dict ([
179- ['r' , data [3 ][1 ]],
180- ['g' , data [3 ][2 ]],
181- ['b' , data [3 ][3 ]],
182- ['a' , data [3 ][0 ]],
220+ ['r' , data [3 ][1 ]],
221+ ['g' , data [3 ][2 ]],
222+ ['b' , data [3 ][3 ]],
223+ ['a' , data [3 ][0 ]],
183224 ])
184225
185226 self .result = None
@@ -191,7 +232,7 @@ def __init__(self, pid, data, realm="us"):
191232 self .avg_apm = 0
192233 self .aps = dict () # Doesn't contain seconds with zero actions
193234 self .apm = dict () # Doesn't contain minutes with zero actions
194-
235+
195236 def __str__ (self ):
196237 return "Player %s - %s (%s)" % (self .pid , self .name , self .actual_race )
197238
@@ -211,7 +252,7 @@ def __init__(self, timestamp, player_id, event_type, event_code):
211252 self .type = event_type
212253 self .code = event_code
213254 self .is_local = (player_id != 16 )
214- self .player = player_id
255+ self .pid = player_id
215256 self .bytes = bytes
216257 self .abilitystr = ""
217258
@@ -258,15 +299,17 @@ def __init__(self, timestamp, player, type, code, ability):
258299 self .ability = ability
259300
260301 def apply (self ):
302+
261303 if self .ability :
262304 if self .ability not in ABILITIES :
263- raise ValueError ("Unknown ability (%s)" % (hex (self .ability )),)
305+ print "Unknown ability (%s) in at %s" % (hex (self .ability ),self .timestr )
306+ #raise ValueError("Unknown ability (%s)" % (hex(self.ability)),)
264307 self .ability = ABILITIES [self .ability ]
265308 able = self .get_able_selection ()
266309 if able :
267310 object = able [0 ]
268311 ability = getattr (object , self .ability )
269- ability (self .timestamp )
312+ ability (self .time )
270313
271314 # claim units
272315 for obj in self .player .get_selection ().current :
@@ -294,14 +337,14 @@ def apply(self):
294337 create_obj = not GameObject .has_type (obj_type & 0xfffffc | 0x2 )
295338
296339 obj = None
297- if obj_id in self .player .game .objects :
298- obj = self .player .game .objects [obj_id ]
340+ if obj_id in self .player .replay .objects :
341+ obj = self .player .replay .objects [obj_id ]
299342 elif create_obj :
300- obj = type_class (obj_id , self .timestamp )
301- self .player .game .objects [obj_id ] = obj
343+ obj = type_class (obj_id , self .time )
344+ self .player .replay .objects [obj_id ] = obj
302345
303346 if obj :
304- obj .visit (self .timestamp , self .player , type_class )
347+ obj .visit (self .time , self .player , type_class )
305348 self .target = obj
306349
307350 super (TargetAbilityEvent , self ).apply ()
@@ -324,11 +367,11 @@ class SetToHotkeyEvent(HotkeyEvent):
324367 def apply (self ):
325368 hotkey = self .player .get_hotkey (self .hotkey )
326369 selection = self .player .get_selection ()
327- hotkey [self .timestamp ] = selection .current
370+ hotkey [self .time ] = selection .current
328371
329372 # They are alive!
330- for obj in selection [self .timestamp ]:
331- obj .visit (self .timestamp , self .player )
373+ for obj in selection [self .time ]:
374+ obj .visit (self .time , self .player )
332375
333376class AddToHotkeyEvent (HotkeyEvent ):
334377 name = 'AddToHotkeyEvent'
@@ -340,13 +383,13 @@ def apply(self):
340383 if self .overlay :
341384 hotkeyed = self .overlay (hotkeyed )
342385
343- hotkeyed .extend (self .player .get_selection ()[self .timestamp ])
386+ hotkeyed .extend (self .player .get_selection ()[self .time ])
344387 hotkeyed = list (set (hotkeyed )) # remove dups
345- hotkey [self .timestamp ] = hotkeyed
388+ hotkey [self .time ] = hotkeyed
346389
347390 # They are alive!
348391 for obj in hotkeyed :
349- obj .visit (self .timestamp , self .player )
392+ obj .visit (self .time , self .player )
350393
351394class GetHotkeyEvent (HotkeyEvent ):
352395 name = 'GetHotkeyEvent'
@@ -358,11 +401,11 @@ def apply(self):
358401 hotkeyed = self .overlay (hotkeyed )
359402
360403 selection = self .player .get_selection ()
361- selection [self .timestamp ] = hotkeyed
404+ selection [self .time ] = hotkeyed
362405
363406 # selection is alive!
364407 for obj in hotkeyed :
365- obj .visit (self .timestamp , self .player )
408+ obj .visit (self .time , self .player )
366409
367410class SelectionEvent (Event ):
368411 name = 'SelectionEvent'
@@ -378,20 +421,20 @@ def apply(self):
378421
379422 selected = selection .current [:]
380423 for obj in selected : # visit all old units
381- obj .visit (self .timestamp , self .player )
424+ obj .visit (self .time , self .player )
382425
383426 if self .deselect :
384427 selected = self .deselect (selected )
385428
386429 # Add new selection
387430 for (obj_id , obj_type ) in self .objects :
388431 type_class = GameObject .get_type (obj_type )
389- if obj_id not in self .player .game .objects :
390- obj = type_class (obj_id , self .timestamp )
391- self .player .game .objects [obj_id ] = obj
432+ if obj_id not in self .player .replay .objects :
433+ obj = type_class (obj_id , self .time )
434+ self .player .replay .objects [obj_id ] = obj
392435 else :
393- obj = self .player .game .objects [obj_id ]
394- obj .visit (self .timestamp , self .player , type_class )
436+ obj = self .player .replay .objects [obj_id ]
437+ obj .visit (self .time , self .player , type_class )
395438 selected .append (obj )
396439
397- selection [self .timestamp ] = selected
440+ selection [self .time ] = selected
0 commit comments