@@ -203,7 +203,8 @@ def __call__(self, buffer, replay):
203203 0x01 : self .get_action_parser ,
204204 0x02 : self .get_unknown2_parser ,
205205 0x03 : self .get_camera_parser ,
206- 0x04 : self .get_unknown4_parser
206+ 0x04 : self .get_unknown4_parser ,
207+ 0x05 : self .get_unknown5_parser
207208 }
208209
209210 game_events , frames = list (), 0
@@ -275,7 +276,7 @@ def get_setup_parser(self, code):
275276 # the game starting immediately afterwords. On occasion, for unknown
276277 # reasons, other events (particularly camera events) will register
277278 # before the game has actually started. Weird.
278- if code in (0x0B , 0x0C , 0x2C ): return self .parse_join_event
279+ if code in (0x0B , 0x0C , 0x1C , 0x2C ): return self .parse_join_event
279280 elif code in (0x05 ,): return self .parse_start_event
280281 else :
281282 raise ParseError ("Unknown Setup Parser Code {0}" .format (code ))
@@ -329,6 +330,9 @@ def get_unknown4_parser(self, code):
329330 else :
330331 raise ParseError ("Unknown Unknown4 Parser Code {0}" .format (code ))
331332
333+ def get_unknown5_parser (self , code ):
334+ return self .parse_05XX_event
335+
332336 def parse_join_event (self , buffer , frames , type , code , pid ):
333337 return PlayerJoinEvent (frames , pid , type , code )
334338
@@ -742,3 +746,109 @@ def right_click_target(self, buffer, frames, type, code, pid, flag, atype):
742746 target = (buffer .read_int (BIG_ENDIAN ), buffer .read_short (BIG_ENDIAN ))
743747 buffer .skip (10 )
744748 return TargetAbilityEvent (frames , pid , type , code , ability , target )
749+
750+ class GameEventsReader_22612 (GameEventsReader_19595 ):
751+ def parse_join_event (self , buffer , frames , type , code , pid ):
752+ buffer .read_byte ()
753+ return PlayerJoinEvent (frames , pid , type , code )
754+
755+ def cancel (self , buffer , frames , type , code , pid , flag , atype ):
756+ ability = buffer .read_short (endian = BIG_ENDIAN )
757+ ability = ability << 8 | buffer .read_byte ()
758+
759+ # creation autoid number / object id
760+ created_id = buffer .read_object_id ()
761+ # TODO : expose the id
762+ buffer .read_byte ()
763+ return AbilityEvent (frames , pid , type , code , ability )
764+
765+ def parse_ability_event (self , buffer , frames , type , code , pid ):
766+ """Moves the right click move to the top level"""
767+ flag = buffer .read_byte ()
768+ atype = buffer .read_byte ()
769+
770+ if atype & 0x20 : # cancels only now
771+ return self .cancel (buffer , frames , type , code , pid , flag , atype )
772+ elif atype & 0x40 : # all command card abilities?
773+ return self .command_card (buffer , frames , type , code , pid , flag , atype )
774+ elif atype & 0x80 : # right-click on target?
775+ return self .right_click_target (buffer , frames , type , code , pid , flag , atype )
776+ elif atype < 0x10 : #new to patch 1.3.3, location now??
777+ return self .right_click_move (buffer , frames , type , code , pid , flag , atype )
778+
779+ raise ParseError ()
780+
781+ def right_click_move (self , buffer , frames , type , code , pid , flag , atype ):
782+ # This may port back to previous versions. Haven't checked
783+ # Can differ by up to (+/-1, +/-8) from sc2gears readings
784+ # See command_card implementation for details
785+ if atype in (0x00 ,0x02 ):
786+ buffer .skip (3 )
787+ while buffer .read_byte () & 0xF0 != 0 :
788+ buffer .skip (8 )
789+ return AbilityEvent (frames ,pid ,type ,code ,0x3601 )
790+
791+
792+ else : # atype == 0x08:
793+ #!?!?!?!?!?
794+ buffer .skip (6 )
795+ if buffer .read_byte () == 0x00 :
796+ buffer .skip (3 )
797+ else :
798+ buffer .skip (12 )
799+ """
800+ buffer.skip(8)
801+ if buffer.read_byte() == 0x0D:
802+ buffer.skip(9)
803+ buffer.read_byte()
804+ """
805+ return AbilityEvent (frames ,pid ,type ,code ,0x3601 )
806+
807+
808+ """
809+ x = buffer.read_short(BIG_ENDIAN)/256.0
810+ buffer.shift(5) # what is this for, why 5 bits instead of 4?
811+ y = buffer.read_short(BIG_ENDIAN)/256.0
812+ buffer.read(bits=5) # I'll just assume we should do it again
813+ """
814+
815+ #buffer.skip(19)
816+
817+ return AbilityEvent (frames , pid , type , code , 0x3601 )
818+
819+ def parse_05XX_event (self , buffer , frames , type , code , pid ):
820+ buffer .skip (4 )
821+ return UnknownEvent (frames , pid , type , code )
822+
823+ def parse_overlay (self , buffer , mode ):
824+ mode = mode >> 1
825+ if mode == 0x01 : # deselect overlay mask
826+ data = buffer .read_bitmask ()
827+ elif mode == 0x02 : # deselect mask
828+ data = [buffer .read_byte () for i in range (buffer .read_byte ())]
829+ elif mode == 0x03 : # replace mask
830+ data = [buffer .read_byte () for i in range (buffer .read_byte ())]
831+ else :
832+ data = None
833+
834+ buffer .align ()
835+
836+ return mode , data
837+
838+ def parse_selection_event (self , buffer , frames , type , code , pid ):
839+
840+ bank = code >> 4
841+ first = buffer .read_byte () # TODO ?
842+
843+ deselect = self .parse_overlay (buffer , buffer .shift (4 ))
844+
845+ # <count> (<type_id>, <count>,)*
846+ object_types = [ (buffer .read_object_type (read_modifier = True ), buffer .read_byte (), ) for i in range (buffer .read_byte ()) ]
847+ # <count> (<object_id>,)*
848+ object_ids = [ buffer .read_object_id () for i in range (buffer .read_byte ()) ]
849+
850+ # repeat types count times
851+ object_types = chain (* [[object_type ,]* count for (object_type , count ) in object_types ])
852+ objects = zip (object_ids , object_types )
853+
854+ return SelectionEvent (frames , pid , type , code , bank , objects , deselect )
0 commit comments