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
end3
BattleScript_SwitchInAbilityMsgRet::
call BattleScript_AbilityPopUp
printfromtable gSwitchInAbilityStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_ActivateAsOne::
call BattleScript_AbilityPopUp
printfromtable gSwitchInAbilityStringIds
@ -8909,3 +8915,14 @@ BattleScript_DarkTypePreventsPrankster::
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
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

@ -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
{
@ -181,6 +182,7 @@ 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;
s32 dmg;
s32 physicalDmg;
s32 specialDmg;

View File

@ -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[];
@ -402,5 +403,6 @@ extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[];
extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
extern const u8 BattleScript_PrimalReversion[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_NeutralizingGasExits[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -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

View File

@ -597,8 +597,10 @@
#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 594
#define STRINGID_BUTHOOPACANTUSEIT 595
#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,
// 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_ASONE 13
#define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14
#define B_MSG_SWITCHIN_NEUTRALIZING_GAS 15
// gMentalHerbCureStringIds
#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.
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_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_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_BROKETHROUGHPROTECTION - 12] = sText_BrokeThroughProtection,
[STRINGID_BUTPOKEMONCANTUSETHEMOVE - 12] = sText_ButPokemonCantUseTheMove,
[STRINGID_BUTHOOPACANTUSEIT - 12] = sText_ButHoopaCantUseIt,
@ -1371,6 +1374,7 @@ const u16 gSwitchInAbilityStringIds[] =
[B_MSG_SWITCHIN_SCREENCLEANER] = STRINGID_SCREENCLEANERENTERS,
[B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS,
[B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS,
[B_MSG_SWITCHIN_NEUTRALIZING_GAS] = STRINGID_NEUTRALIZINGGASENTERS,
};
const u16 gMissStringIds[] =

View File

@ -6078,7 +6078,16 @@ 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)
@ -12282,24 +12291,33 @@ 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 = 0;
BattleScriptPushCursor();
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)

View File

@ -5436,6 +5436,20 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
}
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)
@ -5446,11 +5460,51 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
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)
{
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))
@ -5460,8 +5514,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)