def __item_update(self, gamestate, event_bytes): projectile = Projectile() projectile.x = np.ndarray((1,), ">f", event_bytes, 0x14)[0] projectile.y = np.ndarray((1,), ">f", event_bytes, 0x18)[0] projectile.x_speed = np.ndarray((1,), ">f", event_bytes, 0xc)[0] projectile.y_speed = np.ndarray((1,), ">f", event_bytes, 0x10)[0] try: projectile.owner = np.ndarray((1,), ">B", event_bytes, 0x2A)[0] + 1 if projectile.owner > 4: projectile.owner = -1 except TypeError: projectile.owner = -1 try: projectile.subtype = enums.ProjectileSubtype(np.ndarray((1,), ">H", event_bytes, 0x5)[0]) except ValueError: projectile.subtype = enums.ProjectileSubtype.UNKNOWN_PROJECTILE # Add the projectile to the gamestate list gamestate.projectiles.append(projectile)
def __handle_slippstream_events(self, event_bytes, gamestate): """ Handle a series of events, provided sequentially in a byte array """ gamestate.menu_state = enums.Menu.IN_GAME while len(event_bytes) > 0: event_size = self.eventsize[event_bytes[0]] if len(event_bytes) < event_size: print("WARNING: Something went wrong unpacking events. Data is probably missing") print("\tDidn't have enough data for event") return False if EventType(event_bytes[0]) == EventType.PAYLOADS: cursor = 0x2 payload_size = event_bytes[1] num_commands = (payload_size - 1) // 3 for i in range(0, num_commands): command, command_len = unpack(">bH", event_bytes[cursor:cursor+3]) self.eventsize[command] = command_len+1 cursor += 3 event_bytes = event_bytes[payload_size + 1:] elif EventType(event_bytes[0]) == EventType.FRAME_START: event_bytes = event_bytes[event_size:] elif EventType(event_bytes[0]) == EventType.GAME_START: event_bytes = event_bytes[event_size:] elif EventType(event_bytes[0]) == EventType.GAME_END: event_bytes = event_bytes[event_size:] elif EventType(event_bytes[0]) == EventType.PRE_FRAME: event_bytes = event_bytes[event_size:] elif EventType(event_bytes[0]) == EventType.POST_FRAME: gamestate.frame = unpack(">i", event_bytes[0x1:0x1+4])[0] controller_port = unpack(">B", event_bytes[0x5:0x5+1])[0] + 1 gamestate.player[controller_port].x = unpack(">f", event_bytes[0xa:0xa+4])[0] gamestate.player[controller_port].y = unpack(">f", event_bytes[0xe:0xe+4])[0] gamestate.player[controller_port].character = enums.Character(unpack(">B", event_bytes[0x7:0x7+1])[0]) try: gamestate.player[controller_port].action = enums.Action(unpack(">H", event_bytes[0x8:0x8+2])[0]) except ValueError: gamestate.player[controller_port].action = enums.Action.UNKNOWN_ANIMATION # Melee stores this in a float for no good reason. So we have to convert facing_float = unpack(">f", event_bytes[0x12:0x12+4])[0] gamestate.player[controller_port].facing = facing_float > 0 gamestate.player[controller_port].percent = int(unpack(">f", event_bytes[0x16:0x16+4])[0]) gamestate.player[controller_port].stock = unpack(">B", event_bytes[0x21:0x21+1])[0] gamestate.player[controller_port].action_frame = int(unpack(">f", event_bytes[0x22:0x22+4])[0]) # Extract the bit at mask 0x20 bitflags2 = unpack(">B", event_bytes[0x27:0x27+1])[0] gamestate.player[controller_port].hitlag = bool(bitflags2 & 0x20) try: gamestate.player[controller_port].hitstun_frames_left = int(unpack(">f", event_bytes[0x2b:0x2b+4])[0]) except ValueError: gamestate.player[controller_port].hitstun_frames_left = 0 gamestate.player[controller_port].on_ground = not bool(unpack(">B", event_bytes[0x2f:0x2f+1])[0]) gamestate.player[controller_port].jumps_left = unpack(">B", event_bytes[0x32:0x32+1])[0] gamestate.player[controller_port].invulnerable = int(unpack(">B", event_bytes[0x34:0x34+1])[0]) != 0 try: gamestate.player[controller_port].speed_air_x_self = unpack(">f", event_bytes[0x35:0x35+4])[0] except error: gamestate.player[controller_port].speed_air_x_self = 0 try: gamestate.player[controller_port].speed_y_self = unpack(">f", event_bytes[0x39:0x39+4])[0] except error: gamestate.player[controller_port].speed_y_self = 0 try: gamestate.player[controller_port].speed_x_attack = unpack(">f", event_bytes[0x3d:0x3d+4])[0] except error: gamestate.player[controller_port].speed_x_attack = 0 try: gamestate.player[controller_port].speed_y_attack = unpack(">f", event_bytes[0x41:0x41+4])[0] except error: gamestate.player[controller_port].speed_y_attack = 0 try: gamestate.player[controller_port].speed_ground_x_self = unpack(">f", event_bytes[0x45:0x45+4])[0] except error: gamestate.player[controller_port].speed_ground_x_self = 0 # Keep track of a player's invulnerability due to respawn or ledge grab gamestate.player[controller_port].invulnerability_left = max(0, self._prev_gamestate.player[controller_port].invulnerability_left - 1) if gamestate.player[controller_port].action == Action.ON_HALO_WAIT: gamestate.player[controller_port].invulnerability_left = 120 # Don't give invulnerability to the first descent if gamestate.player[controller_port].action == Action.ON_HALO_DESCENT and gamestate.frame > 150: gamestate.player[controller_port].invulnerability_left = 120 if gamestate.player[controller_port].action == Action.EDGE_CATCHING and gamestate.player[controller_port].action_frame == 1: gamestate.player[controller_port].invulnerability_left = 36 # The pre-warning occurs when we first start a dash dance. if gamestate.player[controller_port].action == Action.DASHING and \ self._prev_gamestate.player[controller_port].action not in [Action.DASHING, Action.TURNING]: gamestate.player[controller_port].moonwalkwarning = True # Take off the warning if the player does an action other than dashing if gamestate.player[controller_port].action != Action.DASHING: gamestate.player[controller_port].moonwalkwarning = False # "off_stage" helper if (abs(gamestate.player[controller_port].x) > stages.EDGE_GROUND_POSITION[gamestate.stage] or \ gamestate.player[controller_port].y < -6) and not gamestate.player[controller_port].on_ground: gamestate.player[controller_port].off_stage = True else: gamestate.player[controller_port].off_stage = False event_bytes = event_bytes[event_size:] elif EventType(event_bytes[0]) == EventType.GECKO_CODES: event_bytes = event_bytes[event_size:] elif EventType(event_bytes[0]) == EventType.FRAME_BOOKEND: self._prev_gamestate = gamestate # Calculate helper distance variable # This is a bit kludgey.... :/ i = 0 player_one_x, player_one_y, player_two_x, player_two_y = 0, 0, 0, 0 for _, player_state in gamestate.player.items(): if i == 0: player_one_x, player_one_y = player_state.x, player_state.y if i == 1: player_two_x, player_two_y = player_state.x, player_state.y i += 1 xdist = player_one_x - player_two_x ydist = player_one_y - player_two_y gamestate.distance = math.sqrt((xdist**2) + (ydist**2)) event_bytes = event_bytes[event_size:] return True elif EventType(event_bytes[0]) == EventType.ITEM_UPDATE: projectile = Projectile() projectile.x = unpack(">f", event_bytes[0x14:0x14+4])[0] projectile.y = unpack(">f", event_bytes[0x18:0x18+4])[0] projectile.x_speed = unpack(">f", event_bytes[0x0c:0x0c+4])[0] projectile.y_speed = unpack(">f", event_bytes[0x10:0x10+4])[0] try: projectile.owner = unpack(">B", event_bytes[0x2A:0x2A+1])[0] + 1 if projectile.owner > 4: projectile.owner = -1 except error: projectile.owner = -1 try: projectile.subtype = enums.ProjectileSubtype(unpack(">H", event_bytes[0x05:0x05+2])[0]) except ValueError: projectile.subtype = enums.ProjectileSubtype.UNKNOWN_PROJECTILE # Add the projectile to the gamestate list gamestate.projectiles.append(projectile) event_bytes = event_bytes[event_size:] else: print("WARNING: Something went wrong unpacking events. " + \ "Data is probably missing") print("\tGot invalid event type: ", event_bytes[0]) return False return False
def __handle_slippstream_events(self, event_bytes, gamestate): """ Handle a series of events, provided sequentially in a byte array """ lastmessage = EventType.GAME_START while len(event_bytes) > 0: lastmessage = EventType(event_bytes[0]) event_size = self.eventsize[event_bytes[0]] if len(event_bytes) < event_size: print( "WARNING: Something went wrong unpacking events. Data is probably missing" ) print("\tDidn't have enough data for event") return False if (EventType(event_bytes[0]) == EventType.PAYLOADS): cursor = 0x2 payload_size = event_bytes[1] num_commands = (payload_size - 1) // 3 for i in range(0, num_commands): command, command_len = unpack( ">bH", event_bytes[cursor:cursor + 3]) self.eventsize[command] = command_len + 1 cursor += 3 event_bytes = event_bytes[payload_size + 1:] continue elif (EventType(event_bytes[0]) == EventType.FRAME_START): self.frame_num = unpack(">i", event_bytes[1:5])[0] event_bytes = event_bytes[event_size:] continue elif (EventType(event_bytes[0]) == EventType.GAME_START): event_bytes = event_bytes[event_size:] continue elif (EventType(event_bytes[0]) == EventType.GAME_END): event_bytes = event_bytes[event_size:] continue elif (EventType(event_bytes[0]) == EventType.PRE_FRAME): event_bytes = event_bytes[event_size:] continue elif (EventType(event_bytes[0]) == EventType.POST_FRAME): gamestate.frame = unpack(">i", event_bytes[0x1:0x1 + 4])[0] controller_port = unpack(">B", event_bytes[0x5:0x5 + 1])[0] + 1 gamestate.player[controller_port].x = unpack( ">f", event_bytes[0xa:0xa + 4])[0] gamestate.player[controller_port].y = unpack( ">f", event_bytes[0xe:0xe + 4])[0] gamestate.player[controller_port].character = enums.Character( unpack(">B", event_bytes[0x7:0x7 + 1])[0]) try: gamestate.player[controller_port].action = enums.Action( unpack(">H", event_bytes[0x8:0x8 + 2])[0]) except ValueError: gamestate.player[ controller_port].action = enums.Action.UNKNOWN_ANIMATION # Melee stores this in a float for no good reason. So we have to convert facing_float = unpack(">f", event_bytes[0x12:0x12 + 4])[0] gamestate.player[controller_port].facing = facing_float > 0 gamestate.player[controller_port].percent = int( unpack(">f", event_bytes[0x16:0x16 + 4])[0]) gamestate.player[controller_port].stock = unpack( ">B", event_bytes[0x21:0x21 + 1])[0] gamestate.player[controller_port].action_frame = int( unpack(">f", event_bytes[0x22:0x22 + 4])[0]) # Extract the bit at mask 0x20 bitflags2 = unpack(">B", event_bytes[0x27:0x27 + 1])[0] gamestate.player[controller_port].hitlag = bool(bitflags2 & 0x20) gamestate.player[controller_port].hitstun_frames_left = int( unpack(">f", event_bytes[0x2b:0x2b + 4])[0]) gamestate.player[controller_port].on_ground = not bool( unpack(">B", event_bytes[0x2f:0x2f + 1])[0]) gamestate.player[controller_port].jumps_left = unpack( ">B", event_bytes[0x32:0x32 + 1])[0] event_bytes = event_bytes[event_size:] continue elif (EventType(event_bytes[0]) == EventType.GECKO_CODES): event_bytes = event_bytes[event_size:] continue elif (EventType(event_bytes[0]) == EventType.FRAME_BOOKEND): event_bytes = event_bytes[event_size:] return True elif (EventType(event_bytes[0]) == EventType.ITEM_UPDATE): # TODO projectiles projectile = Projectile() projectile.x = unpack(">f", event_bytes[0x14:0x14 + 4])[0] projectile.y = unpack(">f", event_bytes[0x18:0x18 + 4])[0] projectile.x_speed = unpack(">f", event_bytes[0x0c:0x0c + 4])[0] projectile.y_speed = unpack(">f", event_bytes[0x10:0x10 + 4])[0] try: projectile.subtype = enums.ProjectileSubtype( unpack(">H", event_bytes[0x05:0x05 + 2])[0]) except ValueError: projectile.subtype = enums.UNKNOWN_PROJECTILE # Add the projectile to the gamestate list gamestate.projectiles.append(projectile) event_bytes = event_bytes[event_size:] continue else: print("WARNING: Something went wrong unpacking events. " + \ "Data is probably missing") print("\tGot invalid event type: ", event_bytes[0]) return False return False
def update(self, mem_update): label = self.locations[mem_update[0]][0] player_int = int(self.locations[mem_update[0]][1]) if label == "frame": self.frame = unpack('<I', mem_update[1])[0] self.newframe = True #Now that the frame is ready, let's calculate some derived information # These are not stored inside Melee anywhere, but are nonetheless # important pieces of information that we don't want to make the # user have to re-calculate on their own for i in self.player: # Move current x,y over to prev self.player[i].prev_x = self.player[i].x self.player[i].prev_y = self.player[i].y # Move future x,y over to current self.player[i].x = self.player[i].next_x self.player[i].y = self.player[i].next_y if (abs(self.player[i].x) > stages.edgegroundposition(self.stage) or \ self.player[i].y < -6) and not self.player[i].on_ground: self.player[i].off_stage = True else: self.player[i].off_stage = False # Keep track of a player's invulnerability due to respawn or ledge grab self.player[i].invulnerability_left = max( 0, self.player[i].invulnerability_left - 1) if self.player[i].action == Action.ON_HALO_WAIT: self.player[i].invulnerability_left = 120 # Don't give invulnerability to the first descent if self.player[ i].action == Action.ON_HALO_DESCENT and self.frame > 150: self.player[i].invulnerability_left = 120 if self.player[ i].action == Action.EDGE_CATCHING and self.player[ i].action_frame == 1: self.player[i].invulnerability_left = 36 # Which character are we right now? if self.player[i].character in [ Character.SHEIK, Character.ZELDA ]: if self.player[i].transformed == self.player[i].iszelda: self.player[i].character = Character.SHEIK else: self.player[i].character = Character.ZELDA # If the player is transformed, then copy over the sub-character attributes if self.player[i].transformed: self.player[i].action = self.player[i + 4].action self.player[i].action_counter = self.player[ i + 4].action_counter self.player[i].action_frame = self.player[i + 4].action_frame self.player[i].invulnerable = self.player[i + 4].invulnerable self.player[i].hitlag_frames_left = self.player[ i + 4].hitlag_frames_left self.player[i].hitstun_frames_left = self.player[ i + 4].hitstun_frames_left self.player[i].charging_smash = self.player[ i + 4].charging_smash self.player[i].jumps_left = self.player[i + 4].jumps_left self.player[i].on_ground = self.player[i + 4].on_ground self.player[i].speed_air_x_self = self.player[ i + 4].speed_air_x_self self.player[i].speed_y_self = self.player[i + 4].speed_y_self self.player[i].speed_x_attack = self.player[ i + 4].speed_x_attack self.player[i].speed_y_attack = self.player[ i + 4].speed_y_attack self.player[i].speed_ground_x_self = self.player[ i + 4].speed_ground_x_self self.player[i].x = self.player[i + 4].x self.player[i].y = self.player[i + 4].y self.player[i].percent = self.player[i + 4].percent self.player[i].facing = self.player[i + 4].facing # The pre-warning occurs when we first start a dash dance. if self.player[i].action == Action.DASHING and self.player[ i].prev_action not in [Action.DASHING, Action.TURNING]: self.player[i].moonwalkwarning = True # Take off the warning if the player does an action other than dashing if self.player[i].action != Action.DASHING: self.player[i].moonwalkwarning = False #TODO: This needs updating in order to support >2 players xdist = self.ai_state.x - self.opponent_state.x ydist = self.ai_state.y - self.opponent_state.y self.distance = math.sqrt((xdist**2) + (ydist**2)) self.fixiasa() self.fixframeindexing() return True if label == "stage": self.stage = unpack('<I', mem_update[1])[0] self.stage = self.stage >> 16 self.stage &= 0x000000ff try: self.stage = enums.Stage(self.stage) except ValueError: self.stage = enums.Stage.NO_STAGE return False if label == "menu_state": self.menu_state = unpack('<I', mem_update[1])[0] self.menu_state &= 0x000000ff self.menu_state = enums.Menu(self.menu_state) return False #Player variables if label == "percent": if player_int > 4: try: self.player[player_int].percent = int( unpack('<f', mem_update[1])[0]) except ValueError: self.player[player_int].percent = 0 return False self.player[player_int].percent = unpack('<I', mem_update[1])[0] self.player[ player_int].percent = self.player[player_int].percent >> 16 return False if label == "stock": self.player[player_int].stock = unpack('<I', mem_update[1])[0] self.player[player_int].stock = self.player[player_int].stock >> 24 return False if label == "facing": self.player[player_int].facing = unpack('<I', mem_update[1])[0] self.player[player_int].facing = not bool( self.player[player_int].facing >> 31) return False if label == "x": self.player[player_int].next_x = unpack('<f', mem_update[1])[0] return False if label == "y": self.player[player_int].next_y = unpack('<f', mem_update[1])[0] return False if label == "character": temp = unpack('<I', mem_update[1])[0] >> 24 try: self.player[player_int].character = enums.Character(temp) except ValueError: self.player[ player_int].character = enums.Character.UNKNOWN_CHARACTER return False if label == "cursor_x": self.player[player_int].cursor_x = unpack('<f', mem_update[1])[0] return False if label == "cursor_y": self.player[player_int].cursor_y = unpack('<f', mem_update[1])[0] return False if label == "action": temp = unpack('<I', mem_update[1])[0] try: # Keep track of old action self.player[player_int].prev_action = self.player[ player_int].action self.player[player_int].action = enums.Action(temp) except ValueError: self.player[player_int].action = enums.Action.UNKNOWN_ANIMATION return False if label == "action_counter": #TODO look if this is backwards temp = unpack('I', mem_update[1])[0] temp = temp >> 8 self.player[player_int].action_counter = temp return False if label == "action_frame": temp = unpack('<f', mem_update[1])[0] try: self.player[player_int].action_frame = int(temp) except ValueError: pass return False if label == "invulnerable": self.player[player_int].invulnerable = unpack('<I', mem_update[1])[0] self.player[player_int].invulnerable = self.player[ player_int].invulnerable >> 31 return False if label == "hitlag_frames_left": temp = unpack('<f', mem_update[1])[0] try: self.player[player_int].hitlag_frames_left = int(temp) except ValueError: pass return False if label == "hitstun_frames_left": temp = unpack('<f', mem_update[1])[0] try: self.player[player_int].hitstun_frames_left = int(temp) except ValueError: pass return False if label == "charging_smash": temp = unpack('<I', mem_update[1])[0] if temp == 2: self.player[player_int].charging_smash = True else: self.player[player_int].charging_smash = False return False if label == "jumps_left": temp = unpack('<I', mem_update[1])[0] temp = temp >> 24 #This value is actually the number of jumps USED # so we have to do some quick math to turn this into what we want try: totaljumps = int(self.characterdata[ self.player[player_int].character]["Jumps"]) self.player[player_int].jumps_left = totaljumps - temp + 1 # Key error will be expected when we first start except KeyError: self.player[player_int].jumps_left = 1 return False if label == "on_ground": temp = unpack('<I', mem_update[1])[0] if temp == 0: self.player[player_int].on_ground = True else: self.player[player_int].on_ground = False return False if label == "speed_air_x_self": self.player[player_int].speed_air_x_self = unpack( '<f', mem_update[1])[0] return False if label == "speed_y_self": self.player[player_int].speed_y_self = unpack('<f', mem_update[1])[0] return False if label == "speed_x_attack": self.player[player_int].speed_x_attack = unpack( '<f', mem_update[1])[0] return False if label == "speed_y_attack": self.player[player_int].speed_y_attack = unpack( '<f', mem_update[1])[0] return False if label == "speed_ground_x_self": self.player[player_int].speed_ground_x_self = unpack( '<f', mem_update[1])[0] return False if label == "coin_down": temp = unpack('<I', mem_update[1])[0] temp = temp & 0x000000ff self.player[player_int].coin_down = (temp == 2) return False if label == "stage_select_cursor_x": self.stage_select_cursor_x = unpack('<f', mem_update[1])[0] return False if label == "stage_select_cursor_y": self.stage_select_cursor_y = unpack('<f', mem_update[1])[0] return False if label == "ready_to_start": temp = unpack('>I', mem_update[1])[0] temp = temp & 0x000000ff self.ready_to_start = not bool(temp) return False if label == "controller_status": temp = unpack('>I', mem_update[1])[0] temp = temp & 0x000000ff self.player[player_int].controller_status = enums.ControllerStatus( temp) return False if label == "hitbox_1_size": self.player[player_int].hitbox_1_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_2_size": self.player[player_int].hitbox_2_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_3_size": self.player[player_int].hitbox_3_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_4_size": self.player[player_int].hitbox_4_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_1_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_1_status = status return False if label == "hitbox_2_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_2_status = status return False if label == "hitbox_3_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_3_status = status return False if label == "hitbox_4_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_4_status = status return False if label == "hitbox_1_x": self.player[player_int].hitbox_1_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_1_y": self.player[player_int].hitbox_1_y = unpack('<f', mem_update[1])[0] return False if label == "hitbox_2_x": self.player[player_int].hitbox_2_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_2_y": self.player[player_int].hitbox_2_y = unpack('<f', mem_update[1])[0] return False if label == "hitbox_3_x": self.player[player_int].hitbox_3_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_3_y": self.player[player_int].hitbox_3_y = unpack('<f', mem_update[1])[0] return False if label == "hitbox_4_x": self.player[player_int].hitbox_4_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_4_y": self.player[player_int].hitbox_4_y = unpack('<f', mem_update[1])[0] return False if label == "iasa": self.player[player_int].iasa = bool( unpack('<I', mem_update[1])[0] >> 31) return False if label == "transformed": temp = unpack('<I', mem_update[1])[0] status = False if temp == 16777216: status = True self.player[player_int].transformed = status return False if label == "iszelda": temp = unpack('<I', mem_update[1])[0] status = False if temp == 18: status = True self.player[player_int].iszelda = status return False if label == "projectiles": #Only once per new frame that we get a projectile, clear the list out if self.newframe: self.projectiles.clear() self.i = 0 self.i += 1 self.newframe = False if len(mem_update[1]) < 10: self.projectiles.clear() return False proj = Projectile() proj.x = unpack('>f', mem_update[1][0x4c:0x50])[0] proj.y = unpack('>f', mem_update[1][0x50:0x54])[0] proj.x_speed = unpack('>f', mem_update[1][0x40:0x44])[0] proj.y_speed = unpack('>f', mem_update[1][0x44:0x48])[0] try: proj.subtype = enums.ProjectileSubtype( unpack('>I', mem_update[1][0x10:0x14])[0]) except ValueError: return False self.projectiles.append(proj) return False
def update(self, mem_update): label = self.locations[mem_update[0]][0] player_int = int(self.locations[mem_update[0]][1]) if label == "frame": self.frame = unpack('<I', mem_update[1])[0] self.newframe = True #Now that the frame is ready, let's calculate some derived information # These are not stored inside Melee anywhere, but are nonetheless # important pieces of information that we don't want to make the # user have to re-calculate on their own for i in self.player: if abs(self.player[i].x) > stages.edgegroundposition( self.stage): self.player[i].off_stage = True else: self.player[i].off_stage = False #TODO: This needs updating in order to support >2 players xdist = self.ai_state.x - self.opponent_state.x ydist = self.ai_state.y - self.opponent_state.y self.distance = math.sqrt((xdist**2) + (ydist**2)) self.fixframeindexing() return True if label == "stage": self.stage = unpack('<I', mem_update[1])[0] self.stage = self.stage >> 16 self.stage &= 0x000000ff try: self.stage = enums.Stage(self.stage) except ValueError: self.stage = enums.Stage.NO_STAGE return False if label == "menu_state": self.menu_state = unpack('<I', mem_update[1])[0] self.menu_state &= 0x000000ff self.menu_state = enums.Menu(self.menu_state) return False #Player variables if label == "percent": self.player[player_int].percent = unpack('<I', mem_update[1])[0] self.player[ player_int].percent = self.player[player_int].percent >> 16 return False if label == "stock": self.player[player_int].stock = unpack('<I', mem_update[1])[0] self.player[player_int].stock = self.player[player_int].stock >> 24 return False if label == "facing": self.player[player_int].facing = unpack('<I', mem_update[1])[0] self.player[player_int].facing = not bool( self.player[player_int].facing >> 31) return False if label == "x": self.player[player_int].x = unpack('<f', mem_update[1])[0] return False if label == "y": self.player[player_int].y = unpack('<f', mem_update[1])[0] return False if label == "character": temp = unpack('<I', mem_update[1])[0] >> 24 try: self.player[player_int].character = enums.Character(temp) except ValueError: self.player[ player_int].character = enums.Character.UNKNOWN_CHARACTER return False if label == "cursor_x": self.player[player_int].cursor_x = unpack('<f', mem_update[1])[0] return False if label == "cursor_y": self.player[player_int].cursor_y = unpack('<f', mem_update[1])[0] return False if label == "action": temp = unpack('<I', mem_update[1])[0] try: self.player[player_int].action = enums.Action(temp) except ValueError: self.player[player_int].action = enums.Action.UNKNOWN_ANIMATION return False if label == "action_counter": #TODO look if this is backwards temp = unpack('I', mem_update[1])[0] temp = temp >> 8 self.player[player_int].action_counter = temp return False if label == "action_frame": temp = unpack('<f', mem_update[1])[0] try: self.player[player_int].action_frame = int(temp) except ValueError: pass return False if label == "invulnerable": self.player[player_int].invulnerable = unpack('<I', mem_update[1])[0] self.player[player_int].invulnerable = self.player[ player_int].invulnerable >> 31 return False if label == "hitlag_frames_left": temp = unpack('<f', mem_update[1])[0] try: self.player[player_int].hitlag_frames_left = int(temp) except ValueError: pass return False if label == "hitstun_frames_left": temp = unpack('<f', mem_update[1])[0] try: self.player[player_int].hitstun_frames_left = int(temp) except ValueError: pass return False if label == "charging_smash": temp = unpack('<I', mem_update[1])[0] if temp == 2: self.player[player_int].charging_smash = True else: self.player[player_int].charging_smash = False return False if label == "jumps_left": temp = unpack('<I', mem_update[1])[0] temp = temp >> 24 #This value is actually the number of jumps USED # so we have to do some quick math to turn this into what we want #TODO = characterstats.maxjumps(self.player[player_int].character) - temp + 1 self.player[player_int].jumps_left = temp return False if label == "on_ground": temp = unpack('<I', mem_update[1])[0] if temp == 0: self.player[player_int].on_ground = True else: self.player[player_int].on_ground = False return False if label == "speed_air_x_self": self.player[player_int].speed_air_x_self = unpack( '<f', mem_update[1])[0] return False if label == "speed_y_self": self.player[player_int].speed_y_self = unpack('<f', mem_update[1])[0] return False if label == "speed_x_attack": self.player[player_int].speed_x_attack = unpack( '<f', mem_update[1])[0] return False if label == "speed_y_attack": self.player[player_int].speed_y_attack = unpack( '<f', mem_update[1])[0] return False if label == "speed_ground_x_self": self.player[player_int].speed_ground_x_self = unpack( '<f', mem_update[1])[0] return False if label == "coin_down": temp = unpack('<I', mem_update[1])[0] temp = temp & 0x000000ff self.player[player_int].coin_down = (temp == 2) return False if label == "stage_select_cursor_x": self.stage_select_cursor_x = unpack('<f', mem_update[1])[0] return False if label == "stage_select_cursor_y": self.stage_select_cursor_y = unpack('<f', mem_update[1])[0] return False if label == "ready_to_start": temp = unpack('>I', mem_update[1])[0] temp = temp & 0x000000ff self.ready_to_start = not bool(temp) return False if label == "controller_status": temp = unpack('>I', mem_update[1])[0] temp = temp & 0x000000ff self.player[player_int].controller_status = enums.ControllerStatus( temp) return False if label == "hitbox_1_size": self.player[player_int].hitbox_1_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_2_size": self.player[player_int].hitbox_2_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_3_size": self.player[player_int].hitbox_3_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_4_size": self.player[player_int].hitbox_4_size = unpack( '<f', mem_update[1])[0] return False if label == "hitbox_1_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_1_status = status return False if label == "hitbox_2_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_2_status = status return False if label == "hitbox_3_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_3_status = status return False if label == "hitbox_4_status": temp = unpack('<I', mem_update[1])[0] status = True if temp == 0: status = False self.player[player_int].hitbox_4_status = status return False if label == "hitbox_1_x": self.player[player_int].hitbox_1_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_1_y": self.player[player_int].hitbox_1_y = unpack('<f', mem_update[1])[0] return False if label == "hitbox_2_x": self.player[player_int].hitbox_2_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_2_y": self.player[player_int].hitbox_2_y = unpack('<f', mem_update[1])[0] return False if label == "hitbox_3_x": self.player[player_int].hitbox_3_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_3_y": self.player[player_int].hitbox_3_y = unpack('<f', mem_update[1])[0] return False if label == "hitbox_4_x": self.player[player_int].hitbox_4_x = unpack('<f', mem_update[1])[0] return False if label == "hitbox_4_y": self.player[player_int].hitbox_4_y = unpack('<f', mem_update[1])[0] return False if label == "projectiles": #Only once per new frame that we get a projectile, clear the list out if self.newframe: self.projectiles.clear() self.i = 0 self.i += 1 self.newframe = False if len(mem_update[1]) < 10: self.projectiles.clear() return False proj = Projectile() proj.x = unpack('>f', mem_update[1][0x4c:0x50])[0] proj.y = unpack('>f', mem_update[1][0x50:0x54])[0] proj.x_speed = unpack('>f', mem_update[1][0x40:0x44])[0] proj.y_speed = unpack('>f', mem_update[1][0x44:0x48])[0] try: proj.subtype = enums.ProjectileSubtype( unpack('>I', mem_update[1][0x10:0x14])[0]) except ValueError: proj.subtype = enums.ProjectileSubtype.UNKNOWN_PROJECTILE self.projectiles.append(proj) return False