Decouple Status set by ability from SetMoveEffect (#7125)

This commit is contained in:
Alex 2025-06-16 15:45:21 +02:00 committed by GitHub
parent 522ccf06da
commit e2f0767be5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 147 additions and 149 deletions

View File

@ -832,7 +832,7 @@
.4byte \failInstr
.endm
.macro unused_0x94
.macro setstatuswithability
.byte 0x94
.endm
@ -1338,8 +1338,9 @@
.4byte \jumpInstr
.endm
.macro setnonvolatilestatus
.macro setnonvolatilestatus trigger:req
.byte 0xfd
.byte \trigger
.endm
.macro tryworryseed failInstr:req

View File

@ -3239,7 +3239,6 @@ BattleScript_EffectBide::
ppreduce
attackanimation
waitanimation
orword gHitMarker, HITMARKER_CHARGING
setbide
goto BattleScript_MoveEnd
@ -3614,7 +3613,6 @@ BattleScript_FirstChargingTurn::
ppreduce
BattleScript_FirstChargingTurnAfterAttackString:
setsemiinvulnerablebit @ only for moves with EFFECT_SEMI_INVULNERABLE/EFFECT_SKY_DROP
orword gHitMarker, HITMARKER_CHARGING
seteffectprimary MOVE_EFFECT_CHARGING | MOVE_EFFECT_AFFECTS_USER
twoturnmoveschargestringandanimation
setadditionaleffects @ only onChargeTurnOnly effects will work here
@ -4714,7 +4712,7 @@ BattleScript_EffectNonVolatileStatus::
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
attackanimation
waitanimation
setnonvolatilestatus
setnonvolatilestatus TRIGGER_ON_MOVE
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@ -8497,9 +8495,9 @@ BattleScript_KingsShieldEffect::
return
BattleScript_BanefulBunkerEffect::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
clearmoveresultflags MOVE_RESULT_NO_EFFECT
seteffectsecondary
setnonvolatilestatus TRIGGER_ON_ATTACKER
setmoveresultflags MOVE_RESULT_MISSED
return
@ -8522,7 +8520,7 @@ BattleScript_GooeyActivates::
BattleScript_AbilityStatusEffect::
waitstate
call BattleScript_AbilityPopUp
seteffectsecondary
setnonvolatilestatus TRIGGER_ON_ABILITY
return
BattleScript_BattleBondActivatesOnMoveEndAttacker::
@ -8570,7 +8568,7 @@ BattleScript_DancerActivates::
BattleScript_SynchronizeActivates::
waitstate
call BattleScript_AbilityPopUp
seteffectprimary
setnonvolatilestatus TRIGGER_ON_ABILITY
return
BattleScript_NoItemSteal::

View File

@ -58,7 +58,6 @@ bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);
void SaveBattlerTarget(u32 battler);
void SaveBattlerAttacker(u32 battler);
bool32 CanBurnHitThaw(u16 move);
void SetNonVolatileStatusCondition(u32 target, enum MoveEffects effect);
extern void (*const gBattleScriptingCommandsTable[])(void);
extern const struct StatFractions gAccuracyStageRatios[];

View File

@ -207,7 +207,7 @@ enum BattlerId
#define STATUS4_SYRUP_BOMB (1 << 5)
#define STATUS4_GLAIVE_RUSH (1 << 6)
#define HITMARKER_UNUSED_1 (1 << 4)
#define HITMARKER_STRING_PRINTED (1 << 4)
#define HITMARKER_IGNORE_BIDE (1 << 5)
#define HITMARKER_DESTINYBOND (1 << 6)
#define HITMARKER_NO_ANIMATIONS (1 << 7) // set from battleSceneOff. Never changed during battle
@ -215,25 +215,24 @@ enum BattlerId
#define HITMARKER_NO_ATTACKSTRING (1 << 9)
#define HITMARKER_ATTACKSTRING_PRINTED (1 << 10)
#define HITMARKER_NO_PPDEDUCT (1 << 11)
#define HITMARKER_UNUSED_2 (1 << 12)
#define HITMARKER_UNUSED_12 (1 << 12)
#define HITMARKER_STATUS_ABILITY_EFFECT (1 << 13)
#define HITMARKER_SYNCHRONIZE_EFFECT (1 << 14)
#define HITMARKER_UNUSED_14 (1 << 14)
#define HITMARKER_RUN (1 << 15)
#define HITMARKER_IGNORE_DISGUISE (1 << 16)
#define HITMARKER_DISABLE_ANIMATION (1 << 17) // disable animations during battle scripts, e.g. for Bug Bite
#define HITMARKER_UNUSED_3 (1 << 18)
#define HITMARKER_UNUSED_18 (1 << 18)
#define HITMARKER_UNABLE_TO_USE_MOVE (1 << 19)
#define HITMARKER_PASSIVE_DAMAGE (1 << 20)
#define HITMARKER_UNUSED_4 (1 << 21)
#define HITMARKER_UNUSED_21 (1 << 21)
#define HITMARKER_PLAYER_FAINTED (1 << 22)
#define HITMARKER_ALLOW_NO_PP (1 << 23)
#define HITMARKER_GRUDGE (1 << 24)
#define HITMARKER_OBEYS (1 << 25)
#define HITMARKER_UNUSED_5 (1 << 26)
#define HITMARKER_CHARGING (1 << 27)
#define HITMARKER_UNUSED_26 (1 << 26)
#define HITMARKER_UNUSED_27 (1 << 27)
#define HITMARKER_FAINTED(battler) (1u << (battler + 28))
#define HITMARKER_FAINTED2(battler) HITMARKER_FAINTED(battler)
#define HITMARKER_STRING_PRINTED (1 << 29)
// Per-side statuses that affect an entire party
#define SIDE_STATUS_REFLECT (1 << 0)
@ -463,7 +462,6 @@ enum MoveEffects
NUM_MOVE_EFFECTS
};
#define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_FROSTBITE // All above move effects apply primary status
#if B_USE_FROSTBITE == TRUE
#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FROSTBITE
#else

View File

@ -301,4 +301,11 @@ enum MoveEndEffects
#define ARG_TRY_REMOVE_TERRAIN_HIT 1
#define ARG_TRY_REMOVE_TERRAIN_FAIL 2
enum StatusTrigger
{
TRIGGER_ON_MOVE,
TRIGGER_ON_ABILITY,
TRIGGER_ON_ATTACKER,
};
#endif // GUARD_CONSTANTS_BATTLE_SCRIPT_COMMANDS_H

View File

@ -3173,8 +3173,10 @@ static inline bool32 TrySetLightScreen(u32 battler)
return FALSE;
}
void SetNonVolatileStatusCondition(u32 effectBattler, enum MoveEffects effect)
static void SetNonVolatileStatusCondition(u32 effectBattler, enum MoveEffects effect, enum StatusTrigger trigger)
{
gEffectBattler = effectBattler;
if (effect == MOVE_EFFECT_SLEEP
|| effect == MOVE_EFFECT_FREEZE)
{
@ -3227,15 +3229,10 @@ void SetNonVolatileStatusCondition(u32 effectBattler, enum MoveEffects effect)
BtlController_EmitSetMonData(effectBattler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[effectBattler].status1), &gBattleMons[effectBattler].status1);
MarkBattlerForControllerExec(effectBattler);
if (gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
{
if (trigger == TRIGGER_ON_ABILITY)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUSED_BY_ABILITY;
gHitMarker &= ~HITMARKER_STATUS_ABILITY_EFFECT;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STATUSED;
}
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
@ -3244,33 +3241,22 @@ void SetNonVolatileStatusCondition(u32 effectBattler, enum MoveEffects effect)
|| effect == MOVE_EFFECT_TOXIC
|| effect == MOVE_EFFECT_PARALYSIS
|| effect == MOVE_EFFECT_BURN)
{
gBattleStruct->synchronizeMoveEffect = effect;
gHitMarker |= HITMARKER_SYNCHRONIZE_EFFECT;
}
if (effect == MOVE_EFFECT_POISON || effect == MOVE_EFFECT_TOXIC)
gBattleStruct->poisonPuppeteerConfusion = TRUE;
}
#define INCREMENT_RESET_RETURN \
{ \
gBattlescriptCurrInstr++; \
gBattleScripting.moveEffect = 0; \
return; \
}
void SetMoveEffect(bool32 primary, bool32 certain)
{
s32 i, affectsUser = 0;
bool32 statusChanged = FALSE;
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
u32 flags = 0;
u32 battlerAbility;
bool32 activateAfterFaint = FALSE;
// NULL move effect
if (gBattleScripting.moveEffect == 0)
if (gBattleScripting.moveEffect == MOVE_EFFECT_NONE)
return;
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT
@ -3313,53 +3299,45 @@ void SetMoveEffect(bool32 primary, bool32 certain)
if (!primary && affectsUser != MOVE_EFFECT_AFFECTS_USER
&& !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
&& IsMoveEffectBlockedByTarget(battlerAbility))
INCREMENT_RESET_RETURN
if (gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
&& !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION)
INCREMENT_RESET_RETURN
if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& !(GetMoveEffect(gCurrentMove) == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker])
&& !primary
&& gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
INCREMENT_RESET_RETURN
if (!IsBattlerAlive(gEffectBattler) && !activateAfterFaint)
INCREMENT_RESET_RETURN
if (DoesSubstituteBlockMove(gBattlerAttacker, gEffectBattler, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER)
INCREMENT_RESET_RETURN
if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) // status change
{
if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)) // Calcs already done
{
statusChanged = CanSetNonVolatileStatus(gBattlerAttacker,
gEffectBattler,
GetBattlerAbility(gBattlerAttacker),
battlerAbility,
gBattleScripting.moveEffect,
STATUS_CHECK_TRIGGER);
}
if (statusChanged || gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
{
SetNonVolatileStatusCondition(gEffectBattler, gBattleScripting.moveEffect);
}
else
{
gBattleScripting.moveEffect = 0;
gBattlescriptCurrInstr++;
}
return;
}
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
else if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& !(GetMoveEffect(gCurrentMove) == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker])
&& !primary
&& gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
else if (!IsBattlerAlive(gEffectBattler) && !activateAfterFaint)
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
else if (DoesSubstituteBlockMove(gBattlerAttacker, gEffectBattler, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER)
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
switch (gBattleScripting.moveEffect)
{
case MOVE_EFFECT_NONE:
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_SLEEP:
case MOVE_EFFECT_POISON:
case MOVE_EFFECT_BURN:
case MOVE_EFFECT_FREEZE:
case MOVE_EFFECT_PARALYSIS:
case MOVE_EFFECT_TOXIC:
case MOVE_EFFECT_FROSTBITE:
if (gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) && !primary)
gBattlescriptCurrInstr++;
else if (CanSetNonVolatileStatus(
gBattlerAttacker,
gEffectBattler,
GetBattlerAbility(gBattlerAttacker),
battlerAbility,
gBattleScripting.moveEffect,
STATUS_CHECK_TRIGGER))
SetNonVolatileStatusCondition(gEffectBattler, gBattleScripting.moveEffect, TRIGGER_ON_MOVE);
break;
case MOVE_EFFECT_CONFUSION:
if (!CanBeConfused(gEffectBattler) || gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION)
if (!CanBeConfused(gEffectBattler)
|| gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION
|| (gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) && !primary))
{
gBattlescriptCurrInstr++;
}
@ -5387,11 +5365,11 @@ static void Cmd_checkteamslost(void)
static void MoveValuesCleanUp(void)
{
gBattleScripting.moveEffect = 0;
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
gBattleCommunication[MISS_TYPE] = 0;
if (!gMultiHitCounter)
gHitMarker &= ~HITMARKER_DESTINYBOND;
gHitMarker &= ~HITMARKER_SYNCHRONIZE_EFFECT;
}
static void Cmd_movevaluescleanup(void)
@ -6385,7 +6363,7 @@ static void Cmd_moveend(void)
if (!IsProtectivePadsProtected(gBattlerAttacker, GetBattlerHoldEffect(gBattlerAttacker, TRUE)))
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
gBattleScripting.moveEffect = MOVE_EFFECT_POISON | MOVE_EFFECT_AFFECTS_USER;
gBattleScripting.moveEffect = MOVE_EFFECT_POISON;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_BANEFUL_BUNKER);
BattleScriptCall(BattleScript_BanefulBunkerEffect);
effect = 1;
@ -6394,8 +6372,9 @@ static void Cmd_moveend(void)
case PROTECT_BURNING_BULWARK:
if (!IsProtectivePadsProtected(gBattlerAttacker, GetBattlerHoldEffect(gBattlerAttacker, TRUE)))
{
gEffectBattler =
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
gBattleScripting.moveEffect = MOVE_EFFECT_BURN | MOVE_EFFECT_AFFECTS_USER;
gBattleScripting.moveEffect = MOVE_EFFECT_BURN;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_BURNING_BULWARK);
BattleScriptCall(BattleScript_BanefulBunkerEffect);
effect = 1;
@ -7412,7 +7391,7 @@ static void Cmd_moveend(void)
gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE;
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE;
gBattleScripting.moveEffect = 0;
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
gBattleStruct->isAtkCancelerForCalledMove = FALSE;
gBattleStruct->swapDamageCategory = FALSE;
gBattleStruct->categoryOverride = FALSE;
@ -16484,9 +16463,23 @@ static void Cmd_jumpifcaptivateaffected(void)
static void Cmd_setnonvolatilestatus(void)
{
CMD_ARGS();
gEffectBattler = gBattlerTarget;
SetNonVolatileStatusCondition(gBattlerTarget, GetMoveNonVolatileStatus(gCurrentMove));
CMD_ARGS(u8 trigger);
switch (cmd->trigger)
{
case TRIGGER_ON_ABILITY:
if (gBattleScripting.moveEffect == MOVE_EFFECT_CONFUSION)
SetMoveEffect(FALSE, FALSE);
else
SetNonVolatileStatusCondition(gEffectBattler, gBattleScripting.moveEffect, TRIGGER_ON_ABILITY);
break;
case TRIGGER_ON_MOVE:
SetNonVolatileStatusCondition(gBattlerTarget, GetMoveNonVolatileStatus(gCurrentMove), TRIGGER_ON_MOVE);
break;
case TRIGGER_ON_ATTACKER:
SetNonVolatileStatusCondition(gBattlerAttacker, gBattleScripting.moveEffect, TRIGGER_ON_ATTACKER);
break;
}
}
static void Cmd_tryworryseed(void)

View File

@ -872,9 +872,10 @@ void HandleAction_NothingIsFainted(void)
{
gCurrentTurnActionNumber++;
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
| HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
| HITMARKER_OBEYS | HITMARKER_SYNCHRONIZE_EFFECT | HITMARKER_CHARGING);
| HITMARKER_OBEYS);
}
void HandleAction_ActionFinished(void)
@ -887,8 +888,7 @@ void HandleAction_ActionFinished(void)
SpecialStatusesClear();
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
| HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
| HITMARKER_OBEYS | HITMARKER_SYNCHRONIZE_EFFECT
| HITMARKER_CHARGING | HITMARKER_IGNORE_DISGUISE);
| HITMARKER_OBEYS | HITMARKER_IGNORE_DISGUISE);
ClearDamageCalcResults();
gCurrentMove = 0;
@ -902,6 +902,7 @@ void HandleAction_ActionFinished(void)
gBattleCommunication[4] = 0;
gBattleScripting.multihitMoveEffect = 0;
gBattleResources->battleScriptsStack->size = 0;
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !IsPursuitTargetSet())
{
@ -2284,7 +2285,7 @@ static void CancellerWeatherPrimal(u32 *effect)
}
if (*effect == 1)
{
gBattleScripting.moveEffect = 0;
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
gProtectStructs[gBattlerAttacker].chargingTurn = FALSE;
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -4650,10 +4651,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
{
if (IsSleepClauseEnabled())
gBattleStruct->battlerState[gBattlerAttacker].sleepClauseEffectExempt = TRUE;
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_SLEEP;
gEffectBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerTarget;
gBattleScripting.moveEffect = MOVE_EFFECT_SLEEP;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
}
@ -4671,10 +4673,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_POISON;
gEffectBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerTarget;
gBattleScripting.moveEffect = MOVE_EFFECT_POISON;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
}
@ -4691,10 +4694,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_PARALYSIS;
gEffectBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerTarget;
gBattleScripting.moveEffect = MOVE_EFFECT_PARALYSIS;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
}
@ -4709,10 +4713,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& CanBeBurned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_FLAME_BODY, 30) : RandomChance(RNG_FLAME_BODY, 1, 3)))
{
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN;
gEffectBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerTarget;
gBattleScripting.moveEffect = MOVE_EFFECT_BURN;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
break;
@ -4914,10 +4919,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
&& RandomPercentage(RNG_POISON_TOUCH, 30))
{
gEffectBattler = gBattlerTarget;
gBattleScripting.battler = gBattlerAttacker;
gBattleScripting.moveEffect = MOVE_EFFECT_POISON;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
break;
@ -4929,10 +4935,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
&& RandomWeighted(RNG_TOXIC_CHAIN, 7, 3))
{
gEffectBattler = gBattlerTarget;
gBattleScripting.battler = gBattlerAttacker;
gBattleScripting.moveEffect = MOVE_EFFECT_TOXIC;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
break;
@ -4969,6 +4976,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
gBattleScripting.moveEffect = MOVE_EFFECT_CONFUSION;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptCall(BattleScript_AbilityStatusEffect);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
break;
@ -5118,69 +5126,63 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITYEFFECT_SYNCHRONIZE:
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONIZE_EFFECT))
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && gBattleStruct->synchronizeMoveEffect != MOVE_EFFECT_NONE)
{
gHitMarker &= ~HITMARKER_SYNCHRONIZE_EFFECT;
bool32 statusChanged = CanSetNonVolatileStatus(gBattlerTarget,
gBattlerAttacker,
gLastUsedAbility,
GetBattlerAbility(gBattlerAttacker),
gBattleStruct->synchronizeMoveEffect,
STATUS_CHECK_TRIGGER);
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
RecordAbilityBattle(gBattlerTarget, ABILITY_SYNCHRONIZE);
if (statusChanged)
if (CanSetNonVolatileStatus(
gBattlerTarget,
gBattlerAttacker,
gLastUsedAbility,
GetBattlerAbility(gBattlerAttacker),
gBattleStruct->synchronizeMoveEffect,
STATUS_CHECK_TRIGGER))
{
gBattleStruct->synchronizeMoveEffect &= ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
if (B_SYNCHRONIZE_TOXIC < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
gBattleScripting.moveEffect = gBattleStruct->synchronizeMoveEffect + MOVE_EFFECT_AFFECTS_USER;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, ABILITY_SYNCHRONIZE);
BattleScriptCall(BattleScript_SynchronizeActivates);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
else // Synchronize ability pop up still shows up even if status fails
{
BattleScriptCall(BattleScript_AbilityPopUp);
}
}
break;
case ABILITYEFFECT_ATK_SYNCHRONIZE:
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONIZE_EFFECT))
{
gHitMarker &= ~HITMARKER_SYNCHRONIZE_EFFECT;
bool32 statusChanged = CanSetNonVolatileStatus(gBattlerAttacker,
gBattlerTarget,
gLastUsedAbility,
GetBattlerAbility(gBattlerAttacker),
gBattleStruct->synchronizeMoveEffect,
STATUS_CHECK_TRIGGER);
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
RecordAbilityBattle(gBattlerAttacker, ABILITY_SYNCHRONIZE);
if (statusChanged)
{
gBattleStruct->synchronizeMoveEffect &= ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
if (gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
gEffectBattler = gBattlerAttacker;
gBattleScripting.moveEffect = gBattleStruct->synchronizeMoveEffect;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, ABILITY_SYNCHRONIZE);
BattleScriptCall(BattleScript_SynchronizeActivates);
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
effect++;
}
else // Synchronize ability pop up still shows up even if status fails
{
BattleScriptCall(BattleScript_AbilityPopUp);
}
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
}
break;
case ABILITYEFFECT_ATK_SYNCHRONIZE:
if (gLastUsedAbility == ABILITY_SYNCHRONIZE && gBattleStruct->synchronizeMoveEffect != MOVE_EFFECT_NONE)
{
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
RecordAbilityBattle(gBattlerAttacker, ABILITY_SYNCHRONIZE);
if (CanSetNonVolatileStatus(
gBattlerAttacker,
gBattlerTarget,
gLastUsedAbility,
GetBattlerAbility(gBattlerAttacker),
gBattleStruct->synchronizeMoveEffect,
STATUS_CHECK_TRIGGER))
{
if (gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC)
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON;
gEffectBattler = gBattlerTarget;
gBattleScripting.moveEffect = gBattleStruct->synchronizeMoveEffect;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, ABILITY_SYNCHRONIZE);
BattleScriptCall(BattleScript_SynchronizeActivates);
effect++;
}
else // Synchronize ability pop up still shows up even if status fails
{
BattleScriptCall(BattleScript_AbilityPopUp);
}
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
}
break;