From a89ce0c38abf74470a78091152c8f5900cdde792 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Tue, 23 Nov 2021 22:54:30 +1300 Subject: [PATCH] Swapped webs don't trigger Defiant Track the side that originally set Sticky Web, and if it matches the side the target of the speed drop is on, don't activate Defiant. Hard to tell if this is a bug or a feature in gen 8 - maybe the swapped webs are considered a "friendly" effect? Also, fix Sticky Web not activating Defiant. --- data/battle_scripts_1.s | 1 + include/battle.h | 2 ++ include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 39 ++++++++++++---------- src/battle_util.c | 5 ++- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index eeeba7cf72..dabdf1383f 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6712,6 +6712,7 @@ BattleScript_ToxicSpikesPoisoned:: BattleScript_StickyWebOnSwitchIn:: savetarget copybyte gBattlerTarget, sBATTLER + setbyte sSTICKY_WEB_STAT_DROP, 1 printstring STRINGID_STICKYWEBSWITCHIN waitmessage B_WAIT_TIME_LONG jumpifability BS_TARGET, ABILITY_MIRROR_ARMOR, BattleScript_MirrorArmorReflectStickyWeb diff --git a/include/battle.h b/include/battle.h index f534f416bc..7ccb492a6c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -211,6 +211,7 @@ struct SideTimer u8 toxicSpikesAmount; u8 stealthRockAmount; u8 stickyWebAmount; + u8 stickyWebBattlerSide; // Used for Court Change u8 auroraVeilTimer; u8 auroraVeilBattlerId; u8 tailwindTimer; @@ -704,6 +705,7 @@ struct BattleScripting u16 abilityPopupOverwrite; u8 switchCase; // Special switching conditions, eg. red card u8 overrideBerryRequirements; + u8 stickyWebStatDrop; // To prevent Defiant activating on a Court Change'd Sticky Web }; // rom_80A5C6C diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 96796ea2d9..3317948165 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -39,6 +39,7 @@ #define sABILITY_OVERWRITE gBattleScripting + 0x34 #define sSWITCH_CASE gBattleScripting + 0x36 #define sBERRY_OVERRIDE gBattleScripting + 0x37 +#define sSTICKY_WEB_STAT_DROP gBattleScripting + 0x38 #define cMULTISTRING_CHOOSER gBattleCommunication + 5 #define cMISS_TYPE gBattleCommunication + 6 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index db3a030ae3..672aa92a19 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7536,30 +7536,30 @@ static bool32 IsRototillerAffected(u32 battlerId) return TRUE; } -#define COURTCHANGE_SWAP(status, structField, temp) \ -{ \ - temp = gSideStatuses[B_SIDE_PLAYER]; \ - if (gSideStatuses[B_SIDE_OPPONENT] & status) \ - gSideStatuses[B_SIDE_PLAYER] |= status; \ - else \ - gSideStatuses[B_SIDE_PLAYER] &= ~(status); \ - if (temp & status) \ - gSideStatuses[B_SIDE_OPPONENT] |= status; \ - else \ - gSideStatuses[B_SIDE_OPPONENT] &= ~(status); \ - SWAP(sideTimer0->structField, sideTimer1->structField, temp);\ -} \ +#define COURTCHANGE_SWAP(status, structField, temp) \ +{ \ + temp = gSideStatuses[B_SIDE_PLAYER]; \ + if (gSideStatuses[B_SIDE_OPPONENT] & status) \ + gSideStatuses[B_SIDE_PLAYER] |= status; \ + else \ + gSideStatuses[B_SIDE_PLAYER] &= ~(status); \ + if (temp & status) \ + gSideStatuses[B_SIDE_OPPONENT] |= status; \ + else \ + gSideStatuses[B_SIDE_OPPONENT] &= ~(status); \ + SWAP(sideTimerPlayer->structField, sideTimerOpp->structField, temp);\ +} \ #define UPDATE_COURTCHANGED_BATTLER(structField)\ { \ - sideTimer0->structField ^= BIT_SIDE; \ - sideTimer1->structField ^= BIT_SIDE; \ + sideTimerPlayer->structField ^= BIT_SIDE; \ + sideTimerOpp->structField ^= BIT_SIDE; \ } \ static bool32 CourtChangeSwapSideStatuses(void) { - struct SideTimer *sideTimer0 = &gSideTimers[B_SIDE_PLAYER]; - struct SideTimer *sideTimer1 = &gSideTimers[B_SIDE_OPPONENT]; + struct SideTimer *sideTimerPlayer = &gSideTimers[B_SIDE_PLAYER]; + struct SideTimer *sideTimerOpp = &gSideTimers[B_SIDE_OPPONENT]; u32 temp; // TODO: add Pledge-related effects @@ -7588,6 +7588,9 @@ static bool32 CourtChangeSwapSideStatuses(void) UPDATE_COURTCHANGED_BATTLER(auroraVeilBattlerId); UPDATE_COURTCHANGED_BATTLER(tailwindBattlerId); UPDATE_COURTCHANGED_BATTLER(luckyChantBattlerId); + + // Track which side originally set the Sticky Web + SWAP(sideTimerPlayer->stickyWebBattlerSide, sideTimerOpp->stickyWebBattlerSide, temp); } static void Cmd_various(void) @@ -11996,6 +11999,7 @@ static void Cmd_recoverbasedonsunlight(void) static void Cmd_setstickyweb(void) { u8 targetSide = GetBattlerSide(gBattlerTarget); + if (gSideStatuses[targetSide] & SIDE_STATUS_STICKY_WEB) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); @@ -12003,6 +12007,7 @@ static void Cmd_setstickyweb(void) else { gSideStatuses[targetSide] |= SIDE_STATUS_STICKY_WEB; + gSideTimers[targetSide].stickyWebBattlerSide = GetBattlerSide(gBattlerAttacker); // For Court Change/Defiant - set this to the user's side gSideTimers[targetSide].stickyWebAmount = 1; gBattleStruct->stickyWebUser = gBattlerAttacker; // For Mirror Armor gBattlescriptCurrInstr += 5; diff --git a/src/battle_util.c b/src/battle_util.c index 0ddff34835..7aba05fc16 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1453,6 +1453,7 @@ bool8 WasUnableToUseMove(u8 battler) void PrepareStringBattle(u16 stringId, u8 battler) { + u32 targetSide = GetBattlerSide(gBattlerTarget); // Support for Contrary ability. // If a move attempted to raise stat - print "won't increase". // If a move attempted to lower stat - print "won't decrease". @@ -1471,8 +1472,10 @@ void PrepareStringBattle(u16 stringId, u8 battler) && ((GetBattlerAbility(gBattlerTarget) == ABILITY_DEFIANT && CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)) || (GetBattlerAbility(gBattlerTarget) == ABILITY_COMPETITIVE && CompareStat(gBattlerTarget, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))) && gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != BATTLE_PARTNER(gBattlerTarget) - && gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != gBattlerTarget) + // && gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != gBattlerTarget) // Why was this here? Needs investigating + && !(gBattleScripting.stickyWebStatDrop == 1 && gSideTimers[targetSide].stickyWebBattlerSide == targetSide)) // Sticky Web must have been set by the foe { + gBattleScripting.stickyWebStatDrop = 0; gBattlerAbility = gBattlerTarget; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_DefiantActivates;