start gen9 hold effects

This commit is contained in:
ghoulslash 2022-12-06 09:48:36 -05:00
parent 3718f58a0a
commit 6d28882e44
6 changed files with 80 additions and 19 deletions

View File

@ -1311,6 +1311,13 @@
.4byte \ptr .4byte \ptr
.endm .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 @ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req .macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES

View File

@ -6996,6 +6996,7 @@ BattleScript_GulpMissileGulping::
tryfaintmon BS_ATTACKER tryfaintmon BS_ATTACKER
getbattlerfainted BS_ATTACKER getbattlerfainted BS_ATTACKER
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGulping 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_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping
jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping
jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping
@ -8211,6 +8212,7 @@ BattleScript_IntimidateActivatesLoop:
setstatchanger STAT_ATK, 1, TRUE setstatchanger STAT_ATK, 1, TRUE
trygetintimidatetarget BattleScript_IntimidateActivatesReturn trygetintimidatetarget BattleScript_IntimidateActivatesReturn
jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateActivatesLoopIncrement 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_CLEAR_BODY, BattleScript_IntimidatePrevented
jumpifability BS_TARGET, ABILITY_HYPER_CUTTER, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_HYPER_CUTTER, BattleScript_IntimidatePrevented
jumpifability BS_TARGET, ABILITY_WHITE_SMOKE, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_WHITE_SMOKE, BattleScript_IntimidatePrevented
@ -8235,6 +8237,7 @@ BattleScript_IntimidateActivatesReturn:
BattleScript_IntimidatePrevented: BattleScript_IntimidatePrevented:
pause B_WAIT_TIME_SHORT pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp
BattleScript_IntimidatePrevented_Item:
setbyte gBattleCommunication STAT_ATK setbyte gBattleCommunication STAT_ATK
stattextbuffer BS_ATTACKER stattextbuffer BS_ATTACKER
printstring STRINGID_STATWASNOTLOWERED printstring STRINGID_STATWASNOTLOWERED

View File

@ -152,6 +152,14 @@
#define HOLD_EFFECT_HEAVY_DUTY_BOOTS 173 #define HOLD_EFFECT_HEAVY_DUTY_BOOTS 173
#define HOLD_EFFECT_THROAT_SPRAY 174 #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)) #define HOLD_EFFECT_CHOICE(holdEffect)((holdEffect == HOLD_EFFECT_CHOICE_BAND || holdEffect == HOLD_EFFECT_CHOICE_SCARF || holdEffect == HOLD_EFFECT_CHOICE_SPECS))
// Terrain seed params // Terrain seed params

View File

@ -1634,7 +1634,8 @@ bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat)
if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY) if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY)
|| (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE)) || (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_WHITE_SMOKE
|| battlerAbility == ABILITY_FULL_METAL_BODY) || battlerAbility == ABILITY_FULL_METAL_BODY)
return FALSE; return FALSE;
@ -1711,7 +1712,8 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_WHITE_SMOKE
&& defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_FULL_METAL_BODY
&& defAbility != ABILITY_HYPER_CUTTER) && defAbility != ABILITY_HYPER_CUTTER
&& AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -1727,7 +1729,8 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_WHITE_SMOKE
&& defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_FULL_METAL_BODY
&& defAbility != ABILITY_BIG_PECKS) && defAbility != ABILITY_BIG_PECKS
&& AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -1741,7 +1744,8 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CONTRARY
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_FULL_METAL_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 TRUE;
return FALSE; return FALSE;
} }
@ -1756,7 +1760,8 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CONTRARY
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_FULL_METAL_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 TRUE;
return FALSE; return FALSE;
} }
@ -1771,7 +1776,8 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CONTRARY
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_FULL_METAL_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 TRUE;
return FALSE; return FALSE;
} }
@ -1785,7 +1791,8 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_WHITE_SMOKE && defAbility != ABILITY_WHITE_SMOKE
&& defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_FULL_METAL_BODY
&& defAbility != ABILITY_KEEN_EYE) && defAbility != ABILITY_KEEN_EYE
&& AI_DATA->holdEffects[battlerDef] != HOLD_EFFECT_CLEAR_AMULET)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -1799,7 +1806,8 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility)
&& defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CONTRARY
&& defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_CLEAR_BODY
&& defAbility != ABILITY_FULL_METAL_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 TRUE;
return FALSE; return FALSE;
} }

View File

@ -2824,13 +2824,16 @@ void SetMoveEffect(bool32 primary, u32 certain)
// Just in case this flag is still set // Just in case this flag is still set
gBattleScripting.moveEffect &= ~MOVE_EFFECT_CERTAIN; gBattleScripting.moveEffect &= ~MOVE_EFFECT_CERTAIN;
if (battlerAbility == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) if ((battlerAbility == ABILITY_SHIELD_DUST
&& !primary && gBattleScripting.moveEffect <= 9) || 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 INCREMENT_RESET_RETURN
if (gSideStatuses[GET_BATTLER_SIDE(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) 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 INCREMENT_RESET_RETURN
if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER) 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 else if (!gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer
&& GetBattlerHoldEffect(gActiveBattler, TRUE) != HOLD_EFFECT_CLEAR_AMULET
&& ability != ABILITY_CLEAR_BODY && ability != ABILITY_CLEAR_BODY
&& ability != ABILITY_FULL_METAL_BODY && ability != ABILITY_FULL_METAL_BODY
&& ability != ABILITY_WHITE_SMOKE && ability != ABILITY_WHITE_SMOKE
@ -8814,7 +8818,8 @@ static void Cmd_various(void)
return; return;
case VARIOUS_SET_SIMPLE_BEAM: case VARIOUS_SET_SIMPLE_BEAM:
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) 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); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
} }
@ -8829,7 +8834,8 @@ static void Cmd_various(void)
return; return;
case VARIOUS_TRY_ENTRAINMENT: case VARIOUS_TRY_ENTRAINMENT:
if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) 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); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return; return;
@ -10748,7 +10754,8 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattlescriptCurrInstr = BattleScript_ButItFailed; gBattlescriptCurrInstr = BattleScript_ButItFailed;
return STAT_CHANGE_DIDNT_WORK; 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_FULL_METAL_BODY
|| activeBattlerAbility == ABILITY_WHITE_SMOKE) || activeBattlerAbility == ABILITY_WHITE_SMOKE)
&& !certain && gCurrentMove != MOVE_CURSE) && !certain && gCurrentMove != MOVE_CURSE)
@ -13362,7 +13369,8 @@ static void Cmd_setroom(void)
static void Cmd_tryswapabilities(void) static void Cmd_tryswapabilities(void)
{ {
if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) 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); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
return; return;
@ -14734,7 +14742,8 @@ static void Cmd_unused(void)
static void Cmd_tryworryseed(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); 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) static bool32 CriticalCapture(u32 odds)
{ {
#if B_CRITICAL_CAPTURE == TRUE #if B_CRITICAL_CAPTURE == TRUE

View File

@ -2946,7 +2946,8 @@ u8 DoBattlerEndTurnEffects(void)
{ {
u16 battlerAbility = GetBattlerAbility(gActiveBattler); u16 battlerAbility = GetBattlerAbility(gActiveBattler);
if (gDisableStructs[gActiveBattler].octolock 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_FULL_METAL_BODY
|| battlerAbility == ABILITY_WHITE_SMOKE)) || battlerAbility == ABILITY_WHITE_SMOKE))
{ {
@ -3871,6 +3872,10 @@ u8 AtkCanceller_UnableToUseMove(void)
{ {
SetRandomMultiHitCounter(); SetRandomMultiHitCounter();
} }
if (gMultiHitCounter < 4 && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE)
gMultiHitCounter = 4;
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
} }
else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES) else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES)
@ -8011,7 +8016,8 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
else else
return FALSE; 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; return FALSE;
} }
@ -8803,6 +8809,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
if (moveType == ItemId_GetSecondaryId(gBattleMons[battlerAtk].item)) if (moveType == ItemId_GetSecondaryId(gBattleMons[battlerAtk].item))
MulModifier(&modifier, holdEffectModifier); MulModifier(&modifier, holdEffectModifier);
break; break;
case HOLD_EFFECT_PUNCHING_GLOVE:
if (gBattleMoves[move].flags & FLAG_IRON_FIST_BOOST)
MulModifier(&modifier, UQ_4_12(1.1));
break;
} }
// move effect // move effect