Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
psytp2 committed Sep 1, 2024
2 parents 1516eef + 484acdc commit 39f4c99
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 162 deletions.
77 changes: 41 additions & 36 deletions asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1674,14 +1674,51 @@
callnative BS_FickleBeamDamageCalculation
.endm

@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
.macro jumpifteainvulnerable battler:req, jumpInstr:req
callnative BS_TeatimeInvul
.byte \battler
.4byte \jumpInstr
.endm

.macro jumpifteanoberry failInstr:req
callnative BS_TeatimeTargets
.4byte \failInstr
.endm

.macro trywindriderpower battler:req, failInstr:req
callnative BS_TryWindRiderPower
.byte \battler
.4byte \failInstr
.endm

.macro activateweatherchangeabilities battler:req
callnative BS_ActivateWeatherChangeAbilities
.byte \battler
.endm

.macro activateterrainchangeabilities battler:req
callnative BS_ActivateTerrainChangeAbilities
.byte \battler
.endm

@ Stores Healing Wish effect.
.macro storehealingwish battler:req
various \battler, VARIOUS_STORE_HEALING_WISH
callnative BS_StoreHealingWish
.byte \battler
.endm

.macro hitswitchtargetfailed
callnative BS_HitSwitchTargetFailed
.endm

.macro tryrevivalblessing, failInstr:req
callnative BS_TryRevivalBlessing
.4byte \failInstr
.endm

@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
.endm

.macro setmagiccoattarget battler:req
Expand Down Expand Up @@ -2230,16 +2267,6 @@
.4byte \failInstr
.endm

.macro jumpifteanoberry jumpInstr:req
various BS_ATTACKER, VARIOUS_TEATIME_TARGETS
.4byte \jumpInstr
.endm

.macro jumpifteainvulnerable battler:req, jumpInstr:req
various \battler, VARIOUS_TEATIME_INVUL
.4byte \jumpInstr
.endm

.macro curecertainstatuses battler:req
various \battler, VARIOUS_CURE_CERTAIN_STATUSES
.endm
Expand Down Expand Up @@ -2284,19 +2311,6 @@
.byte \stat
.endm

.macro trywindriderpower battler:req, failInstr:req
various \battler, VARIOUS_TRY_WIND_RIDER_POWER
.4byte \failInstr
.endm

.macro activateweatherchangeabilities battler:req
various \battler, VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES
.endm

.macro activateterrainchangeabilities battler:req
various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES
.endm

@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7
Expand Down Expand Up @@ -2491,15 +2505,6 @@
waitmessage B_WAIT_TIME_LONG
.endm

.macro hitswitchtargetfailed
various 0, VARIOUS_HIT_SWITCH_TARGET_FAILED
.endm

.macro tryrevivalblessing, jumpInstr:req
various 0, VARIOUS_TRY_REVIVAL_BLESSING
.4byte \jumpInstr
.endm

@ Will jump to script pointer if the specified battler has or has not fainted.
.macro jumpiffainted battler:req, value:req, ptr:req
getbattlerfainted \battler
Expand Down
8 changes: 0 additions & 8 deletions include/constants/battle_script_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,6 @@
#define VARIOUS_SET_BEAK_BLAST 134
#define VARIOUS_SWAP_SIDE_STATUSES 135
#define VARIOUS_SWAP_STATS 136
#define VARIOUS_TEATIME_INVUL 137
#define VARIOUS_TEATIME_TARGETS 138
#define VARIOUS_TRY_WIND_RIDER_POWER 139
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 140
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 141
#define VARIOUS_STORE_HEALING_WISH 142
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 143
#define VARIOUS_TRY_REVIVAL_BLESSING 144

// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0
Expand Down
243 changes: 126 additions & 117 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -10863,123 +10863,6 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_TEATIME_TARGETS:
{
VARIOUS_ARGS(const u8 *jumpInstr);
u32 count = 0;

for (i = 0; i < gBattlersCount; i++)
{
if (IsTeatimeAffected(i))
count++;
}
if (count == 0)
gBattlescriptCurrInstr = cmd->jumpInstr; // Teatime fails
else
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_TEATIME_INVUL:
{
VARIOUS_ARGS(const u8 *jumpInstr);
if (ItemId_GetPocket(gBattleMons[battler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE)))
gBattlescriptCurrInstr = cmd->nextInstr;
else
gBattlescriptCurrInstr = cmd->jumpInstr;
return;
}
case VARIOUS_TRY_WIND_RIDER_POWER:
{
VARIOUS_ARGS(const u8 *failInstr);
u16 ability = GetBattlerAbility(battler);
if (GetBattlerSide(battler) == GetBattlerSide(gBattlerAttacker)
&& (ability == ABILITY_WIND_RIDER || ability == ABILITY_WIND_POWER))
{
gLastUsedAbility = ability;
RecordAbilityBattle(battler, gLastUsedAbility);
gBattlerAbility = gBattleScripting.battler = battler;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
gBattlescriptCurrInstr = cmd->failInstr;
}
return;
}
case VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES:
{
VARIOUS_ARGS();
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, battler, 0, 0, 0);
return;
}
case VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES:
{
VARIOUS_ARGS();
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, battler, 0, 0, 0);
return;
}
case VARIOUS_STORE_HEALING_WISH:
{
VARIOUS_ARGS();
if (gCurrentMove == MOVE_LUNAR_DANCE)
gBattleStruct->storedLunarDance |= 1u << battler;
else
gBattleStruct->storedHealingWish |= 1u << battler;
break;
}
case VARIOUS_HIT_SWITCH_TARGET_FAILED:
{
VARIOUS_ARGS();
gBattleStruct->hitSwitchTargetFailed = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_TRY_REVIVAL_BLESSING:
{
VARIOUS_ARGS(const u8 *failInstr);
u32 side = GetBattlerSide(gBattlerAttacker);
u8 index = GetFirstFaintedPartyIndex(gBattlerAttacker);

// Move fails if there are no battlers to revive.
if (index == PARTY_SIZE)
{
gBattlescriptCurrInstr = cmd->failInstr;
return;
}

// Battler selected! Revive and go to next instruction.
if (gSelectedMonPartyId != PARTY_SIZE)
{
struct Pokemon *party = GetSideParty(side);

u16 hp = GetMonData(&party[gSelectedMonPartyId], MON_DATA_MAX_HP) / 2;
BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_HP_BATTLE, 1u << gSelectedMonPartyId, sizeof(hp), &hp);
MarkBattlerForControllerExec(gBattlerAttacker);
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES));

// If an on-field battler is revived, it needs to be sent out again.
if (IsDoubleBattle() &&
gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId)
{
gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker);
gBattleCommunication[MULTIUSE_STATE] = TRUE;
}

gSelectedMonPartyId = PARTY_SIZE;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}

// Open party menu, wait to go to next instruction.
else
{
BtlController_EmitChoosePokemon(gBattlerAttacker, BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gBattlerAttacker]);
MarkBattlerForControllerExec(gBattlerAttacker);
}
return;
}
} // End of switch (cmd->id)

gBattlescriptCurrInstr = cmd->nextInstr;
Expand Down Expand Up @@ -17197,3 +17080,129 @@ void BS_FickleBeamDamageCalculation(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
}

void BS_TeatimeInvul(void)
{
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);

u32 battler = GetBattlerForBattleScript(cmd->battler);
if (ItemId_GetPocket(gBattleMons[battler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE)))
gBattlescriptCurrInstr = cmd->nextInstr;
else
gBattlescriptCurrInstr = cmd->jumpInstr;
}

void BS_TeatimeTargets(void)
{
NATIVE_ARGS(const u8 *failInstr);
u32 count = 0, i;

for (i = 0; i < gBattlersCount; i++)
{
if (IsTeatimeAffected(i))
count++;
}
if (count == 0)
gBattlescriptCurrInstr = cmd->failInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
}

void BS_TryWindRiderPower(void)
{
NATIVE_ARGS(u8 battler, const u8 *failInstr);

u32 battler = GetBattlerForBattleScript(cmd->battler);
u16 ability = GetBattlerAbility(battler);
if (GetBattlerSide(battler) == GetBattlerSide(gBattlerAttacker)
&& (ability == ABILITY_WIND_RIDER || ability == ABILITY_WIND_POWER))
{
gLastUsedAbility = ability;
RecordAbilityBattle(battler, gLastUsedAbility);
gBattlerAbility = gBattleScripting.battler = battler;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
gBattlescriptCurrInstr = cmd->failInstr;
}
}

void BS_ActivateWeatherChangeAbilities(void)
{
NATIVE_ARGS(u8 battler);

u32 battler = GetBattlerForBattleScript(cmd->battler);
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, battler, 0, 0, 0);
}

void BS_ActivateTerrainChangeAbilities(void)
{
NATIVE_ARGS(u8 battler);

u32 battler = GetBattlerForBattleScript(cmd->battler);
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, battler, 0, 0, 0);
}

void BS_StoreHealingWish(void)
{
NATIVE_ARGS(u8 battler);

u32 battler = GetBattlerForBattleScript(cmd->battler);
if (gCurrentMove == MOVE_LUNAR_DANCE)
gBattleStruct->storedLunarDance |= 1u << battler;
else
gBattleStruct->storedHealingWish |= 1u << battler;
gBattlescriptCurrInstr = cmd->nextInstr;
}

void BS_HitSwitchTargetFailed(void)
{
NATIVE_ARGS();
gBattleStruct->hitSwitchTargetFailed = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
}

void BS_TryRevivalBlessing(void)
{
NATIVE_ARGS(const u8 *failInstr);
u32 side = GetBattlerSide(gBattlerAttacker);
u8 index = GetFirstFaintedPartyIndex(gBattlerAttacker);

// Move fails if there are no battlers to revive.
if (index == PARTY_SIZE)
{
gBattlescriptCurrInstr = cmd->failInstr;
return;
}

// Battler selected! Revive and go to next instruction.
if (gSelectedMonPartyId != PARTY_SIZE)
{
struct Pokemon *party = GetSideParty(side);

u16 hp = GetMonData(&party[gSelectedMonPartyId], MON_DATA_MAX_HP) / 2;
BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_HP_BATTLE, 1u << gSelectedMonPartyId, sizeof(hp), &hp);
MarkBattlerForControllerExec(gBattlerAttacker);
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES));

// If an on-field battler is revived, it needs to be sent out again.
if (IsDoubleBattle() &&
gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId)
{
gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker);
gBattleCommunication[MULTIUSE_STATE] = TRUE;
}

gSelectedMonPartyId = PARTY_SIZE;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
// Open party menu, wait to go to next instruction.
BtlController_EmitChoosePokemon(gBattlerAttacker, BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gBattlerAttacker]);
MarkBattlerForControllerExec(gBattlerAttacker);
}
}
2 changes: 1 addition & 1 deletion test/battle/hold_effect/red_card.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,4 +468,4 @@ SINGLE_BATTLE_TEST("Red Card does not activate if holder is switched in mid-turn
}
}

// SINGLE_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed")
TO_DO_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed");

0 comments on commit 39f4c99

Please sign in to comment.