def __handle_slippstream_menu_event(self, event_bytes, gamestate): """ Internal handler for slippstream menu events Modifies specified gamestate based on the event bytes """ scene = np.ndarray((1,), ">H", event_bytes, 0x1)[0] if scene == 0x02: gamestate.menu_state = enums.Menu.CHARACTER_SELECT # All the controller ports are active on this screen gamestate.players[1] = PlayerState() gamestate.players[2] = PlayerState() gamestate.players[3] = PlayerState() gamestate.players[4] = PlayerState() elif scene in [0x0102, 0x0108]: gamestate.menu_state = enums.Menu.STAGE_SELECT gamestate.players[1] = PlayerState() gamestate.players[2] = PlayerState() gamestate.players[3] = PlayerState() gamestate.players[4] = PlayerState() elif scene == 0x0202: gamestate.menu_state = enums.Menu.IN_GAME elif scene == 0x0001: gamestate.menu_state = enums.Menu.MAIN_MENU elif scene == 0x0008: gamestate.menu_state = enums.Menu.SLIPPI_ONLINE_CSS gamestate.players[1] = PlayerState() gamestate.players[2] = PlayerState() gamestate.players[3] = PlayerState() gamestate.players[4] = PlayerState() elif scene == 0x0000: gamestate.menu_state = enums.Menu.PRESS_START else: gamestate.menu_state = enums.Menu.UNKNOWN_MENU # controller port statuses at CSS if gamestate.menu_state in [enums.Menu.CHARACTER_SELECT, enums.Menu.SLIPPI_ONLINE_CSS]: gamestate.players[1].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x25)[0]) gamestate.players[2].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x26)[0]) gamestate.players[3].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x27)[0]) gamestate.players[4].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x28)[0]) # CSS Cursors gamestate.players[1].cursor_x = np.ndarray((1,), ">f", event_bytes, 0x3)[0] gamestate.players[1].cursor_y = np.ndarray((1,), ">f", event_bytes, 0x7)[0] gamestate.players[2].cursor_x = np.ndarray((1,), ">f", event_bytes, 0xB)[0] gamestate.players[2].cursor_y = np.ndarray((1,), ">f", event_bytes, 0xF)[0] gamestate.players[3].cursor_x = np.ndarray((1,), ">f", event_bytes, 0x13)[0] gamestate.players[3].cursor_y = np.ndarray((1,), ">f", event_bytes, 0x17)[0] gamestate.players[4].cursor_x = np.ndarray((1,), ">f", event_bytes, 0x1B)[0] gamestate.players[4].cursor_y = np.ndarray((1,), ">f", event_bytes, 0x1F)[0] # Ready to fight banner gamestate.ready_to_start = np.ndarray((1,), ">B", event_bytes, 0x23)[0] # Character selected try: gamestate.players[1].character = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x29)[0]) gamestate.players[1].character_selected = gamestate.players[1].character except TypeError: gamestate.players[1].character = enums.Character.UNKNOWN_CHARACTER gamestate.players[1].character_selected = enums.Character.UNKNOWN_CHARACTER try: gamestate.players[2].character = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x2A)[0]) gamestate.players[2].character_selected = gamestate.players[2].character except TypeError: gamestate.players[2].character = enums.Character.UNKNOWN_CHARACTER gamestate.players[2].character_selected = enums.Character.UNKNOWN_CHARACTER try: gamestate.players[3].character = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x2B)[0]) gamestate.players[3].character_selected = gamestate.players[3].character except TypeError: gamestate.players[3].character = enums.Character.UNKNOWN_CHARACTER gamestate.players[3].character_selected = enums.Character.UNKNOWN_CHARACTER try: gamestate.players[4].character = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x2C)[0]) gamestate.players[4].character_selected = gamestate.players[4].character except TypeError: gamestate.players[4].character = enums.Character.UNKNOWN_CHARACTER gamestate.players[4].character_selected = enums.Character.UNKNOWN_CHARACTER # Coin down try: gamestate.players[1].coin_down = np.ndarray((1,), ">B", event_bytes, 0x2D)[0] == 2 except TypeError: gamestate.players[1].coin_down = False try: gamestate.players[2].coin_down = np.ndarray((1,), ">B", event_bytes, 0x2E)[0] == 2 except TypeError: gamestate.players[2].coin_down = False try: gamestate.players[3].coin_down = np.ndarray((1,), ">B", event_bytes, 0x2F)[0] == 2 except TypeError: gamestate.players[3].coin_down = False try: gamestate.players[4].coin_down = np.ndarray((1,), ">B", event_bytes, 0x30)[0] == 2 except TypeError: gamestate.players[4].coin_down = False if gamestate.menu_state == enums.Menu.STAGE_SELECT: # Stage try: gamestate.stage = enums.Stage(np.ndarray((1,), ">B", event_bytes, 0x24)[0]) except ValueError: gamestate.stage = enums.Stage.NO_STAGE # Stage Select Cursor X, Y for _, player in gamestate.players.items(): player.cursor.x = np.ndarray((1,), ">f", event_bytes, 0x31)[0] player.cursor.y = np.ndarray((1,), ">f", event_bytes, 0x35)[0] gamestate.stage_select_cursor_x = player.cursor.x gamestate.stage_select_cursor_y = player.cursor.y # Frame count gamestate.frame = np.ndarray((1,), ">i", event_bytes, 0x39)[0] # Sub-menu try: gamestate.submenu = enums.SubMenu(np.ndarray((1,), ">B", event_bytes, 0x3D)[0]) except TypeError: gamestate.submenu = enums.SubMenu.UNKNOWN_SUBMENU except ValueError: gamestate.submenu = enums.SubMenu.UNKNOWN_SUBMENU # Selected menu try: gamestate.menu_selection = np.ndarray((1,), ">B", event_bytes, 0x3E)[0] except TypeError: gamestate.menu_selection = 0 # Online costume chosen try: if gamestate.menu_state == enums.Menu.SLIPPI_ONLINE_CSS: for i in range(4): gamestate.players[i+1].costume = np.ndarray((1,), ">B", event_bytes, 0x3F)[0] except TypeError: pass # This value is 0x05 in the nametag entry try: if gamestate.menu_state == enums.Menu.SLIPPI_ONLINE_CSS: nametag = np.ndarray((1,), ">B", event_bytes, 0x40)[0] if nametag == 0x05: gamestate.submenu = enums.SubMenu.NAME_ENTRY_SUBMENU elif nametag == 0x00: gamestate.submenu = enums.SubMenu.ONLINE_CSS except TypeError: pass # CPU Level try: for i in range(4): gamestate.players[i+1].cpu_level = np.ndarray((1,), ">B", event_bytes, 0x41 + i)[0] except TypeError: pass except KeyError: pass # Is Holding CPU Slider try: for i in range(4): gamestate.players[i+1].is_holding_cpu_slider = np.ndarray((1,), ">B", event_bytes, 0x45 + i)[0] except TypeError: pass except KeyError: pass # Set CPU level to 0 if we're not a CPU for port in gamestate.players: if gamestate.players[port].controller_status != enums.ControllerStatus.CONTROLLER_CPU: gamestate.players[port].cpu_level = 0
def __handle_slippstream_menu_event(self, event_bytes, gamestate): """ Internal handler for slippstream menu events Modifies specified gamestate based on the event bytes """ scene = unpack(">H", event_bytes[0x1:0x1+2])[0] if scene == 0x02: gamestate.menu_state = enums.Menu.CHARACTER_SELECT elif scene == 0x0102: gamestate.menu_state = enums.Menu.STAGE_SELECT elif scene == 0x0202: gamestate.menu_state = enums.Menu.IN_GAME else: gamestate.menu_state = enums.Menu.UNKNOWN_MENU # CSS Cursors gamestate.player[1].cursor_x = unpack(">f", event_bytes[0x3:0x3+4])[0] gamestate.player[1].cursor_y = unpack(">f", event_bytes[0x7:0x7+4])[0] gamestate.player[2].cursor_x = unpack(">f", event_bytes[0xB:0xB+4])[0] gamestate.player[2].cursor_y = unpack(">f", event_bytes[0xF:0xF+4])[0] gamestate.player[3].cursor_x = unpack(">f", event_bytes[0x13:0x13+4])[0] gamestate.player[3].cursor_y = unpack(">f", event_bytes[0x17:0x17+4])[0] gamestate.player[4].cursor_x = unpack(">f", event_bytes[0x1B:0x1B+4])[0] gamestate.player[4].cursor_y = unpack(">f", event_bytes[0x1F:0x1F+4])[0] # Ready to fight banner gamestate.ready_to_start = unpack(">B", event_bytes[0x23:0x23+1])[0] == 0 # Stage try: gamestate.stage = enums.Stage(unpack(">B", event_bytes[0x24:0x24+1])[0]) except ValueError: gamestate.stage = enums.Stage.NO_STAGE # controller port statuses at CSS try: gamestate.player[1].controller_status = enums.ControllerStatus(unpack(">B", event_bytes[0x25:0x25+1])[0]) except error: gamestate.player[1].controller_status = enums.ControllerStatus.CONTROLLER_UNPLUGGED try: gamestate.player[2].controller_status = enums.ControllerStatus(unpack(">B", event_bytes[0x26:0x26+1])[0]) except error: gamestate.player[2].controller_status = enums.ControllerStatus.CONTROLLER_UNPLUGGED try: gamestate.player[3].controller_status = enums.ControllerStatus(unpack(">B", event_bytes[0x27:0x27+1])[0]) except error: gamestate.player[3].controller_status = enums.ControllerStatus.CONTROLLER_UNPLUGGED try: gamestate.player[4].controller_status = enums.ControllerStatus(unpack(">B", event_bytes[0x28:0x28+1])[0]) except error: gamestate.player[4].controller_status = enums.ControllerStatus.CONTROLLER_UNPLUGGED # Character selected try: tmp = unpack(">B", event_bytes[0x29:0x29+1])[0] gamestate.player[1].character_selected = enums.to_internal(tmp) except error: gamestate.player[1].character_selected = enums.Character.UNKNOWN_CHARACTER try: tmp = unpack(">B", event_bytes[0x2A:0x2A+1])[0] gamestate.player[2].character_selected = enums.to_internal(tmp) except error: gamestate.player[2].character_selected = enums.Character.UNKNOWN_CHARACTER try: tmp = unpack(">B", event_bytes[0x2B:0x2B+1])[0] gamestate.player[3].character_selected = enums.to_internal(tmp) except error: gamestate.player[3].character_selected = enums.Character.UNKNOWN_CHARACTER try: tmp = unpack(">B", event_bytes[0x2C:0x2C+1])[0] gamestate.player[4].character_selected = enums.to_internal(tmp) except error: gamestate.player[4].character_selected = enums.Character.UNKNOWN_CHARACTER # Coin down try: gamestate.player[1].coin_down = unpack(">B", event_bytes[0x2D:0x2D+1])[0] == 2 except error: gamestate.player[1].coin_down = False try: gamestate.player[2].coin_down = unpack(">B", event_bytes[0x2E:0x2E+1])[0] == 2 except error: gamestate.player[2].coin_down = False try: gamestate.player[3].coin_down = unpack(">B", event_bytes[0x2F:0x2F+1])[0] == 2 except error: gamestate.player[3].coin_down = False try: gamestate.player[4].coin_down = unpack(">B", event_bytes[0x30:0x30+1])[0] == 2 except error: gamestate.player[4].coin_down = False # Stage Select Cursor X, Y gamestate.stage_select_cursor_x = unpack(">f", event_bytes[0x31:0x31+4])[0] gamestate.stage_select_cursor_y = unpack(">f", event_bytes[0x35:0x35+4])[0] # Frame count gamestate.frame = unpack(">i", event_bytes[0x39:0x39+4])[0]
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
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 __handle_slippstream_menu_event(self, event_bytes, gamestate): """ Internal handler for slippstream menu events Modifies specified gamestate based on the event bytes """ scene = np.ndarray((1,), ">H", event_bytes, 0x1)[0] if scene == 0x02: gamestate.menu_state = enums.Menu.CHARACTER_SELECT # All the controller ports are active on this screen gamestate.player[1] = PlayerState() gamestate.player[2] = PlayerState() gamestate.player[3] = PlayerState() gamestate.player[4] = PlayerState() elif scene == 0x0102: gamestate.menu_state = enums.Menu.STAGE_SELECT elif scene == 0x0202: gamestate.menu_state = enums.Menu.IN_GAME elif scene == 0x0001: gamestate.menu_state = enums.Menu.MAIN_MENU elif scene == 0x0008: gamestate.menu_state = enums.Menu.SLIPPI_ONLINE_CSS gamestate.player[1] = PlayerState() gamestate.player[2] = PlayerState() gamestate.player[3] = PlayerState() gamestate.player[4] = PlayerState() elif scene == 0x0000: gamestate.menu_state = enums.Menu.PRESS_START else: gamestate.menu_state = enums.Menu.UNKNOWN_MENU # controller port statuses at CSS if gamestate.menu_state in [enums.Menu.CHARACTER_SELECT, enums.Menu.SLIPPI_ONLINE_CSS]: gamestate.player[1].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x25)[0]) gamestate.player[2].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x26)[0]) gamestate.player[3].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x27)[0]) gamestate.player[4].controller_status = enums.ControllerStatus(np.ndarray((1,), ">B", event_bytes, 0x28)[0]) # CSS Cursors gamestate.player[1].cursor_x = np.ndarray((1,), ">f", event_bytes, 0x3)[0] gamestate.player[1].cursor_y = np.ndarray((1,), ">f", event_bytes, 0x7)[0] gamestate.player[2].cursor_x = np.ndarray((1,), ">f", event_bytes, 0xB)[0] gamestate.player[2].cursor_y = np.ndarray((1,), ">f", event_bytes, 0xF)[0] gamestate.player[3].cursor_x = np.ndarray((1,), ">f", event_bytes, 0x13)[0] gamestate.player[3].cursor_y = np.ndarray((1,), ">f", event_bytes, 0x17)[0] gamestate.player[4].cursor_x = np.ndarray((1,), ">f", event_bytes, 0x1B)[0] gamestate.player[4].cursor_y = np.ndarray((1,), ">f", event_bytes, 0x1F)[0] # Ready to fight banner gamestate.ready_to_start = np.ndarray((1,), ">B", event_bytes, 0x23)[0] # Character selected try: gamestate.player[1].character_selected = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x29)[0]) except TypeError: gamestate.player[1].character_selected = enums.Character.UNKNOWN_CHARACTER try: gamestate.player[2].character_selected = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x2A)[0]) except TypeError: gamestate.player[2].character_selected = enums.Character.UNKNOWN_CHARACTER try: gamestate.player[3].character_selected = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x2B)[0]) except TypeError: gamestate.player[3].character_selected = enums.Character.UNKNOWN_CHARACTER try: gamestate.player[4].character_selected = enums.to_internal(np.ndarray((1,), ">B", event_bytes, 0x2C)[0]) except TypeError: gamestate.player[4].character_selected = enums.Character.UNKNOWN_CHARACTER # Coin down try: gamestate.player[1].coin_down = np.ndarray((1,), ">B", event_bytes, 0x2D)[0] == 2 except TypeError: gamestate.player[1].coin_down = False try: gamestate.player[2].coin_down = np.ndarray((1,), ">B", event_bytes, 0x2E)[0] == 2 except TypeError: gamestate.player[2].coin_down = False try: gamestate.player[3].coin_down = np.ndarray((1,), ">B", event_bytes, 0x2F)[0] == 2 except TypeError: gamestate.player[3].coin_down = False try: gamestate.player[4].coin_down = np.ndarray((1,), ">B", event_bytes, 0x30)[0] == 2 except TypeError: gamestate.player[4].coin_down = False if gamestate.menu_state == enums.Menu.STAGE_SELECT: # Stage try: gamestate.stage = enums.Stage(np.ndarray((1,), ">B", event_bytes, 0x24)[0]) except ValueError: gamestate.stage = enums.Stage.NO_STAGE # Stage Select Cursor X, Y gamestate.stage_select_cursor_x = np.ndarray((1,), ">f", event_bytes, 0x31)[0] gamestate.stage_select_cursor_y = np.ndarray((1,), ">f", event_bytes, 0x35)[0] # Frame count gamestate.frame = np.ndarray((1,), ">i", event_bytes, 0x39)[0] # Sub-menu try: gamestate.submenu = enums.SubMenu(np.ndarray((1,), ">B", event_bytes, 0x3D)[0]) except TypeError: gamestate.submenu = enums.SubMenu.UNKNOWN_SUBMENU except ValueError: gamestate.submenu = enums.SubMenu.UNKNOWN_SUBMENU # Selected menu try: gamestate.menu_selection = np.ndarray((1,), ">B", event_bytes, 0x3E)[0] except TypeError: gamestate.menu_selection = 0