diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 0301a35179..940f301608 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 bbbb7d9b7a..42ee1b0e9c 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7171,6 +7171,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 @@ -8488,6 +8489,7 @@ BattleScript_IntimidateLoop: jumpifbyteequal gBattlerTarget, gBattlerAttacker, BattleScript_IntimidateLoopIncrement jumpiftargetally BattleScript_IntimidateLoopIncrement jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateLoopIncrement + 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 @@ -8518,6 +8520,7 @@ BattleScript_IntimidateEnd: BattleScript_IntimidatePrevented: call BattleScript_AbilityPopUp pause B_WAIT_TIME_LONG +BattleScript_IntimidatePrevented_Item: setbyte gBattleCommunication STAT_ATK stattextbuffer BS_TARGET printstring STRINGID_STATWASNOTLOWERED diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index e0361795d7..cd42566321 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_main.c b/src/battle_ai_main.c index 92866a7c2c..560457dcc1 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2142,12 +2142,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: @@ -2158,14 +2160,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_ai_util.c b/src/battle_ai_util.c index 9da8dd5ad9..531a4aa6b7 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_DATA->holdEffects[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 b45684b9b4..2e27f5fdb7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2825,13 +2825,22 @@ 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 + { + 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 <= 7) + && !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION) INCREMENT_RESET_RETURN if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER) @@ -5019,6 +5028,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 @@ -8776,7 +8786,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. @@ -8882,6 +8893,12 @@ static void Cmd_various(void) if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) || 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 @@ -8897,18 +8914,25 @@ static void Cmd_various(void) if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) || 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: @@ -10906,11 +10930,17 @@ 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) && !affectsUser && !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) @@ -10981,6 +11011,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 @@ -13530,21 +13566,28 @@ static void Cmd_tryswapabilities(void) if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) || 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; + } } } @@ -14883,6 +14926,12 @@ static void Cmd_tryworryseed(void) { 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 @@ -14937,6 +14986,23 @@ 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 + { + RecordItemEffectBattle(battler, holdEffect); + 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 b6e131e130..23dd320c66 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2882,7 +2882,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)) { @@ -3811,6 +3812,7 @@ u8 AtkCanceller_UnableToUseMove(void) { SetRandomMultiHitCounter(); } + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) } else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES) @@ -5441,6 +5443,12 @@ 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] = gBattleMons[gBattlerTarget].ability; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MummyActivates; @@ -5472,6 +5480,12 @@ 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; @@ -8186,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) @@ -8193,11 +8209,11 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk) else return FALSE; } - else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH) + 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; } @@ -9072,6 +9088,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 @@ -10864,4 +10884,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); + } }