start ability

This commit is contained in:
ghoulslash 2021-10-29 22:32:19 -04:00
parent cb9f4fbb42
commit 28bc7dc14d
9 changed files with 154 additions and 48 deletions

View File

@ -8091,6 +8091,12 @@ BattleScript_SwitchInAbilityMsg::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
end3 end3
BattleScript_SwitchInAbilityMsgRet::
call BattleScript_AbilityPopUp
printfromtable gSwitchInAbilityStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_ActivateAsOne:: BattleScript_ActivateAsOne::
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp
printfromtable gSwitchInAbilityStringIds printfromtable gSwitchInAbilityStringIds
@ -8909,3 +8915,14 @@ BattleScript_DarkTypePreventsPrankster::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_NeutralizingGasExits::
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, gBattlersCount, BattleScript_NeutralizingGasExitsLoop
return

View File

@ -68,6 +68,7 @@ struct ResourceFlags
#define RESOURCE_FLAG_INTIMIDATED 0x8 #define RESOURCE_FLAG_INTIMIDATED 0x8
#define RESOURCE_FLAG_TRACED 0x10 #define RESOURCE_FLAG_TRACED 0x10
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20 #define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
#define RESOURCE_FLAG_NEUTRALIZING_GAS 0x40
struct DisableStruct struct DisableStruct
{ {
@ -181,6 +182,7 @@ struct SpecialStatus
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
u8 dancerUsedMove:1; u8 dancerUsedMove:1;
u8 dancerOriginalTarget:3; u8 dancerOriginalTarget:3;
u8 announceNeutralizingGas:1;
s32 dmg; s32 dmg;
s32 physicalDmg; s32 physicalDmg;
s32 specialDmg; s32 specialDmg;

View File

@ -261,6 +261,7 @@ extern const u8 BattleScript_AttackerAbilityStatRaiseEnd3[];
extern const u8 BattleScript_PoisonHealActivates[]; extern const u8 BattleScript_PoisonHealActivates[];
extern const u8 BattleScript_BadDreamsActivates[]; extern const u8 BattleScript_BadDreamsActivates[];
extern const u8 BattleScript_SwitchInAbilityMsg[]; extern const u8 BattleScript_SwitchInAbilityMsg[];
extern const u8 BattleScript_SwitchInAbilityMsgRet[];
extern const u8 BattleScript_ToxicSpikesPoisoned[]; extern const u8 BattleScript_ToxicSpikesPoisoned[];
extern const u8 BattleScript_ToxicSpikesAbsorbed[]; extern const u8 BattleScript_ToxicSpikesAbsorbed[];
extern const u8 BattleScript_StickyWebOnSwitchIn[]; extern const u8 BattleScript_StickyWebOnSwitchIn[];
@ -402,5 +403,6 @@ extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[];
extern const u8 BattleScript_BlockedByPrimalWeatherRet[]; extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
extern const u8 BattleScript_PrimalReversion[]; extern const u8 BattleScript_PrimalReversion[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[]; extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_NeutralizingGasExits[];
#endif // GUARD_BATTLE_SCRIPTS_H #endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -8,21 +8,23 @@
#define MOVE_LIMITATION_TAUNT (1 << 4) #define MOVE_LIMITATION_TAUNT (1 << 4)
#define MOVE_LIMITATION_IMPRISON (1 << 5) #define MOVE_LIMITATION_IMPRISON (1 << 5)
#define ABILITYEFFECT_ON_SWITCHIN 0x0 #define ABILITYEFFECT_ON_SWITCHIN 0
#define ABILITYEFFECT_ENDTURN 0x1 #define ABILITYEFFECT_ENDTURN 1
#define ABILITYEFFECT_MOVES_BLOCK 0x2 #define ABILITYEFFECT_MOVES_BLOCK 2
#define ABILITYEFFECT_ABSORBING 0x3 #define ABILITYEFFECT_ABSORBING 3
#define ABILITYEFFECT_MOVE_END_ATTACKER 0x4 #define ABILITYEFFECT_MOVE_END_ATTACKER 4
#define ABILITYEFFECT_MOVE_END 0x5 #define ABILITYEFFECT_MOVE_END 5
#define ABILITYEFFECT_IMMUNITY 0x6 #define ABILITYEFFECT_IMMUNITY 6
#define ABILITYEFFECT_FORECAST 0x7 #define ABILITYEFFECT_FORECAST 7
#define ABILITYEFFECT_SYNCHRONIZE 0x8 #define ABILITYEFFECT_SYNCHRONIZE 8
#define ABILITYEFFECT_ATK_SYNCHRONIZE 0x9 #define ABILITYEFFECT_ATK_SYNCHRONIZE 9
#define ABILITYEFFECT_INTIMIDATE1 0xA #define ABILITYEFFECT_INTIMIDATE1 10
#define ABILITYEFFECT_INTIMIDATE2 0xB #define ABILITYEFFECT_INTIMIDATE2 11
#define ABILITYEFFECT_TRACE1 0xC #define ABILITYEFFECT_TRACE1 12
#define ABILITYEFFECT_TRACE2 0xD #define ABILITYEFFECT_TRACE2 13
#define ABILITYEFFECT_MOVE_END_OTHER 0xE #define ABILITYEFFECT_MOVE_END_OTHER 14
#define ABILITYEFFECT_NEUTRALIZINGGAS 15
// Special cases
#define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE #define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE
#define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF #define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF

View File

@ -597,8 +597,10 @@
#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 594 #define STRINGID_BUTPOKEMONCANTUSETHEMOVE 594
#define STRINGID_BUTHOOPACANTUSEIT 595 #define STRINGID_BUTHOOPACANTUSEIT 595
#define STRINGID_BROKETHROUGHPROTECTION 596 #define STRINGID_BROKETHROUGHPROTECTION 596
#define STRINGID_NEUTRALIZINGGASENTERS 597
#define STRINGID_NEUTRALIZINGGASOVER 598
#define BATTLESTRINGS_COUNT 597 #define BATTLESTRINGS_COUNT 599
// The below IDs are all indexes into battle message tables, // The below IDs are all indexes into battle message tables,
// used to determine which of a set of messages to print. // used to determine which of a set of messages to print.
@ -833,6 +835,7 @@
#define B_MSG_SWITCHIN_SCREENCLEANER 12 #define B_MSG_SWITCHIN_SCREENCLEANER 12
#define B_MSG_SWITCHIN_ASONE 13 #define B_MSG_SWITCHIN_ASONE 13
#define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14 #define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14
#define B_MSG_SWITCHIN_NEUTRALIZING_GAS 15
// gMentalHerbCureStringIds // gMentalHerbCureStringIds
#define B_MSG_MENTALHERBCURE_INFATUATION 0 #define B_MSG_MENTALHERBCURE_INFATUATION 0

View File

@ -3534,6 +3534,10 @@ static void TryDoEventsBeforeFirstTurn(void)
} }
} }
// 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. // Check all switch in abilities happening from the fastest mon to slowest.
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount) while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
{ {

View File

@ -723,9 +723,12 @@ static const u8 sText_PkmnRevertedToPrimal[] = _("{B_ATK_NAME_WITH_PREFIX}'s Pri
static const u8 sText_ButPokemonCantUseTheMove[] = _("But {B_ATK_NAME_WITH_PREFIX} can't\nuse the move!"); static const u8 sText_ButPokemonCantUseTheMove[] = _("But {B_ATK_NAME_WITH_PREFIX} can't\nuse the move!");
static const u8 sText_ButHoopaCantUseIt[] = _("But Hoopa can't use it\nthe way it is now!"); static const u8 sText_ButHoopaCantUseIt[] = _("But Hoopa can't use it\nthe way it is now!");
static const u8 sText_BrokeThroughProtection[] = _("It broke through the\n{B_DEF_NAME_WITH_PREFIX}'s protection!"); static const u8 sText_BrokeThroughProtection[] = _("It broke through the\n{B_DEF_NAME_WITH_PREFIX}'s protection!");
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] = const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{ {
[STRINGID_NEUTRALIZINGGASOVER - 12] = sText_NeutralizingGasOver,
[STRINGID_NEUTRALIZINGGASENTERS - 12] = sText_NeutralizingGasEnters,
[STRINGID_BROKETHROUGHPROTECTION - 12] = sText_BrokeThroughProtection, [STRINGID_BROKETHROUGHPROTECTION - 12] = sText_BrokeThroughProtection,
[STRINGID_BUTPOKEMONCANTUSETHEMOVE - 12] = sText_ButPokemonCantUseTheMove, [STRINGID_BUTPOKEMONCANTUSETHEMOVE - 12] = sText_ButPokemonCantUseTheMove,
[STRINGID_BUTHOOPACANTUSEIT - 12] = sText_ButHoopaCantUseIt, [STRINGID_BUTHOOPACANTUSEIT - 12] = sText_ButHoopaCantUseIt,
@ -1371,6 +1374,7 @@ const u16 gSwitchInAbilityStringIds[] =
[B_MSG_SWITCHIN_SCREENCLEANER] = STRINGID_SCREENCLEANERENTERS, [B_MSG_SWITCHIN_SCREENCLEANER] = STRINGID_SCREENCLEANERENTERS,
[B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS, [B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS,
[B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS, [B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS,
[B_MSG_SWITCHIN_NEUTRALIZING_GAS] = STRINGID_NEUTRALIZINGGASENTERS,
}; };
const u16 gMissStringIds[] = const u16 gMissStringIds[] =

View File

@ -6078,7 +6078,16 @@ static void Cmd_switchineffects(void)
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
gSpecialStatuses[gActiveBattler].flag40 = 0; 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) && (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
&& GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD && GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD
&& IsBattlerAffectedByHazards(gActiveBattler, FALSE) && IsBattlerAffectedByHazards(gActiveBattler, FALSE)
@ -12282,6 +12291,14 @@ static void Cmd_switchoutabilities(void)
{ {
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS)
{
gBattleMons[gActiveBattler].ability = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
}
else
{
switch (GetBattlerAbility(gActiveBattler)) switch (GetBattlerAbility(gActiveBattler))
{ {
case ABILITY_NATURAL_CURE: case ABILITY_NATURAL_CURE:
@ -12301,6 +12318,7 @@ static void Cmd_switchoutabilities(void)
gBattlescriptCurrInstr += 2; gBattlescriptCurrInstr += 2;
} }
}
static void Cmd_jumpifhasnohp(void) static void Cmd_jumpifhasnohp(void)
{ {

View File

@ -5436,6 +5436,20 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
} }
} }
break; break;
case ABILITYEFFECT_NEUTRALIZINGGAS:
// for the start of battle only. The switch-in message plays in Cmd_switchineffects because it comes before the 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++;
}
}
break;
} }
if (effect && gLastUsedAbility != 0xFF) if (effect && gLastUsedAbility != 0xFF)
@ -5446,11 +5460,51 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
return effect; return effect;
} }
static 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;
}
}
static bool32 IsNeutralizingGasOnField(void)
{
u32 i;
for (i = 0; i < gBattlersCount; i++)
{
if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS)
return TRUE;
}
return FALSE;
}
u32 GetBattlerAbility(u8 battlerId) u32 GetBattlerAbility(u8 battlerId)
{ {
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID) if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
return ABILITY_NONE; 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_TERAVOLT
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE) || gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID)) && !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
@ -5460,7 +5514,7 @@ u32 GetBattlerAbility(u8 battlerId)
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE && gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
&& gCurrentTurnActionNumber < gBattlersCount) && gCurrentTurnActionNumber < gBattlersCount)
return ABILITY_NONE; return ABILITY_NONE;
else
return gBattleMons[battlerId].ability; return gBattleMons[battlerId].ability;
} }