mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-01-29 14:53:55 +01:00
Merge pull request #1834 from ghoulslash/be/neutralizing_gas
Add Neutralizing Gas
This commit is contained in:
commit
5b63f53262
@ -1877,6 +1877,10 @@
|
||||
.2byte \species
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryendneutralizinggas battler:req
|
||||
various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS
|
||||
.endm
|
||||
|
||||
.macro trytoapplymimicry battler:req, ptr:req
|
||||
various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY
|
||||
|
@ -2187,6 +2187,7 @@ BattleScript_EffectSimpleBeam:
|
||||
trytoclearprimalweather
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
tryendneutralizinggas BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectSuckerPunch:
|
||||
@ -2409,6 +2410,7 @@ BattleScript_EffectGastroAcid:
|
||||
trytoclearprimalweather
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
tryendneutralizinggas BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectToxicSpikes:
|
||||
@ -8378,6 +8380,12 @@ BattleScript_SwitchInAbilityMsg::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end3
|
||||
|
||||
BattleScript_SwitchInAbilityMsgRet::
|
||||
call BattleScript_AbilityPopUp
|
||||
printfromtable gSwitchInAbilityStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_ActivateAsOne::
|
||||
call BattleScript_AbilityPopUp
|
||||
printfromtable gSwitchInAbilityStringIds
|
||||
@ -9231,3 +9239,19 @@ BattleScript_PastelVeilLoopIncrement:
|
||||
goto BattleScript_PastelVeilEnd
|
||||
BattleScript_PastelVeilEnd:
|
||||
end3
|
||||
|
||||
sByteFour:
|
||||
.byte MAX_BATTLERS_COUNT
|
||||
|
||||
BattleScript_NeutralizingGasExits::
|
||||
savetarget
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_NEUTRALIZINGGASOVER
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte gBattlerTarget, 0
|
||||
BattleScript_NeutralizingGasExitsLoop:
|
||||
switchinabilities BS_TARGET
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, sByteFour, BattleScript_NeutralizingGasExitsLoop @ SOMEHOW, comparing to gBattlersCount is problematic.
|
||||
restoretarget
|
||||
return
|
||||
|
@ -62,12 +62,13 @@ struct ResourceFlags
|
||||
u32 flags[4];
|
||||
};
|
||||
|
||||
#define RESOURCE_FLAG_FLASH_FIRE 0x1
|
||||
#define RESOURCE_FLAG_ROOST 0x2
|
||||
#define RESOURCE_FLAG_UNBURDEN 0x4
|
||||
#define RESOURCE_FLAG_INTIMIDATED 0x8
|
||||
#define RESOURCE_FLAG_TRACED 0x10
|
||||
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
|
||||
#define RESOURCE_FLAG_FLASH_FIRE 0x1
|
||||
#define RESOURCE_FLAG_ROOST 0x2
|
||||
#define RESOURCE_FLAG_UNBURDEN 0x4
|
||||
#define RESOURCE_FLAG_INTIMIDATED 0x8
|
||||
#define RESOURCE_FLAG_TRACED 0x10
|
||||
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
|
||||
#define RESOURCE_FLAG_NEUTRALIZING_GAS 0x40
|
||||
|
||||
struct DisableStruct
|
||||
{
|
||||
@ -184,6 +185,8 @@ struct SpecialStatus
|
||||
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
|
||||
u8 dancerUsedMove:1;
|
||||
u8 dancerOriginalTarget:3;
|
||||
u8 announceNeutralizingGas:1; // See Cmd_switchineffects
|
||||
u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS
|
||||
s32 dmg;
|
||||
s32 physicalDmg;
|
||||
s32 specialDmg;
|
||||
|
@ -261,6 +261,7 @@ extern const u8 BattleScript_AttackerAbilityStatRaiseEnd3[];
|
||||
extern const u8 BattleScript_PoisonHealActivates[];
|
||||
extern const u8 BattleScript_BadDreamsActivates[];
|
||||
extern const u8 BattleScript_SwitchInAbilityMsg[];
|
||||
extern const u8 BattleScript_SwitchInAbilityMsgRet[];
|
||||
extern const u8 BattleScript_ToxicSpikesPoisoned[];
|
||||
extern const u8 BattleScript_ToxicSpikesAbsorbed[];
|
||||
extern const u8 BattleScript_StickyWebOnSwitchIn[];
|
||||
@ -413,5 +414,6 @@ extern const u8 BattleScript_AttackerFormChangeEnd3NoPopup[];
|
||||
extern const u8 BattleScript_AttackerFormChangeMoveEffect[];
|
||||
extern const u8 BattleScript_BothCanNoLongerEscape[];
|
||||
extern const u8 BattleScript_OctolockEndTurn[];
|
||||
extern const u8 BattleScript_NeutralizingGasExits[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
@ -8,21 +8,23 @@
|
||||
#define MOVE_LIMITATION_TAUNT (1 << 4)
|
||||
#define MOVE_LIMITATION_IMPRISON (1 << 5)
|
||||
|
||||
#define ABILITYEFFECT_ON_SWITCHIN 0x0
|
||||
#define ABILITYEFFECT_ENDTURN 0x1
|
||||
#define ABILITYEFFECT_MOVES_BLOCK 0x2
|
||||
#define ABILITYEFFECT_ABSORBING 0x3
|
||||
#define ABILITYEFFECT_MOVE_END_ATTACKER 0x4
|
||||
#define ABILITYEFFECT_MOVE_END 0x5
|
||||
#define ABILITYEFFECT_IMMUNITY 0x6
|
||||
#define ABILITYEFFECT_FORECAST 0x7
|
||||
#define ABILITYEFFECT_SYNCHRONIZE 0x8
|
||||
#define ABILITYEFFECT_ATK_SYNCHRONIZE 0x9
|
||||
#define ABILITYEFFECT_INTIMIDATE1 0xA
|
||||
#define ABILITYEFFECT_INTIMIDATE2 0xB
|
||||
#define ABILITYEFFECT_TRACE1 0xC
|
||||
#define ABILITYEFFECT_TRACE2 0xD
|
||||
#define ABILITYEFFECT_MOVE_END_OTHER 0xE
|
||||
#define ABILITYEFFECT_ON_SWITCHIN 0
|
||||
#define ABILITYEFFECT_ENDTURN 1
|
||||
#define ABILITYEFFECT_MOVES_BLOCK 2
|
||||
#define ABILITYEFFECT_ABSORBING 3
|
||||
#define ABILITYEFFECT_MOVE_END_ATTACKER 4
|
||||
#define ABILITYEFFECT_MOVE_END 5
|
||||
#define ABILITYEFFECT_IMMUNITY 6
|
||||
#define ABILITYEFFECT_FORECAST 7
|
||||
#define ABILITYEFFECT_SYNCHRONIZE 8
|
||||
#define ABILITYEFFECT_ATK_SYNCHRONIZE 9
|
||||
#define ABILITYEFFECT_INTIMIDATE1 10
|
||||
#define ABILITYEFFECT_INTIMIDATE2 11
|
||||
#define ABILITYEFFECT_TRACE1 12
|
||||
#define ABILITYEFFECT_TRACE2 13
|
||||
#define ABILITYEFFECT_MOVE_END_OTHER 14
|
||||
#define ABILITYEFFECT_NEUTRALIZINGGAS 15
|
||||
// Special cases
|
||||
#define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE
|
||||
#define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF
|
||||
|
||||
|
@ -207,6 +207,7 @@
|
||||
#define VARIOUS_CHECK_POLTERGEIST 134
|
||||
#define VARIOUS_SET_OCTOLOCK 135
|
||||
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 136
|
||||
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 137
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
@ -607,8 +607,10 @@
|
||||
#define STRINGID_PKMNBECAMEWEAKERTOFIRE 604
|
||||
#define STRINGID_ABOUTTOUSEPOLTERGEIST 605
|
||||
#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 606
|
||||
#define STRINGID_NEUTRALIZINGGASENTERS 607
|
||||
#define STRINGID_NEUTRALIZINGGASOVER 608
|
||||
|
||||
#define BATTLESTRINGS_COUNT 607
|
||||
#define BATTLESTRINGS_COUNT 609
|
||||
|
||||
// The below IDs are all indexes into battle message tables,
|
||||
// used to determine which of a set of messages to print.
|
||||
@ -844,6 +846,7 @@
|
||||
#define B_MSG_SWITCHIN_ASONE 13
|
||||
#define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14
|
||||
#define B_MSG_SWITCHIN_PASTEL_VEIL 15
|
||||
#define B_MSG_SWITCHIN_NEUTRALIZING_GAS 16
|
||||
|
||||
// gMentalHerbCureStringIds
|
||||
#define B_MSG_MENTALHERBCURE_INFATUATION 0
|
||||
|
@ -82,7 +82,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
|
||||
|
||||
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler));
|
||||
|
||||
if (gBattleMons[GetBattlerAtPosition(opposingPosition)].ability != ABILITY_WONDER_GUARD)
|
||||
if (GetBattlerAbility(GetBattlerAtPosition(opposingPosition)) != ABILITY_WONDER_GUARD)
|
||||
return FALSE;
|
||||
|
||||
// Check if Pokemon has a super effective move.
|
||||
@ -176,7 +176,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility)
|
||||
if (AI_GetAbility(gActiveBattler) == absorbingTypeAbility)
|
||||
return FALSE;
|
||||
|
||||
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||
@ -228,7 +228,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
|
||||
{
|
||||
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE)
|
||||
if (AI_GetAbility(gActiveBattler) != ABILITY_NATURAL_CURE)
|
||||
return FALSE;
|
||||
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2)
|
||||
return FALSE;
|
||||
|
@ -1121,19 +1121,24 @@ bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability)
|
||||
// does NOT include ability suppression checks
|
||||
s32 AI_GetAbility(u32 battlerId)
|
||||
{
|
||||
u32 knownAbility = GetBattlerAbility(battlerId);
|
||||
|
||||
// The AI knows its own ability.
|
||||
if (IsBattlerAIControlled(battlerId))
|
||||
return gBattleMons[battlerId].ability;
|
||||
return knownAbility;
|
||||
|
||||
// Check neutralizing gas, gastro acid
|
||||
if (knownAbility == ABILITY_NONE)
|
||||
return knownAbility;
|
||||
|
||||
if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE)
|
||||
return BATTLE_HISTORY->abilities[battlerId];
|
||||
|
||||
// Abilities that prevent fleeing.
|
||||
if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG
|
||||
|| gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL
|
||||
|| gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP)
|
||||
return gBattleMons[battlerId].ability;
|
||||
// Abilities that prevent fleeing - treat as always known
|
||||
if (knownAbility == ABILITY_SHADOW_TAG || knownAbility == ABILITY_MAGNET_PULL || knownAbility == ABILITY_ARENA_TRAP)
|
||||
return knownAbility;
|
||||
|
||||
// Else, guess the ability
|
||||
if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE)
|
||||
{
|
||||
if (gBaseStats[gBattleMons[battlerId].species].abilities[1] != ABILITY_NONE)
|
||||
@ -1146,6 +1151,7 @@ s32 AI_GetAbility(u32 battlerId)
|
||||
return gBaseStats[gBattleMons[battlerId].species].abilities[0]; // It's definitely ability 1.
|
||||
}
|
||||
}
|
||||
|
||||
return ABILITY_NONE; // Unknown.
|
||||
}
|
||||
|
||||
|
@ -3548,7 +3548,11 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check neutralizing gas
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, 0, 0, 0, 0) != 0)
|
||||
return;
|
||||
|
||||
// Check all switch in abilities happening from the fastest mon to slowest.
|
||||
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
|
||||
{
|
||||
|
@ -733,9 +733,13 @@ static const u8 sText_CantEscapeDueToUsedMove[] = _("{B_ATK_NAME_WITH_PREFIX} ca
|
||||
static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!");
|
||||
static const u8 sText_PkmnAboutToBeAttackedByItsItem[] = _("{B_DEF_NAME_WITH_PREFIX} is about\nto be attacked by its {B_BUFF1}!");
|
||||
static const u8 sText_CantEscapeBecauseOfCurrentMove[] = _("{B_DEF_NAME_WITH_PREFIX} can no longer escape\nbecause of {B_CURRENT_MOVE}!");
|
||||
static const u8 sText_NeutralizingGasEnters[] = _("Neutralizing Gas filled the area!");
|
||||
static const u8 sText_NeutralizingGasOver[] = _("The effects of Neutralizing\nGas wore off!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_NEUTRALIZINGGASOVER - 12] = sText_NeutralizingGasOver,
|
||||
[STRINGID_NEUTRALIZINGGASENTERS - 12] = sText_NeutralizingGasEnters,
|
||||
[STRINGID_BATTLERTYPECHANGEDTO - 12] = sText_BattlerTypeChangedTo,
|
||||
[STRINGID_PASTELVEILENTERS - 12] = sText_PastelVeilEnters,
|
||||
[STRINGID_PASTELVEILPROTECTED -12] = sText_PastelVeilProtected,
|
||||
@ -1392,6 +1396,7 @@ const u16 gSwitchInAbilityStringIds[] =
|
||||
[B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS,
|
||||
[B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS,
|
||||
[B_MSG_SWITCHIN_PASTEL_VEIL] = STRINGID_PASTELVEILENTERS,
|
||||
[B_MSG_SWITCHIN_NEUTRALIZING_GAS] = STRINGID_NEUTRALIZINGGASENTERS,
|
||||
};
|
||||
|
||||
const u16 gMissStringIds[] =
|
||||
|
@ -6159,8 +6159,17 @@ static void Cmd_switchineffects(void)
|
||||
|
||||
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
|
||||
gSpecialStatuses[gActiveBattler].flag40 = 0;
|
||||
|
||||
if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
|
||||
|
||||
// Neutralizing Gas announces itself before hazards
|
||||
if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS && gSpecialStatuses[gActiveBattler].announceNeutralizingGas == 0)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
gSpecialStatuses[gActiveBattler].announceNeutralizingGas = TRUE;
|
||||
gBattlerAbility = gActiveBattler;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_SwitchInAbilityMsgRet;
|
||||
}
|
||||
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
|
||||
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
|
||||
&& GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD
|
||||
&& IsBattlerAffectedByHazards(gActiveBattler, FALSE)
|
||||
@ -6234,7 +6243,7 @@ static void Cmd_switchineffects(void)
|
||||
{
|
||||
// There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts.
|
||||
// The truant counter is not updated in the case where a mon switches in after a lost judgement in the battle arena.
|
||||
if (gBattleMons[gActiveBattler].ability == ABILITY_TRUANT
|
||||
if (GetBattlerAbility(gActiveBattler) == ABILITY_TRUANT
|
||||
&& gCurrentActionFuncId != B_ACTION_USE_MOVE
|
||||
&& !gDisableStructs[gActiveBattler].truantSwitchInHack)
|
||||
gDisableStructs[gActiveBattler].truantCounter = 1;
|
||||
@ -7425,7 +7434,7 @@ u32 IsLeafGuardProtected(u32 battler)
|
||||
|
||||
bool32 IsShieldsDownProtected(u32 battler)
|
||||
{
|
||||
return (gBattleMons[battler].ability == ABILITY_SHIELDS_DOWN
|
||||
return (GetBattlerAbility(battler) == ABILITY_SHIELDS_DOWN
|
||||
&& GetFormIdFromFormSpeciesId(gBattleMons[battler].species) < GetFormIdFromFormSpeciesId(SPECIES_MINIOR_CORE_RED)); // Minior is not in core form
|
||||
}
|
||||
|
||||
@ -7893,6 +7902,7 @@ static void Cmd_various(void)
|
||||
break;
|
||||
case VARIOUS_SWITCHIN_ABILITIES:
|
||||
gBattlescriptCurrInstr += 3;
|
||||
AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, gActiveBattler, 0, 0, 0);
|
||||
AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0);
|
||||
AbilityBattleEffects(ABILITYEFFECT_INTIMIDATE2, gActiveBattler, 0, 0, 0);
|
||||
AbilityBattleEffects(ABILITYEFFECT_TRACE2, gActiveBattler, 0, 0, 0);
|
||||
@ -8073,6 +8083,9 @@ static void Cmd_various(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS)
|
||||
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE;
|
||||
|
||||
gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
@ -8976,6 +8989,15 @@ static void Cmd_various(void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VARIOUS_TRY_END_NEUTRALIZING_GAS:
|
||||
if (gSpecialStatuses[gActiveBattler].neutralizingGasRemoved)
|
||||
{
|
||||
gSpecialStatuses[gActiveBattler].neutralizingGasRemoved = FALSE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 3);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case VARIOUS_GET_ROTOTILLER_TARGETS:
|
||||
// Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!'
|
||||
{
|
||||
@ -11391,11 +11413,11 @@ static void Cmd_healpartystatus(void)
|
||||
u16 ability;
|
||||
|
||||
if (gBattlerPartyIndexes[gBattlerAttacker] == i)
|
||||
ability = gBattleMons[gBattlerAttacker].ability;
|
||||
ability = GetBattlerAbility(gBattlerAttacker);
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattlerPartyIndexes[gActiveBattler] == i
|
||||
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
|
||||
ability = gBattleMons[gActiveBattler].ability;
|
||||
ability = GetBattlerAbility(gActiveBattler);
|
||||
else
|
||||
ability = GetAbilityBySpecies(species, abilityNum);
|
||||
|
||||
@ -12345,6 +12367,9 @@ static void Cmd_setgastroacid(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS)
|
||||
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE;
|
||||
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
}
|
||||
@ -12625,25 +12650,33 @@ static void Cmd_trygetintimidatetarget(void)
|
||||
static void Cmd_switchoutabilities(void)
|
||||
{
|
||||
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
|
||||
|
||||
switch (GetBattlerAbility(gActiveBattler))
|
||||
if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS)
|
||||
{
|
||||
case ABILITY_NATURAL_CURE:
|
||||
gBattleMons[gActiveBattler].status1 = 0;
|
||||
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
break;
|
||||
case ABILITY_REGENERATOR:
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3;
|
||||
gBattleMoveDamage += gBattleMons[gActiveBattler].hp;
|
||||
if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP)
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP;
|
||||
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
break;
|
||||
gBattleMons[gActiveBattler].ability = ABILITY_NONE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (GetBattlerAbility(gActiveBattler))
|
||||
{
|
||||
case ABILITY_NATURAL_CURE:
|
||||
gBattleMons[gActiveBattler].status1 = 0;
|
||||
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
break;
|
||||
case ABILITY_REGENERATOR:
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3;
|
||||
gBattleMoveDamage += gBattleMons[gActiveBattler].hp;
|
||||
if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP)
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP;
|
||||
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
break;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr += 2;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr += 2;
|
||||
}
|
||||
|
||||
static void Cmd_jumpifhasnohp(void)
|
||||
|
@ -317,8 +317,8 @@ void HandleAction_UseMove(void)
|
||||
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
&& gSideTimers[side].followmeTimer == 0
|
||||
&& (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER)
|
||||
&& ((gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|
||||
|| (gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
|
||||
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|
||||
|| (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
|
||||
{
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
||||
@ -387,9 +387,9 @@ void HandleAction_UseMove(void)
|
||||
{
|
||||
gActiveBattler = gBattlerByTurnOrder[var];
|
||||
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
|
||||
if (gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD)
|
||||
if (GetBattlerAbility(gActiveBattler) == ABILITY_LIGHTNING_ROD)
|
||||
gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE;
|
||||
else if (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN)
|
||||
else if (GetBattlerAbility(gActiveBattler) == ABILITY_STORM_DRAIN)
|
||||
gSpecialStatuses[gActiveBattler].stormDrainRedirected = TRUE;
|
||||
gBattlerTarget = gActiveBattler;
|
||||
}
|
||||
@ -627,7 +627,7 @@ bool8 TryRunFromBattle(u8 battler)
|
||||
effect++;
|
||||
}
|
||||
#endif
|
||||
else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY)
|
||||
else if (GetBattlerAbility(battler) == ABILITY_RUN_AWAY)
|
||||
{
|
||||
if (InBattlePyramid())
|
||||
{
|
||||
@ -2727,7 +2727,7 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
|
||||
{
|
||||
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
|
||||
&& gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 &= ~(STATUS1_SLEEP);
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
|
||||
@ -3311,7 +3311,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_TRUANT: // truant
|
||||
if (gBattleMons[gBattlerAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
|
||||
{
|
||||
CancelMultiTurnMoves(gBattlerAttacker);
|
||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||
@ -3752,7 +3752,7 @@ u8 TryWeatherFormChange(u8 battler)
|
||||
|
||||
if (gBattleMons[battler].species == SPECIES_CASTFORM)
|
||||
{
|
||||
if (gBattleMons[battler].ability != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
|
||||
if (GetBattlerAbility(battler) != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
@ -3788,7 +3788,7 @@ u8 TryWeatherFormChange(u8 battler)
|
||||
}
|
||||
else if (gBattleMons[battler].species == SPECIES_CHERRIM)
|
||||
{
|
||||
if (gBattleMons[battler].ability != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0)
|
||||
if (GetBattlerAbility(battler) != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0)
|
||||
ret = 0;
|
||||
else if (gBattleMonForms[battler] == 0 && weatherEffect && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_SUN_ANY)
|
||||
ret = 2;
|
||||
@ -3878,7 +3878,7 @@ static bool32 ShouldChangeFormHpBased(u32 battler)
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(forms); i++)
|
||||
{
|
||||
if (gBattleMons[battler].ability == forms[i][0])
|
||||
if (GetBattlerAbility(battler) == forms[i][0])
|
||||
{
|
||||
if (gBattleMons[battler].species == forms[i][2]
|
||||
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3])
|
||||
@ -5373,7 +5373,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
case ABILITYEFFECT_IMMUNITY: // 5
|
||||
for (battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
switch (gBattleMons[battler].ability)
|
||||
switch (GetBattlerAbility(battler))
|
||||
{
|
||||
case ABILITY_IMMUNITY:
|
||||
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER))
|
||||
@ -5463,7 +5463,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
case ABILITYEFFECT_FORECAST: // 6
|
||||
for (battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (gBattleMons[battler].ability == ABILITY_FORECAST || gBattleMons[battler].ability == ABILITY_FLOWER_GIFT)
|
||||
if (GetBattlerAbility(battler) == ABILITY_FORECAST || GetBattlerAbility(battler) == ABILITY_FLOWER_GIFT)
|
||||
{
|
||||
effect = TryWeatherFormChange(battler);
|
||||
if (effect)
|
||||
@ -5524,7 +5524,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
case ABILITYEFFECT_INTIMIDATE2:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED)
|
||||
if (GetBattlerAbility(i) == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED)
|
||||
{
|
||||
gLastUsedAbility = ABILITY_INTIMIDATE;
|
||||
gBattleResources->flags->flags[i] &= ~(RESOURCE_FLAG_INTIMIDATED);
|
||||
@ -5591,6 +5591,23 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_NEUTRALIZINGGAS:
|
||||
// Prints message only. separate from ABILITYEFFECT_ON_SWITCHIN bc activates before entry hazards
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gBattleResources->flags->flags[i] & RESOURCE_FLAG_NEUTRALIZING_GAS))
|
||||
{
|
||||
gBattleResources->flags->flags[i] |= RESOURCE_FLAG_NEUTRALIZING_GAS;
|
||||
gBattlerAbility = i;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
|
||||
effect++;
|
||||
}
|
||||
|
||||
if (effect)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (effect && gLastUsedAbility != 0xFF)
|
||||
@ -5601,11 +5618,51 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
return effect;
|
||||
}
|
||||
|
||||
bool32 IsNeutralizingGasBannedAbility(u32 ability)
|
||||
{
|
||||
switch (ability)
|
||||
{
|
||||
case ABILITY_MULTITYPE:
|
||||
case ABILITY_ZEN_MODE:
|
||||
case ABILITY_STANCE_CHANGE:
|
||||
case ABILITY_POWER_CONSTRUCT:
|
||||
case ABILITY_SCHOOLING:
|
||||
case ABILITY_RKS_SYSTEM:
|
||||
case ABILITY_SHIELDS_DOWN:
|
||||
case ABILITY_COMATOSE:
|
||||
case ABILITY_DISGUISE:
|
||||
case ABILITY_GULP_MISSILE:
|
||||
case ABILITY_ICE_FACE:
|
||||
case ABILITY_AS_ONE_ICE_RIDER:
|
||||
case ABILITY_AS_ONE_SHADOW_RIDER:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsNeutralizingGasOnField(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gStatuses3[i] & STATUS3_GASTRO_ACID))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GetBattlerAbility(u8 battlerId)
|
||||
{
|
||||
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
|
||||
return ABILITY_NONE;
|
||||
else if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|
||||
|
||||
if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battlerId].ability))
|
||||
return ABILITY_NONE;
|
||||
|
||||
if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|
||||
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT
|
||||
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
|
||||
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
|
||||
@ -5615,8 +5672,8 @@ u32 GetBattlerAbility(u8 battlerId)
|
||||
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
|
||||
&& gCurrentTurnActionNumber < gBattlersCount)
|
||||
return ABILITY_NONE;
|
||||
else
|
||||
return gBattleMons[battlerId].ability;
|
||||
|
||||
return gBattleMons[battlerId].ability;
|
||||
}
|
||||
|
||||
u32 IsAbilityOnSide(u32 battlerId, u32 ability)
|
||||
@ -5668,7 +5725,7 @@ u32 IsAbilityPreventingEscape(u32 battlerId)
|
||||
return 0;
|
||||
#endif
|
||||
#if B_SHADOW_TAG_ESCAPE >= GEN_4
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG)
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && GetBattlerAbility(battlerId) != ABILITY_SHADOW_TAG)
|
||||
#else
|
||||
if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG))
|
||||
#endif
|
||||
@ -7219,7 +7276,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
|
||||
targetBattler = SetRandomTarget(gBattlerAttacker);
|
||||
if (gBattleMoves[move].type == TYPE_ELECTRIC
|
||||
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD)
|
||||
&& gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD)
|
||||
&& GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD)
|
||||
{
|
||||
targetBattler ^= BIT_FLANK;
|
||||
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
|
||||
@ -7227,7 +7284,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
|
||||
}
|
||||
else if (gBattleMoves[move].type == TYPE_WATER
|
||||
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN)
|
||||
&& gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN)
|
||||
&& GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN)
|
||||
{
|
||||
targetBattler ^= BIT_FLANK;
|
||||
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
|
||||
@ -7405,7 +7462,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating)
|
||||
return HOLD_EFFECT_NONE;
|
||||
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)
|
||||
return HOLD_EFFECT_NONE;
|
||||
if (gBattleMons[battlerId].ability == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID))
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID))
|
||||
return HOLD_EFFECT_NONE;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ u32 sub_805725C(u8 battlerId)
|
||||
{
|
||||
u32 toSub;
|
||||
|
||||
if (gBattleMons[battlerId].ability == ABILITY_EARLY_BIRD)
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_EARLY_BIRD)
|
||||
toSub = 2;
|
||||
else
|
||||
toSub = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user