Stealth Rock and Toxic Spikes

This commit is contained in:
DizzyEggg 2018-07-24 21:47:00 +02:00
parent 45bc76d94c
commit f8b1f0a45c
10 changed files with 202 additions and 53 deletions

View File

@ -3789,58 +3789,71 @@ BattleScript_DestinyBondTakesLife::
tryfaintmon BS_ATTACKER, FALSE, NULL tryfaintmon BS_ATTACKER, FALSE, NULL
return return
BattleScript_SpikesOnAttacker:: BattleScript_DmgHazardsOnAttacker::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
healthbarupdate BS_ATTACKER healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER datahpupdate BS_ATTACKER
call BattleScript_PrintHurtBySpikes call BattleScript_PrintHurtByDmgHazards
tryfaintmon BS_ATTACKER, FALSE, NULL tryfaintmon BS_ATTACKER, FALSE, NULL
tryfaintmon BS_ATTACKER, TRUE, BattleScript_SpikesOnAttackerFainted tryfaintmon BS_ATTACKER, TRUE, BattleScript_DmgHazardsOnAttackerFainted
return return
BattleScript_SpikesOnAttackerFainted:: BattleScript_DmgHazardsOnAttackerFainted::
setbyte sGIVEEXP_STATE, 0x0 setbyte sGIVEEXP_STATE, 0x0
getexp BS_ATTACKER getexp BS_ATTACKER
setbyte sMOVEEND_STATE, 0x0 setbyte sMOVEEND_STATE, 0x0
moveend 0x0, 0x0 moveend 0x0, 0x0
goto BattleScript_HandleFaintedMon goto BattleScript_HandleFaintedMon
BattleScript_SpikesOnTarget:: BattleScript_DmgHazardsOnTarget::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
healthbarupdate BS_TARGET healthbarupdate BS_TARGET
datahpupdate BS_TARGET datahpupdate BS_TARGET
call BattleScript_PrintHurtBySpikes call BattleScript_PrintHurtByDmgHazards
tryfaintmon BS_TARGET, FALSE, NULL tryfaintmon BS_TARGET, FALSE, NULL
tryfaintmon BS_TARGET, TRUE, BattleScript_SpikesOnTargetFainted tryfaintmon BS_TARGET, TRUE, BattleScript_DmgHazardsOnTargetFainted
return return
BattleScript_SpikesOnTargetFainted:: BattleScript_DmgHazardsOnTargetFainted::
setbyte sGIVEEXP_STATE, 0x0 setbyte sGIVEEXP_STATE, 0x0
getexp BS_TARGET getexp BS_TARGET
setbyte sMOVEEND_STATE, 0x0 setbyte sMOVEEND_STATE, 0x0
moveend 0x0, 0x0 moveend 0x0, 0x0
goto BattleScript_HandleFaintedMon goto BattleScript_HandleFaintedMon
BattleScript_SpikesOnFaintedBattler:: BattleScript_DmgHazardsOnFaintedBattler::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
healthbarupdate BS_FAINTED healthbarupdate BS_FAINTED
datahpupdate BS_FAINTED datahpupdate BS_FAINTED
call BattleScript_PrintHurtBySpikes call BattleScript_PrintHurtByDmgHazards
tryfaintmon BS_FAINTED, FALSE, NULL tryfaintmon BS_FAINTED, FALSE, NULL
tryfaintmon BS_FAINTED, TRUE, BattleScript_SpikesOnFaintedBattlerFainted tryfaintmon BS_FAINTED, TRUE, BattleScript_DmgHazardsOnFaintedBattlerFainted
return return
BattleScript_SpikesOnFaintedBattlerFainted:: BattleScript_DmgHazardsOnFaintedBattlerFainted::
setbyte sGIVEEXP_STATE, 0x0 setbyte sGIVEEXP_STATE, 0x0
getexp BS_FAINTED getexp BS_FAINTED
setbyte sMOVEEND_STATE, 0x0 setbyte sMOVEEND_STATE, 0x0
moveend 0x0, 0x0 moveend 0x0, 0x0
goto BattleScript_HandleFaintedMon goto BattleScript_HandleFaintedMon
BattleScript_PrintHurtBySpikes:: BattleScript_PrintHurtByDmgHazards::
printstring STRINGID_PKMNHURTBYSPIKES printfromtable gDmgHazardsStringIds
waitmessage 0x40 waitmessage 0x40
return return
BattleScript_ToxicSpikesAbsorbed::
printstring STRINGID_TOXICSPIKESABSORBED
waitmessage 0x40
return
BattleScript_ToxicSpikesPoisoned::
printstring STRINGID_TOXICSPIKESPOISONED
waitmessage 0x40
statusanimation BS_SCRIPTING
updatestatusicon BS_SCRIPTING
waitstate
return
BattleScript_PerishSongTakesLife:: BattleScript_PerishSongTakesLife::
printstring STRINGID_PKMNPERISHCOUNTFELL printstring STRINGID_PKMNPERISHCOUNTFELL

View File

@ -256,6 +256,7 @@ struct SideTimer
/*0x09*/ u8 followmeTarget; /*0x09*/ u8 followmeTarget;
/*0x0A*/ u8 spikesAmount; /*0x0A*/ u8 spikesAmount;
u8 toxicSpikesAmount; u8 toxicSpikesAmount;
u8 stealthRockAmount;
u8 auroraVeilTimer; u8 auroraVeilTimer;
u8 auroraVeilBattlerId; u8 auroraVeilBattlerId;
u8 tailwindTimer; u8 tailwindTimer;

View File

@ -78,11 +78,11 @@ extern const u8 BattleScript_SelectingDisabledMoveInPalace[];
extern const u8 BattleScript_SelectingUnusableMoveInPalace[]; extern const u8 BattleScript_SelectingUnusableMoveInPalace[];
extern const u8 BattleScript_EncoredNoMore[]; extern const u8 BattleScript_EncoredNoMore[];
extern const u8 BattleScript_DestinyBondTakesLife[]; extern const u8 BattleScript_DestinyBondTakesLife[];
extern const u8 BattleScript_SpikesOnAttacker[]; extern const u8 BattleScript_DmgHazardsOnAttacker[];
extern const u8 BattleScript_82DAE7A[]; extern const u8 BattleScript_82DAE7A[];
extern const u8 BattleScript_SpikesOnTarget[]; extern const u8 BattleScript_DmgHazardsOnTarget[];
extern const u8 BattleScript_82DAEB1[]; extern const u8 BattleScript_82DAEB1[];
extern const u8 BattleScript_SpikesOnFaintedBattler[]; extern const u8 BattleScript_DmgHazardsOnFaintedBattler[];
extern const u8 BattleScript_82DAEE8[]; extern const u8 BattleScript_82DAEE8[];
extern const u8 BattleScript_82DAEFE[]; extern const u8 BattleScript_82DAEFE[];
extern const u8 BattleScript_PerishSongTakesLife[]; extern const u8 BattleScript_PerishSongTakesLife[];
@ -314,5 +314,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_ToxicSpikesPoisoned[];
extern const u8 BattleScript_ToxicSpikesAbsorbed[];
#endif // GUARD_BATTLE_SCRIPTS_H #endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -84,5 +84,6 @@ s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32
u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities); u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities);
u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 abilityDef); u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 abilityDef);
u16 GetTypeModifier(u8 atkType, u8 defType); u16 GetTypeModifier(u8 atkType, u8 defType);
s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId);
#endif // GUARD_BATTLE_UTIL_H #endif // GUARD_BATTLE_UTIL_H

View File

@ -188,19 +188,22 @@
#define HITMARKER_UNK(battler) (0x10000000 << battler) #define HITMARKER_UNK(battler) (0x10000000 << battler)
// Per-side statuses that affect an entire party // Per-side statuses that affect an entire party
#define SIDE_STATUS_REFLECT (1 << 0) #define SIDE_STATUS_REFLECT (1 << 0)
#define SIDE_STATUS_LIGHTSCREEN (1 << 1) #define SIDE_STATUS_LIGHTSCREEN (1 << 1)
#define SIDE_STATUS_X4 (1 << 2) #define SIDE_STATUS_STICKY_WEB (1 << 2)
#define SIDE_STATUS_SPIKES (1 << 4) #define SIDE_STATUS_SPIKES (1 << 4)
#define SIDE_STATUS_SAFEGUARD (1 << 5) #define SIDE_STATUS_SAFEGUARD (1 << 5)
#define SIDE_STATUS_FUTUREATTACK (1 << 6) #define SIDE_STATUS_FUTUREATTACK (1 << 6)
#define SIDE_STATUS_MIST (1 << 8) #define SIDE_STATUS_MIST (1 << 8)
#define SIDE_STATUS_SPIKES_DAMAGED (1 << 9) #define SIDE_STATUS_SPIKES_DAMAGED (1 << 9)
#define SIDE_STATUS_TAILWIND (1 << 10) #define SIDE_STATUS_TAILWIND (1 << 10)
#define SIDE_STATUS_AURORA_VEIL (1 << 11) #define SIDE_STATUS_AURORA_VEIL (1 << 11)
#define SIDE_STATUS_LUCKY_CHANT (1 << 12) #define SIDE_STATUS_LUCKY_CHANT (1 << 12)
#define SIDE_STATUS_TOXIC_SPIKES (1 << 13) #define SIDE_STATUS_TOXIC_SPIKES (1 << 13)
#define SIDE_STATUS_STEALTH_ROCK (1 << 14) #define SIDE_STATUS_STEALTH_ROCK (1 << 14)
#define SIDE_STATUS_STEALTH_ROCK_DAMAGED (1 << 15)
#define SIDE_STATUS_TOXIC_SPIKES_DAMAGED (1 << 16)
#define SIDE_STATUS_STICKY_WEB_DAMAGED (1 << 17)
// Field affecting statuses. // Field affecting statuses.
#define STATUS_FIELD_MAGIC_ROOM 0x1 #define STATUS_FIELD_MAGIC_ROOM 0x1

View File

@ -473,7 +473,10 @@
#define STRINGID_MAGICBOUNCEACTIVATES 470 #define STRINGID_MAGICBOUNCEACTIVATES 470
#define STRINGID_PROTEANTYPECHANGE 471 #define STRINGID_PROTEANTYPECHANGE 471
#define STRINGID_SYMBIOSISITEMPASS 472 #define STRINGID_SYMBIOSISITEMPASS 472
#define STRINGID_STEALTHROCKDMG 473
#define STRINGID_TOXICSPIKESABSORBED 474
#define STRINGID_TOXICSPIKESPOISONED 475
#define BATTLESTRINGS_COUNT 463 #define BATTLESTRINGS_COUNT 466
#endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H

View File

@ -115,7 +115,9 @@ enum
LIST_SIDE_MIST, LIST_SIDE_MIST,
LIST_SIDE_AURORA_VEIL, LIST_SIDE_AURORA_VEIL,
LIST_SIDE_LUCKY_CHANT, LIST_SIDE_LUCKY_CHANT,
LIST_SIDE_TAILWIND LIST_SIDE_TAILWIND,
LIST_SIDE_STEALTH_ROCK,
LIST_SIDE_TOXIC_SPIKES,
}; };
// const rom data // const rom data
@ -173,6 +175,8 @@ static const u8 sText_AuroraVeil[] = _("Aurora Veil");
static const u8 sText_LuckyChant[] = _("Lucky Chant"); static const u8 sText_LuckyChant[] = _("Lucky Chant");
static const u8 sText_Tailwind[] = _("Tailwind"); static const u8 sText_Tailwind[] = _("Tailwind");
static const u8 sText_PP[] = _("PP"); static const u8 sText_PP[] = _("PP");
static const u8 sText_StealthRock[] = _("Stealth Rock");
static const u8 sText_ToxicSpikes[] = _("Toxic Spikes");
static const u8 sText_EmptyString[] = _(""); static const u8 sText_EmptyString[] = _("");
@ -323,6 +327,8 @@ static const struct ListMenuItem sSideStatusListItems[] =
{sText_AuroraVeil, LIST_SIDE_AURORA_VEIL}, {sText_AuroraVeil, LIST_SIDE_AURORA_VEIL},
{sText_LuckyChant, LIST_SIDE_LUCKY_CHANT}, {sText_LuckyChant, LIST_SIDE_LUCKY_CHANT},
{sText_Tailwind, LIST_SIDE_TAILWIND}, {sText_Tailwind, LIST_SIDE_TAILWIND},
{sText_StealthRock, LIST_SIDE_STEALTH_ROCK},
{sText_ToxicSpikes, LIST_SIDE_TOXIC_SPIKES},
}; };
static const struct ListMenuItem sSecondaryListItems[] = static const struct ListMenuItem sSecondaryListItems[] =
@ -1111,6 +1117,24 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus,
sideTimer->tailwindBattlerId = data->battlerId; sideTimer->tailwindBattlerId = data->battlerId;
} }
return &sideTimer->tailwindTimer; return &sideTimer->tailwindTimer;
case LIST_SIDE_STEALTH_ROCK:
if (changeStatus)
{
if (statusTrue)
*(u32*)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_STEALTH_ROCK;
else
*(u32*)(data->modifyArrows.modifiedValPtr) &= ~(SIDE_STATUS_STEALTH_ROCK);
}
return &sideTimer->stealthRockAmount;
case LIST_SIDE_TOXIC_SPIKES:
if (changeStatus)
{
if (statusTrue)
*(u32*)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_TOXIC_SPIKES;
else
*(u32*)(data->modifyArrows.modifiedValPtr) &= ~(SIDE_STATUS_TOXIC_SPIKES);
}
return &sideTimer->toxicSpikesAmount;
default: default:
return NULL; return NULL;
} }
@ -1219,6 +1243,8 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data)
if (data->currentSecondaryListItemId == LIST_SIDE_SPIKES) if (data->currentSecondaryListItemId == LIST_SIDE_SPIKES)
data->modifyArrows.maxValue = 3; data->modifyArrows.maxValue = 3;
else if (data->currentSecondaryListItemId == LIST_SIDE_STEALTH_ROCK)
data->modifyArrows.maxValue = 1;
else else
data->modifyArrows.maxValue = 9; data->modifyArrows.maxValue = 9;

View File

@ -588,8 +588,6 @@ static const u8 sText_GravityEnds[] = _("Gravity returned to normal!");
static const u8 sText_AquaRingHeal[] = _("Aqua Ring restored\n{B_ATK_NAME_WITH_PREFIX}s HP!"); static const u8 sText_AquaRingHeal[] = _("Aqua Ring restored\n{B_ATK_NAME_WITH_PREFIX}s HP!");
static const u8 sText_TargetAbilityRaisedStat[] = _("{B_DEF_NAME_WITH_PREFIX}s {B_ATK_ABILITY}\n raised its {B_BUFF1}!"); static const u8 sText_TargetAbilityRaisedStat[] = _("{B_DEF_NAME_WITH_PREFIX}s {B_ATK_ABILITY}\n raised its {B_BUFF1}!");
static const u8 sText_AttackerAbilityRaisedStat[] = _("{B_ATK_NAME_WITH_PREFIX}s {B_ATK_ABILITY}\n raised its {B_BUFF1}!"); static const u8 sText_AttackerAbilityRaisedStat[] = _("{B_ATK_NAME_WITH_PREFIX}s {B_ATK_ABILITY}\n raised its {B_BUFF1}!");
// These strings are currently placeholders, to be fixed.
static const u8 sText_AuroraVeilEnds[] = _("{B_DEF_NAME_WITH_PREFIX}s {B_DEF_ABILITY}\nwore off!"); static const u8 sText_AuroraVeilEnds[] = _("{B_DEF_NAME_WITH_PREFIX}s {B_DEF_ABILITY}\nwore off!");
static const u8 sText_ElectricTerrainEnds[] = _("{B_ATK_ABILITY} wore off."); static const u8 sText_ElectricTerrainEnds[] = _("{B_ATK_ABILITY} wore off.");
static const u8 sText_MistyTerrainEnds[] = _("{B_ATK_ABILITY} wore off."); static const u8 sText_MistyTerrainEnds[] = _("{B_ATK_ABILITY} wore off.");
@ -616,6 +614,9 @@ static const u8 sText_MoxieAtkRise[] = _("{B_ATK_NAME_WITH_PREFIX}s {B_ATK_AB
static const u8 sText_MagicBounceActivates[] = _("The {B_DEF_NAME_WITH_PREFIX} bounced the\n{B_ATK_NAME_WITH_PREFIX} back!"); static const u8 sText_MagicBounceActivates[] = _("The {B_DEF_NAME_WITH_PREFIX} bounced the\n{B_ATK_NAME_WITH_PREFIX} back!");
static const u8 sText_ProteanTypeChange[] = _("{B_ATK_NAME_WITH_PREFIX}s {B_ATK_ABILITY} transformed\nit into the {B_BUFF1} type!"); static const u8 sText_ProteanTypeChange[] = _("{B_ATK_NAME_WITH_PREFIX}s {B_ATK_ABILITY} transformed\nit into the {B_BUFF1} type!");
static const u8 sText_SymbiosisItemPass[] = _("{B_ATK_NAME_WITH_PREFIX} passed its {B_LAST_ITEM}\nto {B_SCR_ACTIVE_NAME_WITH_PREFIX} through {B_ATK_ABILITY}!"); static const u8 sText_SymbiosisItemPass[] = _("{B_ATK_NAME_WITH_PREFIX} passed its {B_LAST_ITEM}\nto {B_SCR_ACTIVE_NAME_WITH_PREFIX} through {B_ATK_ABILITY}!");
static const u8 sText_StealthRockDmg[] = _("Pointed stones dug into\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
static const u8 sText_ToxicSpikesAbsorbed[] = _("");
static const u8 sText_ToxicSpikesPoisoned[] = _("");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{ {
@ -1081,6 +1082,14 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
sText_MagicBounceActivates, sText_MagicBounceActivates,
sText_ProteanTypeChange, sText_ProteanTypeChange,
sText_SymbiosisItemPass, sText_SymbiosisItemPass,
sText_StealthRockDmg,
sText_ToxicSpikesAbsorbed,
sText_ToxicSpikesPoisoned,
};
const u16 gDmgHazardsStringIds[] =
{
STRINGID_PKMNHURTBYSPIKES, STRINGID_STEALTHROCKDMG
}; };
const u16 gSwitchInAbilityStringIds[] = const u16 gSwitchInAbilityStringIds[] =

View File

@ -2765,7 +2765,7 @@ static void atk19_tryfaintmon(void)
BattleScriptPop(); BattleScriptPop();
gBattlescriptCurrInstr = BS_ptr; gBattlescriptCurrInstr = BS_ptr;
gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED);
} }
else else
{ {
@ -5315,6 +5315,22 @@ static void atk51_switchhandleorder(void)
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;
} }
static void SetDmgHazardsBattlescript(u8 battlerId, u8 multistringId)
{
gBattleMons[battlerId].status2 &= ~(STATUS2_DESTINY_BOND);
gHitMarker &= ~(HITMARKER_DESTINYBOND);
gBattleScripting.battler = battlerId;
gBattleCommunication[MULTISTRING_CHOOSER] = multistringId;
BattleScriptPushCursor();
if (gBattlescriptCurrInstr[1] == BS_TARGET)
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnTarget;
else if (gBattlescriptCurrInstr[1] == BS_ATTACKER)
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnAttacker;
else
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnFaintedBattler;
}
static void atk52_switchineffects(void) static void atk52_switchineffects(void)
{ {
s32 i; s32 i;
@ -5327,30 +5343,57 @@ static void atk52_switchineffects(void)
if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED) if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES) && (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING) && IsBattlerGrounded(gActiveBattler))
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE)
{ {
u8 spikesDmg; u8 spikesDmg = (5 - gSideTimers[GetBattlerSide(gActiveBattler)].spikesAmount) * 2;
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_SPIKES_DAMAGED;
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_DESTINY_BOND);
gHitMarker &= ~(HITMARKER_DESTINYBOND);
spikesDmg = (5 - gSideTimers[GetBattlerSide(gActiveBattler)].spikesAmount) * 2;
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (spikesDmg); gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (spikesDmg);
if (gBattleMoveDamage == 0) if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1; gBattleMoveDamage = 1;
gBattleScripting.battler = gActiveBattler; gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_SPIKES_DAMAGED;
BattleScriptPushCursor(); SetDmgHazardsBattlescript(gActiveBattler, 0);
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STEALTH_ROCK_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STEALTH_ROCK))
{
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_STEALTH_ROCK_DAMAGED;
gBattleMoveDamage = GetStealthHazardDamage(gBattleMoves[MOVE_STEALTH_ROCK].type, gActiveBattler);
if (gBattlescriptCurrInstr[1] == BS_TARGET) if (gBattleMoveDamage != 0)
gBattlescriptCurrInstr = BattleScript_SpikesOnTarget; SetDmgHazardsBattlescript(gActiveBattler, 1);
else if (gBattlescriptCurrInstr[1] == BS_ATTACKER) }
gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker; else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_TOXIC_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_TOXIC_SPIKES)
&& IsBattlerGrounded(gActiveBattler))
{
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_TOXIC_SPIKES_DAMAGED;
if (IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_POISON)) // Absorb the toxic spikes.
{
gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_TOXIC_SPIKES);
gSideTimers[GetBattlerSide(gActiveBattler)].toxicSpikesAmount = 0;
gBattleScripting.battler = gActiveBattler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ToxicSpikesAbsorbed;
}
else else
gBattlescriptCurrInstr = BattleScript_SpikesOnFaintedBattler; {
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)
&& GetBattlerAbility(gActiveBattler) != ABILITY_IMMUNITY
&& !(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SAFEGUARD))
{
if (gSideTimers[GetBattlerSide(gActiveBattler)].toxicSpikesAmount >= 2)
gBattleMons[gActiveBattler].status1 |= STATUS1_TOXIC_POISON;
else
gBattleMons[gActiveBattler].status1 |= STATUS1_POISON;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
gBattleScripting.battler = gActiveBattler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ToxicSpikesPoisoned;
}
}
} }
else else
{ {
@ -5362,7 +5405,7 @@ static void atk52_switchineffects(void)
if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0) == 0 && if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0) == 0 &&
ItemBattleEffects(0, gActiveBattler, 0) == 0) ItemBattleEffects(0, gActiveBattler, 0) == 0)
{ {
gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED);
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
@ -9484,6 +9527,7 @@ static void atkDC_setstealthrock(void)
else else
{ {
gSideStatuses[targetSide] |= SIDE_STATUS_STEALTH_ROCK; gSideStatuses[targetSide] |= SIDE_STATUS_STEALTH_ROCK;
gSideTimers[targetSide].stealthRockAmount = 1;
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
} }
} }

View File

@ -5230,3 +5230,50 @@ u16 GetTypeModifier(u8 atkType, u8 defType)
{ {
return sTypeEffectivenessTable[atkType][defType]; return sTypeEffectivenessTable[atkType][defType];
} }
s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId)
{
u8 type1 = gBattleMons[battlerId].type1;
u8 type2 = gBattleMons[battlerId].type2;
u32 maxHp = gBattleMons[battlerId].maxHP;
s32 dmg = 0;
u16 modifier = UQ_4_12(1.0);
MulModifier(&modifier, GetTypeModifier(hazardType, type1));
if (type2 != type1)
MulModifier(&modifier, GetTypeModifier(hazardType, type2));
switch (modifier)
{
case UQ_4_12(0.0):
dmg = 0;
break;
case UQ_4_12(0.25):
dmg = maxHp / 32;
if (dmg == 0)
dmg = 1;
break;
case UQ_4_12(0.5):
dmg = maxHp / 16;
if (dmg == 0)
dmg = 1;
break;
case UQ_4_12(1.0):
dmg = maxHp / 8;
if (dmg == 0)
dmg = 1;
break;
case UQ_4_12(2.0):
dmg = maxHp / 4;
if (dmg == 0)
dmg = 1;
break;
case UQ_4_12(4.0):
dmg = maxHp / 2;
if (dmg == 0)
dmg = 1;
break;
}
return dmg;
}