예제 #1
0
    def __pre_frame(self, gamestate, event_bytes):
        # Grab the physical controller state and put that into the controller state
        controller_port = np.ndarray((1, ), ">B", event_bytes, 0x5)[0] + 1

        if controller_port not in gamestate.players:
            gamestate.players[controller_port] = PlayerState()
        playerstate = gamestate.players[controller_port]

        # Is this Nana?
        if np.ndarray((1, ), ">B", event_bytes, 0x6)[0] == 1:
            playerstate.nana = PlayerState()
            playerstate = playerstate.nana

        playerstate.costume = self._costumes[controller_port - 1]
        playerstate.cpu_level = self._cpu_level[controller_port - 1]

        main_x = (np.ndarray((1, ), ">f", event_bytes, 0x19)[0] / 2) + 0.5
        main_y = (np.ndarray((1, ), ">f", event_bytes, 0x1D)[0] / 2) + 0.5
        playerstate.controller_state.main_stick = (main_x, main_y)

        c_x = (np.ndarray((1, ), ">f", event_bytes, 0x21)[0] / 2) + 0.5
        c_y = (np.ndarray((1, ), ">f", event_bytes, 0x25)[0] / 2) + 0.5
        playerstate.controller_state.c_stick = (c_x, c_y)

        # The game interprets both shoulders together, so the processed value will always be the same
        trigger = (np.ndarray((1, ), ">f", event_bytes, 0x29)[0])
        playerstate.controller_state.l_shoulder = trigger
        playerstate.controller_state.r_shoulder = trigger

        buttonbits = np.ndarray((1, ), ">H", event_bytes, 0x31)[0]
        playerstate.controller_state.button[enums.Button.BUTTON_A] = bool(
            int(buttonbits) & 0x0100)
        playerstate.controller_state.button[enums.Button.BUTTON_B] = bool(
            int(buttonbits) & 0x0200)
        playerstate.controller_state.button[enums.Button.BUTTON_X] = bool(
            int(buttonbits) & 0x0400)
        playerstate.controller_state.button[enums.Button.BUTTON_Y] = bool(
            int(buttonbits) & 0x0800)
        playerstate.controller_state.button[enums.Button.BUTTON_START] = bool(
            int(buttonbits) & 0x1000)
        playerstate.controller_state.button[enums.Button.BUTTON_Z] = bool(
            int(buttonbits) & 0x0010)
        playerstate.controller_state.button[enums.Button.BUTTON_R] = bool(
            int(buttonbits) & 0x0020)
        playerstate.controller_state.button[enums.Button.BUTTON_L] = bool(
            int(buttonbits) & 0x0040)
        playerstate.controller_state.button[enums.Button.BUTTON_D_LEFT] = bool(
            int(buttonbits) & 0x0001)
        playerstate.controller_state.button[
            enums.Button.BUTTON_D_RIGHT] = bool(int(buttonbits) & 0x0002)
        playerstate.controller_state.button[enums.Button.BUTTON_D_DOWN] = bool(
            int(buttonbits) & 0x0004)
        playerstate.controller_state.button[enums.Button.BUTTON_D_UP] = bool(
            int(buttonbits) & 0x0008)
        if self._use_manual_bookends:
            self._frame = gamestate.frame
예제 #2
0
    def __pre_frame(self, gamestate, event_bytes):
        # Grab the physical controller state and put that into the controller state
        controller_port = np.ndarray((1,), ">B", event_bytes, 0x5)[0] + 1

        if controller_port not in gamestate.player:
            gamestate.player[controller_port] = PlayerState()
        playerstate = gamestate.player[controller_port]

        main_x = (np.ndarray((1,), ">f", event_bytes, 0x19)[0] / 2) + 0.5
        main_y = (np.ndarray((1,), ">f", event_bytes, 0x1D)[0] / 2) + 0.5
        playerstate.controller_state.main_stick = (main_x, main_y)

        c_x = (np.ndarray((1,), ">f", event_bytes, 0x21)[0] / 2) + 0.5
        c_y = (np.ndarray((1,), ">f", event_bytes, 0x25)[0] / 2) + 0.5
        playerstate.controller_state.c_stick = (c_x, c_y)

        buttonbits = np.ndarray((1,), ">H", event_bytes, 0x31)[0]
        playerstate.controller_state.button[enums.Button.BUTTON_A] = bool(int(buttonbits) & 0x0100)
        playerstate.controller_state.button[enums.Button.BUTTON_B] = bool(int(buttonbits) & 0x0200)
        playerstate.controller_state.button[enums.Button.BUTTON_X] = bool(int(buttonbits) & 0x0400)
        playerstate.controller_state.button[enums.Button.BUTTON_Y] = bool(int(buttonbits) & 0x0800)
        playerstate.controller_state.button[enums.Button.BUTTON_START] = bool(int(buttonbits) & 0x1000)
        playerstate.controller_state.button[enums.Button.BUTTON_Z] = bool(int(buttonbits) & 0x0010)
        playerstate.controller_state.button[enums.Button.BUTTON_R] = bool(int(buttonbits) & 0x0020)
        playerstate.controller_state.button[enums.Button.BUTTON_L] = bool(int(buttonbits) & 0x0040)
        playerstate.controller_state.button[enums.Button.BUTTON_D_LEFT] = bool(int(buttonbits) & 0x0001)
        playerstate.controller_state.button[enums.Button.BUTTON_D_RIGHT] = bool(int(buttonbits) & 0x0002)
        playerstate.controller_state.button[enums.Button.BUTTON_D_DOWN] = bool(int(buttonbits) & 0x0004)
        playerstate.controller_state.button[enums.Button.BUTTON_D_UP] = bool(int(buttonbits) & 0x0008)
        if self._allow_old_version:
            self._frame = gamestate.frame
예제 #3
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
예제 #4
0
    def __post_frame(self, gamestate, event_bytes):
        gamestate.stage = self._current_stage
        gamestate.frame = np.ndarray((1,), ">i", event_bytes, 0x1)[0]
        controller_port = np.ndarray((1,), ">B", event_bytes, 0x5)[0] + 1

        if controller_port not in gamestate.players:
            gamestate.players[controller_port] = PlayerState()
        playerstate = gamestate.players[controller_port]

        # Is this Nana?
        if np.ndarray((1,), ">B", event_bytes, 0x6)[0] == 1:
            playerstate.nana = PlayerState()
            playerstate = playerstate.nana

        playerstate.position.x = np.ndarray((1,), ">f", event_bytes, 0xa)[0]
        playerstate.position.y = np.ndarray((1,), ">f", event_bytes, 0xe)[0]

        playerstate.x = playerstate.position.x
        playerstate.y = playerstate.position.y

        playerstate.character = enums.Character(np.ndarray((1,), ">B", event_bytes, 0x7)[0])
        try:
            playerstate.action = enums.Action(np.ndarray((1,), ">H", event_bytes, 0x8)[0])
        except ValueError:
            playerstate.action = enums.Action.UNKNOWN_ANIMATION

        # Melee stores this in a float for no good reason. So we have to convert
        playerstate.facing = np.ndarray((1,), ">f", event_bytes, 0x12)[0] > 0

        playerstate.percent = int(np.ndarray((1,), ">f", event_bytes, 0x16)[0])
        playerstate.shield_strength = np.ndarray((1,), ">f", event_bytes, 0x1A)[0]
        playerstate.stock = np.ndarray((1,), ">B", event_bytes, 0x21)[0]
        playerstate.action_frame = int(np.ndarray((1,), ">f", event_bytes, 0x22)[0])

        try:
            playerstate.hitstun_frames_left = int(np.ndarray((1,), ">f", event_bytes, 0x2B)[0])
        except TypeError:
            playerstate.hitstun_frames_left = 0
        except ValueError:
            playerstate.hitstun_frames_left = 0
        try:
            playerstate.on_ground = not bool(np.ndarray((1,), ">B", event_bytes, 0x2F)[0])
        except TypeError:
            playerstate.on_ground = True
        try:
            playerstate.jumps_left = np.ndarray((1,), ">B", event_bytes, 0x32)[0]
        except TypeError:
            playerstate.jumps_left = 1

        try:
            playerstate.invulnerable = int(np.ndarray((1,), ">B", event_bytes, 0x34)[0]) != 0
        except TypeError:
            playerstate.invulnerable = False

        try:
            playerstate.speed_air_x_self = np.ndarray((1,), ">f", event_bytes, 0x35)[0]
        except TypeError:
            playerstate.speed_air_x_self = 0

        try:
            playerstate.speed_y_self = np.ndarray((1,), ">f", event_bytes, 0x39)[0]
        except TypeError:
            playerstate.speed_y_self = 0

        try:
            playerstate.speed_x_attack = np.ndarray((1,), ">f", event_bytes, 0x3D)[0]
        except TypeError:
            playerstate.speed_x_attack = 0

        try:
            playerstate.speed_y_attack = np.ndarray((1,), ">f", event_bytes, 0x41)[0]
        except TypeError:
            playerstate.speed_y_attack = 0

        try:
            playerstate.speed_ground_x_self = np.ndarray((1,), ">f", event_bytes, 0x45)[0]
        except TypeError:
            playerstate.speed_ground_x_self = 0

        try:
            playerstate.hitlag_left = int(np.ndarray((1,), ">f", event_bytes, 0x49)[0])
        except TypeError:
            playerstate.hitlag_left = 0

        # Keep track of a player's invulnerability due to respawn or ledge grab
        if controller_port in self._prev_gamestate.players:
            playerstate.invulnerability_left = max(0, self._invuln_start[controller_port][1] - (gamestate.frame - self._invuln_start[controller_port][0]))
        if playerstate.action == Action.ON_HALO_WAIT:
            playerstate.invulnerability_left = 120
            self._invuln_start[controller_port] = (gamestate.frame, 120)
        # Don't give invulnerability to the first descent
        if playerstate.action == Action.ON_HALO_DESCENT and gamestate.frame > 150:
            playerstate.invulnerability_left = 120
            self._invuln_start[controller_port] = (gamestate.frame, 120)
        if playerstate.action == Action.EDGE_CATCHING and playerstate.action_frame == 1:
            playerstate.invulnerability_left = 36
            self._invuln_start[controller_port] = (gamestate.frame, 36)
        # First frame of the game
        if gamestate.frame == -123:
            playerstate.invulnerability_left = 0
            self._invuln_start[controller_port] = (gamestate.frame, 0)

        # The pre-warning occurs when we first start a dash dance.
        if controller_port in self._prev_gamestate.players:
            if playerstate.action == Action.DASHING and \
                    self._prev_gamestate.players[controller_port].action not in [Action.DASHING, Action.TURNING]:
                playerstate.moonwalkwarning = True

        # Take off the warning if the player does an action other than dashing
        if playerstate.action != Action.DASHING:
            playerstate.moonwalkwarning = False

        # "off_stage" helper
        try:
            if (abs(playerstate.position.x) > stages.EDGE_GROUND_POSITION[gamestate.stage] or \
                    playerstate.y < -6) and not playerstate.on_ground:
                playerstate.off_stage = True
            else:
                playerstate.off_stage = False
        except KeyError:
            playerstate.off_stage = False

        # ECB top edge, x
        ecb_top_x = 0
        ecb_top_y = 0
        try:
            ecb_top_x = np.ndarray((1,), ">f", event_bytes, 0x4D)[0]
        except TypeError:
            ecb_top_x = 0
        # ECB Top edge, y
        try:
            ecb_top_y = np.ndarray((1,), ">f", event_bytes, 0x51)[0]
        except TypeError:
            ecb_top_y = 0
        playerstate.ecb.top = collections.namedtuple("Position", ['x', 'y'])
        playerstate.ecb.top.x = ecb_top_x
        playerstate.ecb.top.y = ecb_top_y
        playerstate.ecb_top = (ecb_top_x, ecb_top_y)

        # ECB bottom edge, x coord
        ecb_bot_x = 0
        ecb_bot_y = 0
        try:
            ecb_bot_x = np.ndarray((1,), ">f", event_bytes, 0x55)[0]
        except TypeError:
            ecb_bot_x = 0
        # ECB Bottom edge, y coord
        try:
            ecb_bot_y = np.ndarray((1,), ">f", event_bytes, 0x59)[0]
        except TypeError:
            ecb_bot_y = 0
        playerstate.ecb.bottom = collections.namedtuple("Position", ['x', 'y'])
        playerstate.ecb.bottom.x = ecb_bot_x
        playerstate.ecb.bottom.y = ecb_bot_y
        playerstate.ecb_bottom = (ecb_bot_x, ecb_bot_y)

        # ECB left edge, x coord
        ecb_left_x = 0
        ecb_left_y = 0
        try:
            ecb_left_x = np.ndarray((1,), ">f", event_bytes, 0x5D)[0]
        except TypeError:
            ecb_left_x = 0
        # ECB left edge, y coord
        try:
            ecb_left_y = np.ndarray((1,), ">f", event_bytes, 0x61)[0]
        except TypeError:
            ecb_left_y = 0
        playerstate.ecb.left = collections.namedtuple("Position", ['x', 'y'])
        playerstate.ecb.left.x = ecb_left_x
        playerstate.ecb.left.y = ecb_left_y
        playerstate.ecb_left = (ecb_left_x, ecb_left_y)

        # ECB right edge, x coord
        ecb_right_x = 0
        ecb_right_y = 0
        try:
            ecb_right_x = np.ndarray((1,), ">f", event_bytes, 0x65)[0]
        except TypeError:
            ecb_right_x = 0
        # ECB right edge, y coord
        try:
            ecb_right_y = np.ndarray((1,), ">f", event_bytes, 0x69)[0]
        except TypeError:
            ecb_right_y = 0
        playerstate.ecb.right = collections.namedtuple("Position", ['x', 'y'])
        playerstate.ecb.right.x = ecb_right_x
        playerstate.ecb.right.y = ecb_right_y
        playerstate.ecb_right = (ecb_right_x, ecb_right_y)
        if self._use_manual_bookends:
            self._frame = gamestate.frame
예제 #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
예제 #6
0
    def __post_frame(self, gamestate, event_bytes):
        gamestate.stage = self._current_stage
        gamestate.frame = np.ndarray((1,), ">i", event_bytes, 0x1)[0]
        controller_port = np.ndarray((1,), ">B", event_bytes, 0x5)[0] + 1

        if controller_port not in gamestate.player:
            gamestate.player[controller_port] = PlayerState()

        playerstate = gamestate.player[controller_port]
        playerstate.x = np.ndarray((1,), ">f", event_bytes, 0xa)[0]
        playerstate.y = np.ndarray((1,), ">f", event_bytes, 0xe)[0]

        playerstate.character = enums.Character(np.ndarray((1,), ">B", event_bytes, 0x7)[0])
        try:
            playerstate.action = enums.Action(np.ndarray((1,), ">H", event_bytes, 0x8)[0])
        except ValueError:
            playerstate.action = enums.Action.UNKNOWN_ANIMATION

        # Melee stores this in a float for no good reason. So we have to convert
        playerstate.facing = np.ndarray((1,), ">f", event_bytes, 0x12)[0] > 0

        playerstate.percent = int(np.ndarray((1,), ">f", event_bytes, 0x16)[0])
        playerstate.shield_strength = np.ndarray((1,), ">f", event_bytes, 0x1A)[0]
        playerstate.stock = np.ndarray((1,), ">B", event_bytes, 0x21)[0]
        playerstate.action_frame = int(np.ndarray((1,), ">f", event_bytes, 0x22)[0])

        # Extract the bit at mask 0x20
        try:
            bitflags2 = np.ndarray((1,), ">B", event_bytes, 0x27)[0]
            playerstate.hitlag = bool(bitflags2 & 0x20)
        except TypeError:
            playerstate.hitlag = False

        try:
            playerstate.hitstun_frames_left = int(np.ndarray((1,), ">f", event_bytes, 0x2B)[0])
        except TypeError:
            playerstate.hitstun_frames_left = 0
        except ValueError:
            playerstate.hitstun_frames_left = 0
        try:
            playerstate.on_ground = not bool(np.ndarray((1,), ">B", event_bytes, 0x2F)[0])
        except TypeError:
            playerstate.on_ground = True
        try:
            playerstate.jumps_left = np.ndarray((1,), ">B", event_bytes, 0x32)[0]
        except TypeError:
            playerstate.jumps_left = 1

        try:
            playerstate.invulnerable = int(np.ndarray((1,), ">B", event_bytes, 0x34)[0]) != 0
        except TypeError:
            playerstate.invulnerable = False

        try:
            playerstate.speed_air_x_self = np.ndarray((1,), ">f", event_bytes, 0x35)[0]
        except TypeError:
            playerstate.speed_air_x_self = 0

        try:
            playerstate.speed_y_self = np.ndarray((1,), ">f", event_bytes, 0x39)[0]
        except TypeError:
            playerstate.speed_y_self = 0

        try:
            playerstate.speed_x_attack = np.ndarray((1,), ">f", event_bytes, 0x3D)[0]
        except TypeError:
            playerstate.speed_x_attack = 0

        try:
            playerstate.speed_y_attack = np.ndarray((1,), ">f", event_bytes, 0x41)[0]
        except TypeError:
            playerstate.speed_y_attack = 0

        try:
            playerstate.speed_ground_x_self = np.ndarray((1,), ">f", event_bytes, 0x45)[0]
        except TypeError:
            playerstate.speed_ground_x_self = 0

        # Keep track of a player's invulnerability due to respawn or ledge grab
        if controller_port in self._prev_gamestate.player:
            playerstate.invulnerability_left = max(0, self._prev_gamestate.player[controller_port].invulnerability_left - 1)
        if playerstate.action == Action.ON_HALO_WAIT:
            playerstate.invulnerability_left = 120
        # Don't give invulnerability to the first descent
        if playerstate.action == Action.ON_HALO_DESCENT and gamestate.frame > 150:
            playerstate.invulnerability_left = 120
        if playerstate.action == Action.EDGE_CATCHING and playerstate.action_frame == 1:
            playerstate.invulnerability_left = 36

        # The pre-warning occurs when we first start a dash dance.
        if controller_port in self._prev_gamestate.player:
            if playerstate.action == Action.DASHING and \
                    self._prev_gamestate.player[controller_port].action not in [Action.DASHING, Action.TURNING]:
                playerstate.moonwalkwarning = True

        # Take off the warning if the player does an action other than dashing
        if playerstate.action != Action.DASHING:
            playerstate.moonwalkwarning = False

        # "off_stage" helper
        if (abs(playerstate.x) > stages.EDGE_GROUND_POSITION[gamestate.stage] or \
                playerstate.y < -6) and not playerstate.on_ground:
            playerstate.off_stage = True
        else:
            playerstate.off_stage = False

        # ECB top edge, x
        ecb_top_x = 0
        ecb_top_y = 0
        try:
            ecb_top_x = np.ndarray((1,), ">f", event_bytes, 0x49)[0]
        except TypeError:
            ecb_top_x = 0
        # ECB Top edge, y
        try:
            ecb_top_y = np.ndarray((1,), ">f", event_bytes, 0x4D)[0]
        except TypeError:
            ecb_top_y = 0
        playerstate.ecb_top = (ecb_top_x, ecb_top_y)

        # ECB bottom edge, x coord
        ecb_bot_x = 0
        ecb_bot_y = 0
        try:
            ecb_bot_x = np.ndarray((1,), ">f", event_bytes, 0x51)[0]
        except TypeError:
            ecb_bot_x = 0
        # ECB Bottom edge, y coord
        try:
            ecb_bot_y = np.ndarray((1,), ">f", event_bytes, 0x55)[0]
        except TypeError:
            ecb_bot_y = 0
        playerstate.ecb_bottom = (ecb_bot_x, ecb_bot_y)

        # ECB left edge, x coord
        ecb_left_x = 0
        ecb_left_y = 0
        try:
            ecb_left_x = np.ndarray((1,), ">f", event_bytes, 0x59)[0]
        except TypeError:
            ecb_left_x = 0
        # ECB left edge, y coord
        try:
            ecb_left_y = np.ndarray((1,), ">f", event_bytes, 0x5D)[0]
        except TypeError:
            ecb_left_y = 0
        playerstate.ecb_left = (ecb_left_x, ecb_left_y)

        # ECB right edge, x coord
        ecb_right_x = 0
        ecb_right_y = 0
        try:
            ecb_right_x = np.ndarray((1,), ">f", event_bytes, 0x61)[0]
        except TypeError:
            ecb_right_x = 0
        # ECB right edge, y coord
        try:
            ecb_right_y = np.ndarray((1,), ">f", event_bytes, 0x65)[0]
        except TypeError:
            ecb_right_y = 0
        playerstate.ecb_right = (ecb_right_x, ecb_right_y)
        if self._allow_old_version:
            self._frame = gamestate.frame