Example #1
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 = 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
Example #2
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]
Example #3
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
Example #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:
                # 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
Example #5
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 = 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