Fixes Neutralizing Gas displaying message when exiting with multiple users (#8318)
This commit is contained in:
parent
7229305ff9
commit
65a5d1e7d8
@ -1924,8 +1924,8 @@
|
||||
1:
|
||||
.endm
|
||||
|
||||
.macro jumpifabilitycantbesuppressed battler:req, jumpInstr:req
|
||||
callnative BS_JumpIfAbilityCantBeSuppressed
|
||||
.macro jumpifabilitycantbereactivated battler:req, jumpInstr:req
|
||||
callnative BS_JumpIfAbilityCantBeReactivated
|
||||
.byte \battler
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
@ -9296,8 +9296,7 @@ BattleScript_NeutralizingGasExits::
|
||||
setbyte gBattlerAttacker, 0
|
||||
BattleScript_NeutralizingGasExitsLoop:
|
||||
copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1
|
||||
jumpifabilitycantbesuppressed BS_TARGET, BattleScript_NeutralizingGasExitsLoopIncrement
|
||||
jumpifability BS_TARGET, ABILITY_IMPOSTER, BattleScript_NeutralizingGasExitsLoopIncrement @ Imposter only activates when first entering the field
|
||||
jumpifabilitycantbereactivated BS_TARGET, BattleScript_NeutralizingGasExitsLoopIncrement
|
||||
saveattacker
|
||||
switchinabilities BS_TARGET
|
||||
restoreattacker
|
||||
|
||||
@ -3861,8 +3861,13 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
gBattleStruct->eventsBeforeFirstTurnState++;
|
||||
break;
|
||||
case FIRST_TURN_EVENTS_NEUTRALIZING_GAS:
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, 0, 0, 0, 0) != 0)
|
||||
return;
|
||||
while (gBattleStruct->switchInBattlerCounter < gBattlersCount) // From fastest to slowest
|
||||
{
|
||||
i = gBattlerByTurnOrder[gBattleStruct->switchInBattlerCounter++];
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, i, 0, 0, 0) != 0)
|
||||
return;
|
||||
}
|
||||
gBattleStruct->switchInBattlerCounter = 0;
|
||||
gBattleStruct->eventsBeforeFirstTurnState++;
|
||||
break;
|
||||
case FIRST_TURN_EVENTS_SWITCH_IN_ABILITIES:
|
||||
|
||||
@ -4244,14 +4244,17 @@ static void Cmd_tryfaintmon(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS
|
||||
if (gDisableStructs[battler].neutralizingGas
|
||||
&& !(gAbsentBattlerFlags & (1u << battler))
|
||||
&& !IsBattlerAlive(battler))
|
||||
{
|
||||
gBattleMons[battler].ability = ABILITY_NONE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
gDisableStructs[battler].neutralizingGas = FALSE;
|
||||
if (!IsNeutralizingGasOnField())
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cmd->battler == BS_ATTACKER)
|
||||
{
|
||||
@ -13424,44 +13427,46 @@ static void Cmd_switchoutabilities(void)
|
||||
CMD_ARGS(u8 battler);
|
||||
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS)
|
||||
if (gDisableStructs[battler].neutralizingGas)
|
||||
{
|
||||
gBattleMons[battler].ability = ABILITY_NONE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
gDisableStructs[battler].neutralizingGas = FALSE;
|
||||
if (!IsNeutralizingGasOnField())
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
switch (GetBattlerAbility(battler))
|
||||
{
|
||||
switch (GetBattlerAbility(battler))
|
||||
{
|
||||
case ABILITY_NATURAL_CURE:
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
case ABILITY_NATURAL_CURE:
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
|
||||
gBattleMons[battler].status1 = 0;
|
||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE,
|
||||
1u << gBattleStruct->battlerPartyIndexes[battler],
|
||||
sizeof(gBattleMons[battler].status1),
|
||||
&gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
case ABILITY_REGENERATOR:
|
||||
{
|
||||
u32 regenerate = GetNonDynamaxMaxHP(battler) / 3;
|
||||
regenerate += gBattleMons[battler].hp;
|
||||
if (regenerate > gBattleMons[battler].maxHP)
|
||||
regenerate = gBattleMons[battler].maxHP;
|
||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_HP_BATTLE,
|
||||
1u << gBattleStruct->battlerPartyIndexes[battler],
|
||||
sizeof(regenerate),
|
||||
®enerate);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
gBattleMons[battler].status1 = 0;
|
||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE,
|
||||
1u << gBattleStruct->battlerPartyIndexes[battler],
|
||||
sizeof(gBattleMons[battler].status1),
|
||||
&gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
case ABILITY_REGENERATOR:
|
||||
{
|
||||
u32 regenerate = GetNonDynamaxMaxHP(battler) / 3;
|
||||
regenerate += gBattleMons[battler].hp;
|
||||
if (regenerate > gBattleMons[battler].maxHP)
|
||||
regenerate = gBattleMons[battler].maxHP;
|
||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_HP_BATTLE,
|
||||
1u << gBattleStruct->battlerPartyIndexes[battler],
|
||||
sizeof(regenerate),
|
||||
®enerate);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void Cmd_jumpifhasnohp(void)
|
||||
@ -16797,15 +16802,27 @@ void BS_TryBoosterEnergy(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_JumpIfAbilityCantBeSuppressed(void)
|
||||
void BS_JumpIfAbilityCantBeReactivated(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
u32 ability = gBattleMons[battler].ability;
|
||||
|
||||
if (gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed)
|
||||
switch (ability)
|
||||
{
|
||||
case ABILITY_IMPOSTER:
|
||||
case ABILITY_NEUTRALIZING_GAS:
|
||||
case ABILITY_AIR_LOCK:
|
||||
case ABILITY_CLOUD_NINE:
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
break;
|
||||
default:
|
||||
if (gAbilitiesInfo[ability].cantBeSuppressed)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BS_TryActivateAbilityShield(void)
|
||||
@ -18245,13 +18262,16 @@ void BS_TryEndNeutralizingGas(void)
|
||||
if (gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved)
|
||||
{
|
||||
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = FALSE;
|
||||
BattleScriptPush(cmd->nextInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
gDisableStructs[gBattlerTarget].neutralizingGas = FALSE;
|
||||
if (!IsNeutralizingGasOnField())
|
||||
{
|
||||
BattleScriptPush(cmd->nextInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_GetRototillerTargets(void)
|
||||
|
||||
@ -5170,19 +5170,13 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
|
||||
case ABILITYEFFECT_NEUTRALIZINGGAS:
|
||||
// Prints message only. separate from ABILITYEFFECT_ON_SWITCHIN bc activates before entry hazards
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS && !gDisableStructs[battler].neutralizingGas)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !gDisableStructs[i].neutralizingGas)
|
||||
{
|
||||
gDisableStructs[i].neutralizingGas = TRUE;
|
||||
gBattlerAbility = i;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
|
||||
effect++;
|
||||
}
|
||||
|
||||
if (effect != 0)
|
||||
break;
|
||||
gDisableStructs[battler].neutralizingGas = TRUE;
|
||||
gBattlerAbility = battler;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes.
|
||||
@ -5295,7 +5289,7 @@ bool32 IsNeutralizingGasOnField(void)
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !gBattleMons[i].volatiles.gastroAcid)
|
||||
if (gDisableStructs[i].neutralizingGas && !gBattleMons[i].volatiles.gastroAcid)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -5371,7 +5365,7 @@ u32 GetBattlerAbilityInternal(u32 battler, u32 ignoreMoldBreaker, u32 noAbilityS
|
||||
|
||||
if (!hasAbilityShield
|
||||
&& IsNeutralizingGasOnField()
|
||||
&& gBattleMons[battler].ability != ABILITY_NEUTRALIZING_GAS)
|
||||
&& !gDisableStructs[battler].neutralizingGas)
|
||||
return ABILITY_NONE;
|
||||
|
||||
if (CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability, hasAbilityShield, ignoreMoldBreaker))
|
||||
|
||||
@ -310,3 +310,46 @@ SINGLE_BATTLE_TEST("Neutralizing Gas exiting the field does not activate Imposte
|
||||
NOT ABILITY_POPUP(player, ABILITY_IMPOSTER);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Neutralizing Gas exiting the field does not activate Air Lock/Cloud Nine but their effects are kept")
|
||||
{
|
||||
u32 species, ability;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_GOLDUCK; ability = ABILITY_CLOUD_NINE; }
|
||||
PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(species) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
OPPONENT(SPECIES_LUDICOLO) { Ability(ABILITY_RAIN_DISH); }
|
||||
} WHEN {
|
||||
TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
|
||||
TURN { MOVE(player, MOVE_RAIN_DANCE); }
|
||||
} SCENE {
|
||||
NOT ABILITY_POPUP(player, ABILITY_AIR_LOCK);
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
NOT ABILITY_POPUP(player, ABILITY_AIR_LOCK);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_RAIN_DANCE, player);
|
||||
NOT ABILITY_POPUP(opponent, ABILITY_RAIN_DISH);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Neutralizing Gas only displays exiting message for the last user leaving the field")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
|
||||
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
|
||||
SEND_IN_MESSAGE("Wobbuffet");
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
NOT MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user