Skip to content

Commit

Permalink
Explosion and Mind Blown / Steel Beam refactor (CFRU port) (#4516)
Browse files Browse the repository at this point in the history
* Explosion and Mind Blown / Steel Beam refactor (CFRU port)

* forgot ndebug

* Restored EFFECT_MIND_BLOWN

* requested changes

---------

Co-authored-by: Eduardo Quezada <[email protected]>
  • Loading branch information
AlexOn1ine and AsparagusEduardo authored May 12, 2024
1 parent f502ba2 commit 56cee80
Show file tree
Hide file tree
Showing 15 changed files with 318 additions and 187 deletions.
4 changes: 0 additions & 4 deletions asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2379,10 +2379,6 @@
manipulatedamage DMG_CURR_ATTACKER_HP
.endm

.macro dmg_1_2_attackerhp
manipulatedamage DMG_1_2_ATTACKER_HP
.endm

.macro jumpifflowerveil jumpInstr:req
jumpifnottype BS_TARGET, TYPE_GRASS, 1f
jumpifability BS_TARGET_SIDE, ABILITY_FLOWER_VEIL, \jumpInstr
Expand Down
119 changes: 20 additions & 99 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -547,36 +547,6 @@ BattleScript_EffectShellTrap::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd

BattleScript_EffectMaxHp50Recoil::
attackcanceler
attackstring
ppreduce
accuracycheck BattleScript_SteelBeamMiss, ACC_CURR_MOVE
call BattleScript_EffectHit_RetFromCritCalc
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_SteelBeamAfterSelfDamage
call BattleScript_SteelBeamSelfDamage
BattleScript_SteelBeamAfterSelfDamage::
waitstate
tryfaintmon BS_ATTACKER
tryfaintmon BS_TARGET
goto BattleScript_MoveEnd
BattleScript_SteelBeamMiss::
pause B_WAIT_TIME_SHORT
effectivenesssound
resultmessage
waitmessage B_WAIT_TIME_LONG
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_MoveEnd
bichalfword gMoveResultFlags, MOVE_RESULT_MISSED
call BattleScript_SteelBeamSelfDamage
orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
goto BattleScript_SteelBeamAfterSelfDamage

BattleScript_SteelBeamSelfDamage::
dmg_1_2_attackerhp
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
return

BattleScript_EffectCourtChange::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
Expand Down Expand Up @@ -2968,84 +2938,26 @@ BattleScript_AbsorbHealBlock::
tryfaintmon BS_TARGET
goto BattleScript_MoveEnd

BattleScript_EffectExplosion_AnimDmgRet:
jumpifbyte CMP_NO_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_MISSED, BattleScript_ExplosionAnimRet
call BattleScript_PreserveMissedBitDoMoveAnim
goto BattleScript_ExplosionDmgRet
BattleScript_ExplosionAnimRet:
attackanimation
waitanimation
BattleScript_ExplosionDmgRet:
movevaluescleanup
critcalc
damagecalc
adjustdamage
accuracycheck BattleScript_ExplosionMissedRet, ACC_CURR_MOVE
effectivenesssound
hitanimation BS_TARGET
waitstate
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
critmessage
waitmessage B_WAIT_TIME_LONG
resultmessage
waitmessage B_WAIT_TIME_LONG
tryfaintmon BS_TARGET
BattleScript_ExplosionAnimEndRet_Return:
return
BattleScript_ExplosionMissedRet:
effectivenesssound
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_ExplosionAnimEndRet_Return

BattleScript_EffectExplosion::
attackcanceler
attackstring
ppreduce
@ Below jumps to BattleScript_DampStopsExplosion if it fails (only way it can)
tryexplosion
waitstate
BattleScript_EffectExplosion_AnimDmgFaintAttacker:
call BattleScript_EffectExplosion_AnimDmgRet
moveendall
setatkhptozero
waitstate
jumpiffainted BS_TARGET, TRUE, BattleScript_MoveEnd
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
goto BattleScript_HitFromCritCalc

BattleScript_FaintAttackerForExplosion::
tryfaintmon BS_ATTACKER
end
return

BattleScript_EffectMindBlown::
attackcanceler
attackstring
ppreduce
jumpifbyte CMP_GREATER_THAN, sB_ANIM_TARGETS_HIT, 0, BattleScript_EffectMindBlown_NoHpLoss
jumpifabilitypresent ABILITY_DAMP, BattleScript_MindBlownDamp
jumpifmorethanhalfHP BS_ATTACKER, BattleScript_EffectMindBlown_HpDown
setbyte sMULTIHIT_EFFECT, 0 @ Note to faint the attacker
instanthpdrop BS_ATTACKER
waitstate
goto BattleScript_EffectExplosion_AnimDmgFaintAttacker
BattleScript_EffectMindBlown_NoHpLoss:
jumpifbyte CMP_EQUAL, sMULTIHIT_EFFECT, 0, BattleScript_EffectExplosion_AnimDmgFaintAttacker
goto BattleScript_EffectMindBlown_AnimDmgNoFaint
BattleScript_MindBlownDamp:
copybyte gBattlerTarget, gBattlerAbility
goto BattleScript_DampStopsExplosion
BattleScript_EffectMindBlown_HpDown:
setbyte sMULTIHIT_EFFECT, 1 @ Note to not faint the attacker
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_EffectMindBlown_AnimDmgNoFaint
dmg_1_2_attackerhp
BattleScript_MaxHp50Recoil::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
waitstate
BattleScript_EffectMindBlown_AnimDmgNoFaint:
call BattleScript_EffectExplosion_AnimDmgRet
goto BattleScript_MoveEnd

BattleScript_PreserveMissedBitDoMoveAnim:
bichalfword gMoveResultFlags, MOVE_RESULT_MISSED
attackanimation
waitanimation
orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
tryfaintmon BS_ATTACKER
return

BattleScript_EffectDreamEater::
Expand Down Expand Up @@ -7597,6 +7509,15 @@ BattleScript_AbilityPopUp:
sethword sABILITY_OVERWRITE, 0
return

BattleScript_AbilityPopUpScripting:
.if B_ABILITY_POP_UP == TRUE
showabilitypopup BS_SCRIPTING
pause 40
.endif
recordability BS_SCRIPTING
sethword sABILITY_OVERWRITE, 0
return

BattleScript_SpeedBoostActivates::
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_SpeedBoostActivatesEnd
call BattleScript_AbilityPopUp
Expand Down Expand Up @@ -8130,7 +8051,7 @@ BattleScript_SturdyPreventsOHKO::

BattleScript_DampStopsExplosion::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUpTarget
call BattleScript_AbilityPopUpScripting
printstring STRINGID_PKMNPREVENTSUSAGE
pause B_WAIT_TIME_LONG
moveendto MOVEEND_NEXT_TARGET
Expand Down
4 changes: 2 additions & 2 deletions include/battle_scripts.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ extern const u8 BattleScript_MoveEffectPayDay[];
extern const u8 BattleScript_MoveEffectWrap[];
extern const u8 BattleScript_MoveEffectConfusion[];
extern const u8 BattleScript_MoveEffectRecoil[];
extern const u8 BattleScript_FaintAttackerForExplosion[];
extern const u8 BattleScript_MaxHp50Recoil[];
extern const u8 BattleScript_DoRecoil33[];
extern const u8 BattleScript_Recoil33End[];
extern const u8 BattleScript_ItemSteal[];
Expand Down Expand Up @@ -772,7 +774,6 @@ extern const u8 BattleScript_EffectLaserFocus[];
extern const u8 BattleScript_EffectMagneticFlux[];
extern const u8 BattleScript_EffectGearUp[];
extern const u8 BattleScript_EffectStrengthSap[];
extern const u8 BattleScript_EffectMindBlown[];
extern const u8 BattleScript_EffectPurify[];
extern const u8 BattleScript_FailIfNotArgType[];
extern const u8 BattleScript_EffectShoreUp[];
Expand Down Expand Up @@ -804,7 +805,6 @@ extern const u8 BattleScript_EffectClangorousSoul[];
extern const u8 BattleScript_EffectSkyDrop[];
extern const u8 BattleScript_EffectMeteorBeam[];
extern const u8 BattleScript_EffectCourtChange[];
extern const u8 BattleScript_EffectMaxHp50Recoil[];
extern const u8 BattleScript_EffectExtremeEvoboost[];
extern const u8 BattleScript_EffectHitSetRemoveTerrain[];
extern const u8 BattleScript_EffectDarkVoid[];
Expand Down
1 change: 1 addition & 0 deletions include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ enum
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP,
CANCELLER_EXPLODING_DAMP,
CANCELLER_MULTIHIT_MOVES,
CANCELLER_Z_MOVES,
CANCELLER_END,
Expand Down
2 changes: 1 addition & 1 deletion include/constants/battle_move_effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ enum {
EFFECT_MAGNETIC_FLUX,
EFFECT_GEAR_UP,
EFFECT_STRENGTH_SAP,
EFFECT_MIND_BLOWN,
EFFECT_PURIFY,
EFFECT_FAIL_IF_NOT_ARG_TYPE,
EFFECT_SHORE_UP,
Expand Down Expand Up @@ -318,6 +317,7 @@ enum {
EFFECT_BEAK_BLAST,
EFFECT_COURT_CHANGE,
EFFECT_MAX_HP_50_RECOIL,
EFFECT_MIND_BLOWN, // Same as EFFECT_MAX_HP_50_RECOIL but is cancelled by Damp
EFFECT_EXTREME_EVOBOOST,
EFFECT_HIT_SET_REMOVE_TERRAIN,
EFFECT_DARK_VOID,
Expand Down
3 changes: 1 addition & 2 deletions include/constants/battle_script_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,7 @@
#define DMG_FULL_ATTACKER_HP 4
#define DMG_CURR_ATTACKER_HP 5
#define DMG_BIG_ROOT 6
#define DMG_1_2_ATTACKER_HP 7
#define DMG_RECOIL_FROM_IMMUNE 8 // Used to calculate recoil for the Gen 4 version of Jump Kick
#define DMG_RECOIL_FROM_IMMUNE 7 // Used to calculate recoil for the Gen 4 version of Jump Kick

// Cmd_jumpifcantswitch
#define SWITCH_IGNORE_ESCAPE_PREVENTION (1 << 7)
Expand Down
2 changes: 1 addition & 1 deletion src/battle_ai_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,8 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s

switch (gMovesInfo[move].effect)
{
case EFFECT_MIND_BLOWN:
case EFFECT_MAX_HP_50_RECOIL:
case EFFECT_MIND_BLOWN:
return TRUE;
case EFFECT_RECOIL_IF_MISS:
if (AI_IsDamagedByRecoil(battlerAtk))
Expand Down
83 changes: 41 additions & 42 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ static void Cmd_attackcanceler(void)
gCurrentActionFuncId = B_ACTION_FINISHED;
return;
}
if (gBattleMons[gBattlerAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
if (gBattleMons[gBattlerAttacker].hp == 0 && gMovesInfo[gCurrentMove].effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
gBattlescriptCurrInstr = BattleScript_MoveEnd;
Expand Down Expand Up @@ -5549,18 +5549,38 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_RECOIL:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& IsBattlerAlive(gBattlerAttacker)
&& gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one
if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
{
if (gMovesInfo[gCurrentMove].recoil > 0)
{
gBattleMoveDamage = max(1, gBattleScripting.savedDmg * max(1, gMovesInfo[gCurrentMove].recoil) / 100);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
effect = TRUE;
}
gBattleScripting.moveendState++;
break;
}
else if (gMovesInfo[gCurrentMove].recoil > 0
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& IsBattlerAlive(gBattlerAttacker)
&& gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one
{
gBattleMoveDamage = max(1, gBattleScripting.savedDmg * max(1, gMovesInfo[gCurrentMove].recoil) / 100);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
effect = TRUE;
}
else if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION && !IsAbilityOnField(ABILITY_DAMP))
{
gBattleMoveDamage = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_FaintAttackerForExplosion;
effect = TRUE;
}
else if ((gMovesInfo[gCurrentMove].effect == EFFECT_MAX_HP_50_RECOIL
|| gMovesInfo[gCurrentMove].effect == EFFECT_MIND_BLOWN)
&& IsBattlerAlive(gBattlerAttacker)
&& !(gMoveResultFlags & MOVE_RESULT_FAILED)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MaxHp50Recoil;
effect = TRUE;
}
gBattleScripting.moveendState++;
break;
Expand Down Expand Up @@ -5905,7 +5925,11 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState = 0;
MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove));

if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION)
BattleScriptPush(gBattleMoveEffects[EFFECT_HIT].battleScript); // Edge case for Explosion not changing targets
else
BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove));
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
Expand Down Expand Up @@ -7200,22 +7224,10 @@ static void Cmd_switchineffects(void)

gDisableStructs[battler].truantSwitchInHack = 0;

// Don't activate switch-in abilities if the opposing field is empty.
// This could happen when a mon uses explosion and causes everyone to faint.
if ((battlerAbility == ABILITY_INTIMIDATE || battlerAbility == ABILITY_SUPERSWEET_SYRUP || battlerAbility == ABILITY_DOWNLOAD)
&& !IsBattlerAlive(BATTLE_OPPOSITE(battler))
&& !IsBattlerAlive(BATTLE_PARTNER(BATTLE_OPPOSITE(battler))))
{
if (ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, battler, FALSE))
return;
}
else
{
if (DoSwitchInAbilities(battler) || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, battler, FALSE))
return;
else if (AbilityBattleEffects(ABILITYEFFECT_OPPORTUNIST, battler, 0, 0, 0))
return;
}
if (DoSwitchInAbilities(battler) || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, battler, FALSE))
return;
else if (AbilityBattleEffects(ABILITYEFFECT_OPPORTUNIST, battler, 0, 0, 0))
return;

gDisableStructs[battler].stickyWebDone = FALSE;
gDisableStructs[battler].spikesDone = FALSE;
Expand Down Expand Up @@ -10946,19 +10958,9 @@ static void Cmd_tryexplosion(void)
{
CMD_ARGS();

u32 dampBattler;
if (gBattleControllerExecFlags)
return;

if ((dampBattler = IsAbilityOnField(ABILITY_DAMP)))
{
// Failed, a battler has Damp
gLastUsedAbility = ABILITY_DAMP;
gBattlerTarget = --dampBattler;
gBattlescriptCurrInstr = BattleScript_DampStopsExplosion;
return;
}

gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp;
BtlController_EmitHealthBarUpdate(gBattlerAttacker, BUFFER_A, INSTANT_HP_BAR_DROP);
MarkBattlerForControllerExec(gBattlerAttacker);
Expand Down Expand Up @@ -11183,9 +11185,6 @@ static void Cmd_manipulatedamage(void)
case DMG_BIG_ROOT:
gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage);
break;
case DMG_1_2_ATTACKER_HP:
gBattleMoveDamage = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
break;
case DMG_RECOIL_FROM_IMMUNE:
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
break;
Expand Down
14 changes: 14 additions & 0 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -3554,6 +3554,20 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
}
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_EXPLODING_DAMP:
{
u32 dampBattler = IsAbilityOnField(ABILITY_DAMP);
if (dampBattler && (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION
|| gMovesInfo[gCurrentMove].effect == EFFECT_MIND_BLOWN))
{
gBattleScripting.battler = dampBattler - 1;
gBattlescriptCurrInstr = BattleScript_DampStopsExplosion;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
effect = 1;
}
gBattleStruct->atkCancellerTracker++;
break;
}
case CANCELLER_MULTIHIT_MOVES:
if (gMovesInfo[gCurrentMove].effect == EFFECT_MULTI_HIT)
{
Expand Down
Loading

0 comments on commit 56cee80

Please sign in to comment.