Multiple bugfixes (mostly Dancer/called moves) (#8401)
This commit is contained in:
parent
81192c9146
commit
1a6d03344a
@ -868,8 +868,8 @@ BattleScript_StuffCheeksEnd:
|
||||
BattleScript_EffectDecorate::
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
|
||||
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_ATK, 12, BattleScript_DecorateBoost
|
||||
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_SPATK, 12, BattleScript_DecorateBoost
|
||||
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_DecorateBoost
|
||||
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_DecorateBoost
|
||||
goto BattleScript_ButItFailed
|
||||
BattleScript_DecorateBoost:
|
||||
attackanimation
|
||||
@ -1040,6 +1040,7 @@ BattleScript_EffectStrengthSap::
|
||||
statbuffchange BS_TARGET, STAT_CHANGE_ALLOW_PTR, BattleScript_MoveEnd
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setmoveresultflags MOVE_RESULT_MISSED @ TODO: Is this even necessary?
|
||||
goto BattleScript_MoveEnd
|
||||
BattleScript_StrengthSapTryLower:
|
||||
getstatvalue STAT_ATK
|
||||
@ -1218,6 +1219,7 @@ BattleScript_EffectAromaticMistWontGoHigher:
|
||||
pause B_WAIT_TIME_SHORTEST
|
||||
printstring STRINGID_TARGETSTATWONTGOHIGHER
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setmoveresultflags MOVE_RESULT_MISSED @ TODO: Is this even necessary?
|
||||
goto BattleScript_EffectAromaticMistEnd
|
||||
|
||||
BattleScript_EffectMagneticFlux::
|
||||
@ -1501,6 +1503,7 @@ BattleScript_DefogWorks:
|
||||
jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_CHANGE, BattleScript_DefogDoAnim
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_CHANGE_EMPTY, BattleScript_DefogTryHazardsWithAnim
|
||||
pause B_WAIT_TIME_SHORT
|
||||
setmoveresultflags MOVE_RESULT_MISSED @ TODO: Is this even necessary?
|
||||
goto BattleScript_DefogPrintString
|
||||
BattleScript_DefogDoAnim::
|
||||
attackanimation
|
||||
@ -2608,6 +2611,7 @@ BattleScript_EffectStatUpAfterAtkCanceler::
|
||||
statbuffchange BS_ATTACKER, STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_ONLY_CHECKING, BattleScript_StatUpEnd
|
||||
jumpifbyte CMP_NOT_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_CHANGE, BattleScript_StatUpAttackAnim
|
||||
pause B_WAIT_TIME_SHORT
|
||||
setmoveresultflags MOVE_RESULT_MISSED @ TODO: Is this even necessary?
|
||||
goto BattleScript_StatUpPrintString
|
||||
BattleScript_StatUpAttackAnim::
|
||||
attackanimation
|
||||
@ -2661,6 +2665,7 @@ BattleScript_EffectStatDownFromStatBuffChange:
|
||||
jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_CHANGE, BattleScript_StatDownDoAnim
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_CHANGE_EMPTY, BattleScript_StatDownEnd
|
||||
pause B_WAIT_TIME_SHORT
|
||||
setmoveresultflags MOVE_RESULT_MISSED @ TODO: Is this even necessary?
|
||||
goto BattleScript_StatDownPrintString
|
||||
BattleScript_StatDownDoAnim::
|
||||
attackanimation
|
||||
@ -6773,6 +6778,7 @@ BattleScript_DeltaStreamActivates::
|
||||
printstring STRINGID_MYSTERIOUSAIRCURRENT
|
||||
waitstate
|
||||
playanimation BS_ATTACKER, B_ANIM_STRONG_WINDS
|
||||
call BattleScript_ActivateWeatherAbilities
|
||||
end3
|
||||
|
||||
BattleScript_ProtosynthesisActivates::
|
||||
|
||||
@ -1032,9 +1032,6 @@ static void TryClearChargeVolatile(u32 moveType)
|
||||
|
||||
static bool32 IsAnyTargetAffected(void)
|
||||
{
|
||||
if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
return FALSE;
|
||||
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (battler == gBattlerAttacker)
|
||||
@ -1234,8 +1231,6 @@ static void Cmd_attackcanceler(void)
|
||||
{
|
||||
gBattleStruct->bouncedMoveIsUsed = TRUE;
|
||||
// Edge case for bouncing a powder move against a grass type pokemon.
|
||||
|
||||
ClearDamageCalcResults();
|
||||
gEffectBattler = gBattlerTarget;
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE))
|
||||
{
|
||||
@ -1268,7 +1263,6 @@ static void Cmd_attackcanceler(void)
|
||||
|
||||
if (gBattleStruct->bouncedMoveIsUsed)
|
||||
{
|
||||
ClearDamageCalcResults();
|
||||
BattleScriptCall(BattleScript_MagicBounce);
|
||||
gBattlerAbility = battler;
|
||||
return;
|
||||
@ -7046,7 +7040,7 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_SAME_MOVE_TURNS:
|
||||
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || !IsAnyTargetAffected())
|
||||
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) || !IsAnyTargetAffected())
|
||||
gBattleStruct->metronomeItemCounter[gBattlerAttacker] = 0;
|
||||
else if (gCurrentMove == gLastResultingMoves[gBattlerAttacker] && gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
|
||||
gBattleStruct->metronomeItemCounter[gBattlerAttacker]++;
|
||||
@ -7073,7 +7067,6 @@ static void Cmd_moveend(void)
|
||||
gProtectStructs[gBattlerAttacker].shellTrap = FALSE;
|
||||
gBattleStruct->battlerState[gBattlerAttacker].ateBoost = FALSE;
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
|
||||
gBattleStruct->moldBreakerActive = FALSE;
|
||||
gBattleStruct->swapDamageCategory = FALSE;
|
||||
gBattleStruct->categoryOverride = FALSE;
|
||||
gBattleStruct->additionalEffectsCounter = 0;
|
||||
@ -7132,7 +7125,7 @@ static void Cmd_moveend(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)
|
||||
if (!(!IsAnyTargetAffected()
|
||||
|| (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE && !hasDancerTriggered)
|
||||
|| (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove && gBattleStruct->bouncedMoveIsUsed)))
|
||||
{ // Dance move succeeds
|
||||
@ -10457,7 +10450,6 @@ static u32 ChangeStatBuffs(u32 battler, s8 statValue, enum Stat statId, union St
|
||||
{
|
||||
if (!flags.allowPtr)
|
||||
return STAT_CHANGE_DIDNT_WORK;
|
||||
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
|
||||
return STAT_CHANGE_WORKED;
|
||||
}
|
||||
|
||||
@ -15737,9 +15729,9 @@ void BS_TryTarShot(void)
|
||||
void BS_CanTarShotWork(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
// Tar Shot will fail if it's already been used on the target or if its speed can't be lowered further
|
||||
if (!gDisableStructs[gBattlerTarget].tarShot
|
||||
&& CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerTarget)))
|
||||
// Tar Shot fails if the target can't be made weaker to fire and it's speed can't be lowered further
|
||||
if (!(gDisableStructs[gBattlerTarget].tarShot || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA)
|
||||
|| CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN, GetBattlerAbility(gBattlerTarget)))
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
@ -15769,6 +15761,7 @@ void BS_SetMagicCoatTarget(void)
|
||||
gBattlerAttacker = gBattlerTarget;
|
||||
gBattlerTarget = gBattleStruct->attackerBeforeBounce;
|
||||
HandleMoveTargetRedirection();
|
||||
ClearDamageCalcResults();
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
@ -461,11 +461,6 @@ void HandleAction_UseMove(void)
|
||||
return;
|
||||
}
|
||||
|
||||
gBattleStruct->eventState.atkCanceler = 0;
|
||||
ClearDamageCalcResults();
|
||||
gMultiHitCounter = 0;
|
||||
gBattleScripting.savedDmg = 0;
|
||||
gBattleCommunication[MISS_TYPE] = 0;
|
||||
gCurrMovePos = gChosenMovePos = gBattleStruct->chosenMovePositions[gBattlerAttacker];
|
||||
|
||||
// choose move
|
||||
@ -533,8 +528,10 @@ void HandleAction_UseMove(void)
|
||||
gCurrentMove = gChosenMove = GetMaxMove(gBattlerAttacker, gCurrentMove);
|
||||
}
|
||||
|
||||
if (IsMoldBreakerTypeAbility(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)) || MoveIgnoresTargetAbility(gCurrentMove))
|
||||
gBattleStruct->moldBreakerActive = TRUE;
|
||||
gBattleStruct->eventState.atkCanceler = 0;
|
||||
ClearDamageCalcResults();
|
||||
gMultiHitCounter = 0;
|
||||
gBattleCommunication[MISS_TYPE] = 0;
|
||||
|
||||
moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
|
||||
@ -960,14 +957,13 @@ void HandleAction_ActionFinished(void)
|
||||
memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses));
|
||||
gHitMarker &= ~(HITMARKER_OBEYS);
|
||||
|
||||
ClearDamageCalcResults();
|
||||
gCurrentMove = MOVE_NONE;
|
||||
ClearDamageCalcResults();
|
||||
gBattleScripting.animTurn = 0;
|
||||
gBattleScripting.animTargetsHit = 0;
|
||||
gBattleStruct->dynamicMoveType = 0;
|
||||
gBattleStruct->bouncedMoveIsUsed = FALSE;
|
||||
gBattleStruct->snatchedMoveIsUsed = FALSE;
|
||||
gBattleStruct->moldBreakerActive = FALSE;
|
||||
gBattleScripting.moveendState = 0;
|
||||
gBattleCommunication[3] = 0;
|
||||
gBattleCommunication[4] = 0;
|
||||
@ -2589,6 +2585,7 @@ static enum MoveCanceler CancelerPPDeduction(struct BattleContext *ctx)
|
||||
// Possibly better to just move type setting and redirection to attackcanceler as a new case at this point
|
||||
SetTypeBeforeUsingMove(ctx->currentMove, ctx->battlerAtk);
|
||||
HandleMoveTargetRedirection();
|
||||
ClearDamageCalcResults();
|
||||
gBattlescriptCurrInstr = GetMoveBattleScript(ctx->currentMove);
|
||||
return MOVE_STEP_BREAK;
|
||||
}
|
||||
@ -5277,7 +5274,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ab
|
||||
if (!IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_MAGIC_GUARD))
|
||||
SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 4);
|
||||
|
||||
switch(gBattleMons[gBattlerTarget].species)
|
||||
switch (gBattleMons[gBattlerTarget].species)
|
||||
{
|
||||
case SPECIES_CRAMORANT_GORGING:
|
||||
TryBattleFormChange(battler, FORM_CHANGE_HIT_BY_MOVE);
|
||||
@ -10408,8 +10405,8 @@ void ClearDamageCalcResults(void)
|
||||
{
|
||||
gBattleStruct->moveDamage[battler] = 0;
|
||||
gBattleStruct->critChance[battler] = 0;
|
||||
gBattleStruct->moveResultFlags[battler] = CAN_DAMAGE;
|
||||
gBattleStruct->noResultString[battler] = 0;
|
||||
gBattleStruct->moveResultFlags[battler] = 0;
|
||||
gBattleStruct->noResultString[battler] = CAN_DAMAGE;
|
||||
gBattleStruct->missStringId[battler] = 0;
|
||||
gSpecialStatuses[battler].criticalHit = FALSE;
|
||||
}
|
||||
@ -10419,6 +10416,11 @@ void ClearDamageCalcResults(void)
|
||||
gBattleStruct->calculatedSpreadMoveAccuracy = FALSE;
|
||||
gBattleStruct->printedStrongWindsWeakenedAttack = FALSE;
|
||||
gBattleStruct->numSpreadTargets = 0;
|
||||
gBattleScripting.savedDmg = 0;
|
||||
if (gCurrentMove != MOVE_NONE)
|
||||
gBattleStruct->moldBreakerActive = IsMoldBreakerTypeAbility(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)) || MoveIgnoresTargetAbility(gCurrentMove);
|
||||
else
|
||||
gBattleStruct->moldBreakerActive = FALSE;
|
||||
}
|
||||
|
||||
bool32 DoesDestinyBondFail(u32 battler)
|
||||
|
||||
@ -146,6 +146,27 @@ SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dancer-called attacks do not trigger Life Orb if target is immune")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(IsDanceMove(MOVE_REVELATION_DANCE));
|
||||
ASSUME(GetMoveEffect(MOVE_REVELATION_DANCE) == EFFECT_REVELATION_DANCE);
|
||||
ASSUME(GetMoveEffect(MOVE_ROOST) == EFFECT_ROOST);
|
||||
ASSUME(GetItemHoldEffect(ITEM_LIFE_ORB) == HOLD_EFFECT_LIFE_ORB);
|
||||
ASSUME(GetSpeciesType(SPECIES_ORICORIO_POM_POM, 0) == TYPE_ELECTRIC || GetSpeciesType(SPECIES_ORICORIO_POM_POM, 1) == TYPE_ELECTRIC);
|
||||
PLAYER(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
|
||||
OPPONENT(SPECIES_ORICORIO_POM_POM) { Ability(ABILITY_DANCER); Item(ITEM_LIFE_ORB); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ROOST); MOVE(player, MOVE_REVELATION_DANCE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
|
||||
ABILITY_POPUP(opponent, ABILITY_DANCER);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_LIGHTNING_ROD);
|
||||
NOT HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Dancer doesn't trigger on a snatched move")
|
||||
{
|
||||
GIVEN {
|
||||
|
||||
@ -147,6 +147,27 @@ DOUBLE_BATTLE_TEST("Sleep Talk calls move and that move may be redirected by Sto
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sleep Talk calls move and that move correctly ignores ability if it should")
|
||||
{
|
||||
u32 species;
|
||||
enum Ability ability;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_KINGLER; ability = ABILITY_SHELL_ARMOR; }
|
||||
PARAMETRIZE { species = SPECIES_ARMALDO; ability = ABILITY_BATTLE_ARMOR; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(MoveIgnoresTargetAbility(MOVE_SUNSTEEL_STRIKE));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_SUNSTEEL_STRIKE); }
|
||||
OPPONENT(species) { Ability(ability); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SLEEP_TALK, criticalHit: TRUE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNSTEEL_STRIKE, player);
|
||||
MESSAGE("A critical hit!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sleep Talk deducts power points from itself, not the called move")
|
||||
{
|
||||
ASSUME(GetMovePP(MOVE_SLEEP_TALK) == 10);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user