Fixes Instructed moves looking at the wrong turn order number (#7788)
This commit is contained in:
parent
b244740f52
commit
58b9642cb1
@ -44,7 +44,8 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA
|
||||
s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, enum ItemHoldEffect holdEffectAtk);
|
||||
s32 GetCritHitOdds(s32 critChanceIndex);
|
||||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
||||
u8 GetBattlerTurnOrderNum(u8 battler);
|
||||
bool32 HasBattlerActedThisTurn(u32 battler);
|
||||
u32 GetBattlerTurnOrderNum(u32 battler);
|
||||
bool32 NoAliveMonsForBattlerSide(u32 battler);
|
||||
bool32 NoAliveMonsForPlayer(void);
|
||||
bool32 NoAliveMonsForEitherParty(void);
|
||||
|
||||
@ -2804,9 +2804,20 @@ static void Cmd_printselectionstringfromtable(void)
|
||||
}
|
||||
}
|
||||
|
||||
u8 GetBattlerTurnOrderNum(u8 battler)
|
||||
bool32 HasBattlerActedThisTurn(u32 battler)
|
||||
{
|
||||
s32 i;
|
||||
u32 i;
|
||||
for (i = 0; i < gCurrentTurnActionNumber; i++)
|
||||
{
|
||||
if (gBattlerByTurnOrder[i] == battler)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GetBattlerTurnOrderNum(u32 battler)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattlerByTurnOrder[i] == battler)
|
||||
@ -3091,8 +3102,8 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber
|
||||
&& !(GetActiveGimmick(gEffectBattler) == GIMMICK_DYNAMAX))
|
||||
else if (!HasBattlerActedThisTurn(gEffectBattler)
|
||||
&& GetActiveGimmick(gEffectBattler) != GIMMICK_DYNAMAX)
|
||||
{
|
||||
gBattleMons[gEffectBattler].volatiles.flinched = TRUE;
|
||||
gBattlescriptCurrInstr++;
|
||||
@ -3425,7 +3436,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_CORE_ENFORCER:
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)
|
||||
if (HasBattlerActedThisTurn(gBattlerTarget)
|
||||
&& !NoAliveMonsForEitherParty())
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
@ -9455,10 +9466,12 @@ static bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
u32 i;
|
||||
u8 data[MAX_BATTLERS_COUNT];
|
||||
u8 actionsData[MAX_BATTLERS_COUNT];
|
||||
u32 attackerTurnOrderNum = GetBattlerTurnOrderNum(gBattlerAttacker);
|
||||
u32 targetTurnOrderNum = GetBattlerTurnOrderNum(gBattlerTarget);
|
||||
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
if (attackerTurnOrderNum > targetTurnOrderNum)
|
||||
return FALSE;
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
if (attackerTurnOrderNum + 1 == targetTurnOrderNum)
|
||||
return GetGenConfig(GEN_CONFIG_AFTER_YOU_TURN_ORDER) >= GEN_8;
|
||||
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
@ -9466,14 +9479,14 @@ static bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
data[i] = gBattlerByTurnOrder[i];
|
||||
actionsData[i] = gActionsByTurnOrder[i];
|
||||
}
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) == 0 && GetBattlerTurnOrderNum(gBattlerTarget) == 2)
|
||||
if (attackerTurnOrderNum == 0 && targetTurnOrderNum == 2)
|
||||
{
|
||||
gBattlerByTurnOrder[1] = gBattlerTarget;
|
||||
gActionsByTurnOrder[1] = actionsData[2];
|
||||
gBattlerByTurnOrder[2] = data[1];
|
||||
gActionsByTurnOrder[2] = actionsData[1];
|
||||
}
|
||||
else if (GetBattlerTurnOrderNum(gBattlerAttacker) == 0 && GetBattlerTurnOrderNum(gBattlerTarget) == 3)
|
||||
else if (attackerTurnOrderNum == 0 && targetTurnOrderNum == 3)
|
||||
{
|
||||
gBattlerByTurnOrder[1] = gBattlerTarget;
|
||||
gActionsByTurnOrder[1] = actionsData[3];
|
||||
@ -9482,7 +9495,7 @@ static bool32 ChangeOrderTargetAfterAttacker(void)
|
||||
gBattlerByTurnOrder[3] = data[2];
|
||||
gActionsByTurnOrder[3] = actionsData[2];
|
||||
}
|
||||
else // Attacker == 1, Target == 3
|
||||
else // attackerTurnOrderNum == 1, targetTurnOrderNum == 3
|
||||
{
|
||||
gBattlerByTurnOrder[2] = gBattlerTarget;
|
||||
gActionsByTurnOrder[2] = actionsData[3];
|
||||
@ -11436,7 +11449,7 @@ static void Cmd_trysetencore(void)
|
||||
gDisableStructs[gBattlerTarget].encoredMove = gBattleMons[gBattlerTarget].moves[i];
|
||||
gDisableStructs[gBattlerTarget].encoredMovePos = i;
|
||||
// Encore always lasts 3 turns, but we need to account for a scenario where Encore changes the move during the same turn.
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
if (HasBattlerActedThisTurn(gBattlerTarget))
|
||||
gDisableStructs[gBattlerTarget].encoreTimer = 4;
|
||||
else
|
||||
gDisableStructs[gBattlerTarget].encoreTimer = 3;
|
||||
@ -12742,7 +12755,7 @@ static void Cmd_settaunt(void)
|
||||
if (B_TAUNT_TURNS >= GEN_5)
|
||||
{
|
||||
turns = 4;
|
||||
if (GetBattlerTurnOrderNum(gBattlerTarget) > GetBattlerTurnOrderNum(gBattlerAttacker))
|
||||
if (!HasBattlerActedThisTurn(gBattlerTarget))
|
||||
turns--; // If the target hasn't yet moved this turn, Taunt lasts for only three turns (source: Bulbapedia)
|
||||
}
|
||||
else if (B_TAUNT_TURNS >= GEN_4)
|
||||
@ -12771,7 +12784,7 @@ static void Cmd_trysethelpinghand(void)
|
||||
|
||||
if (IsDoubleBattle()
|
||||
&& !(gAbsentBattlerFlags & (1u << gBattlerTarget))
|
||||
&& gCurrentTurnActionNumber < GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
&& !HasBattlerActedThisTurn(gBattlerTarget))
|
||||
{
|
||||
gProtectStructs[gBattlerTarget].helpingHand++;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -15401,7 +15414,7 @@ void BS_SetPledge(void)
|
||||
else if ((gChosenActionByBattler[partner] == B_ACTION_USE_MOVE)
|
||||
&& IsDoubleBattle()
|
||||
&& IsBattlerAlive(partner)
|
||||
&& GetBattlerTurnOrderNum(gBattlerAttacker) < GetBattlerTurnOrderNum(partner)
|
||||
&& !HasBattlerActedThisTurn(partner)
|
||||
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
&& gCurrentMove != partnerMove
|
||||
&& GetMoveEffect(partnerMove) == EFFECT_PLEDGE)
|
||||
@ -15600,7 +15613,7 @@ void BS_TryUpperHand(void)
|
||||
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
|
||||
u32 prio = GetChosenMovePriority(gBattlerTarget, abilityDef);
|
||||
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)
|
||||
if (HasBattlerActedThisTurn(gBattlerTarget)
|
||||
|| gChosenMoveByBattler[gBattlerTarget] == MOVE_NONE
|
||||
|| IsBattleMoveStatus(gChosenMoveByBattler[gBattlerTarget])
|
||||
|| prio < 1
|
||||
@ -15817,7 +15830,7 @@ void BS_TryQuash(void)
|
||||
u32 i, j;
|
||||
|
||||
// It's true if foe is faster, has a bigger priority, or switches
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
if (HasBattlerActedThisTurn(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
return;
|
||||
@ -17346,7 +17359,7 @@ void BS_SuckerPunchCheck(void)
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
if (gProtectStructs[gBattlerTarget].protected == PROTECT_OBSTRUCT)
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
else if (HasBattlerActedThisTurn(gBattlerTarget))
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
else if (IsBattleMoveStatus(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]) && !gProtectStructs[gBattlerTarget].noValidMoves)
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
@ -17433,7 +17446,7 @@ void BS_TryMeFirst(void)
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]];
|
||||
if (IsBattleMoveStatus(move) || IsMoveMeFirstBanned(move)
|
||||
|| GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
|| HasBattlerActedThisTurn(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
@ -17457,7 +17470,7 @@ void BS_TryMeFirst(void)
|
||||
void BS_TryElectrify(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
if (HasBattlerActedThisTurn(gBattlerTarget))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
|
||||
@ -8169,12 +8169,12 @@ static inline u32 CalcMoveBasePower(struct DamageContext *ctx)
|
||||
}
|
||||
break;
|
||||
case EFFECT_PAYBACK:
|
||||
if (GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef)
|
||||
if (HasBattlerActedThisTurn(battlerDef)
|
||||
&& (B_PAYBACK_SWITCH_BOOST < GEN_5 || gDisableStructs[battlerDef].isFirstTurn != 2))
|
||||
basePower *= 2;
|
||||
break;
|
||||
case EFFECT_BOLT_BEAK:
|
||||
if (GetBattlerTurnOrderNum(battlerAtk) < GetBattlerTurnOrderNum(battlerDef)
|
||||
if (!HasBattlerActedThisTurn(battlerDef)
|
||||
|| gDisableStructs[battlerDef].isFirstTurn == 2)
|
||||
basePower *= 2;
|
||||
break;
|
||||
@ -11818,7 +11818,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
|
||||
calc = (calc * (100 + atkParam)) / 100;
|
||||
break;
|
||||
case HOLD_EFFECT_ZOOM_LENS:
|
||||
if (GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef))
|
||||
if (HasBattlerActedThisTurn(battlerDef))
|
||||
calc = (calc * (100 + atkParam)) / 100;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -51,3 +51,22 @@ SINGLE_BATTLE_TEST("Sucker Punch doesn't hit targets that has already moved")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sucker Punch fails if the target has attempted to act even if previously successful")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_SCRATCH, target: playerLeft); MOVE(playerLeft, MOVE_SUCKER_PUNCH, target: opponentLeft); MOVE(playerRight, MOVE_INSTRUCT, target: playerLeft); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUCKER_PUNCH, playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SUCKER_PUNCH, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,3 +132,25 @@ AI_SINGLE_BATTLE_TEST("AI won't use Upper Hand unless it has seen a priority mov
|
||||
TURN { MOVE(player, move); EXPECT_MOVE(opponent, move == MOVE_QUICK_ATTACK ? MOVE_UPPER_HAND : MOVE_KARATE_CHOP); }
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Upper Hand fails if the target has attempted to act even if previously successful")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveCategory(MOVE_EXTREME_SPEED) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
ASSUME(GetMovePriority(MOVE_EXTREME_SPEED) == 2);
|
||||
ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT);
|
||||
PLAYER(SPECIES_MIENSHAO);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_EXTREME_SPEED, target: playerLeft); MOVE(playerLeft, MOVE_UPPER_HAND, target: opponentLeft); MOVE(playerRight, MOVE_INSTRUCT, target: playerLeft); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_UPPER_HAND, playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
MESSAGE("The opposing Wobbuffet flinched and couldn't move!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_EXTREME_SPEED, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_UPPER_HAND, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user