diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 258f8a331e..91b9ae523c 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -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 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2d6a0c7d7a..2d1999464b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -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:: diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index c0d47436fd..b28988bf55 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -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[]; diff --git a/include/constants/battle.h b/include/constants/battle.h index d8ade2adec..68a1c25e6f 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -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 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index e09ff706ec..2fcc0d4d58 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -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 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a97c6ee7a5..9091796fce 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -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) diff --git a/src/battle_util.c b/src/battle_util.c index dd1603e6b5..a3367e27b5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -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;