From 4923af960e5ff514e2bc3e02fb32b39fcfc82fe8 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 5 Jan 2021 15:44:12 -0700 Subject: [PATCH 1/4] steely spirit, screen cleaner, transistor, dragon's maw --- src/battle_util.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index aeeefa7347..397a011bba 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -53,6 +53,8 @@ match the ROM; this is also why sSoundMovesTable's declaration is in the middle functions instead of at the top of the file with the other declarations. */ +static bool32 TryRemoveScreens(u8 battler); + extern const u8 *const gBattleScriptsForMoveEffects[]; extern const u8 *const gBattlescriptsForBallThrow[]; extern const u8 *const gBattlescriptsForRunningByItem[]; @@ -3830,7 +3832,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITY_SCREEN_CLEANER: - if (!gSpecialStatuses[battler].switchInAbilityDone) + if (!gSpecialStatuses[battler].switchInAbilityDone && TryRemoveScreens(battler)) { gBattleCommunication[MULTISTRING_CHOOSER] = MULTI_SWITCHIN_SCREENCLEANER; gSpecialStatuses[battler].switchInAbilityDone = 1; @@ -6682,6 +6684,18 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe if (moveType == TYPE_NORMAL && gBattleStruct->ateBoost[battlerAtk]) MulModifier(&modifier, UQ_4_12(1.2)); break; + case ABILITY_STEELY_SPIRIT: + if (moveType == TYPE_STEEL) + MulModifier(&modifier, UQ_4_12(1.5)); + break; + case ABILITY_TRANSISTOR: + if (moveType == TYPE_ELECTRIC) + MulModifier(&modifier, UQ_4_12(1.5)); + break; + case ABILITY_DRAGONS_MAW: + if (moveType == TYPE_DRAGON) + MulModifier(&modifier, UQ_4_12(1.5)); + break; } // field abilities @@ -6703,6 +6717,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe if (IS_MOVE_SPECIAL(move)) MulModifier(&modifier, UQ_4_12(1.3)); break; + case ABILITY_STEELY_SPIRIT: + if (moveType == TYPE_STEEL) + MulModifier(&modifier, UQ_4_12(1.5)); + break; } } @@ -7830,3 +7848,26 @@ u8 GetBattleMoveSplit(u32 moveId) else return SPLIT_SPECIAL; } + +static bool32 TryRemoveScreens(u8 battler) +{ + bool32 removed = FALSE; + u8 battlerSide = GetBattlerSide(battler); + u8 enemySide = GetBattlerSide(BATTLE_OPPOSITE(battler)); + + // try to remove from battler's side + if (gSideStatuses[battlerSide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)) + { + gSideStatuses[battlerSide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL); + removed = TRUE; + } + + // try to remove from battler opponent's side + if (gSideStatuses[enemySide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)) + { + gSideStatuses[enemySide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL); + removed = TRUE; + } + + return removed; +} From 0a3908ee924c8028725b1995c424ed308610fa26 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 5 Jan 2021 19:37:23 -0700 Subject: [PATCH 2/4] add neigh and as one abilities --- asm/macros/battle_script.inc | 4 ++++ data/battle_scripts_1.s | 3 ++- include/constants/battle_script_commands.h | 1 + include/constants/battle_string_ids.h | 4 +++- src/battle_message.c | 3 +++ src/battle_script_commands.c | 27 ++++++++++++++++++---- src/battle_util.c | 24 +++++++++++++++++-- 7 files changed, 57 insertions(+), 9 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 135960c124..ec83a6c2d0 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1760,6 +1760,10 @@ various BS_ABILITY_BATTLER, VARIOUS_DESTROY_ABILITY_POPUP .endm + .macro tryactivategrimneigh, battler:req + various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 3eb1f5cbe6..88e4743732 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4965,8 +4965,9 @@ BattleScript_FaintTarget:: tryactivatefellstinger BS_ATTACKER tryactivatesoulheart tryactivatereceiver BS_TARGET - tryactivatemoxie BS_ATTACKER + tryactivatemoxie BS_ATTACKER @ and chilling neigh, as one ice rider tryactivatebeastboost BS_ATTACKER + tryactivategrimneigh BS_ATTACKER @ and as one shadow rider trytrainerslidefirstdownmsg BS_TARGET return diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 2f52da3197..e68278b1d2 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -167,6 +167,7 @@ #define VARIOUS_PARALYZE_TYPE_IMMUNITY 100 #define VARIOUS_JUMP_IF_ABSENT 101 #define VARIOUS_DESTROY_ABILITY_POPUP 102 +#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 103 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 9348d67d5d..10562bd988 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -558,8 +558,9 @@ #define STRINGID_AURABREAKENTERS 554 #define STRINGID_COMATOSEENTERS 555 #define STRINGID_SCREENCLEANERENTERS 556 +#define STRINGID_ASONEENTERS 557 -#define BATTLESTRINGS_COUNT 557 +#define BATTLESTRINGS_COUNT 558 //// multichoice message IDs // switch in ability message @@ -576,5 +577,6 @@ #define MULTI_SWITCHIN_AURABREAK 10 #define MULTI_SWITCHIN_COMATOSE 11 #define MULTI_SWITCHIN_SCREENCLEANER 12 +#define MULTI_SWITCHIN_ASONE 13 #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H diff --git a/src/battle_message.c b/src/battle_message.c index 35ccc6e268..c629d30927 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -685,9 +685,11 @@ static const u8 sText_FairyAuraActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} static const u8 sText_AuraBreakActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} reversed all\nother POKéMON's auras!"); static const u8 sText_ComatoseActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is drowsing!"); static const u8 sText_ScreenCleanerActivates[] = _("All screens on the field were\ncleansed!"); +static const u8 sText_AsOneEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two Abilities!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_ASONEENTERS - 12] = sText_AsOneEnters, [STRINGID_STATWASNOTLOWERED - 12] = sText_StatWasNotLowered, [STRINGID_CLOAKEDINAFREEZINGLIGHT - 12] = sText_CloakedInAFreezingLight, [STRINGID_DESTINYKNOTACTIVATES - 12] = sText_DestinyKnotActivates, @@ -1275,6 +1277,7 @@ const u16 gSwitchInAbilityStringIds[] = [MULTI_SWITCHIN_AURABREAK] = STRINGID_AURABREAKENTERS, [MULTI_SWITCHIN_COMATOSE] = STRINGID_COMATOSEENTERS, [MULTI_SWITCHIN_SCREENCLEANER] = STRINGID_SCREENCLEANERENTERS, + [MULTI_SWITCHIN_ASONE] = STRINGID_ASONEENTERS, }; const u16 gMissStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index bc427698ef..0857b1c5e9 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7527,11 +7527,13 @@ static void Cmd_various(void) BtlController_EmitSetMonData(0, REQUEST_PP_DATA_BATTLE, 0, 5, data); MarkBattlerForControllerExec(gActiveBattler); break; - case VARIOUS_TRY_ACTIVATE_MOXIE: - if (GetBattlerAbility(gActiveBattler) == ABILITY_MOXIE - && HasAttackerFaintedTarget() - && !NoAliveMonsForEitherParty() - && gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12) + case VARIOUS_TRY_ACTIVATE_MOXIE: // and chilling neigh + as one ice rider + if ((GetBattlerAbility(gActiveBattler) == ABILITY_MOXIE + || GetBattlerAbility(gActiveBattler) == ABILITY_CHILLING_NEIGH + || GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_ICE_RIDER) + && HasAttackerFaintedTarget() + && !NoAliveMonsForEitherParty() + && gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12) { gBattleMons[gBattlerAttacker].statStages[STAT_ATK]++; SET_STATCHANGER(STAT_ATK, 1, FALSE); @@ -7541,6 +7543,21 @@ static void Cmd_various(void) return; } break; + case VARIOUS_TRY_ACTIVATE_GRIM_NEIGH: // and as one shadow rider + if ((GetBattlerAbility(gActiveBattler) == ABILITY_GRIM_NEIGH + || GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_SHADOW_RIDER) + && HasAttackerFaintedTarget() + && !NoAliveMonsForEitherParty() + && gBattleMons[gBattlerAttacker].statStages[STAT_SPATK] != 12) + { + gBattleMons[gBattlerAttacker].statStages[STAT_SPATK]++; + SET_STATCHANGER(STAT_SPATK, 1, FALSE); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); + BattleScriptPush(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = BattleScript_AttackerAbilityStatRaise; + return; + } + break; case VARIOUS_TRY_ACTIVATE_RECEIVER: // Partner gets fainted's ally ability gBattlerAbility = BATTLE_PARTNER(gActiveBattler); i = GetBattlerAbility(gBattlerAbility); diff --git a/src/battle_util.c b/src/battle_util.c index 397a011bba..f7804851c4 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -54,6 +54,7 @@ functions instead of at the top of the file with the other declarations. */ static bool32 TryRemoveScreens(u8 battler); +static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId); extern const u8 *const gBattleScriptsForMoveEffects[]; extern const u8 *const gBattlescriptsForBallThrow[]; @@ -3701,6 +3702,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_AS_ONE_ICE_RIDER: + case ABILITY_AS_ONE_SHADOW_RIDER: + if (!gSpecialStatuses[battler].switchInAbilityDone) + { + gBattleCommunication[MULTISTRING_CHOOSER] = MULTI_SWITCHIN_ASONE; + gSpecialStatuses[battler].switchInAbilityDone = 1; + BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); + effect++; + } + break; case ABILITY_ANTICIPATION: if (!gSpecialStatuses[battler].switchInAbilityDone) { @@ -4986,7 +4997,7 @@ static bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId) if (gBattleMons[battlerId].hp == 0) return FALSE; // Unnerve prevents consumption of opponents' berries. - if (isBerry && IsAbilityOnOpposingSide(battlerId, ABILITY_UNNERVE)) + if (isBerry && IsUnnerveAbilityOnOpposingSide(battlerId)) return FALSE; if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / hpFraction) return TRUE; @@ -5100,7 +5111,7 @@ static u8 ItemHealHp(u32 battlerId, u32 itemId, bool32 end2, bool32 percentHeal) static bool32 UnnerveOn(u32 battlerId, u32 itemId) { - if (ItemId_GetPocket(itemId) == POCKET_BERRIES && IsAbilityOnOpposingSide(battlerId, ABILITY_UNNERVE)) + if (ItemId_GetPocket(itemId) == POCKET_BERRIES && IsUnnerveAbilityOnOpposingSide(battlerId)) return TRUE; return FALSE; } @@ -7871,3 +7882,12 @@ static bool32 TryRemoveScreens(u8 battler) return removed; } + +static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId) +{ + if (IsAbilityOnOpposingSide(battlerId, ABILITY_UNNERVE) + || IsAbilityOnOpposingSide(battlerId, ABILITY_AS_ONE_ICE_RIDER) + || IsAbilityOnOpposingSide(battlerId, ABILITY_AS_ONE_SHADOW_RIDER)) + return TRUE; + return FALSE; +} From 4c1e8f2f2ebed06769dfcc8e93b2466fb4b9f7a5 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 5 Jan 2021 20:02:11 -0700 Subject: [PATCH 3/4] add curious medicine --- include/battle_script_commands.h | 1 + include/constants/battle_string_ids.h | 4 +++- src/battle_message.c | 2 ++ src/battle_script_commands.c | 17 +++++++++++------ src/battle_util.c | 13 +++++++++++++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index 454b6ab345..14ed1ebb87 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -26,6 +26,7 @@ u32 IsFlowerVeilProtected(u32 battler); u32 IsLeafGuardProtected(u32 battler); bool32 IsShieldsDownProtected(u32 battler); u32 IsAbilityStatusProtected(u32 battler); +void ResetBattlerStatChanges(u8 battler); extern void (* const gBattleScriptingCommandsTable[])(void); extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4]; diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 10562bd988..665d47c273 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -559,8 +559,9 @@ #define STRINGID_COMATOSEENTERS 555 #define STRINGID_SCREENCLEANERENTERS 556 #define STRINGID_ASONEENTERS 557 +#define STRINGID_CURIOUSMEDICINEENTERS 558 -#define BATTLESTRINGS_COUNT 558 +#define BATTLESTRINGS_COUNT 559 //// multichoice message IDs // switch in ability message @@ -578,5 +579,6 @@ #define MULTI_SWITCHIN_COMATOSE 11 #define MULTI_SWITCHIN_SCREENCLEANER 12 #define MULTI_SWITCHIN_ASONE 13 +#define MULTI_SWITCHIN_CURIOUS_MEDICINE 14 #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H diff --git a/src/battle_message.c b/src/battle_message.c index c629d30927..48c297d72e 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -686,9 +686,11 @@ static const u8 sText_AuraBreakActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} static const u8 sText_ComatoseActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is drowsing!"); static const u8 sText_ScreenCleanerActivates[] = _("All screens on the field were\ncleansed!"); static const u8 sText_AsOneEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two Abilities!"); +static const u8 sText_CuriousMedicineEnters[] = _("{B_EFF_NAME_WITH_PREFIX}'s\nstat changes were reset!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_CURIOUSMEDICINEENTERS - 12] = sText_CuriousMedicineEnters, [STRINGID_ASONEENTERS - 12] = sText_AsOneEnters, [STRINGID_STATWASNOTLOWERED - 12] = sText_StatWasNotLowered, [STRINGID_CLOAKEDINAFREEZINGLIGHT - 12] = sText_CloakedInAFreezingLight, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 0857b1c5e9..61a54e3d85 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9074,17 +9074,22 @@ static void Cmd_statbuffchange(void) gBattlescriptCurrInstr = jumpPtr; } +void ResetBattlerStatChanges(u8 battler) +{ + u32 j; + + gDisableStructs[battler].stockpileDef = 0; + gDisableStructs[battler].stockpileSpDef = 0; + for (j = 0; j < NUM_BATTLE_STATS; j++) + gBattleMons[battler].statStages[j] = DEFAULT_STAT_STAGE; +} + static void Cmd_normalisebuffs(void) // haze { s32 i, j; for (i = 0; i < gBattlersCount; i++) - { - gDisableStructs[i].stockpileDef = 0; - gDisableStructs[i].stockpileSpDef = 0; - for (j = 0; j < NUM_BATTLE_STATS; j++) - gBattleMons[i].statStages[j] = DEFAULT_STAT_STAGE; - } + ResetBattlerStatChanges(i); gBattlescriptCurrInstr++; } diff --git a/src/battle_util.c b/src/battle_util.c index f7804851c4..10a38a26bc 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3712,6 +3712,18 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_CURIOUS_MEDICINE: + if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() && IsBattlerAlive(BATTLE_PARTNER(battler))) + { + u32 i; + gEffectBattler = BATTLE_PARTNER(battler); + ResetBattlerStatChanges(gEffectBattler); + gBattleCommunication[MULTISTRING_CHOOSER] = MULTI_SWITCHIN_CURIOUS_MEDICINE; + gSpecialStatuses[battler].switchInAbilityDone = 1; + BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); + effect++; + } + break; case ABILITY_ANTICIPATION: if (!gSpecialStatuses[battler].switchInAbilityDone) { @@ -7891,3 +7903,4 @@ static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId) return TRUE; return FALSE; } + From f4d4cf262e2a7c408444ae79083bb31a92a1cdd1 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 2 Feb 2021 09:00:07 -0700 Subject: [PATCH 4/4] fix screen cleaner, curious medicine, as one --- data/battle_scripts_1.s | 23 ++++++++++++++++++++++ include/battle.h | 1 + include/battle_script_commands.h | 2 +- include/battle_scripts.h | 2 ++ include/constants/battle_script_commands.h | 1 + include/constants/battle_string_ids.h | 2 +- src/battle_interface.c | 3 +++ src/battle_message.c | 5 +++-- src/battle_script_commands.c | 22 +++++++++++++++++---- src/battle_util.c | 12 ++++++++--- 10 files changed, 62 insertions(+), 11 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index d1d867ae01..297cd4159a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6628,6 +6628,7 @@ BattleScript_AbilityPopUp: showabilitypopup BS_ABILITY_BATTLER recordability BS_ABILITY_BATTLER pause 40 + sethword sABILITY_OVERWRITE, 0 return BattleScript_SpeedBoostActivates:: @@ -7219,6 +7220,16 @@ BattleScript_WeakArmorSpeedAnim: BattleScript_WeakArmorActivatesEnd: return +BattleScript_RaiseStatOnFaintingTarget:: + copybyte gBattlerAbility, gBattlerAttacker + call BattleScript_AbilityPopUp + setgraphicalstatchangevalues + playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + waitanimation + printstring STRINGID_LASTABILITYRAISEDSTAT + waitmessage 0x40 + return + BattleScript_AttackerAbilityStatRaise:: copybyte gBattlerAbility, gBattlerAttacker call BattleScript_AbilityPopUp @@ -7248,6 +7259,18 @@ BattleScript_SwitchInAbilityMsg:: printfromtable gSwitchInAbilityStringIds waitmessage 0x40 end3 + +BattleScript_ActivateAsOne:: + call BattleScript_AbilityPopUp + printfromtable gSwitchInAbilityStringIds + waitmessage 0x40 + @ show unnerve + sethword sABILITY_OVERWRITE, ABILITY_UNNERVE + setbyte cMULTISTRING_CHOOSER, MULTI_SWITCHIN_UNNERVE + call BattleScript_AbilityPopUp + printfromtable gSwitchInAbilityStringIds + waitmessage 0x40 + end3 BattleScript_FriskMsgWithPopup:: copybyte gBattlerAbility, gBattlerAttacker diff --git a/include/battle.h b/include/battle.h index 5917a4ab3a..326616e385 100644 --- a/include/battle.h +++ b/include/battle.h @@ -613,6 +613,7 @@ struct BattleScripting u16 multihitMoveEffect; u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN. bool8 fixedPopup; // force ability popup to stick until manually called back + u16 abilityPopupOverwrite; }; // rom_80A5C6C diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index 14ed1ebb87..ff35570088 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -26,7 +26,7 @@ u32 IsFlowerVeilProtected(u32 battler); u32 IsLeafGuardProtected(u32 battler); bool32 IsShieldsDownProtected(u32 battler); u32 IsAbilityStatusProtected(u32 battler); -void ResetBattlerStatChanges(u8 battler); +bool32 TryResetBattlerStatChanges(u8 battler); extern void (* const gBattleScriptingCommandsTable[])(void); extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4]; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 009590f3a3..0461721699 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -357,5 +357,7 @@ extern const u8 BattleScript_CottonDownActivates[]; extern const u8 BattleScript_BallFetch[]; extern const u8 BattleScript_SandSpitActivates[]; extern const u8 BattleScript_PerishBodyActivates[]; +extern const u8 BattleScript_ActivateAsOne[]; +extern const u8 BattleScript_RaiseStatOnFaintingTarget[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 5ddda25588..0b8b84d7c3 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -36,6 +36,7 @@ #define sMULTIHIT_EFFECT gBattleScripting + 0x30 #define sILLUSION_NICK_HACK gBattleScripting + 0x32 #define sFIXED_ABILITY_POPUP gBattleScripting + 0x33 +#define sABILITY_OVERWRITE gBattleScripting + 0x34 #define cMULTISTRING_CHOOSER gBattleCommunication + 5 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 453c122c04..9821e6df33 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -470,7 +470,7 @@ #define STRINGID_FRISKACTIVATES 466 #define STRINGID_UNNERVEENTERS 467 #define STRINGID_HARVESTBERRY 468 -#define STRINGID_MOXIEATKRISE 469 +#define STRINGID_LASTABILITYRAISEDSTAT 469 #define STRINGID_MAGICBOUNCEACTIVATES 470 #define STRINGID_PROTEANTYPECHANGE 471 #define STRINGID_SYMBIOSISITEMPASS 472 diff --git a/src/battle_interface.c b/src/battle_interface.c index a77aacde5d..d68c15e870 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3018,6 +3018,9 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) if (!B_ABILITY_POP_UP) return; + + if (gBattleScripting.abilityPopupOverwrite != 0) + ability = gBattleScripting.abilityPopupOverwrite; if (!gBattleStruct->activeAbilityPopUps) { diff --git a/src/battle_message.c b/src/battle_message.c index 2cacbd1276..abc74ef593 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -601,7 +601,7 @@ static const u8 sText_SnowWarningHail[] = _("It started to hail!"); static const u8 sText_FriskActivates[] = _("{B_ATK_NAME_WITH_PREFIX} frisked {B_DEF_NAME_WITH_PREFIX} and\nfound its {B_LAST_ITEM}!"); static const u8 sText_UnnerveEnters[] = _("The opposing team is too nervous\nto eat Berries!"); static const u8 sText_HarvestBerry[] = _("{B_ATK_NAME_WITH_PREFIX} harvested\nits {B_LAST_ITEM}!"); -static const u8 sText_MoxieAtkRise[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} raised its Attack!"); +static const u8 sText_LastAbilityRaisedBuff1[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}\nraised its {B_BUFF1}!"); 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_SymbiosisItemPass[] = _("{B_ATK_NAME_WITH_PREFIX} passed its {B_LAST_ITEM}\nto {B_SCR_ACTIVE_NAME_WITH_PREFIX} through {B_ATK_ABILITY}!"); @@ -1189,7 +1189,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_FRISKACTIVATES - 12] = sText_FriskActivates, [STRINGID_UNNERVEENTERS - 12] = sText_UnnerveEnters, [STRINGID_HARVESTBERRY - 12] = sText_HarvestBerry, - [STRINGID_MOXIEATKRISE - 12] = sText_MoxieAtkRise, + [STRINGID_LASTABILITYRAISEDSTAT - 12] = sText_LastAbilityRaisedBuff1, [STRINGID_MAGICBOUNCEACTIVATES - 12] = sText_MagicBounceActivates, [STRINGID_PROTEANTYPECHANGE - 12] = sText_ProteanTypeChange, [STRINGID_SYMBIOSISITEMPASS - 12] = sText_SymbiosisItemPass, @@ -1292,6 +1292,7 @@ const u16 gSwitchInAbilityStringIds[] = [MULTI_SWITCHIN_COMATOSE] = STRINGID_COMATOSEENTERS, [MULTI_SWITCHIN_SCREENCLEANER] = STRINGID_SCREENCLEANERENTERS, [MULTI_SWITCHIN_ASONE] = STRINGID_ASONEENTERS, + [MULTI_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS, }; const u16 gMissStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e67d56b612..233efd9d3b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7534,7 +7534,10 @@ static void Cmd_various(void) SET_STATCHANGER(STAT_ATK, 1, FALSE); PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK); BattleScriptPush(gBattlescriptCurrInstr + 3); - gBattlescriptCurrInstr = BattleScript_AttackerAbilityStatRaise; + gLastUsedAbility = GetBattlerAbility(gActiveBattler); + if (GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_ICE_RIDER) + gBattleScripting.abilityPopupOverwrite = gLastUsedAbility = ABILITY_CHILLING_NEIGH; + gBattlescriptCurrInstr = BattleScript_RaiseStatOnFaintingTarget; return; } break; @@ -7549,7 +7552,10 @@ static void Cmd_various(void) SET_STATCHANGER(STAT_SPATK, 1, FALSE); PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); BattleScriptPush(gBattlescriptCurrInstr + 3); - gBattlescriptCurrInstr = BattleScript_AttackerAbilityStatRaise; + gLastUsedAbility = GetBattlerAbility(gActiveBattler); + if (GetBattlerAbility(gActiveBattler) == ABILITY_AS_ONE_SHADOW_RIDER) + gBattleScripting.abilityPopupOverwrite = gLastUsedAbility = ABILITY_GRIM_NEIGH; + gBattlescriptCurrInstr = BattleScript_RaiseStatOnFaintingTarget; return; } break; @@ -9104,14 +9110,22 @@ static void Cmd_statbuffchange(void) gBattlescriptCurrInstr = jumpPtr; } -void ResetBattlerStatChanges(u8 battler) +bool32 TryResetBattlerStatChanges(u8 battler) { u32 j; + bool32 ret = FALSE; gDisableStructs[battler].stockpileDef = 0; gDisableStructs[battler].stockpileSpDef = 0; for (j = 0; j < NUM_BATTLE_STATS; j++) + { + if (gBattleMons[battler].statStages[j] != DEFAULT_STAT_STAGE) + ret = TRUE; // returns TRUE if any stat was reset + gBattleMons[battler].statStages[j] = DEFAULT_STAT_STAGE; + } + + return ret; } static void Cmd_normalisebuffs(void) // haze @@ -9119,7 +9133,7 @@ static void Cmd_normalisebuffs(void) // haze s32 i, j; for (i = 0; i < gBattlersCount; i++) - ResetBattlerStatChanges(i); + TryResetBattlerStatChanges(i); gBattlescriptCurrInstr++; } diff --git a/src/battle_util.c b/src/battle_util.c index c6115735e6..652fc8f499 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3714,16 +3714,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move { gBattleCommunication[MULTISTRING_CHOOSER] = MULTI_SWITCHIN_ASONE; gSpecialStatuses[battler].switchInAbilityDone = 1; - BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); + BattleScriptPushCursorAndCallback(BattleScript_ActivateAsOne); effect++; } break; case ABILITY_CURIOUS_MEDICINE: - if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() && IsBattlerAlive(BATTLE_PARTNER(battler))) + if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() + && IsBattlerAlive(BATTLE_PARTNER(battler)) && TryResetBattlerStatChanges(BATTLE_PARTNER(battler))) { u32 i; gEffectBattler = BATTLE_PARTNER(battler); - ResetBattlerStatChanges(gEffectBattler); gBattleCommunication[MULTISTRING_CHOOSER] = MULTI_SWITCHIN_CURIOUS_MEDICINE; gSpecialStatuses[battler].switchInAbilityDone = 1; BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); @@ -7998,6 +7998,9 @@ static bool32 TryRemoveScreens(u8 battler) if (gSideStatuses[battlerSide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)) { gSideStatuses[battlerSide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL); + gSideTimers[battlerSide].reflectTimer = 0; + gSideTimers[battlerSide].lightscreenTimer = 0; + gSideTimers[battlerSide].auroraVeilTimer = 0; removed = TRUE; } @@ -8005,6 +8008,9 @@ static bool32 TryRemoveScreens(u8 battler) if (gSideStatuses[enemySide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)) { gSideStatuses[enemySide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL); + gSideTimers[enemySide].reflectTimer = 0; + gSideTimers[enemySide].lightscreenTimer = 0; + gSideTimers[enemySide].auroraVeilTimer = 0; removed = TRUE; }