Fixes Coaching on semi-invulnerable ally, Air Balloon being stolen, Immunity abilities being ignored by Mold Breaker (#6327)

This commit is contained in:
PhallenTree 2025-02-23 19:50:52 +00:00 committed by GitHub
parent 5b4de20455
commit 320c6cf11f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 22 additions and 18 deletions

View File

@ -1035,6 +1035,7 @@ BattleScript_EffectCoaching::
setallytonexttarget EffectCoaching_CheckAllyStats
goto BattleScript_ButItFailed
EffectCoaching_CheckAllyStats:
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_CoachingWorks
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_DEF, MAX_STAT_STAGE, BattleScript_CoachingWorks
goto BattleScript_ButItFailed @ ally at max atk, def
@ -3775,6 +3776,7 @@ BattleScript_TwoTurnMovesSecondTurn::
BattleScript_TwoTurnMovesSecondTurnRet:
setbyte sB_ANIM_TURN, 1
setbyte sB_ANIM_TARGETS_HIT, 0
clearstatusfromeffect BS_ATTACKER, MOVE_EFFECT_CHARGING
clearsemiinvulnerablebit @ only for moves with EFFECT_SEMI_INVULNERABLE/EFFECT_SKY_DROP
return

View File

@ -829,7 +829,8 @@ struct BattleStruct
u16 commanderActive[MAX_BATTLERS_COUNT];
u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side
u8 redCardActivates:1;
u8 padding:7;
u8 bypassMoldBreakerChecks:1; // for ABILITYEFFECT_IMMUNITY
u8 padding:6;
u8 usedEjectItem;
u8 usedMicleBerry;
u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT];

View File

@ -3639,7 +3639,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gProtectStructs[gBattlerTarget].banefulBunkered = FALSE;
gProtectStructs[gBattlerTarget].obstructed = FALSE;
gProtectStructs[gBattlerTarget].silkTrapped = FALSE;
gProtectStructs[gBattlerAttacker].burningBulwarked = FALSE;
gProtectStructs[gBattlerTarget].burningBulwarked = FALSE;
BattleScriptPush(gBattlescriptCurrInstr + 1);
if (gCurrentMove == MOVE_HYPERSPACE_FURY)
gBattlescriptCurrInstr = BattleScript_HyperspaceFuryRemoveProtect;

View File

@ -6251,6 +6251,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITYEFFECT_IMMUNITY:
gBattleStruct->bypassMoldBreakerChecks = TRUE;
for (battler = 0; battler < gBattlersCount; battler++)
{
switch (GetBattlerAbility(battler))
@ -6341,6 +6342,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
return effect;
}
}
gBattleStruct->bypassMoldBreakerChecks = FALSE;
break;
case ABILITYEFFECT_SYNCHRONIZE:
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT))
@ -6570,7 +6572,9 @@ u32 GetBattlerAbility(u32 battler)
&& gBattleMons[battler].ability == ABILITY_COMATOSE)
return ABILITY_NONE;
if (noAbilityShield && CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability))
if (!gBattleStruct->bypassMoldBreakerChecks
&& noAbilityShield
&& CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability))
return ABILITY_NONE;
return gBattleMons[battler].ability;
@ -6584,7 +6588,9 @@ u32 GetBattlerAbility(u32 battler)
&& noAbilityShield)
return ABILITY_NONE;
if (noAbilityShield && CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability))
if (!gBattleStruct->bypassMoldBreakerChecks
&& noAbilityShield
&& CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability))
return ABILITY_NONE;
return gBattleMons[battler].ability;
@ -11436,8 +11442,12 @@ bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item)
return FALSE;
}
// It's supposed to pop before trying to steal but this also works
if (ItemId_GetHoldEffect(item) == HOLD_EFFECT_AIR_BALLOON)
return FALSE;
if (!CanBattlerGetOrLoseItem(battlerItem, item) // Battler with item cannot have it stolen
||!CanBattlerGetOrLoseItem(battlerStealing, item)) // Stealer cannot take the item
|| !CanBattlerGetOrLoseItem(battlerStealing, item)) // Stealer cannot take the item
return FALSE;
return TRUE;

View File

@ -58,7 +58,6 @@ SINGLE_BATTLE_TEST("Own Tempo prevents confusion from moves by the user")
SINGLE_BATTLE_TEST("Mold Breaker ignores Own Tempo")
{
KNOWN_FAILING; // Ideally the func CanBeConfused should be split into AttackerCanBeConfused and TargetCanBeConfused or we do it in the same func but have a check for when battlerAtk == battlerDef
GIVEN {
ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
@ -66,16 +65,13 @@ SINGLE_BATTLE_TEST("Mold Breaker ignores Own Tempo")
} WHEN {
TURN { MOVE(player, MOVE_CONFUSE_RAY); }
} SCENE {
NONE_OF {
ABILITY_POPUP(opponent, ABILITY_OWN_TEMPO);
MESSAGE("The opposing Slowpoke's Own Tempo prevents confusion!");
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFUSE_RAY, player);
NOT MESSAGE("The opposing Slowpoke's Own Tempo prevents confusion!");
}
}
SINGLE_BATTLE_TEST("Mold Breaker does not prevent Own Tempo from curing confusion right after")
{
KNOWN_FAILING;
GIVEN {
ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); };

View File

@ -33,7 +33,6 @@ DOUBLE_BATTLE_TEST("Pastel Veil prevents Poison Sting poison on partner")
SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison")
{
KNOWN_FAILING;
GIVEN {
ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }

View File

@ -105,7 +105,6 @@ SINGLE_BATTLE_TEST("Air Balloon pops before it can be stolen with Magician")
SINGLE_BATTLE_TEST("Air Balloon pops before it can be stolen with Thief or Covet")
{
u32 move;
KNOWN_FAILING;
PARAMETRIZE { move = MOVE_THIEF; }
PARAMETRIZE { move = MOVE_COVET; }
GIVEN {

View File

@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Jaboca Berry tirggers before Bug Bite can steal it")
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
HP_BAR(player);
MESSAGE("Wyanut was hurt by the opposing Wobbuffet's Jaboca Berry!");
NOT MESSAGE("Wynaut stole and ate the opposing its target's Jaboca Berry!");
MESSAGE("Wynaut was hurt by the opposing Wobbuffet's Jaboca Berry!");
NOT MESSAGE("Wynaut stole and ate the opposing Wobbuffet's Jaboca Berry!");
}
}

View File

@ -58,7 +58,6 @@ DOUBLE_BATTLE_TEST("Coaching bypasses Crafty Shield")
DOUBLE_BATTLE_TEST("Coaching fails if all allies are is semi-invulnerable")
{
KNOWN_FAILING; // Coaching succeeds
GIVEN {
ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE);
PLAYER(SPECIES_WOBBUFFET);

View File

@ -49,7 +49,6 @@ SINGLE_BATTLE_TEST("Razor Wind needs a charging turn")
SINGLE_BATTLE_TEST("Razor Wind doesn't need to charge with Power Herb")
{
KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POWER_HERB); }
OPPONENT(SPECIES_WOBBUFFET);
@ -69,7 +68,6 @@ SINGLE_BATTLE_TEST("Razor Wind doesn't need to charge with Power Herb")
MESSAGE("Wobbuffet became fully charged due to its Power Herb!");
if (B_UPDATED_MOVE_DATA < GEN_5)
MESSAGE("Wobbuffet used Razor Wind!");
// For some reason, this breaks with and only with Razor Wind...
ANIMATION(ANIM_TYPE_MOVE, MOVE_RAZOR_WIND, player);
HP_BAR(opponent);
}