# Path: Chains/smashattack.py
# class SMASH_DIRECTION(Enum):
#     UP = 0
#     DOWN = 1
#     LEFT = 2
#     RIGHT = 3
# 
# Path: Chains/shffl.py
# class SHFFL_DIRECTION(Enum):
#     UP = 0
#     DOWN = 1
#     FORWARD = 2
#     BACK = 3
#     NEUTRAL = 4
# 
# Path: Chains/shieldaction.py
# class SHIELD_ACTION(Enum):
#     PSSHINE = 0
#     PSUTILT = 1
#     PSDTILT = 2
#     PSJAB = 3


import melee
import Chains
import math
from melee.enums import Action, Button, Character
from Tactics.tactic import Tactic
from Chains.smashattack import SMASH_DIRECTION
from Chains.shffl import SHFFL_DIRECTION
from Chains.shieldaction import SHIELD_ACTION
        if self.logger:
            self.logger.log("Notes", "framesleft: " + str(framesleft) + " ", concat=True)

        #If we can't interrupt the chain, just continue it
        if self.chain != None and not self.chain.interruptible:
            self.chain.step(gamestate, smashbot_state, opponent_state)
            return

        # TODO: May be missing some relevant inactionable states
        inactionablestates = [Action.THROW_DOWN, Action.THROW_UP, Action.THROW_FORWARD, Action.THROW_BACK, Action.UAIR_LANDING, Action.FAIR_LANDING, \
                Action.DAIR_LANDING, Action.BAIR_LANDING, Action.NAIR_LANDING, Action.UPTILT, Action.DOWNTILT, Action.UPSMASH, \
                Action.DOWNSMASH, Action.FSMASH_MID, Action.FTILT_MID, Action.FTILT_LOW, Action.FTILT_HIGH]
        if smashbot_state.action in inactionablestates:
            self.pickchain(Chains.Nothing)
            return

        # Attempt powershield action, note, we don't have a way of knowing for sure if we hit a physical PS
        opponentxvelocity = (opponent_state.speed_air_x_self + opponent_state.speed_ground_x_self + opponent_state.speed_x_attack)
        opponentyvelocity = (opponent_state.speed_y_attack + opponent_state.speed_y_self)
        opponentonright = opponent_state.position.x > smashbot_state.position.x

        if smashbot_state.action == Action.SHIELD_RELEASE and gamestate.custom["powershielded_last"]:
            # Sometimes shine OOS will miss because the oppponent is still rising with an aerial. Peach's float can be hard to shine OOS.
            if opponent_state.position.y >= 11.5:
                # If the opponent is above a certain height and still rising, or outside of a small x range, don't shine, just WD.
                if opponentyvelocity >= 0 or abs(opponent_state.position.x - smashbot_state.position.x) > 6:
                    self.pickchain(Chains.Wavedash)
                    return
                # Shine otherwise (i.e. if they're above a certain height but falling towards us or in a certain x range)
                else:

# Path: Chains/smashattack.py
# class SMASH_DIRECTION(Enum):
#     UP = 0
#     DOWN = 1
#     LEFT = 2
#     RIGHT = 3
# 
# Path: Chains/shffl.py
# class SHFFL_DIRECTION(Enum):
#     UP = 0
#     DOWN = 1
#     FORWARD = 2
#     BACK = 3
#     NEUTRAL = 4
# 
# Path: Chains/shieldaction.py
# class SHIELD_ACTION(Enum):
#     PSSHINE = 0
#     PSUTILT = 1
#     PSDTILT = 2
#     PSJAB = 3


# Path: Tactics/punish.py
import melee
import Chains
import math
from melee.enums import Action, Button, Character
from Tactics.tactic import Tactic
from Chains.smashattack import SMASH_DIRECTION
from Chains.shffl import SHFFL_DIRECTION
from Chains.shieldaction import SHIELD_ACTION

        if self.logger:
            self.logger.log("Notes", "framesleft: " + str(framesleft) + " ", concat=True)

        #If we can't interrupt the chain, just continue it
        if self.chain != None and not self.chain.interruptible:
            self.chain.step(gamestate, smashbot_state, opponent_state)
            return

        # TODO: May be missing some relevant inactionable states
        inactionablestates = [Action.THROW_DOWN, Action.THROW_UP, Action.THROW_FORWARD, Action.THROW_BACK, Action.UAIR_LANDING, Action.FAIR_LANDING, \
                Action.DAIR_LANDING, Action.BAIR_LANDING, Action.NAIR_LANDING, Action.UPTILT, Action.DOWNTILT, Action.UPSMASH, \
                Action.DOWNSMASH, Action.FSMASH_MID, Action.FTILT_MID, Action.FTILT_LOW, Action.FTILT_HIGH]
        if smashbot_state.action in inactionablestates:
            self.pickchain(Chains.Nothing)
            return

        # Attempt powershield action, note, we don't have a way of knowing for sure if we hit a physical PS
        opponentxvelocity = (opponent_state.speed_air_x_self + opponent_state.speed_ground_x_self + opponent_state.speed_x_attack)
        opponentyvelocity = (opponent_state.speed_y_attack + opponent_state.speed_y_self)
        opponentonright = opponent_state.position.x > smashbot_state.position.x

        if smashbot_state.action == Action.SHIELD_RELEASE and gamestate.custom["powershielded_last"]:
            # Sometimes shine OOS will miss because the oppponent is still rising with an aerial. Peach's float can be hard to shine OOS.
            if opponent_state.position.y >= 11.5:
                # If the opponent is above a certain height and still rising, or outside of a small x range, don't shine, just WD.
                if opponentyvelocity >= 0 or abs(opponent_state.position.x - smashbot_state.position.x) > 6:
                    self.pickchain(Chains.Wavedash)
                    return
                # Shine otherwise (i.e. if they're above a certain height but falling towards us or in a certain x range)
                else:

                    self.pickchain(Chains.ShieldAction, [SHIELD_ACTION.PSSHINE])