1+ from sc2reader import events
2+ from sc2reader import utils
3+
4+ class GameState (dict ):
5+ def __init__ (self , initial_state ):
6+ self [0 ] = initial_state
7+
8+ def __getitem__ (self , frame ):
9+ if frame in self :
10+ return super (GameState , self ).__getitem__ (frame )
11+
12+ # If this particular key doesn't exist, create it
13+ prev_frame = sorted (filter (lambda key : key < frame , self .keys ()))[- 1 ]
14+ state = self [prev_frame ].copy ()
15+ self [frame ] = state
16+ return state
17+
18+ class UnitSelection (object ):
19+ def __init__ (self , * new_objects ):
20+ self .objects = list ()
21+ self .select (new_objects )
22+
23+ def select (self , new_objects ):
24+ object_set = set (self .objects + list (new_objects ))
25+ self .objects = sorted (object_set , key = lambda obj : obj .id )
26+
27+ def deselect (self , mode , data ):
28+ if mode == 0x01 :
29+ """ Deselect objects according to deselect mask """
30+ mask = data
31+ if len (mask ) < len (self .objects ):
32+ # pad to the right
33+ mask = mask + [False ,]* (len (self .objects )- len (mask ))
34+ self .objects = [ obj for (slct , obj ) in filter (lambda (slct , obj ): not slct , zip (mask , self .objects )) ]
35+
36+ elif mode == 0x02 :
37+ """ Deselect objects according to indexes """
38+ self .objects = [ self .objects [i ] for i in range (len (self .objects )) if i not in data ]
39+
40+ elif mode == 0x03 :
41+ """ Deselect objects according to indexes """
42+ self .objects = [ self .objects [i ] for i in data ]
43+
44+ def __str__ (self ):
45+ return ', ' .join (str (obj ) for obj in self .objects )
46+
47+ def copy (self ):
48+ return UnitSelection (* self .objects )
49+
50+ class PlayerSelection (dict ):
51+ def __init__ (self ):
52+ for bank in range (0x00 , 0x0B ):
53+ self [bank ]= UnitSelection ()
54+
55+ def copy (self ):
56+ new = PlayerSelection ()
57+ for bank , selection in self .iteritems ():
58+ new [bank ] = UnitSelection (* selection .objects )
59+ return new
60+
61+ class SelectionListener (object ):
62+
63+ def setup (self , replay ):
64+ for player in replay .players :
65+ player .selections = GameState (PlayerSelection ())
66+
67+ def __call__ (self , event , replay ):
68+ selections = event .player .selections [event .frame ]
69+
70+ if isinstance (event , events .HotkeyEvent ):
71+ hotkey_selection = selections [event .hotkey ]
72+
73+ if isinstance (event , events .SetToHotkeyEvent ):
74+ selections [event .hotkey ] = selections [0x0A ].copy ()
75+ print "[{0}] {1} set hotkey {2} to current selection" .format (utils .Length (seconds = event .second ),event .player .name ,event .hotkey )
76+
77+ if isinstance (event , events .AddToHotkeyEvent ):
78+ selections [event .hotkey ].deselect (* event .deselect )
79+ selections [event .hotkey ].select (selections [0x0A ].objects )
80+ print "[{0}] {1} added current selection to hotkey {2}" .format (utils .Length (seconds = event .second ),event .player .name ,event .hotkey )
81+
82+ if isinstance (event , events .GetFromHotkeyEvent ):
83+ selections [0x0A ] = selections [event .hotkey ]
84+ print "[{0}] {1} retrieved hotkey {2}: {3}" .format (utils .Length (seconds = event .second ),event .player .name ,event .hotkey ,selections [event .hotkey ])
85+
86+ event .selected = selections [event .hotkey ]
87+
88+ if isinstance (event , events .SelectionEvent ):
89+ selections [0x0A ].deselect (* event .deselect )
90+ selections [0x0A ].select (event .objects )
91+
92+ event .selected = selections [0x0A ]
93+ print "[{0}] {1} selected: {2}" .format (utils .Length (seconds = event .second ),event .player .name ,event .selected )
0 commit comments