From cb0d503f66b2d53fb7e173b0ba291af3caa3544d Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 19 Oct 2025 16:40:13 +0200 Subject: [PATCH] Decouple passive hp updates from move damage updates (#7942) --- asm/macros/battle_script.inc | 13 +- data/battle_scripts_1.s | 337 +++++------ data/battle_scripts_2.s | 5 +- include/battle.h | 22 +- include/battle_util.h | 1 + include/constants/battle.h | 5 +- include/constants/battle_script_commands.h | 6 + src/battle_ai_util.c | 4 +- src/battle_end_turn.c | 100 ++-- src/battle_hold_effects.c | 74 +-- src/battle_main.c | 2 - src/battle_script_commands.c | 615 ++++++++++----------- src/battle_util.c | 60 +- src/battle_z_move.c | 2 +- 14 files changed, 550 insertions(+), 696 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index c0f5bd4db5..9170ffc85d 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -45,14 +45,16 @@ .byte 0xa .endm - .macro healthbarupdate battler:req + .macro healthbarupdate battler:req updateState:req .byte 0xb .byte \battler + .byte \updateState .endm - .macro datahpupdate battler:req + .macro datahpupdate battler:req updateState:req .byte 0xc .byte \battler + .byte \updateState .endm .macro critmessage @@ -358,9 +360,8 @@ .byte 0x3a .endm - .macro absorbhealthbarupdate battler:req + .macro isdmgblockedbydisguise .byte 0x3b - .byte \battler .endm .macro return @@ -759,7 +760,7 @@ callnative BS_RemoveStockpileCounters .endm - .macro setdrainedhp + .macro unused_0x88 .byte 0x88 .endm @@ -1293,7 +1294,7 @@ .byte 0xf3 .endm - .macro subattackerhpbydmg + .macro unused_0xf4 .byte 0xf4 .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index b5dadafa0a..94ad23d029 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -136,11 +136,10 @@ BattleScript_EffectShedTail:: jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_ButItFailed setsubstitute jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SUBSTITUTE_FAILED, BattleScript_SubstituteString - orword gHitMarker, HITMARKER_PASSIVE_HP_UPDATE attackanimation waitanimation - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_SHEDITSTAIL waitmessage B_WAIT_TIME_LONG moveendto MOVEEND_ATTACKER_VISIBLE @@ -159,7 +158,6 @@ BattleScript_EffectFilletAway:: jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MAX_STAT_STAGE, BattleScript_ButItFailed BattleScript_FilletAwayTryAttack:: halvehp BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE attackanimation waitanimation setstatchanger STAT_ATK, 2, FALSE @@ -178,8 +176,8 @@ BattleScript_FilletAwayTrySpeed:: waitmessage B_WAIT_TIME_LONG BattleScript_FilletAwayEnd:: clearmoveresultflags MOVE_RESULT_NO_EFFECT - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE goto BattleScript_MoveEnd BattleScript_EffectDoodle:: @@ -381,20 +379,13 @@ BattleScript_MoveEffectSaltCure:: BattleScript_SaltCureExtraDamage:: playanimation BS_ATTACKER, B_ANIM_SALT_CURE_DAMAGE, NULL waitanimation - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_TARGETISHURTBYSALTCURE waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER end2 -BattleScript_HurtTarget_NoString: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET - return - BattleScript_EffectCorrosiveGas:: attackcanceler accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE @@ -508,10 +499,8 @@ BattleScript_TeatimeLoop: jumpifelectricabilityaffected BS_TARGET, ABILITY_VOLT_ABSORB, BattleScript_Teatimesorb jumpifelectricabilityaffected BS_TARGET, ABILITY_MOTOR_DRIVE, BattleScript_Teatimemotor jumpifteainvulnerable BS_TARGET, BattleScript_Teatimevul @ in semi-invulnerable state OR held item is not a Berry - orword gHitMarker, HITMARKER_DISABLE_ANIMATION | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries consumeberry BS_TARGET, TRUE @ consume the berry, then restore the item from changedItems - bicword gHitMarker, HITMARKER_DISABLE_ANIMATION | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE setbyte sBERRY_OVERRIDE, FALSE removeitem BS_TARGET moveendto MOVEEND_NEXT_TARGET @@ -526,8 +515,8 @@ BattleScript_Teatimevul: BattleScript_Teatimesorb: call BattleScript_AbilityPopUpTarget tryhealquarterhealth BS_TARGET, BattleScript_Teatimesorb_end - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG BattleScript_Teatimesorb_end: @@ -701,8 +690,8 @@ BattleScript_EffectFling:: effectivenesssound hitanimation BS_TARGET waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE + datahpupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE critmessage waitmessage B_WAIT_TIME_MED resultmessage @@ -780,11 +769,10 @@ BattleScript_FlingMissed: BattleScript_EffectClangorousSoul:: attackcanceler cutonethirdhpandraisestats BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_BIDE | HITMARKER_PASSIVE_HP_UPDATE attackanimation waitanimation - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE call BattleScript_AllStatsUp goto BattleScript_MoveEnd @@ -972,9 +960,8 @@ BattleScript_EffectJungleHealing:: JungleHealing_RestoreTargetHealth: copybyte gBattlerAttacker, gBattlerTarget tryhealquarterhealth BS_TARGET, BattleScript_JungleHealing_TryCureStatus - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG BattleScript_JungleHealing_TryCureStatus: @@ -1015,10 +1002,9 @@ BattleScript_EffectLifeDewCheckPartner: setallytonexttarget BattleScript_EffectLifeDewNextTarget BattleScript_EffectLifeDewHealing: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE tryhealquarterhealth BS_TARGET, BattleScript_EffectLifeDewEnd - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG return @@ -1108,10 +1094,9 @@ BattleScript_StrengthSapHp: jumpiffullhp BS_ATTACKER, BattleScript_MoveEnd BattleScript_StrengthSapManipulateDmg: manipulatedamage DMG_BIG_ROOT - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_StrengthSapLiquidOoze - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_PKMNENERGYDRAINED waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -1119,8 +1104,8 @@ BattleScript_StrengthSapLiquidOoze: call BattleScript_AbilityPopUpTarget manipulatedamage DMG_CHANGE_SIGN setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB_OOZE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printfromtable gAbsorbDrainStringIds waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -1477,9 +1462,8 @@ BattleScript_EffectAfterYou:: BattleScript_MoveEffectFlameBurst:: printstring STRINGID_BURSTINGFLAMESHIT waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE tryfaintmon BS_SCRIPTING return @@ -1612,8 +1596,8 @@ BattleScript_AutotomizeWeightLoss:: BattleScript_FinalGambit:: setatkhptozero - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER return @@ -2024,8 +2008,8 @@ BattleScript_EffectHealPulse:: tryhealpulse BattleScript_AlreadyAtFullHp attackanimation waitanimation - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -2125,8 +2109,8 @@ BattleScript_EffectHealingWishRestore: waitanimation dmgtomaxattackerhp manipulatedamage DMG_CHANGE_SIGN - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE clearstatus waitstate updatestatusicon BS_ATTACKER @@ -2479,8 +2463,8 @@ BattleScript_Hit_RetFromAtkAnimation:: effectivenesssound hitanimation BS_TARGET waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE + datahpupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE critmessage waitmessage B_WAIT_TIME_LONG resultmessage @@ -2610,12 +2594,11 @@ BattleScript_EffectAbsorbLiquidOoze:: goto BattleScript_EffectAbsorb BattleScript_EffectAbsorb:: - absorbhealthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printfromtable gAbsorbDrainStringIds waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER - bicword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE | HITMARKER_PASSIVE_HP_UPDATE return BattleScript_EffectExplosion:: @@ -2632,9 +2615,8 @@ BattleScript_FaintAttackerForExplosion:: return BattleScript_MaxHp50Recoil:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER return @@ -2841,9 +2823,8 @@ BattleScript_EffectRestoreHp:: attackanimation waitanimation BattleScript_RestoreHp: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -2918,9 +2899,8 @@ BattleScript_RecoilIfMiss:: printstring STRINGID_PKMNCRASHED waitmessage B_WAIT_TIME_LONG jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_RecoilEnd - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER return @@ -3158,11 +3138,10 @@ BattleScript_EffectSubstitute:: jumpifvolatile BS_ATTACKER, VOLATILE_SUBSTITUTE, BattleScript_AlreadyHasSubstitute setsubstitute jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SUBSTITUTE_FAILED, BattleScript_SubstituteString - orword gHitMarker, HITMARKER_PASSIVE_HP_UPDATE attackanimation waitanimation - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE BattleScript_SubstituteString:: pause B_WAIT_TIME_SHORT printfromtable gSubstituteUsedStringIds @@ -3282,11 +3261,10 @@ BattleScript_EffectPainSplit:: painsplitdmgcalc BattleScript_ButItFailed attackanimation waitanimation - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_SHAREDPAIN waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -3462,12 +3440,11 @@ BattleScript_DoGhostCurse:: attackcanceler accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON cursetarget BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE setbyte sB_ANIM_TURN, 0 attackanimation waitanimation - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_PKMNLAIDCURSE waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -3758,11 +3735,10 @@ BattleScript_EffectBellyDrum:: attackcanceler jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed halvehp BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE attackanimation waitanimation - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE setstatchanger STAT_ATK, MAX_STAT_STAGE, FALSE statbuffchange BS_ATTACKER, STAT_CHANGE_ALLOW_PTR, BattleScript_MoveEnd printstring STRINGID_PKMNCUTHPMAXEDATTACK @@ -3834,8 +3810,8 @@ BattleScript_BeatUpAttack:: effectivenesssound hitanimation BS_TARGET waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE + datahpupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE critmessage waitmessage B_WAIT_TIME_LONG resultmessage @@ -3863,9 +3839,8 @@ BattleScript_EffectSoftboiled:: BattleScript_PresentHealTarget:: attackanimation waitanimation - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -3974,9 +3949,8 @@ BattleScript_EffectSwallow:: stockpiletohpheal BattleScript_ButItFailed attackanimation waitanimation - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG removestockpilecounters @@ -4216,8 +4190,8 @@ BattleScript_BrickBreakDoHit:: effectivenesssound hitanimation BS_TARGET waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE + datahpupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE critmessage waitmessage B_WAIT_TIME_LONG resultmessage @@ -4903,8 +4877,8 @@ BattleScript_FogEnded_Ret:: BattleScript_IceBodyHeal:: call BattleScript_AbilityPopUp playanimation BS_ATTACKER, B_ANIM_SIMPLE_HEAL - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_ICEBODYHPGAIN waitmessage B_WAIT_TIME_LONG end2 @@ -5031,9 +5005,8 @@ BattleScript_LeechSeedTurnDrainHealBlock:: BattleScript_LeechSeedTurnDrainRecovery:: call BattleScript_LeechSeedTurnDrain BattleScript_LeechSeedTurnDrainGainHp: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printfromtable gLeechSeedStringIds waitmessage B_WAIT_TIME_LONG tryfaintmon BS_TARGET @@ -5041,8 +5014,8 @@ BattleScript_LeechSeedTurnDrainGainHp: BattleScript_LeechSeedTurnDrain: playanimation BS_ATTACKER, B_ANIM_LEECH_SEED_DRAIN, sB_ANIM_ARG1 - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER return @@ -5067,8 +5040,8 @@ BattleScript_BideAttack:: effectivenesssound hitanimation BS_TARGET waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE + datahpupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE resultmessage waitmessage B_WAIT_TIME_LONG tryfaintmon BS_TARGET @@ -5216,16 +5189,14 @@ BattleScript_EncoredNoMore:: BattleScript_DestinyBondTakesLife:: printstring STRINGID_PKMNTOOKFOE waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER return BattleScript_DmgHazardsOnAttacker:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE call BattleScript_PrintHurtByDmgHazards tryfaintmon BS_ATTACKER tryfaintmon_spikes BS_ATTACKER, BattleScript_DmgHazardsOnAttackerFainted @@ -5238,9 +5209,8 @@ BattleScript_DmgHazardsOnAttackerFainted:: goto BattleScript_HandleFaintedMon BattleScript_DmgHazardsOnTarget:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE call BattleScript_PrintHurtByDmgHazards tryfaintmon BS_TARGET tryfaintmon_spikes BS_TARGET, BattleScript_DmgHazardsOnTargetFainted @@ -5253,9 +5223,8 @@ BattleScript_DmgHazardsOnTargetFainted:: goto BattleScript_HandleFaintedMon BattleScript_DmgHazardsOnBattlerScripting:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE call BattleScript_PrintHurtByDmgHazards tryfaintmon BS_SCRIPTING tryfaintmon_spikes BS_SCRIPTING, BattleScript_DmgHazardsOnBattlerScriptingFainted @@ -5268,9 +5237,8 @@ BattleScript_DmgHazardsOnBattlerScriptingFainted:: goto BattleScript_HandleFaintedMon BattleScript_DmgHazardsOnFaintedBattler:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_FAINTED - datahpupdate BS_FAINTED + healthbarupdate BS_FAINTED, PASSIVE_HP_UPDATE + datahpupdate BS_FAINTED, PASSIVE_HP_UPDATE call BattleScript_PrintHurtByDmgHazards tryfaintmon BS_FAINTED tryfaintmon_spikes BS_FAINTED, BattleScript_DmgHazardsOnFaintedBattlerFainted @@ -5329,9 +5297,8 @@ BattleScript_StickyWebOnSwitchInEnd: BattleScript_PerishSongTakesLife:: printstring STRINGID_PKMNPERISHCOUNTFELL waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER end2 @@ -5339,20 +5306,18 @@ BattleScript_PerishBodyActivates:: call BattleScript_AbilityPopUp printstring STRINGID_PKMNSWILLPERISHIN3TURNS waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE return BattleScript_GulpMissileGorging:: call BattleScript_AbilityPopUp playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE waitanimation - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE effectivenesssound hitanimation BS_ATTACKER waitstate jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGorging - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER jumpiffainted BS_ATTACKER, TRUE, BattleScript_GulpMissileNoSecondEffectGorging BattleScript_GulpMissileNoDmgGorging: @@ -5373,13 +5338,12 @@ BattleScript_GulpMissileGulping:: call BattleScript_AbilityPopUp playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE waitanimation - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE effectivenesssound hitanimation BS_ATTACKER waitstate jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGulping - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER jumpiffainted BS_ATTACKER, TRUE, BattleScript_GulpMissileNoSecondEffectGulping BattleScript_GulpMissileNoDmgGulping: @@ -5462,9 +5426,8 @@ BattleScript_EarthEaterActivates:: call BattleScript_AbilityPopUp pause B_WAIT_TIME_LONG tryhealquarterhealth BS_TARGET, BattleScript_EarthEaterRet - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG BattleScript_EarthEaterRet: @@ -5559,8 +5522,8 @@ BattleScript_DoFutureAttackHit:: effectivenesssound hitanimation BS_TARGET waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE + datahpupdate BS_TARGET, MOVE_DAMAGE_HP_UPDATE critmessage waitmessage B_WAIT_TIME_LONG BattleScript_DoFutureAttackResult: @@ -5707,9 +5670,8 @@ BattleScript_WishComesTrue:: playanimation BS_TARGET, B_ANIM_WISH_HEAL printstring STRINGID_PKMNWISHCAMETRUE waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG end2 @@ -5735,9 +5697,8 @@ BattleScript_IngrainTurnHeal:: printstring STRINGID_PKMNABSORBEDNUTRIENTS BattleScript_TurnHeal: waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE end2 BattleScript_AquaRingHeal:: @@ -6019,9 +5980,8 @@ BattleScript_CudChewActivates:: BattleScript_ApplyDisguiseFormChangeHPLoss:: jumpifgenconfiglowerthan GEN_CONFIG_DISGUISE_HP_LOSS, GEN_8, BattleScript_ApplyDisguiseFormChangeHPLossReturn - orword gHitMarker, HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE BattleScript_ApplyDisguiseFormChangeHPLossReturn: return @@ -6110,9 +6070,8 @@ BattleScript_AftermathDmg:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUpScripting jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_AftermathDmgRet - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_AFTERMATHDMG waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -6153,9 +6112,8 @@ BattleScript_PoisonTurnDmg:: BattleScript_DoStatusTurnDmg:: statusanimation BS_ATTACKER BattleScript_DoTurnDmg: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE tryfaintmon BS_ATTACKER checkteamslost BattleScript_DoTurnDmgEnd tryactivateitem BS_ATTACKER, ON_ITEM_HP_THRESHOLD @@ -6168,9 +6126,8 @@ BattleScript_PoisonHealActivates:: printstring STRINGID_POISONHEALHPUP waitmessage B_WAIT_TIME_LONG statusanimation BS_ATTACKER - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE end2 BattleScript_BurnTurnDmg:: @@ -6279,9 +6236,9 @@ BattleScript_DoSelfConfusionDmg:: effectivenesssound hitanimation BS_ATTACKER waitstate - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + isdmgblockedbydisguise + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE resultmessage waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -6297,9 +6254,8 @@ BattleScript_MoveUsedPowder:: effectivenesssound hitanimation BS_ATTACKER waitstate - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_POWDEREXPLODES waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -6487,9 +6443,8 @@ BattleScript_MoveEffectRecoil:: jumpifability BS_ATTACKER, ABILITY_ROCK_HEAD, BattleScript_RecoilEnd jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_RecoilEnd BattleScript_DoRecoil:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_PKMNHITWITHRECOIL waitmessage B_WAIT_TIME_LONG tryupdaterecoiltracker @@ -6668,9 +6623,8 @@ BattleScript_AbilityHpHeal: call BattleScript_AbilityPopUp printstring STRINGID_PKMNSXRESTOREDHPALITTLE2 waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE return BattleScript_RainDishActivates:: @@ -6705,10 +6659,9 @@ BattleScript_HarvestActivatesEnd: end2 BattleScript_SolarPowerActivates:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE call BattleScript_AbilityPopUp - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_SOLARPOWERHPDROP waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -6992,10 +6945,9 @@ BattleScript_HospitalityActivates:: call BattleScript_AbilityPopUp printstring STRINGID_HOSPITALITYRESTORATION waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE playanimation BS_EFFECT_BATTLER, B_ANIM_SIMPLE_HEAL - healthbarupdate BS_EFFECT_BATTLER - datahpupdate BS_EFFECT_BATTLER + healthbarupdate BS_EFFECT_BATTLER, PASSIVE_HP_UPDATE + datahpupdate BS_EFFECT_BATTLER, PASSIVE_HP_UPDATE end3 BattleScript_AttackWeakenedByStrongWinds:: @@ -7097,9 +7049,8 @@ BattleScript_BadDreams_DmgAfterPopUp: printstring STRINGID_BADDREAMSDMG waitmessage B_WAIT_TIME_LONG dmg_1_8_targethp - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE jumpifhasnohp BS_TARGET, BattleScript_BadDreams_HidePopUp BattleScript_BadDreamsIncrement: addbyte gBattlerTarget, 1 @@ -7144,9 +7095,8 @@ BattleScript_DampStopsExplosion:: BattleScript_MoveHPDrain:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNRESTOREDHPUSING waitmessage B_WAIT_TIME_LONG setmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE @@ -7257,10 +7207,8 @@ BattleScript_MoveUsedPsychicTerrainPrevents:: BattleScript_GrassyTerrainHeals:: printstring STRINGID_GRASSYTERRAINHEALS waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER - bicword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE end2 BattleScript_AbilityNoSpecificStatLoss:: @@ -7505,9 +7453,8 @@ BattleScript_ImposterActivates:: end3 BattleScript_HurtAttacker: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_PKMNHURTSWITH waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -7529,10 +7476,9 @@ BattleScript_RockyHelmetActivatesDmg: BattleScript_SpikyShieldEffect:: jumpifabsent BS_ATTACKER, BattleScript_SpikyShieldRet - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE clearmoveresultflags MOVE_RESULT_NO_EFFECT - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_PKMNHURTSWITH waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -7541,7 +7487,6 @@ BattleScript_SpikyShieldRet:: return BattleScript_KingsShieldEffect:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE clearmoveresultflags MOVE_RESULT_NO_EFFECT seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_NONE copybyte sBATTLER, gBattlerTarget @@ -7551,7 +7496,6 @@ BattleScript_KingsShieldEffect:: return BattleScript_BanefulBunkerEffect:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE clearmoveresultflags MOVE_RESULT_NO_EFFECT setnonvolatilestatus TRIGGER_ON_PROTECT setmoveresultflags MOVE_RESULT_MISSED @@ -7775,9 +7719,8 @@ BattleScript_ItemHealHP_RemoveItemRet_Anim: playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE removeitem BS_SCRIPTING return @@ -7790,9 +7733,8 @@ BattleScript_ItemHealHP_RemoveItemEnd2_Anim: playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE removeitem BS_ATTACKER end2 @@ -7833,9 +7775,8 @@ BattleScript_AirBaloonMsgPop:: return BattleScript_ItemHurtRet:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE printstring STRINGID_HURTBYITEM waitmessage B_WAIT_TIME_LONG tryfaintmon BS_ATTACKER @@ -7851,9 +7792,8 @@ BattleScript_ItemHealHP_Ret:: playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT printstring STRINGID_PKMNSITEMRESTOREDHPALITTLE waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE + datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE return BattleScript_SelectingNotAllowedMoveChoiceItem:: @@ -7906,9 +7846,8 @@ BattleScript_BerryConfuseHealEnd2_Anim: playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE seteffectprimary BS_SCRIPTING, BS_SCRIPTING, MOVE_EFFECT_CONFUSION removeitem BS_SCRIPTING end2 @@ -7922,9 +7861,8 @@ BattleScript_BerryConfuseHealRet_Anim: playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE seteffectprimary BS_SCRIPTING, BS_SCRIPTING, MOVE_EFFECT_CONFUSION removeitem BS_SCRIPTING return @@ -8268,8 +8206,8 @@ BattleScript_ZEffectPrintString:: return BattleScript_RecoverHPZMove:: - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE printfromtable gZEffectStringIds waitmessage B_WAIT_TIME_LONG return @@ -8288,8 +8226,8 @@ BattleScript_HealReplacementZMove:: playanimation BS_SCRIPTING, B_ANIM_WISH_HEAL, 0x0 printfromtable gZEffectStringIds waitmessage B_WAIT_TIME_LONG - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE return BattleScript_EffectExtremeEvoboost:: @@ -8759,9 +8697,8 @@ BattleScript_EffectHealOneSixthAllies:: BattleScript_HealOneSixthAlliesLoop: jumpifabsent BS_TARGET, BattleScript_HealOneSixthAlliesIncrement tryhealsixthhealth BattleScript_HealOneSixthAlliesIncrement - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_TARGET - datahpupdate BS_TARGET + healthbarupdate BS_TARGET, PASSIVE_HP_UPDATE + datahpupdate BS_TARGET, PASSIVE_HP_UPDATE printstring STRINGID_PKMNREGAINEDHEALTH waitmessage B_WAIT_TIME_LONG BattleScript_HealOneSixthAlliesIncrement: diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index 586a79c5ef..57c5e752e4 100755 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -49,9 +49,8 @@ BattleScript_UseItemMessage: BattleScript_ItemRestoreHPRet: clearmoveresultflags MOVE_RESULT_NO_EFFECT - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_SCRIPTING, PASSIVE_HP_UPDATE + datahpupdate BS_SCRIPTING, PASSIVE_HP_UPDATE printstring STRINGID_ITEMRESTOREDSPECIESHEALTH waitmessage B_WAIT_TIME_LONG return diff --git a/include/battle.h b/include/battle.h index 74e9f1c611..1888c249de 100644 --- a/include/battle.h +++ b/include/battle.h @@ -761,6 +761,7 @@ struct BattleStruct u8 pursuitStoredSwitch; // Stored id for the Pursuit target's switch s32 battlerExpReward; u16 prevTurnSpecies[MAX_BATTLERS_COUNT]; // Stores species the AI has in play at start of turn + s16 passiveHpUpdate[MAX_BATTLERS_COUNT]; // non-move damage and healing s16 moveDamage[MAX_BATTLERS_COUNT]; s16 critChance[MAX_BATTLERS_COUNT]; u16 moveResultFlags[MAX_BATTLERS_COUNT]; @@ -772,15 +773,14 @@ struct BattleStruct u8 printedStrongWindsWeakenedAttack:1; u8 numSpreadTargets:2; u8 noTargetPresent:1; - u8 cheekPouchActivated:1; - s16 savedcheekPouchDamage; // Cheek Pouch can happen in the middle of an attack execution so we need to store the current dmg + u8 padding1:1; struct MessageStatus slideMessageStatus; u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT]; u8 hazardsQueue[NUM_BATTLE_SIDES][HAZARDS_MAX_COUNT]; u8 numHazards[NUM_BATTLE_SIDES]; u8 hazardsCounter:4; // Counter for applying hazard on switch in enum SubmoveState submoveAnnouncement:2; - u8 padding1:2; + u8 padding2:2; }; struct AiBattleData @@ -1234,7 +1234,7 @@ static inline bool32 IsSpreadMove(u32 moveTarget) static inline bool32 IsDoubleSpreadMove(void) { return gBattleStruct->numSpreadTargets > 1 - && !(gHitMarker & (HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE | HITMARKER_UNABLE_TO_USE_MOVE)) + && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && IsSpreadMove(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove)); } @@ -1250,4 +1250,18 @@ static inline u32 GetChosenMoveFromPosition(u32 battler) return gBattleMons[battler].moves[gBattleStruct->chosenMovePositions[battler]]; } +static inline void SetPassiveDamageAmount(u32 battler, s32 value) +{ + if (value == 0) + value = 1; + gBattleStruct->passiveHpUpdate[battler] = value; +} + +static inline void SetHealAmount(u32 battler, s32 value) +{ + if (value == 0) + value = 1; + gBattleStruct->passiveHpUpdate[battler] = -1 * value; +} + #endif // GUARD_BATTLE_H diff --git a/include/battle_util.h b/include/battle_util.h index aed03afae1..7dc639c300 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -421,5 +421,6 @@ void RemoveAbilityFlags(u32 battler); bool32 IsDazzlingAbility(enum Ability ability); bool32 IsAllowedToUseBag(void); bool32 IsAnyTargetTurnDamaged(u32 battlerAtk); +bool32 IsMimikyuDisguised(u32 battler); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 775546c5c6..b47b1a99da 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -237,10 +237,9 @@ enum SemiInvulnerableExclusion EXCLUDE_COMMANDER, }; -#define HITMARKER_IGNORE_BIDE (1 << 5) #define HITMARKER_DESTINYBOND (1 << 6) #define HITMARKER_NO_ANIMATIONS (1 << 7) // set from battleSceneOff. Never changed during battle -#define HITMARKER_IGNORE_SUBSTITUTE (1 << 8) +#define HITMARKER_UNUSED_8 (1 << 8) #define HITMARKER_ATTACKSTRING_PRINTED (1 << 9) #define HITMARKER_UNUSED_10 (1 << 10) #define HITMARKER_UNUSED_11 (1 << 11) @@ -252,7 +251,7 @@ enum SemiInvulnerableExclusion #define HITMARKER_DISABLE_ANIMATION (1 << 17) // disable animations during battle scripts, e.g. for Bug Bite #define HITMARKER_UNUSED_18 (1 << 18) #define HITMARKER_UNABLE_TO_USE_MOVE (1 << 19) -#define HITMARKER_PASSIVE_HP_UPDATE (1 << 20) +#define HITMARKER_UNUSED_20 (1 << 20) #define HITMARKER_UNUSED_21 (1 << 21) #define HITMARKER_PLAYER_FAINTED (1 << 22) #define HITMARKER_UNUSED_23 (1 << 23) diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 8d8517df7f..0c53134ce9 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -200,4 +200,10 @@ enum TriggerOnFieldStatus ON_WEATHER, }; +enum HealthUpdate +{ + PASSIVE_HP_UPDATE, + MOVE_DAMAGE_HP_UPDATE, +}; + #endif // GUARD_CONSTANTS_BATTLE_SCRIPT_COMMANDS_H diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index c735913af3..d34040ffc8 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1423,7 +1423,7 @@ bool32 CanEndureHit(u32 battler, u32 battlerTarget, u32 move) { if (B_STURDY >= GEN_5 && gAiLogicData->abilities[battlerTarget] == ABILITY_STURDY) return TRUE; - if (gBattleMons[battlerTarget].species == SPECIES_MIMIKYU_DISGUISED) + if (IsMimikyuDisguised(battlerTarget)) return TRUE; } @@ -5184,7 +5184,7 @@ bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove) if (gBattleMons[battlerDef].ability == ABILITY_DISGUISE && !MoveIgnoresTargetAbility(zMove) - && (gBattleMons[battlerDef].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battlerDef].species == SPECIES_MIMIKYU_TOTEM_DISGUISED)) + && IsMimikyuDisguised(battlerDef)) return FALSE; // Don't waste a Z-Move busting disguise if (gBattleMons[battlerDef].ability == ABILITY_ICE_FACE && !MoveIgnoresTargetAbility(zMove) diff --git a/src/battle_end_turn.c b/src/battle_end_turn.c index 6dc762e5c7..842a69078c 100644 --- a/src/battle_end_turn.c +++ b/src/battle_end_turn.c @@ -236,9 +236,7 @@ static bool32 HandleEndTurnWeatherDamage(u32 battler) && GetBattlerHoldEffect(battler) != HOLD_EFFECT_SAFETY_GOGGLES && !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 16); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SANDSTORM; BattleScriptExecute(BattleScript_DamagingWeather); effect = TRUE; @@ -261,9 +259,7 @@ static bool32 HandleEndTurnWeatherDamage(u32 battler) && GetBattlerHoldEffect(battler) != HOLD_EFFECT_SAFETY_GOGGLES && !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 16); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_HAIL; BattleScriptExecute(BattleScript_DamagingWeather); effect = TRUE; @@ -378,21 +374,22 @@ static bool32 HandleEndTurnWish(u32 battler) if (gWishFutureKnock.wishCounter[battler] == gBattleTurnCounter && IsBattlerAlive(battler)) { + s32 wishHeal = 0; gBattlerTarget = battler; PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battler, gWishFutureKnock.wishPartyId[battler]) if (B_WISH_HP_SOURCE >= GEN_5) { if (IsOnPlayerSide(battler)) - gBattleStruct->moveDamage[battler] = max(1, GetMonData(&gPlayerParty[gWishFutureKnock.wishPartyId[battler]], MON_DATA_MAX_HP) / 2); + wishHeal = GetMonData(&gPlayerParty[gWishFutureKnock.wishPartyId[battler]], MON_DATA_MAX_HP) / 2; else - gBattleStruct->moveDamage[battler] = max(1, GetMonData(&gEnemyParty[gWishFutureKnock.wishPartyId[battler]], MON_DATA_MAX_HP) / 2); + wishHeal = GetMonData(&gEnemyParty[gWishFutureKnock.wishPartyId[battler]], MON_DATA_MAX_HP) / 2; } else { - gBattleStruct->moveDamage[battler] = max(1, GetNonDynamaxMaxHP(battler) / 2); + wishHeal = GetNonDynamaxMaxHP(battler) / 2; } - gBattleStruct->moveDamage[battler] *= -1; + SetHealAmount(battler, wishHeal); if (gBattleMons[battler].volatiles.healBlock) BattleScriptExecute(BattleScript_WishButHealBlocked); else if (gBattleMons[battler].hp == gBattleMons[battler].maxHP) @@ -427,8 +424,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler) if (!IS_BATTLER_OF_TYPE(battler, gSideTimers[side].damageNonTypesType) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - gBattlerAttacker = battler; - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 6; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 6); ChooseDamageNonTypesString(gSideTimers[side].damageNonTypesType); BattleScriptExecute(BattleScript_DamageNonTypesContinues); effect = TRUE; @@ -440,7 +436,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler) if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SEA_OF_FIRE) { gBattlerAttacker = battler; - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8); BtlController_EmitStatusAnimation(battler, B_COMM_TO_CONTROLLER, FALSE, STATUS1_BURN); MarkBattlerForControllerExec(battler); BattleScriptExecute(BattleScript_HurtByTheSeaOfFire); @@ -478,10 +474,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler) && !IsSemiInvulnerable(battler, CHECK_ALL) && IsBattlerGrounded(battler, GetBattlerAbility(battler), GetBattlerHoldEffect(battler))) { - gBattlerAttacker = battler; - gBattleStruct->moveDamage[battler] = -(GetNonDynamaxMaxHP(battler) / 16); - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = -1; + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 16); BattleScriptExecute(BattleScript_GrassyTerrainHeals); effect = TRUE; } @@ -526,7 +519,7 @@ static bool32 HandleEndTurnAquaRing(u32 battler) && !IsBattlerAtMaxHp(battler) && IsBattlerAlive(battler)) { - gBattleStruct->moveDamage[battler] = GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16); + SetHealAmount(battler, GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16)); BattleScriptExecute(BattleScript_AquaRingHeal); effect = TRUE; } @@ -545,7 +538,7 @@ static bool32 HandleEndTurnIngrain(u32 battler) && !IsBattlerAtMaxHp(battler) && IsBattlerAlive(battler)) { - gBattleStruct->moveDamage[battler] = GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16); + SetHealAmount(battler, GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16)); BattleScriptExecute(BattleScript_IngrainTurnHeal); effect = TRUE; } @@ -567,12 +560,12 @@ static bool32 HandleEndTurnLeechSeed(u32 battler) gBattlerTarget = gBattleMons[battler].volatiles.leechSeed - 1; // leech seed receiver gBattleScripting.animArg1 = gBattlerTarget; gBattleScripting.animArg2 = gBattlerAttacker; - gBattleStruct->moveDamage[gBattlerAttacker] = max(1, GetNonDynamaxMaxHP(battler) / 8); - gBattleStruct->moveDamage[gBattlerTarget] = GetDrainedBigRootHp(gBattlerTarget, gBattleStruct->moveDamage[gBattlerAttacker]); - gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE; + s32 drainAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 8; + s32 healAmount = GetDrainedBigRootHp(gBattlerTarget, drainAmount); if (GetBattlerAbility(battler) == ABILITY_LIQUID_OOZE) { - gBattleStruct->moveDamage[gBattlerTarget] = gBattleStruct->moveDamage[gBattlerTarget] * -1; + SetPassiveDamageAmount(gBattlerAttacker, drainAmount); + SetPassiveDamageAmount(gBattlerTarget, healAmount); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_OOZE; BattleScriptExecute(BattleScript_LeechSeedTurnDrainLiquidOoze); } @@ -582,6 +575,8 @@ static bool32 HandleEndTurnLeechSeed(u32 battler) } else { + SetPassiveDamageAmount(gBattlerAttacker, drainAmount); + SetHealAmount(gBattlerTarget, healAmount); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_DRAIN; BattleScriptExecute(BattleScript_LeechSeedTurnDrainRecovery); } @@ -607,30 +602,23 @@ static bool32 HandleEndTurnPoison(u32 battler) { if (!IsBattlerAtMaxHp(battler) && !gBattleMons[battler].volatiles.healBlock) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 8); BattleScriptExecute(BattleScript_PoisonHealActivates); effect = TRUE; } } else if (gBattleMons[battler].status1 & STATUS1_TOXIC_POISON) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 16); if ((gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns gBattleMons[battler].status1 += STATUS1_TOXIC_TURN(1); - gBattleStruct->moveDamage[battler] *= (gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) >> 8; + gBattleStruct->passiveHpUpdate[battler] *= (gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) >> 8; BattleScriptExecute(BattleScript_PoisonTurnDmg); effect = TRUE; } else { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8); BattleScriptExecute(BattleScript_PoisonTurnDmg); effect = TRUE; } @@ -651,15 +639,14 @@ static bool32 HandleEndTurnBurn(u32 battler) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8); + s32 burnDamage = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8); if (ability == ABILITY_HEATPROOF) { - if (gBattleStruct->moveDamage[battler] > (gBattleStruct->moveDamage[battler] / 2) + 1) // Record ability if the burn takes less damage than it normally would. + if (burnDamage > (burnDamage / 2) + 1) // Record ability if the burn takes less damage than it normally would. RecordAbilityBattle(battler, ABILITY_HEATPROOF); - gBattleStruct->moveDamage[battler] /= 2; + burnDamage /= 2; } - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, burnDamage); BattleScriptExecute(BattleScript_BurnTurnDmg); effect = TRUE; } @@ -677,9 +664,7 @@ static bool32 HandleEndTurnFrostbite(u32 battler) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8); - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8)); BattleScriptExecute(BattleScript_FrostbiteTurnDmg); effect = TRUE; } @@ -699,9 +684,7 @@ static bool32 HandleEndTurnNightmare(u32 battler) { if (gBattleMons[battler].status1 & STATUS1_SLEEP) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 4); BattleScriptExecute(BattleScript_NightmareTurnDmg); effect = TRUE; } @@ -724,9 +707,7 @@ static bool32 HandleEndTurnCurse(u32 battler) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 4); BattleScriptExecute(BattleScript_CurseTurnDmg); effect = TRUE; } @@ -752,13 +733,12 @@ static bool32 HandleEndTurnWrap(u32 battler) gBattleScripting.animArg2 = gBattleStruct->wrappedMove[battler] >> 8; PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleStruct->wrappedMove[battler]); BattleScriptExecute(BattleScript_WrapTurnDmg); + s32 bindDamage = 0; if (GetBattlerHoldEffect(gBattleStruct->wrappedBy[battler]) == HOLD_EFFECT_BINDING_BAND) - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 6 : 8); + bindDamage = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 6 : 8); else - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 8 : 16); - - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + bindDamage = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 8 : 16); + SetPassiveDamageAmount(battler, bindDamage); } else // broke free { @@ -782,12 +762,12 @@ static bool32 HandleEndTurnSaltCure(u32 battler) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { + s32 saltCureDamage = 0; if (IS_BATTLER_ANY_TYPE(battler, TYPE_STEEL, TYPE_WATER)) - gBattleStruct->moveDamage[battler] = gBattleMons[battler].maxHP / 4; + saltCureDamage = gBattleMons[battler].maxHP / 4; else - gBattleStruct->moveDamage[battler] = gBattleMons[battler].maxHP / 8; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + saltCureDamage = gBattleMons[battler].maxHP / 8; + SetPassiveDamageAmount(battler, saltCureDamage); PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SALT_CURE); BattleScriptExecute(BattleScript_SaltCureExtraDamage); effect = TRUE; @@ -1065,7 +1045,7 @@ static bool32 HandleEndTurnPerishSong(u32 battler) if (gDisableStructs[battler].perishSongTimer == 0) { gBattleMons[battler].volatiles.perishSong = FALSE; - gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp; + SetPassiveDamageAmount(battler, gBattleMons[battler].hp); BattleScriptExecute(BattleScript_PerishSongTakesLife); } else @@ -1560,7 +1540,7 @@ static bool32 (*const sEndTurnEffectHandlers[])(u32 battler) = u32 DoEndTurnEffects(void) { u32 battler = MAX_BATTLERS_COUNT; - gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_IGNORE_BIDE); + gHitMarker |= HITMARKER_GRUDGE; for (;;) { @@ -1576,7 +1556,7 @@ u32 DoEndTurnEffects(void) // Jump out if possible after endTurnEventsCounter was increased in the above code block if (gBattleStruct->endTurnEventsCounter == ENDTURN_COUNT) { - gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_IGNORE_BIDE); + gHitMarker &= ~HITMARKER_GRUDGE; return FALSE; } diff --git a/src/battle_hold_effects.c b/src/battle_hold_effects.c index fc8678a613..907350cff5 100644 --- a/src/battle_hold_effects.c +++ b/src/battle_hold_effects.c @@ -266,9 +266,7 @@ static enum ItemEffect TryRockyHelmet(u32 battlerDef, u32 battlerAtk) && !CanBattlerAvoidContactEffects(battlerAtk, battlerDef, ability, GetBattlerHoldEffect(battlerAtk), gCurrentMove) && !IsAbilityAndRecord(battlerAtk, ability, ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battlerAtk] = GetNonDynamaxMaxHP(battlerAtk) / 6; - if (gBattleStruct->moveDamage[battlerAtk] == 0) - gBattleStruct->moveDamage[battlerAtk] = 1; + SetPassiveDamageAmount(battlerAtk, GetNonDynamaxMaxHP(battlerAtk) / 6); PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battlerDef].item); BattleScriptCall(BattleScript_RockyHelmetActivates); effect = ITEM_HP_CHANGE; @@ -366,12 +364,10 @@ static enum ItemEffect TryJabocaBerry(u32 battlerDef, u32 battlerAtk) && IsBattleMovePhysical(gCurrentMove) && !IsAbilityAndRecord(battlerAtk, GetBattlerAbility(battlerAtk), ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battlerAtk] = GetNonDynamaxMaxHP(battlerAtk) / 8; - if (gBattleStruct->moveDamage[battlerAtk] == 0) - gBattleStruct->moveDamage[battlerAtk] = 1; + s32 jabocaDamage = GetNonDynamaxMaxHP(battlerAtk) / 8; if (GetBattlerAbility(battlerDef) == ABILITY_RIPEN) - gBattleStruct->moveDamage[gBattlerAttacker] *= 2; - + jabocaDamage *= 2; + SetPassiveDamageAmount(battlerAtk, jabocaDamage); BattleScriptCall(BattleScript_JabocaRowapBerryActivates); PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battlerDef].item); effect = ITEM_HP_CHANGE; @@ -390,12 +386,10 @@ static enum ItemEffect TryRowapBerry(u32 battlerDef, u32 battlerAtk) && IsBattleMoveSpecial(gCurrentMove) && !IsAbilityAndRecord(battlerAtk, GetBattlerAbility(battlerAtk), ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battlerAtk] = GetNonDynamaxMaxHP(battlerAtk) / 8; - if (gBattleStruct->moveDamage[battlerAtk] == 0) - gBattleStruct->moveDamage[battlerAtk] = 1; + s32 rowapDamage = GetNonDynamaxMaxHP(battlerAtk) / 8; if (GetBattlerAbility(battlerDef) == ABILITY_RIPEN) - gBattleStruct->moveDamage[battlerAtk] *= 2; - + rowapDamage *= 2; + SetPassiveDamageAmount(battlerAtk, rowapDamage); BattleScriptCall(BattleScript_JabocaRowapBerryActivates); PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battlerDef].item); effect = ITEM_HP_CHANGE; @@ -414,10 +408,10 @@ static enum ItemEffect TrySetEnigmaBerry(u32 battlerDef, u32 battlerAtk) && !(gBattleScripting.overrideBerryRequirements && gBattleMons[battlerDef].hp == gBattleMons[battlerDef].maxHP) && !(B_HEAL_BLOCKING >= GEN_5 && gBattleMons[battlerDef].volatiles.healBlock)) { - gBattleStruct->moveDamage[battlerDef] = (gBattleMons[battlerDef].maxHP * 25 / 100) * -1; + s32 healAmount = gBattleMons[battlerDef].maxHP * 25 / 100; if (GetBattlerAbility(battlerDef) == ABILITY_RIPEN) - gBattleStruct->moveDamage[battlerDef] *= 2; - + healAmount *= 2; + SetHealAmount(battlerDef, healAmount); BattleScriptCall(BattleScript_ItemHealHP_RemoveItemRet); effect = ITEM_HP_CHANGE; } @@ -560,9 +554,7 @@ static enum ItemEffect TryShellBell(u32 battlerAtk) && !IsFutureSightAttackerInParty(battlerAtk, gBattlerTarget, gCurrentMove) && !(B_HEAL_BLOCKING >= GEN_5 && gBattleMons[battlerAtk].volatiles.healBlock)) { - gBattleStruct->moveDamage[battlerAtk] = (gBattleScripting.savedDmg / GetBattlerHoldEffectParam(battlerAtk)) * -1; - if (gBattleStruct->moveDamage[battlerAtk] == 0) - gBattleStruct->moveDamage[battlerAtk] = -1; + SetHealAmount(battlerAtk, gBattleScripting.savedDmg / GetBattlerHoldEffectParam(battlerAtk)); BattleScriptCall(BattleScript_ItemHealHP_Ret); effect = ITEM_HP_CHANGE; } @@ -581,10 +573,7 @@ static enum ItemEffect TryLifeOrb(u32 battlerAtk) && GetMoveEffect(gCurrentMove) != EFFECT_PAIN_SPLIT && !IsFutureSightAttackerInParty(battlerAtk, gBattlerTarget, gCurrentMove)) { - DebugPrintf("move %d", gCurrentMove); - gBattleStruct->moveDamage[battlerAtk] = GetNonDynamaxMaxHP(battlerAtk) / 10; - if (gBattleStruct->moveDamage[battlerAtk] == 0) - gBattleStruct->moveDamage[battlerAtk] = 1; + SetPassiveDamageAmount(battlerAtk, GetNonDynamaxMaxHP(battlerAtk) / 10); BattleScriptCall(BattleScript_ItemHurtRet); effect = ITEM_HP_CHANGE; } @@ -619,9 +608,7 @@ static enum ItemEffect TryStickyBarbOnEndTurn(u32 battler) if (!IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8); PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battler].item); BattleScriptExecute(BattleScript_ItemHurtEnd2); effect = ITEM_HP_CHANGE; @@ -667,10 +654,7 @@ static enum ItemEffect TryLeftovers(u32 battler, enum HoldEffect holdEffect) if (gBattleMons[battler].hp < gBattleMons[battler].maxHP && !(B_HEAL_BLOCKING >= GEN_5 && gBattleMons[battler].volatiles.healBlock)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 16); RecordItemEffectBattle(battler, holdEffect); BattleScriptExecute(BattleScript_ItemHealHP_End2); effect = ITEM_HP_CHANGE; @@ -679,15 +663,13 @@ static enum ItemEffect TryLeftovers(u32 battler, enum HoldEffect holdEffect) return effect; } -static enum ItemEffect TryBlackSludge(u32 battler, enum HoldEffect holdEffect) +static enum ItemEffect TryBlackSludgeDamage(u32 battler, enum HoldEffect holdEffect) { enum ItemEffect effect = ITEM_NO_EFFECT; if (!IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8); RecordItemEffectBattle(battler, holdEffect); BattleScriptExecute(BattleScript_ItemHurtEnd2); effect = ITEM_HP_CHANGE; @@ -885,14 +867,16 @@ static u32 ItemHealHp(u32 battler, u32 itemId, enum HealAmount percentHeal, Acti && !(B_HEAL_BLOCKING >= GEN_5 && gBattleMons[battler].volatiles.healBlock) && HasEnoughHpToEatBerry(battler, ability, 2, itemId)) { + s32 healAmount = 0; if (percentHeal == PERCENT_HEAL_AMOUNT) - gBattleStruct->moveDamage[battler] = (GetNonDynamaxMaxHP(battler) * GetItemHoldEffectParam(itemId) / 100) * -1; + healAmount = (GetNonDynamaxMaxHP(battler) * GetItemHoldEffectParam(itemId) / 100); else - gBattleStruct->moveDamage[battler] = GetItemHoldEffectParam(itemId) * -1; + healAmount = GetItemHoldEffectParam(itemId); if (ability == ABILITY_RIPEN && GetItemPocket(itemId) == POCKET_BERRIES) - gBattleStruct->moveDamage[battler] *= 2; + healAmount *= 2; + SetHealAmount(battler, healAmount); if (timing == IsOnSwitchInFirstTurnActivation) BattleScriptExecute(BattleScript_ItemHealHP_RemoveItemEnd2); else @@ -958,16 +942,10 @@ static enum ItemEffect HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, A if (HasEnoughHpToEatBerry(battler, ability, hpFraction, itemId) && !(B_HEAL_BLOCKING >= GEN_5 && gBattleMons[battler].volatiles.healBlock)) { - PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, flavorId); - - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / GetItemHoldEffectParam(itemId); - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; - + s32 healAmount = GetNonDynamaxMaxHP(battler) / GetItemHoldEffectParam(itemId); if (ability == ABILITY_RIPEN) - gBattleStruct->moveDamage[battler] *= 2; - + healAmount *= 2; + SetHealAmount(battler, healAmount); if (timing == IsOnSwitchInFirstTurnActivation) { if (GetFlavorRelationByPersonality(gBattleMons[battler].personality, flavorId) < 0) @@ -982,7 +960,7 @@ static enum ItemEffect HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, A else BattleScriptCall(BattleScript_ItemHealHP_RemoveItemRet); } - + PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, flavorId); effect = ITEM_HP_CHANGE; } @@ -1200,7 +1178,7 @@ enum ItemEffect ItemBattleEffects(u32 itemBattler, u32 battler, enum HoldEffect if (IS_BATTLER_OF_TYPE(itemBattler, TYPE_POISON)) effect = TryLeftovers(itemBattler, holdEffect); else - effect = TryBlackSludge(itemBattler, holdEffect); + effect = TryBlackSludgeDamage(itemBattler, holdEffect); break; case HOLD_EFFECT_CURE_PAR: // Cheri Berry effect = TryCureParalysis(itemBattler, timing); diff --git a/src/battle_main.c b/src/battle_main.c index 62f4b95ca9..cbe58051cb 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4023,7 +4023,6 @@ void BattleTurnPassed(void) gHitMarker &= ~HITMARKER_UNABLE_TO_USE_MOVE; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gHitMarker &= ~HITMARKER_PLAYER_FAINTED; - gHitMarker &= ~HITMARKER_PASSIVE_HP_UPDATE; gBattleScripting.animTurn = 0; gBattleScripting.animTargetsHit = 0; gBattleScripting.moveendState = 0; @@ -5416,7 +5415,6 @@ static void RunTurnActionsFunctions(void) if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished { - gHitMarker &= ~HITMARKER_PASSIVE_HP_UPDATE; gBattleMainFunc = sEndTurnFuncsTable[gBattleOutcome & 0x7F]; } else diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a690295833..e74265b649 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -333,7 +333,6 @@ static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent); static void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16 usedMove); static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u8 *failInstr, u16 move); static void ResetValuesForCalledMove(void); -static void TryRestoreDamageAfterCheekPouch(u32 battler); static bool32 TrySymbiosis(u32 battler, u32 itemId, bool32 moveEnd); static bool32 CanAbilityShieldActivateForBattler(u32 battler); @@ -396,7 +395,7 @@ static void Cmd_bichalfword(void); static void Cmd_bicword(void); static void Cmd_pause(void); static void Cmd_waitstate(void); -static void Cmd_absorb(void); +static void Cmd_isdmgblockedbydisguise(void); static void Cmd_return(void); static void Cmd_end(void); static void Cmd_end2(void); @@ -473,7 +472,7 @@ static void Cmd_jumpifuproarwakes(void); static void Cmd_stockpile(void); static void Cmd_stockpiletobasedamage(void); static void Cmd_stockpiletohpheal(void); -static void Cmd_setdrainedhp(void); +static void Cmd_unused_0x88(void); static void Cmd_statbuffchange(void); static void Cmd_normalisebuffs(void); static void Cmd_setbide(void); @@ -581,7 +580,7 @@ static void Cmd_givecaughtmon(void); static void Cmd_trysetcaughtmondexflags(void); static void Cmd_displaydexinfo(void); static void Cmd_trygivecaughtmonnick(void); -static void Cmd_subattackerhpbydmg(void); +static void Cmd_unused_0xf4(void); static void Cmd_removeattackerstatus1(void); static void Cmd_finishaction(void); static void Cmd_finishturn(void); @@ -655,7 +654,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_bicword, //0x38 Cmd_pause, //0x39 Cmd_waitstate, //0x3A - Cmd_absorb, //0x3B + Cmd_isdmgblockedbydisguise, //0x3B Cmd_return, //0x3C Cmd_end, //0x3D Cmd_end2, //0x3E @@ -732,7 +731,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_stockpile, //0x85 Cmd_stockpiletobasedamage, //0x86 Cmd_stockpiletohpheal, //0x87 - Cmd_setdrainedhp, //0x88 + Cmd_unused_0x88, //0x88 Cmd_statbuffchange, //0x89 Cmd_normalisebuffs, //0x8A Cmd_setbide, //0x8B @@ -840,7 +839,7 @@ void (*const gBattleScriptingCommandsTable[])(void) = Cmd_trysetcaughtmondexflags, //0xF1 Cmd_displaydexinfo, //0xF2 Cmd_trygivecaughtmonnick, //0xF3 - Cmd_subattackerhpbydmg, //0xF4 + Cmd_unused_0xf4, //0xF4 Cmd_removeattackerstatus1, //0xF5 Cmd_finishaction, //0xF6 Cmd_finishturn, //0xF7 @@ -2196,8 +2195,7 @@ static void Cmd_waitanimation(void) static void DoublesHPBarReduction(void) { - if (gBattleStruct->doneDoublesSpreadHit - || gHitMarker & (HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE)) + if (gBattleStruct->doneDoublesSpreadHit) return; for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++) @@ -2209,12 +2207,10 @@ static void DoublesHPBarReduction(void) || DoesDisguiseBlockMove(battlerDef, gCurrentMove)) continue; - s32 currDmg = gBattleStruct->moveDamage[battlerDef]; - s32 healthValue = min(currDmg, 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign - BtlController_EmitHealthBarUpdate(battlerDef, B_COMM_TO_CONTROLLER, healthValue); + s32 dmgUpdate = min(gBattleStruct->moveDamage[battlerDef], 10000); + BtlController_EmitHealthBarUpdate(battlerDef, B_COMM_TO_CONTROLLER, dmgUpdate); MarkBattlerForControllerExec(battlerDef); - - if (IsOnPlayerSide(battlerDef) && currDmg > 0) + if (IsOnPlayerSide(battlerDef) && dmgUpdate > 0) gBattleResults.playerMonWasDamaged = TRUE; } @@ -2223,176 +2219,199 @@ static void DoublesHPBarReduction(void) static void Cmd_healthbarupdate(void) { - CMD_ARGS(u8 battler); + CMD_ARGS(u8 battler, u8 updateState); u32 battler = GetBattlerForBattleScript(cmd->battler); if (gBattleControllerExecFlags) return; - if (!(gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_NO_EFFECT) || (gHitMarker & HITMARKER_PASSIVE_HP_UPDATE)) + switch (cmd->updateState) { - if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && gDisableStructs[battler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + case PASSIVE_HP_UPDATE: + BtlController_EmitHealthBarUpdate(battler, B_COMM_TO_CONTROLLER, min(gBattleStruct->passiveHpUpdate[battler], 10000)); + MarkBattlerForControllerExec(battler); + break; + case MOVE_DAMAGE_HP_UPDATE: + if (IsDoubleSpreadMove()) + { + DoublesHPBarReduction(); + if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)) + PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, battler); + } + else if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)) { PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, battler); - if (IsDoubleSpreadMove()) - DoublesHPBarReduction(); } - else if (!DoesDisguiseBlockMove(battler, gCurrentMove)) + else if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) + && !DoesDisguiseBlockMove(battler, gCurrentMove)) { - if (IsDoubleSpreadMove()) - { - DoublesHPBarReduction(); - } - else - { - s16 healthValue = min(gBattleStruct->moveDamage[battler], 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign - - BtlController_EmitHealthBarUpdate(battler, B_COMM_TO_CONTROLLER, healthValue); - MarkBattlerForControllerExec(battler); - - if (IsOnPlayerSide(battler) && gBattleStruct->moveDamage[battler] > 0) - gBattleResults.playerMonWasDamaged = TRUE; - } + s32 damage = min(gBattleStruct->moveDamage[battler], 10000); + BtlController_EmitHealthBarUpdate(battler, B_COMM_TO_CONTROLLER, damage); + MarkBattlerForControllerExec(battler); + if (IsOnPlayerSide(battler) && damage > 0) + gBattleResults.playerMonWasDamaged = TRUE; } - } - else if (IsDoubleSpreadMove()) - { - DoublesHPBarReduction(); + break; } gBattlescriptCurrInstr = cmd->nextInstr; } -// Update the active battler's HP and various HP trackers (Substitute, Bide, etc.) +static void PassiveDataHpUpdate(u32 battler, const u8 *nextInstr) +{ + if (gBattleStruct->passiveHpUpdate[battler] < 0) + { + // Negative damage is HP gain + gBattleMons[battler].hp += -gBattleStruct->passiveHpUpdate[battler]; + if (gBattleMons[battler].hp > gBattleMons[battler].maxHP) + gBattleMons[battler].hp = gBattleMons[battler].maxHP; + } + else + { + if (gBattleMons[battler].hp > gBattleStruct->passiveHpUpdate[battler]) + gBattleMons[battler].hp -= gBattleStruct->passiveHpUpdate[battler]; + else + gBattleMons[battler].hp = 0; + } + + // Send updated HP + BtlController_EmitSetMonData( + battler, + B_COMM_TO_CONTROLLER, + REQUEST_HP_BATTLE, + 0, + sizeof(gBattleMons[battler].hp), &gBattleMons[battler].hp); + MarkBattlerForControllerExec(battler); + + gBattleStruct->passiveHpUpdate[battler] = 0; + gBattlescriptCurrInstr = nextInstr; +} + +static void MoveDamageDataHpUpdate(u32 battler, u32 scriptBattler, const u8 *nextInstr) +{ + if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) + { + gBattlescriptCurrInstr = nextInstr; + } + else if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && gDisableStructs[battler].substituteHP) + { + if (gDisableStructs[battler].substituteHP >= gBattleStruct->moveDamage[battler]) + { + gDisableStructs[battler].substituteHP -= gBattleStruct->moveDamage[battler]; + } + else + { + gBattleStruct->moveDamage[battler] = gDisableStructs[battler].substituteHP; + gDisableStructs[battler].substituteHP = 0; + } + // check substitute fading + if (gDisableStructs[battler].substituteHP == 0) + { + gBattlescriptCurrInstr = nextInstr; + BattleScriptCall(BattleScript_SubstituteFade); + return; + } + else + { + gBattlescriptCurrInstr = nextInstr; + return; + } + } + else if (DoesDisguiseBlockMove(battler, gCurrentMove)) + { + // TODO: Convert this to a proper FORM_CHANGE type. + gBattleScripting.battler = battler; + if (GetBattlerPartyState(battler)->changedSpecies == SPECIES_NONE) + GetBattlerPartyState(battler)->changedSpecies = gBattleMons[battler].species; + if (gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) + gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED_TOTEM; + else + gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED; + if (GetGenConfig(GEN_CONFIG_DISGUISE_HP_LOSS) >= GEN_8) + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8); + BattleScriptPush(nextInstr); + gBattlescriptCurrInstr = BattleScript_TargetFormChange; + } + else + { + if (gBattleStruct->moveDamage[battler] < 0) + { + // Negative damage is HP gain + gBattleMons[battler].hp += -gBattleStruct->moveDamage[battler]; + if (gBattleMons[battler].hp > gBattleMons[battler].maxHP) + gBattleMons[battler].hp = gBattleMons[battler].maxHP; + } + else + { + gBideDmg[battler] += gBattleStruct->moveDamage[battler]; + if (scriptBattler == BS_TARGET) + gBideTarget[battler] = gBattlerAttacker; + else + gBideTarget[battler] = gBattlerTarget; + + // Deal damage to the battler + if (gBattleMons[battler].hp > gBattleStruct->moveDamage[battler]) + { + gBattleMons[battler].hp -= gBattleStruct->moveDamage[battler]; + } + else + { + gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp; + gBattleMons[battler].hp = 0; + } + + // Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat, they are + // used in combination as general damage trackers for other purposes. specialDmg is additionally used + // to help determine if a fire move should defrost the target. + if (IsBattleMovePhysical(gCurrentMove)) + { + gProtectStructs[battler].physicalDmg = gBattleStruct->moveDamage[battler]; + gSpecialStatuses[battler].physicalDmg = gBattleStruct->moveDamage[battler]; + if (scriptBattler == BS_TARGET) // What's the point of this??? It will be always target + gProtectStructs[battler].physicalBattlerId = gBattlerAttacker; + else + gProtectStructs[battler].physicalBattlerId = gBattlerTarget; + gProtectStructs[battler].assuranceDoubled = TRUE; + } + else // Physical move + { + gProtectStructs[battler].specialDmg = gBattleStruct->moveDamage[battler]; + gSpecialStatuses[battler].specialDmg = gBattleStruct->moveDamage[battler]; + if (scriptBattler == BS_TARGET) // What's the point of this??? It will be always target + gProtectStructs[battler].specialBattlerId = gBattlerAttacker; + else + gProtectStructs[battler].specialBattlerId = gBattlerTarget; + gProtectStructs[battler].assuranceDoubled = TRUE; + } + } + // Send updated HP + BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_HP_BATTLE, 0, sizeof(gBattleMons[battler].hp), &gBattleMons[battler].hp); + MarkBattlerForControllerExec(battler); + gBattlescriptCurrInstr = nextInstr; + } + + if (IsBattlerTurnDamaged(gBattlerTarget) && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS) + GetBattlerPartyState(battler)->timesGotHit++; +} + static void Cmd_datahpupdate(void) { - CMD_ARGS(u8 battler); - bool32 isPassiveHpUpdate = gHitMarker & HITMARKER_PASSIVE_HP_UPDATE; - bool32 disguiseActivates = FALSE; + CMD_ARGS(u8 battler, u8 updateState); + u32 battler = GetBattlerForBattleScript(cmd->battler); if (gBattleControllerExecFlags) return; - u32 battler = GetBattlerForBattleScript(cmd->battler); - - if (!(gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_NO_EFFECT) || (gHitMarker & HITMARKER_PASSIVE_HP_UPDATE)) + switch (cmd->updateState) { - if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && gDisableStructs[battler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) - { - if (gDisableStructs[battler].substituteHP >= gBattleStruct->moveDamage[battler]) - { - gDisableStructs[battler].substituteHP -= gBattleStruct->moveDamage[battler]; - } - else - { - gBattleStruct->moveDamage[battler] = gDisableStructs[battler].substituteHP; - gDisableStructs[battler].substituteHP = 0; - } - // check substitute fading - if (gDisableStructs[battler].substituteHP == 0) - { - gBattlescriptCurrInstr = cmd->nextInstr; - BattleScriptCall(BattleScript_SubstituteFade); - return; - } - } - else if (DoesDisguiseBlockMove(battler, gCurrentMove)) - { - // TODO: Convert this to a proper FORM_CHANGE type. - gBattleScripting.battler = battler; - if (GetBattlerPartyState(battler)->changedSpecies == SPECIES_NONE) - GetBattlerPartyState(battler)->changedSpecies = gBattleMons[battler].species; - if (gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) - gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED_TOTEM; - else - gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED; - if (GetGenConfig(GEN_CONFIG_DISGUISE_HP_LOSS) >= GEN_8) - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_TargetFormChange; - disguiseActivates = TRUE; - } - else - { - gHitMarker &= ~HITMARKER_IGNORE_SUBSTITUTE; - if (gBattleStruct->moveDamage[battler] < 0) - { - // Negative damage is HP gain - gBattleMons[battler].hp += -gBattleStruct->moveDamage[battler]; - if (gBattleMons[battler].hp > gBattleMons[battler].maxHP) - gBattleMons[battler].hp = gBattleMons[battler].maxHP; - } - else - { - if (gHitMarker & HITMARKER_IGNORE_BIDE) - { - gHitMarker &= ~HITMARKER_IGNORE_BIDE; - } - else - { - gBideDmg[battler] += gBattleStruct->moveDamage[battler]; - if (cmd->battler == BS_TARGET) - gBideTarget[battler] = gBattlerAttacker; - else - gBideTarget[battler] = gBattlerTarget; - } - - // Deal damage to the battler - if (gBattleMons[battler].hp > gBattleStruct->moveDamage[battler]) - { - gBattleMons[battler].hp -= gBattleStruct->moveDamage[battler]; - } - else - { - gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp; - gBattleMons[battler].hp = 0; - } - - enum BattleMoveEffects effect = GetMoveEffect(gCurrentMove); - - // Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat, they are - // used in combination as general damage trackers for other purposes. specialDmg is additionally used - // to help determine if a fire move should defrost the target. - if (IsBattleMovePhysical(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_HP_UPDATE) && effect != EFFECT_PAIN_SPLIT) - { - gProtectStructs[battler].physicalDmg = gBattleStruct->moveDamage[battler]; - gSpecialStatuses[battler].physicalDmg = gBattleStruct->moveDamage[battler]; - if (cmd->battler == BS_TARGET) - gProtectStructs[battler].physicalBattlerId = gBattlerAttacker; - else - gProtectStructs[battler].physicalBattlerId = gBattlerTarget; - gProtectStructs[battler].assuranceDoubled = TRUE; - } - else if (!IsBattleMovePhysical(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_HP_UPDATE) && effect != EFFECT_PAIN_SPLIT) - { - // Record special damage/attacker for Mirror Coat - gProtectStructs[battler].specialDmg = gBattleStruct->moveDamage[battler]; - gSpecialStatuses[battler].specialDmg = gBattleStruct->moveDamage[battler]; - if (cmd->battler == BS_TARGET) - gProtectStructs[battler].specialBattlerId = gBattlerAttacker; - else - gProtectStructs[battler].specialBattlerId = gBattlerTarget; - gProtectStructs[battler].assuranceDoubled = TRUE; - } - } - gHitMarker &= ~HITMARKER_PASSIVE_HP_UPDATE; - // Send updated HP - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_HP_BATTLE, 0, sizeof(gBattleMons[battler].hp), &gBattleMons[battler].hp); - MarkBattlerForControllerExec(battler); - } - - if (gBattlerAttacker != gBattlerTarget - && !isPassiveHpUpdate - && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS - && IsBattlerTurnDamaged(gBattlerTarget)) - GetBattlerPartyState(gBattlerTarget)->timesGotHit++; - - if (disguiseActivates) - return; + case PASSIVE_HP_UPDATE: + PassiveDataHpUpdate(battler, cmd->nextInstr); + break; + case MOVE_DAMAGE_HP_UPDATE: + MoveDamageDataHpUpdate(battler, cmd->battler, cmd->nextInstr); + break; } - TryRestoreDamageAfterCheekPouch(battler); - gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_critmessage(void) @@ -3296,12 +3315,12 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai } break; case MOVE_EFFECT_RECOIL_HP_25: // Struggle - gBattleStruct->moveDamage[gEffectBattler] = (gBattleMons[gEffectBattler].maxHP) / 4; - if (gBattleStruct->moveDamage[gEffectBattler] == 0) - gBattleStruct->moveDamage[gEffectBattler] = 1; + s32 recoil = (gBattleMons[gEffectBattler].maxHP) / 4; + if (recoil == 0) + recoil = 1; if (GetBattlerAbility(gEffectBattler) == ABILITY_PARENTAL_BOND) - gBattleStruct->moveDamage[gEffectBattler] *= 2; - + recoil *= 2; + SetPassiveDamageAmount(gEffectBattler, recoil); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil; break; @@ -3337,10 +3356,9 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai && !IsSemiInvulnerable(BATTLE_PARTNER(gBattlerTarget), CHECK_ALL) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD) { - gBattleScripting.battler = i = BATTLE_PARTNER(gBattlerTarget); - gBattleStruct->moveDamage[i] = gBattleMons[i].maxHP / 16; - if (gBattleStruct->moveDamage[i] == 0) - gBattleStruct->moveDamage[i] = 1; + u32 partnerTarget = BATTLE_PARTNER(gBattlerTarget); + gBattleScripting.battler = partnerTarget; + SetPassiveDamageAmount(partnerTarget, gBattleMons[partnerTarget].maxHP / 16); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_MoveEffectFlameBurst; } @@ -4218,7 +4236,7 @@ static void Cmd_tryfaintmon(void) { gHitMarker &= ~HITMARKER_DESTINYBOND; BattleScriptPush(gBattlescriptCurrInstr); - gBattleStruct->moveDamage[destinyBondBattler] = gBattleMons[destinyBondBattler].hp; + gBattleStruct->passiveHpUpdate[destinyBondBattler] = gBattleMons[destinyBondBattler].hp; gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; } if (gBattleMons[gBattlerTarget].volatiles.grudge @@ -5283,21 +5301,29 @@ static void Cmd_waitstate(void) gBattlescriptCurrInstr = cmd->nextInstr; } -static void Cmd_absorb(void) +static void Cmd_isdmgblockedbydisguise(void) { - CMD_ARGS(u8 battler); + CMD_ARGS(); - if (gBattleControllerExecFlags) + if (!IsMimikyuDisguised(gBattlerAttacker) + || gBattleMons[gBattlerAttacker].volatiles.transformed + || !IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_DISGUISE)) + { + gBattlescriptCurrInstr = cmd->nextInstr; return; + } - u32 battler = GetBattlerForBattleScript(cmd->battler); - BtlController_EmitHealthBarUpdate(battler, B_COMM_TO_CONTROLLER, gBattleStruct->moveDamage[battler]); - MarkBattlerForControllerExec(battler); - - if (IsOnPlayerSide(battler) && gBattleStruct->moveDamage[battler] > 0) - gBattleResults.playerMonWasDamaged = TRUE; - - gBattlescriptCurrInstr = cmd->nextInstr; + gBattleScripting.battler = gBattlerAttacker; + if (GetBattlerPartyState(gBattlerAttacker)->changedSpecies == SPECIES_NONE) + GetBattlerPartyState(gBattlerAttacker)->changedSpecies = gBattleMons[gBattlerAttacker].species; + if (gBattleMons[gBattlerAttacker].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) + gBattleMons[gBattlerAttacker].species = SPECIES_MIMIKYU_BUSTED_TOTEM; + else + gBattleMons[gBattlerAttacker].species = SPECIES_MIMIKYU_BUSTED; + if (GetGenConfig(GEN_CONFIG_DISGUISE_HP_LOSS) >= GEN_8) + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 8); + BattleScriptPush(BattleScript_MoveEnd); + gBattlescriptCurrInstr = BattleScript_TargetFormChange; } static void Cmd_return(void) @@ -5771,16 +5797,14 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) && (!IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) && !gBattleStruct->noTargetPresent) { + s32 recoil = 0; if (B_RECOIL_IF_MISS_DMG >= GEN_5 || (B_CRASH_IF_TARGET_IMMUNE == GEN_4 && gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_DOESNT_AFFECT_FOE)) - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; + recoil = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; else if (B_RECOIL_IF_MISS_DMG == GEN_4 && (GetNonDynamaxMaxHP(gBattlerTarget) / 2) < gBattleStruct->moveDamage[gBattlerTarget]) - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; + recoil = GetNonDynamaxMaxHP(gBattlerTarget) / 2; else // Fallback if B_RECOIL_IF_MISS_DMG is set to gen3 or lower. - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; - - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - + recoil = GetNonDynamaxMaxHP(gBattlerTarget) / 2; + SetPassiveDamageAmount(gBattlerAttacker, recoil); BattleScriptCall(BattleScript_RecoilIfMiss); effect = TRUE; } @@ -5788,7 +5812,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) case EFFECT_RECOIL: if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker)) { - gBattleStruct->moveDamage[gBattlerAttacker] = max(1, gBattleScripting.savedDmg * max(1, GetMoveRecoil(gCurrentMove)) / 100); + SetPassiveDamageAmount(gBattlerAttacker, gBattleScripting.savedDmg * max(1, GetMoveRecoil(gCurrentMove)) / 100); BattleScriptCall(BattleScript_MoveEffectRecoil); effect = TRUE; } @@ -5796,7 +5820,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) case EFFECT_EXPLOSION: if (!IsAbilityOnField(ABILITY_DAMP)) { - gBattleStruct->moveDamage[gBattlerAttacker] = 0; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = 0; BattleScriptCall(BattleScript_FaintAttackerForExplosion); effect = TRUE; } @@ -5806,7 +5830,8 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) { - gBattleStruct->moveDamage[gBattlerAttacker] = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP + s32 recoil = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP + SetPassiveDamageAmount(gBattlerAttacker, recoil); BattleScriptCall(BattleScript_MaxHp50Recoil); effect = TRUE; } @@ -5814,7 +5839,8 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect) case EFFECT_CHLOROBLAST: if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker)) { - gBattleStruct->moveDamage[gBattlerAttacker] = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP + s32 recoil = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP + SetPassiveDamageAmount(gBattlerAttacker, recoil); BattleScriptCall(BattleScript_MoveEffectRecoil); effect = TRUE; } @@ -5921,9 +5947,7 @@ static void Cmd_moveend(void) && !IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_MAGIC_GUARD)) { gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 8; - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 8); PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SPIKY_SHIELD); BattleScriptCall(BattleScript_SpikyShieldEffect); effect = 1; @@ -6027,20 +6051,19 @@ static void Cmd_moveend(void) && gBattleStruct->moveDamage[gBattlerTarget] > 0 && IsBattlerAlive(gBattlerAttacker)) { - gBattleStruct->moveDamage[gBattlerAttacker] = max(1, (gBattleStruct->moveDamage[gBattlerTarget] * GetMoveAbsorbPercentage(gCurrentMove) / 100)); - gBattleStruct->moveDamage[gBattlerAttacker] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]); - - gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_HP_UPDATE; + s32 healAmount = (gBattleStruct->moveDamage[gBattlerTarget] * GetMoveAbsorbPercentage(gCurrentMove) / 100); + healAmount = GetDrainedBigRootHp(gBattlerAttacker, healAmount); effect = TRUE; if ((moveEffect == EFFECT_DREAM_EATER && GetGenConfig(GEN_DREAM_EATER_LIQUID_OOZE) < GEN_5) || GetBattlerAbility(gBattlerTarget) != ABILITY_LIQUID_OOZE) { + SetHealAmount(gBattlerAttacker, healAmount); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB; BattleScriptCall(BattleScript_EffectAbsorb); } - else + else // Liquid Ooze damage { - gBattleStruct->moveDamage[gBattlerAttacker] *= -1; + SetPassiveDamageAmount(gBattlerAttacker, healAmount); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB_OOZE; BattleScriptCall(BattleScript_EffectAbsorbLiquidOoze); } @@ -7703,10 +7726,8 @@ void TryHazardsOnSwitchIn(u32 battler, u32 side, enum Hazards hazardType) && IsBattlerAffectedByHazards(battler, FALSE) && IsBattlerGrounded(battler, ability, GetBattlerHoldEffect(battler))) { - u8 spikesDmg = (5 - gSideTimers[side].spikesAmount) * 2; - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (spikesDmg); - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; + s32 spikesDmg = GetNonDynamaxMaxHP(battler) / ((5 - gSideTimers[side].spikesAmount) * 2); + SetPassiveDamageAmount(battler, spikesDmg); SetDmgHazardsBattlescript(battler, B_MSG_PKMNHURTBYSPIKES); } break; @@ -7754,16 +7775,16 @@ void TryHazardsOnSwitchIn(u32 battler, u32 side, enum Hazards hazardType) case HAZARDS_STEALTH_ROCK: if (IsBattlerAffectedByHazards(battler, FALSE) && GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD) { - gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(TYPE_SIDE_HAZARD_POINTED_STONES, battler); - if (gBattleStruct->moveDamage[battler] != 0) + gBattleStruct->passiveHpUpdate[battler] = GetStealthHazardDamage(TYPE_SIDE_HAZARD_POINTED_STONES, battler); + if (gBattleStruct->passiveHpUpdate[battler] != 0) SetDmgHazardsBattlescript(battler, B_MSG_STEALTHROCKDMG); } break; case HAZARDS_STEELSURGE: if (IsBattlerAffectedByHazards(battler, FALSE) && GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD) { - gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(TYPE_SIDE_HAZARD_SHARP_STEEL, battler); - if (gBattleStruct->moveDamage[battler] != 0) + gBattleStruct->passiveHpUpdate[battler] = GetStealthHazardDamage(TYPE_SIDE_HAZARD_SHARP_STEEL, battler); + if (gBattleStruct->passiveHpUpdate[battler] != 0) SetDmgHazardsBattlescript(battler, B_MSG_SHARPSTEELDMG); } break; @@ -7814,7 +7835,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) else if (gBattleMons[battler].hp != gBattleMons[battler].maxHP && gBattleStruct->zmove.healReplacement) { gBattleStruct->zmove.healReplacement = FALSE; - gBattleStruct->moveDamage[battler] = -1 * (gBattleMons[battler].maxHP); + SetHealAmount(battler, gBattleMons[battler].maxHP); gBattleScripting.battler = battler; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_HP_TRAP; BattleScriptCall(BattleScript_HealReplacementZMove); @@ -8256,6 +8277,7 @@ static void Cmd_yesnoboxstoplearningmove(void) } } +// TODO: passive damage hit anim for sub static void Cmd_hitanimation(void) { CMD_ARGS(u8 battler); @@ -8266,7 +8288,7 @@ static void Cmd_hitanimation(void) if (!(gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_NO_EFFECT)) { - if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) + if (gBattleStruct->passiveHpUpdate[battler] > 0 || !(DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)) || gDisableStructs[battler].substituteHP == 0) { @@ -8284,8 +8306,7 @@ static void Cmd_hitanimation(void) || gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE) continue; - if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) - || !(DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove)) + if (!(DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove)) || gDisableStructs[battlerDef].substituteHP == 0) { BtlController_EmitHitAnimation(battlerDef, B_COMM_TO_CONTROLLER); @@ -8602,13 +8623,8 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId) && GetBattlerPartyState(battler)->ateBerry && !IsBattlerAtMaxHp(battler)) { - gBattleStruct->cheekPouchActivated = TRUE; - gBattleStruct->savedcheekPouchDamage = gBattleStruct->moveDamage[battler]; - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 3; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; gBattlerAbility = battler; + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 3); BattleScriptPush(gBattlescriptCurrInstr + 2); gBattlescriptCurrInstr = BattleScript_CheekPouchActivates; return TRUE; @@ -8616,16 +8632,6 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId) return FALSE; } -// When Cheek Pouch activates mid-battle it overwrites the current damage, so restore it -static void TryRestoreDamageAfterCheekPouch(u32 battler) -{ - if (gBattleStruct->cheekPouchActivated) - { - gBattleStruct->moveDamage[battler] = gBattleStruct->savedcheekPouchDamage; - gBattleStruct->cheekPouchActivated = FALSE; - } -} - // Used by Bestow and Symbiosis to take an item from one battler and give to another. static void BestowItem(u32 battlerAtk, u32 battlerDef) { @@ -9614,7 +9620,7 @@ static void Cmd_tryexplosion(void) if (gBattleControllerExecFlags) return; - gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp; BtlController_EmitHealthBarUpdate(gBattlerAttacker, B_COMM_TO_CONTROLLER, INSTANT_HP_BAR_DROP); MarkBattlerForControllerExec(gBattlerAttacker); gBattlescriptCurrInstr = cmd->nextInstr; @@ -9668,11 +9674,7 @@ static void Cmd_tryhealhalfhealth(void) if (cmd->battler == BS_ATTACKER) gBattlerTarget = gBattlerAttacker; - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = 1; - gBattleStruct->moveDamage[gBattlerTarget] *= -1; - + SetHealAmount(gBattlerTarget, GetNonDynamaxMaxHP(gBattlerTarget) / 2); if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) gBattlescriptCurrInstr = failInstr; else @@ -9762,21 +9764,19 @@ static void Cmd_manipulatedamage(void) switch (cmd->mode) { case DMG_CHANGE_SIGN: - gBattleStruct->moveDamage[gBattlerAttacker] *= -1; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] *= -1; break; case DMG_DOUBLED: gBattleStruct->moveDamage[gBattlerTarget] *= 2; break; case DMG_1_8_TARGET_HP: - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerTarget) / 8; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = 1; + SetPassiveDamageAmount(gBattlerTarget, GetNonDynamaxMaxHP(gBattlerTarget) / 8); break; case DMG_FULL_ATTACKER_HP: - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerAttacker); + gBattleStruct->passiveHpUpdate[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerAttacker); break; case DMG_BIG_ROOT: - gBattleStruct->moveDamage[gBattlerAttacker] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]); + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = -1 * GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->passiveHpUpdate[gBattlerAttacker]); break; } @@ -9788,7 +9788,7 @@ static void Cmd_trysetrest(void) CMD_ARGS(); gBattlerTarget = gBattlerAttacker; - gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].maxHP * (-1); + SetHealAmount(gBattlerTarget, gBattleMons[gBattlerTarget].maxHP); enum Ability ability = GetBattlerAbility(gBattlerTarget); enum HoldEffect holdEffect = GetBattlerHoldEffect(gBattlerTarget); @@ -9910,19 +9910,15 @@ static void Cmd_stockpiletohpheal(void) { if (gDisableStructs[gBattlerAttacker].stockpileCounter > 0) { - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / (1 << (3 - gDisableStructs[gBattlerAttacker].stockpileCounter)); + SetHealAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / (1 << (3 - gDisableStructs[gBattlerAttacker].stockpileCounter))); gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter; } else // Snatched move { - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; + SetHealAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 4); gBattleScripting.animTurn = 1; } - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - gBattleStruct->moveDamage[gBattlerAttacker] *= -1; - gBattlescriptCurrInstr = cmd->nextInstr; gBattlerTarget = gBattlerAttacker; } @@ -9946,17 +9942,8 @@ void BS_RemoveStockpileCounters(void) } } -// Sign change for drained HP handled in GetDrainedBigRootHp -static void Cmd_setdrainedhp(void) +static void Cmd_unused_0x88(void) { - CMD_ARGS(); - - gBattleStruct->moveDamage[gBattlerAttacker] = (gBattleStruct->moveDamage[gBattlerTarget] * GetMoveAbsorbPercentage(gCurrentMove) / 100); - - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - - gBattlescriptCurrInstr = cmd->nextInstr; } static u16 ReverseStatChangeMoveEffect(u16 moveEffect) @@ -11143,7 +11130,7 @@ static void Cmd_setsubstitute(void) CMD_ARGS(); u32 factor = GetMoveEffect(gCurrentMove) == EFFECT_SHED_TAIL ? 2 : 4; - u32 hp; + s32 hp = 0; if (factor == 2) hp = (GetNonDynamaxMaxHP(gBattlerAttacker)+1) / factor; // shed tail rounds up @@ -11155,25 +11142,22 @@ static void Cmd_setsubstitute(void) if (gBattleMons[gBattlerAttacker].hp <= hp) { - gBattleStruct->moveDamage[gBattlerAttacker] = 0; + hp = 0; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SUBSTITUTE_FAILED; } else { - gBattleStruct->moveDamage[gBattlerAttacker] = hp; // one bit value will only work for Pokémon which max hp can go to 1020(which is more than possible in games) - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - gBattleMons[gBattlerAttacker].volatiles.substitute = TRUE; gBattleMons[gBattlerAttacker].volatiles.wrapped = FALSE; + // gDisableStructs[gBattlerAttacker].substituteHP = (factor == 2) ? (hp / 2) : hp; if (factor == 2) - gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker] / 2; + gDisableStructs[gBattlerAttacker].substituteHP = hp / 2; else - gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker]; + gDisableStructs[gBattlerAttacker].substituteHP = hp; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SUBSTITUTE; - gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; } + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = hp; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -11374,8 +11358,8 @@ static void Cmd_painsplitdmgcalc(void) { s32 hpDiff = (gBattleMons[gBattlerAttacker].hp + GetNonDynamaxHP(gBattlerTarget)) / 2; - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) - hpDiff; - gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp - hpDiff; + gBattleStruct->passiveHpUpdate[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) - hpDiff; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp - hpDiff; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -11806,10 +11790,7 @@ static void Cmd_cursetarget(void) else { gBattleMons[gBattlerTarget].volatiles.cursed = TRUE; - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 2); gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -11980,11 +11961,7 @@ static void Cmd_presentdamagecalculation(void) } else { - // TODO: Check if this is correct - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerTarget) / 4; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = 1; - gBattleStruct->moveDamage[gBattlerTarget] *= -1; + SetHealAmount(gBattlerTarget, GetNonDynamaxMaxHP(gBattlerTarget) / 4); gBattleStruct->presentBasePower = 0; } } @@ -12159,10 +12136,7 @@ static void Cmd_halvehp(void) if (gBattleMons[gBattlerAttacker].hp > halfHp) { - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 2); gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -12236,21 +12210,22 @@ static void Cmd_recoverbasedonsunlight(void) gBattlerTarget = gBattlerAttacker; if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP) { + s32 recoverAmount = 0; if (GetMoveEffect(gCurrentMove) == EFFECT_SHORE_UP) { if (HasWeatherEffect() && gBattleWeather & B_WEATHER_SANDSTORM) - gBattleStruct->moveDamage[gBattlerAttacker] = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30; + recoverAmount = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30; else - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; + recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; } else if (GetGenConfig(GEN_CONFIG_TIME_OF_DAY_HEALING_MOVES) != GEN_2) { if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA) - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; + recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; else if (gBattleWeather & B_WEATHER_SUN) - gBattleStruct->moveDamage[gBattlerAttacker] = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30; + recoverAmount = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30; else // not sunny weather - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; + recoverAmount = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; } else // B_TIME_OF_DAY_HEALING_MOVES == GEN_2 { @@ -12278,18 +12253,15 @@ static void Cmd_recoverbasedonsunlight(void) } if (!(gBattleWeather & B_WEATHER_ANY) || !HasWeatherEffect() || GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_UTILITY_UMBRELLA) - gBattleStruct->moveDamage[gBattlerAttacker] = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 4; + recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 4; else if (gBattleWeather & B_WEATHER_SUN) - gBattleStruct->moveDamage[gBattlerAttacker] = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 2; + recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 2; else // not sunny weather - gBattleStruct->moveDamage[gBattlerAttacker] = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 8; + recoverAmount = healingModifier * GetNonDynamaxMaxHP(gBattlerAttacker) / 8; } - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - gBattleStruct->moveDamage[gBattlerAttacker] *= -1; - + SetHealAmount(gBattlerAttacker, recoverAmount); gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -12480,9 +12452,10 @@ static void Cmd_trymemento(void) else { // Success, drop user's HP bar to 0 - gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp; BtlController_EmitHealthBarUpdate(gBattlerAttacker, B_COMM_TO_CONTROLLER, INSTANT_HP_BAR_DROP); MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -13305,10 +13278,10 @@ bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move) bool32 DoesDisguiseBlockMove(u32 battler, u32 move) { - if (!(gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) - || gBattleMons[battler].volatiles.transformed - || (!gProtectStructs[battler].confusionSelfDmg && (IsBattleMoveStatus(move) || gHitMarker & HITMARKER_PASSIVE_HP_UPDATE)) - || !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_DISGUISE)) + if (!IsMimikyuDisguised(battler) + || gBattleMons[battler].volatiles.transformed + || (!gProtectStructs[battler].confusionSelfDmg && IsBattleMoveStatus(move)) + || !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_DISGUISE)) return FALSE; else return TRUE; @@ -14178,12 +14151,8 @@ static void Cmd_trygivecaughtmonnick(void) } } -static void Cmd_subattackerhpbydmg(void) +static void Cmd_unused_0xf4(void) { - CMD_ARGS(); - - gBattleMons[gBattlerAttacker].hp -= gBattleStruct->moveDamage[gBattlerTarget]; - gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_removeattackerstatus1(void) @@ -14853,7 +14822,7 @@ void BS_ItemRestoreHP(void) // Heal is applied as move damage if battler is active. if (battler != MAX_BATTLERS_COUNT && hp != 0) { - gBattleStruct->moveDamage[battler] = -healAmount; + gBattleStruct->passiveHpUpdate[battler] = -healAmount; gBattlescriptCurrInstr = cmd->restoreBattlerInstr; } else @@ -15328,15 +15297,15 @@ void BS_TryHealPulse(void) } else { + s32 healAmount = 0; if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && IsPulseMove(gCurrentMove)) - gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 75 / 100); + healAmount = GetNonDynamaxMaxHP(gBattlerTarget) * 75 / 100; else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_FLORAL_HEALING) - gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 2 / 3); + healAmount = GetNonDynamaxMaxHP(gBattlerTarget) * 2 / 3; else - gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) / 2); + healAmount = GetNonDynamaxMaxHP(gBattlerTarget) / 2; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = -1; + SetHealAmount(gBattlerTarget, healAmount); gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -15548,12 +15517,8 @@ void BS_TryActivateGulpMissile(void) && gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT && GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE) { - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) - { - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = 1; - } + if (!IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_MAGIC_GUARD)) + SetPassiveDamageAmount(gBattlerTarget, GetNonDynamaxMaxHP(gBattlerAttacker) / 4); switch(gBattleMons[gBattlerTarget].species) { @@ -16268,11 +16233,7 @@ void BS_TrySetTorment(void) void BS_HealOneSixth(void) { NATIVE_ARGS(const u8* failInstr); - gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].maxHP / 6; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = 1; - gBattleStruct->moveDamage[gBattlerTarget] *= -1; - + SetHealAmount(gBattlerTarget, gBattleMons[gBattlerTarget].maxHP / 6); if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) gBattlescriptCurrInstr = cmd->failInstr; // fail else @@ -16568,9 +16529,9 @@ void BS_GetStatValue(void) { NATIVE_ARGS(u8 stat); u32 stat = cmd->stat; - gBattleStruct->moveDamage[gBattlerAttacker] = *(u16 *)(&gBattleMons[gBattlerTarget].attack) + (stat - 1); - gBattleStruct->moveDamage[gBattlerAttacker] *= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][0]; - gBattleStruct->moveDamage[gBattlerAttacker] /= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][1]; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = *(u16 *)(&gBattleMons[gBattlerTarget].attack) + (stat - 1); + gBattleStruct->passiveHpUpdate[gBattlerAttacker] *= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][0]; + gBattleStruct->passiveHpUpdate[gBattlerAttacker] /= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][1]; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -17672,11 +17633,7 @@ void BS_TryHealQuarterHealth(void) { NATIVE_ARGS(u8 battler, const u8 *failInstr); u32 battler = GetBattlerForBattleScript(cmd->battler); - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; - + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 4); if (gBattleMons[battler].hp == gBattleMons[battler].maxHP) gBattlescriptCurrInstr = cmd->failInstr; // fail else @@ -17950,7 +17907,7 @@ void BS_CutOneThirdHpAndRaiseStats(void) } if (atLeastOneStatBoosted) { - gBattleStruct->moveDamage[gBattlerAttacker] = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 3); + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 3); gBattlescriptCurrInstr = cmd->nextInstr; } else diff --git a/src/battle_util.c b/src/battle_util.c index 53ec033938..22b26e11e4 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -914,9 +914,7 @@ void HandleAction_NothingIsFainted(void) gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE; gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_ATTACKSTRING_PRINTED - | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_STATUS_ABILITY_EFFECT - | HITMARKER_PASSIVE_HP_UPDATE | HITMARKER_OBEYS); } @@ -929,10 +927,8 @@ void HandleAction_ActionFinished(void) gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses)); gHitMarker &= ~(HITMARKER_DESTINYBOND - | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED | HITMARKER_STATUS_ABILITY_EFFECT - | HITMARKER_PASSIVE_HP_UPDATE | HITMARKER_OBEYS); ClearDamageCalcResults(); @@ -1790,7 +1786,7 @@ void TryToRevertMimicryAndFlags(void) bool32 BattleArenaTurnEnd(void) { - gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_IGNORE_BIDE); + gHitMarker |= HITMARKER_GRUDGE; if ((gBattleTypeFlags & BATTLE_TYPE_ARENA) && gBattleStruct->arenaTurnCounter == 2 @@ -1804,7 +1800,7 @@ bool32 BattleArenaTurnEnd(void) return TRUE; } - gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_IGNORE_BIDE); + gHitMarker &= ~HITMARKER_GRUDGE; return FALSE; } @@ -1817,7 +1813,7 @@ s32 GetDrainedBigRootHp(u32 battler, s32 hp) if (hp == 0) hp = 1; - return hp * -1; + return hp; } // Should always be the last check. Otherwise the ability might be wrongly recorded. @@ -2258,7 +2254,7 @@ static enum MoveCanceller CancellerConfused(struct BattleContext *ctx) dmgCtx.randomFactor = FALSE; dmgCtx.updateFlags = TRUE; dmgCtx.fixedBasePower = 40; - gBattleStruct->moveDamage[ctx->battlerAtk] = CalculateMoveDamage(&dmgCtx); + gBattleStruct->passiveHpUpdate[ctx->battlerAtk] = CalculateMoveDamage(&dmgCtx); gProtectStructs[ctx->battlerAtk].confusionSelfDmg = TRUE; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused; @@ -2735,7 +2731,7 @@ static enum MoveCanceller CancellerPowderStatus(struct BattleContext *ctx) if (TryActivatePowderStatus(ctx->currentMove)) { if (!IsAbilityAndRecord(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk], ABILITY_MAGIC_GUARD)) - gBattleStruct->moveDamage[ctx->battlerAtk] = GetNonDynamaxMaxHP(ctx->battlerAtk) / 4; + SetPassiveDamageAmount(ctx->battlerAtk, GetNonDynamaxMaxHP(ctx->battlerAtk) / 4); // This might be incorrect if (GetActiveGimmick(ctx->battlerAtk) != GIMMICK_Z_MOVE @@ -3543,10 +3539,7 @@ bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, enum Ability ability else { battleScript = BattleScript_MoveHPDrain; - gBattleStruct->moveDamage[battlerDef] = GetNonDynamaxMaxHP(battlerDef) / 4; - if (gBattleStruct->moveDamage[battlerDef] == 0) - gBattleStruct->moveDamage[battlerDef] = 1; - gBattleStruct->moveDamage[battlerDef] *= -1; + SetHealAmount(battlerDef, GetNonDynamaxMaxHP(battlerDef) / 4); } break; case MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY: @@ -4459,7 +4452,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec { gEffectBattler = partner; gSpecialStatuses[battler].switchInAbilityDone = TRUE; - gBattleStruct->moveDamage[partner] = (GetNonDynamaxMaxHP(partner) / 4) * -1; + SetHealAmount(partner, GetNonDynamaxMaxHP(partner) / 4); BattleScriptPushCursorAndCallback(BattleScript_HospitalityActivates); effect++; } @@ -4575,10 +4568,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec && !gBattleMons[battler].volatiles.healBlock) { BattleScriptExecute(BattleScript_IceBodyHeal); - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / 16); effect++; } break; @@ -4591,11 +4581,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec && !IsBattlerAtMaxHp(battler) && !gBattleMons[battler].volatiles.healBlock) { + s32 healAmount = gLastUsedAbility == ABILITY_RAIN_DISH ? 16 : 8; + SetHealAmount(battler, GetNonDynamaxMaxHP(battler) / healAmount); BattleScriptExecute(BattleScript_RainDishActivates); - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (gLastUsedAbility == ABILITY_RAIN_DISH ? 16 : 8); - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; effect++; } break; @@ -4694,10 +4682,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec if (IsBattlerWeatherAffected(battler, B_WEATHER_SUN)) { SOLAR_POWER_HP_DROP: + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8); BattleScriptExecute(BattleScript_SolarPowerActivates); - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; effect++; } break; @@ -4985,9 +4971,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec && IsBattlerTurnDamaged(gBattlerTarget) && !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker), move)) { - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / (B_ROUGH_SKIN_DMG >= GEN_4 ? 8 : 16); - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / (B_ROUGH_SKIN_DMG >= GEN_4 ? 8 : 16)); PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility); BattleScriptCall(BattleScript_RoughSkinActivates); effect++; @@ -5007,9 +4991,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec else { gBattleScripting.battler = gBattlerTarget; - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 4); BattleScriptCall(BattleScript_AftermathDmg); } effect++; @@ -5025,7 +5007,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec break; gBattleScripting.battler = gBattlerTarget; - gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget]; + SetPassiveDamageAmount(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerTarget]); BattleScriptCall(BattleScript_AftermathDmg); effect++; } @@ -5225,12 +5207,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, enum Ability ability, u32 spec && IsBattlerAlive(gBattlerAttacker) && gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT) { - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) - { - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - } + if (!IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_MAGIC_GUARD)) + SetPassiveDamageAmount(gBattlerAttacker, GetNonDynamaxMaxHP(gBattlerAttacker) / 4); switch(gBattleMons[gBattlerTarget].species) { @@ -10966,3 +10944,9 @@ bool32 IsAllowedToUseBag(void) return TRUE; // Undefined Behavior } } + +bool32 IsMimikyuDisguised(u32 battler) +{ + return gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED + || gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED; +} diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 196d462d62..be3ae07265 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -506,7 +506,7 @@ void SetZEffect(void) case Z_EFFECT_RECOVER_HP: if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP) { - gBattleStruct->moveDamage[gBattlerAttacker] = (-1) * gBattleMons[gBattlerAttacker].maxHP; + SetHealAmount(gBattlerAttacker, gBattleMons[gBattlerAttacker].maxHP); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_RECOVER_HP; BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH); gBattlescriptCurrInstr = BattleScript_RecoverHPZMove;