From 6d28882e444da0f774ccab67d0801d92a28ffbda Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 09:48:36 -0500 Subject: [PATCH 01/12] start gen9 hold effects --- asm/macros/battle_script.inc | 7 ++++++ data/battle_scripts_1.s | 3 +++ include/constants/hold_effects.h | 8 ++++++ src/battle_ai_util.c | 24 ++++++++++++------ src/battle_script_commands.c | 43 +++++++++++++++++++++++++------- src/battle_util.c | 14 +++++++++-- 6 files changed, 80 insertions(+), 19 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 27c5a86c4..a19c7308d 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1311,6 +1311,13 @@ .4byte \ptr .endm + .macro jumpifholdeffect battler:req, holdEffect:req, ptr:req + callnative BS_JumpIfHoldEffect + .byte \battler + .2byte \holdEffect + .4byte \ptr + .endm + @ various command changed to more readable macros .macro cancelmultiturnmoves battler:req various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6b8067721..8010d4ee7 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6996,6 +6996,7 @@ BattleScript_GulpMissileGulping:: tryfaintmon BS_ATTACKER getbattlerfainted BS_ATTACKER jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGulping + jumpifholdeffect BS_ATTACKER, HOLD_EFFECT_CLEAR_AMULET, BattleScript_GulpMissileNoSecondEffectGulping jumpifability BS_ATTACKER, ABILITY_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping @@ -8211,6 +8212,7 @@ BattleScript_IntimidateActivatesLoop: setstatchanger STAT_ATK, 1, TRUE trygetintimidatetarget BattleScript_IntimidateActivatesReturn jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateActivatesLoopIncrement + jumpifholdeffect BS_TARGET, HOLD_EFFECT_CLEAR_AMULET, BattleScript_IntimidatePrevented_Item jumpifability BS_TARGET, ABILITY_CLEAR_BODY, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_HYPER_CUTTER, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_WHITE_SMOKE, BattleScript_IntimidatePrevented @@ -8235,6 +8237,7 @@ BattleScript_IntimidateActivatesReturn: BattleScript_IntimidatePrevented: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp +BattleScript_IntimidatePrevented_Item: setbyte gBattleCommunication STAT_ATK stattextbuffer BS_ATTACKER printstring STRINGID_STATWASNOTLOWERED diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index e0361795d..cd4256632 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -152,6 +152,14 @@ #define HOLD_EFFECT_HEAVY_DUTY_BOOTS 173 #define HOLD_EFFECT_THROAT_SPRAY 174 +// Gen9 hold effects +#define HOLD_EFFECT_ABILITY_SHIELD 175 +#define HOLD_EFFECT_CLEAR_AMULET 176 +#define HOLD_EFFECT_MIRROR_HERB 177 // Not implemented. +#define HOLD_EFFECT_PUNCHING_GLOVE 178 +#define HOLD_EFFECT_COVERT_CLOAK 179 +#define HOLD_EFFECT_LOADED_DICE 180 + #define HOLD_EFFECT_CHOICE(holdEffect)((holdEffect == HOLD_EFFECT_CHOICE_BAND || holdEffect == HOLD_EFFECT_CHOICE_SCARF || holdEffect == HOLD_EFFECT_CHOICE_SPECS)) // Terrain seed params diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 35b1b3bfd..c624e02e1 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1634,7 +1634,8 @@ bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat) if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY) || (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE)) { - if (battlerAbility == ABILITY_CLEAR_BODY + if (AI_GetHoldEffect(battler) == HOLD_EFFECT_CLEAR_AMULET + || battlerAbility == ABILITY_CLEAR_BODY || battlerAbility == ABILITY_WHITE_SMOKE || battlerAbility == ABILITY_FULL_METAL_BODY) return FALSE; @@ -1711,7 +1712,8 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_HYPER_CUTTER) + && defAbility != ABILITY_HYPER_CUTTER + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } @@ -1727,7 +1729,8 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_BIG_PECKS) + && defAbility != ABILITY_BIG_PECKS + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } @@ -1741,7 +1744,8 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_WHITE_SMOKE) + && defAbility != ABILITY_WHITE_SMOKE + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } @@ -1756,7 +1760,8 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_WHITE_SMOKE) + && defAbility != ABILITY_WHITE_SMOKE + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } @@ -1771,7 +1776,8 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_WHITE_SMOKE) + && defAbility != ABILITY_WHITE_SMOKE + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } @@ -1785,7 +1791,8 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_KEEN_EYE) + && defAbility != ABILITY_KEEN_EYE + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } @@ -1799,7 +1806,8 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_FULL_METAL_BODY - && defAbility != ABILITY_WHITE_SMOKE) + && defAbility != ABILITY_WHITE_SMOKE + && AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET) return TRUE; return FALSE; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 09ef738df..6c207e8d4 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2824,13 +2824,16 @@ void SetMoveEffect(bool32 primary, u32 certain) // Just in case this flag is still set gBattleScripting.moveEffect &= ~MOVE_EFFECT_CERTAIN; - - if (battlerAbility == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && !primary && gBattleScripting.moveEffect <= 9) + + if ((battlerAbility == ABILITY_SHIELD_DUST + || GetBattlerHoldEffect(gEffectBattler, TRUE) == HOLD_EFFECT_COVERT_CLOAK) + && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && !primary + && (gBattleScripting.moveEffect <= MOVE_EFFECT_TRI_ATTACK || gBattleScripting.moveEffect >= MOVE_EFFECT_SMACK_DOWN)) // Exclude stat lowering effects INCREMENT_RESET_RETURN if (gSideStatuses[GET_BATTLER_SIDE(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && !primary && gBattleScripting.moveEffect <= 7) + && !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION) INCREMENT_RESET_RETURN if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER) @@ -5016,6 +5019,7 @@ static void Cmd_playstatchangeanimation(void) } } else if (!gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer + && GetBattlerHoldEffect(gActiveBattler, TRUE) != HOLD_EFFECT_CLEAR_AMULET && ability != ABILITY_CLEAR_BODY && ability != ABILITY_FULL_METAL_BODY && ability != ABILITY_WHITE_SMOKE @@ -8814,7 +8818,8 @@ static void Cmd_various(void) return; case VARIOUS_SET_SIMPLE_BEAM: if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) - || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) + || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE + || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } @@ -8829,7 +8834,8 @@ static void Cmd_various(void) return; case VARIOUS_TRY_ENTRAINMENT: if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) - || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)) + || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) + || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); return; @@ -10748,7 +10754,8 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr gBattlescriptCurrInstr = BattleScript_ButItFailed; return STAT_CHANGE_DIDNT_WORK; } - else if ((activeBattlerAbility == ABILITY_CLEAR_BODY + else if ((GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_CLEAR_AMULET + || activeBattlerAbility == ABILITY_CLEAR_BODY || activeBattlerAbility == ABILITY_FULL_METAL_BODY || activeBattlerAbility == ABILITY_WHITE_SMOKE) && !certain && gCurrentMove != MOVE_CURSE) @@ -13362,7 +13369,8 @@ static void Cmd_setroom(void) static void Cmd_tryswapabilities(void) { if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) - || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability)) + || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability) + || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); return; @@ -14734,7 +14742,8 @@ static void Cmd_unused(void) static void Cmd_tryworryseed(void) { - if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability) + || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); } @@ -14790,6 +14799,22 @@ void BS_CalcMetalBurstDmg(void) } } +void BS_JumpIfHoldEffect(void) +{ + u8 battler = gBattlescriptCurrInstr[5]; + u16 holdEffect = T1_READ_16(gBattlescriptCurrInstr + 6); + + if (GetBattlerHoldEffect(battler, TRUE) == holdEffect) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 8); + } + else + { + gLastUsedItem = gBattleMons[battler].item; // For B_LAST_USED_ITEM + gBattlescriptCurrInstr += 12; + } +} + static bool32 CriticalCapture(u32 odds) { #if B_CRITICAL_CAPTURE == TRUE diff --git a/src/battle_util.c b/src/battle_util.c index d8ec3f079..08c0542df 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2946,7 +2946,8 @@ u8 DoBattlerEndTurnEffects(void) { u16 battlerAbility = GetBattlerAbility(gActiveBattler); if (gDisableStructs[gActiveBattler].octolock - && !(battlerAbility == ABILITY_CLEAR_BODY + && !(GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_CLEAR_AMULET + || battlerAbility == ABILITY_CLEAR_BODY || battlerAbility == ABILITY_FULL_METAL_BODY || battlerAbility == ABILITY_WHITE_SMOKE)) { @@ -3871,6 +3872,10 @@ u8 AtkCanceller_UnableToUseMove(void) { SetRandomMultiHitCounter(); } + + if (gMultiHitCounter < 4 && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE) + gMultiHitCounter = 4; + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) } else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES) @@ -8011,7 +8016,8 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk) else return FALSE; } - else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH) + else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH + || GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_PUNCHING_GLOVE) { return FALSE; } @@ -8803,6 +8809,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe if (moveType == ItemId_GetSecondaryId(gBattleMons[battlerAtk].item)) MulModifier(&modifier, holdEffectModifier); break; + case HOLD_EFFECT_PUNCHING_GLOVE: + if (gBattleMoves[move].flags & FLAG_IRON_FIST_BOOST) + MulModifier(&modifier, UQ_4_12(1.1)); + break; } // move effect From b6258adc6dc706fa9759933f08edf085a33343be Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 10:43:01 -0500 Subject: [PATCH 02/12] fix ShouldLowerStat clear amulet check --- src/battle_ai_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index c624e02e1..a945b8f6b 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1634,7 +1634,7 @@ bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat) if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY) || (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE)) { - if (AI_GetHoldEffect(battler) == HOLD_EFFECT_CLEAR_AMULET + if (AI_DATA->holdEffects[battler] == HOLD_EFFECT_CLEAR_AMULET || battlerAbility == ABILITY_CLEAR_BODY || battlerAbility == ABILITY_WHITE_SMOKE || battlerAbility == ABILITY_FULL_METAL_BODY) From bdb480765c998a8629993d4b591475a3ed7f9755 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 10:50:33 -0500 Subject: [PATCH 03/12] add ability shield check to mummy, wandering spirit --- src/battle_util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 08c0542df..134c45ae5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5363,7 +5363,8 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED - && (IsMoveMakingContact(move, gBattlerAttacker))) + && (IsMoveMakingContact(move, gBattlerAttacker)) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_ABILITY_SHIELD) { switch (gBattleMons[gBattlerAttacker].ability) { @@ -5391,7 +5392,8 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED - && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_ABILITY_SHIELD) { switch (gBattleMons[gBattlerAttacker].ability) { From 5a26a69ccd57b24c3f92676047b011a2b8ac868f Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 11:00:57 -0500 Subject: [PATCH 04/12] add some RecordItemEffect and RecordAbilityBattle situations, ai checks --- src/battle_ai_main.c | 12 ++++-- src/battle_script_commands.c | 74 ++++++++++++++++++++++++++---------- src/battle_util.c | 16 ++++++-- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 9604f1195..58ff917fe 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2130,12 +2130,14 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) break; case EFFECT_SKILL_SWAP: if (AI_DATA->abilities[battlerAtk] == ABILITY_NONE || AI_DATA->abilities[battlerDef] == ABILITY_NONE - || IsSkillSwapBannedAbility(AI_DATA->abilities[battlerAtk]) || IsSkillSwapBannedAbility(AI_DATA->abilities[battlerDef])) + || IsSkillSwapBannedAbility(AI_DATA->abilities[battlerAtk]) || IsSkillSwapBannedAbility(AI_DATA->abilities[battlerDef]) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) score -= 10; break; case EFFECT_WORRY_SEED: if (AI_DATA->abilities[battlerDef] == ABILITY_INSOMNIA - || IsWorrySeedBannedAbility(AI_DATA->abilities[battlerDef])) + || IsWorrySeedBannedAbility(AI_DATA->abilities[battlerDef]) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) score -= 10; break; case EFFECT_GASTRO_ACID: @@ -2146,14 +2148,16 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_ENTRAINMENT: if (AI_DATA->abilities[battlerAtk] == ABILITY_NONE || IsEntrainmentBannedAbilityAttacker(AI_DATA->abilities[battlerAtk]) - || IsEntrainmentTargetOrSimpleBeamBannedAbility(AI_DATA->abilities[battlerDef])) + || IsEntrainmentTargetOrSimpleBeamBannedAbility(AI_DATA->abilities[battlerDef]) + || AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_ABILITY_SHIELD) score -= 10; break; case EFFECT_CORE_ENFORCER: break; case EFFECT_SIMPLE_BEAM: if (AI_DATA->abilities[battlerDef] == ABILITY_SIMPLE - || IsEntrainmentTargetOrSimpleBeamBannedAbility(AI_DATA->abilities[battlerDef])) + || IsEntrainmentTargetOrSimpleBeamBannedAbility(AI_DATA->abilities[battlerDef]) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) score -= 10; break; case EFFECT_SNATCH: diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6c207e8d4..c5cf75280 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2830,7 +2830,13 @@ void SetMoveEffect(bool32 primary, u32 certain) && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && !primary && (gBattleScripting.moveEffect <= MOVE_EFFECT_TRI_ATTACK || gBattleScripting.moveEffect >= MOVE_EFFECT_SMACK_DOWN)) // Exclude stat lowering effects + { + if (battlerAbility == ABILITY_SHIELD_DUST) + RecordAbilityBattle(gEffectBattler, battlerAbility) + else + RecordItemEffectBattle(gEffectBattler, HOLD_EFFECT_COVERT_CLOAK); INCREMENT_RESET_RETURN + } if (gSideStatuses[GET_BATTLER_SIDE(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION) @@ -8818,9 +8824,14 @@ static void Cmd_various(void) return; case VARIOUS_SET_SIMPLE_BEAM: if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) - || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE - || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) { + RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } else @@ -8834,21 +8845,27 @@ static void Cmd_various(void) return; case VARIOUS_TRY_ENTRAINMENT: if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) - || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) - || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)) { + RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - return; } - - if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability) + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } else { - gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gBattleMons[gBattlerAttacker].ability; - gBattlescriptCurrInstr += 7; + if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gBattleMons[gBattlerAttacker].ability; + gBattlescriptCurrInstr += 7; + } } return; case VARIOUS_SET_LAST_USED_ABILITY: @@ -10760,6 +10777,11 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr || activeBattlerAbility == ABILITY_WHITE_SMOKE) && !certain && gCurrentMove != MOVE_CURSE) { + if (GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_CLEAR_AMULET) + { + RecordItemEffectBattle(gActiveBattler, HOLD_EFFECT_CLEAR_AMULET); + } + if (flags == STAT_CHANGE_ALLOW_PTR) { if (gSpecialStatuses[gActiveBattler].statLowered) @@ -13369,24 +13391,30 @@ static void Cmd_setroom(void) static void Cmd_tryswapabilities(void) { if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) - || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability) - || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability)) { + RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - return; } - - if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); } else { - u16 abilityAtk = gBattleMons[gBattlerAttacker].ability; - gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; - gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = abilityAtk; + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + u16 abilityAtk = gBattleMons[gBattlerAttacker].ability; + gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; + gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = abilityAtk; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr += 5; + } } } @@ -14742,9 +14770,14 @@ static void Cmd_unused(void) static void Cmd_tryworryseed(void) { - if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability) - || GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability)) { + RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); } else @@ -14810,6 +14843,7 @@ void BS_JumpIfHoldEffect(void) } else { + RecordItemEffectBattle(battler, holdEffect); gLastUsedItem = gBattleMons[battler].item; // For B_LAST_USED_ITEM gBattlescriptCurrInstr += 12; } diff --git a/src/battle_util.c b/src/battle_util.c index 134c45ae5..6416c592b 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5363,8 +5363,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED - && (IsMoveMakingContact(move, gBattlerAttacker)) - && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_ABILITY_SHIELD) + && (IsMoveMakingContact(move, gBattlerAttacker))) { switch (gBattleMons[gBattlerAttacker].ability) { @@ -5380,6 +5379,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITY_STANCE_CHANGE: break; default: + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); + break; + } + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = ABILITY_MUMMY; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MummyActivates; @@ -5392,8 +5396,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED - && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) - && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_ABILITY_SHIELD) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)) { switch (gBattleMons[gBattlerAttacker].ability) { @@ -5412,6 +5415,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITY_ZEN_MODE: break; default: + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); + break; + } + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gLastUsedAbility; From c327655ef595d7d6bfe6ea756a0484009aa2b713 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 11:12:20 -0500 Subject: [PATCH 05/12] small fixes --- src/battle_script_commands.c | 5 +++-- src/battle_util.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index c5cf75280..059265588 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2832,7 +2832,7 @@ void SetMoveEffect(bool32 primary, u32 certain) && (gBattleScripting.moveEffect <= MOVE_EFFECT_TRI_ATTACK || gBattleScripting.moveEffect >= MOVE_EFFECT_SMACK_DOWN)) // Exclude stat lowering effects { if (battlerAbility == ABILITY_SHIELD_DUST) - RecordAbilityBattle(gEffectBattler, battlerAbility) + RecordAbilityBattle(gEffectBattler, battlerAbility); else RecordItemEffectBattle(gEffectBattler, HOLD_EFFECT_COVERT_CLOAK); INCREMENT_RESET_RETURN @@ -8720,7 +8720,8 @@ static void Cmd_various(void) gBattlerAbility = BATTLE_PARTNER(gActiveBattler); i = GetBattlerAbility(gBattlerAbility); if (IsBattlerAlive(gBattlerAbility) - && (i == ABILITY_RECEIVER || i == ABILITY_POWER_OF_ALCHEMY)) + && (i == ABILITY_RECEIVER || i == ABILITY_POWER_OF_ALCHEMY) + && GetBattlerHoldEffect(gActiveBattler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD) { switch (gBattleMons[gActiveBattler].ability) { // Can't copy these abilities. diff --git a/src/battle_util.c b/src/battle_util.c index 6416c592b..d3f78fd94 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5379,7 +5379,8 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITY_STANCE_CHANGE: break; default: - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } @@ -5415,7 +5416,8 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITY_ZEN_MODE: break; default: - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } From c8661a1bc1e2fb4ecbd6125697782dc5b84f2b61 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 11:24:04 -0500 Subject: [PATCH 06/12] CreateAbilityPopup always records ability --- src/battle_interface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/battle_interface.c b/src/battle_interface.c index e8bc31608..2d43db855 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3139,6 +3139,9 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) if (gBattleScripting.abilityPopupOverwrite != 0) ability = gBattleScripting.abilityPopupOverwrite; + else + RecordAbilityBattle(battlerId, ability); + if (!gBattleStruct->activeAbilityPopUps) { From 239115027440fa9c459b18d125ae1871e99f7737 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 11:25:27 -0500 Subject: [PATCH 07/12] Revert "CreateAbilityPopup always records ability" This reverts commit c8661a1bc1e2fb4ecbd6125697782dc5b84f2b61. --- src/battle_interface.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index 2d43db855..e8bc31608 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3139,9 +3139,6 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) if (gBattleScripting.abilityPopupOverwrite != 0) ability = gBattleScripting.abilityPopupOverwrite; - else - RecordAbilityBattle(battlerId, ability); - if (!gBattleStruct->activeAbilityPopUps) { From 04e9c181ad01998fca9ec335fcf9f964d00e8ba6 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 6 Dec 2022 12:42:01 -0500 Subject: [PATCH 08/12] add covert cloak check for stats --- src/battle_script_commands.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 059265588..07ccc8e1c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10853,6 +10853,12 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr } else if (activeBattlerAbility == ABILITY_SHIELD_DUST && flags == 0) { + RecordAbilityBattle(gActiveBattler, ABILITY_SHIELD_DUST); + return STAT_CHANGE_DIDNT_WORK; + } + else if (flags == 0 && GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_COVERT_CLOAK) + { + RecordItemEffectBattle(gActiveBattler, HOLD_EFFECT_COVERT_CLOAK); return STAT_CHANGE_DIDNT_WORK; } else // try to decrease From 0a9e3c8dc87757518fba216e46ff5a4484a6cce4 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 11 Dec 2022 16:16:10 -0500 Subject: [PATCH 09/12] fix stattextbuffer in BattleScript_IntimidatePrevented_Item --- data/battle_scripts_1.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 8010d4ee7..22e750eaf 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8239,7 +8239,7 @@ BattleScript_IntimidatePrevented: call BattleScript_AbilityPopUp BattleScript_IntimidatePrevented_Item: setbyte gBattleCommunication STAT_ATK - stattextbuffer BS_ATTACKER + stattextbuffer BS_TARGET printstring STRINGID_STATWASNOTLOWERED waitmessage B_WAIT_TIME_LONG call BattleScript_TryAdrenalineOrb From 125e73dd07fc1dd8ccfaea6b9608e349b20724e9 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 23 Jan 2023 09:36:17 -0500 Subject: [PATCH 10/12] loaded dice fix --- src/battle_util.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 181f3615a..8adb32b33 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3813,9 +3813,6 @@ u8 AtkCanceller_UnableToUseMove(void) SetRandomMultiHitCounter(); } - if (gMultiHitCounter < 4 && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE) - gMultiHitCounter = 4; - PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) } else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES) @@ -10886,4 +10883,10 @@ static void SetRandomMultiHitCounter() else gMultiHitCounter += 2; #endif + + if (gMultiHitCounter < 4 && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE) + { + // If roll 4 or 5 Loaded Dice doesn't do anything. Otherwise it rolls the number of hits as 5 minus a random integer from 0 to 1 inclusive. + gMultiHitCounter = 5 - Random() & 1; + } } From e93d22c0f16744295977c787a8997c0bc45f4b3f Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 23 Jan 2023 09:37:05 -0500 Subject: [PATCH 11/12] optimize IsMoveMakingContact --- src/battle_util.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 8adb32b33..4c6e5f707 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8200,6 +8200,8 @@ u32 GetBattlerHoldEffectParam(u8 battlerId) bool32 IsMoveMakingContact(u16 move, u8 battlerAtk) { + u16 atkHoldEffect = GetBattlerHoldEffect(battlerAtk, TRUE); + if (!(gBattleMoves[move].flags & FLAG_MAKES_CONTACT)) { if (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->swapDamageCategory) @@ -8207,12 +8209,11 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk) else return FALSE; } - else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH - || GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_PUNCHING_GLOVE) + else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH || atkHoldEffect == HOLD_EFFECT_PUNCHING_GLOVE) { return FALSE; } - else if (GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_PROTECTIVE_PADS) + else if (atkHoldEffect == HOLD_EFFECT_PROTECTIVE_PADS) { return FALSE; } From 8cc923ebcc5ba86fc8763eff3531fd831538b043 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 23 Jan 2023 09:42:04 -0500 Subject: [PATCH 12/12] parentheses around random & 1 --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index 4c6e5f707..23dd320c6 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10888,6 +10888,6 @@ static void SetRandomMultiHitCounter() if (gMultiHitCounter < 4 && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE) { // If roll 4 or 5 Loaded Dice doesn't do anything. Otherwise it rolls the number of hits as 5 minus a random integer from 0 to 1 inclusive. - gMultiHitCounter = 5 - Random() & 1; + gMultiHitCounter = 5 - (Random() & 1); } }