Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert 8 various to callnatives #5172

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
AsparagusEduardo marked this conversation as resolved.
Show resolved Hide resolved
.4byte \jumpInstr
.endm

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

.macro trywindriderpower battler:req, failInstr:req
callnative BS_TryWindRiderPower
.byte \battler
AsparagusEduardo marked this conversation as resolved.
Show resolved Hide resolved
.4byte \failInstr
.endm

.macro activateweatherchangeabilities battler:req
callnative BS_ActivateWeatherChangeAbilities
.byte \battler
AsparagusEduardo marked this conversation as resolved.
Show resolved Hide resolved
.endm

.macro activateterrainchangeabilities battler:req
callnative BS_ActivateTerrainChangeAbilities
.byte \battler
AsparagusEduardo marked this conversation as resolved.
Show resolved Hide resolved
.endm

@ Stores Healing Wish effect.
.macro storehealingwish battler:req
various \battler, VARIOUS_STORE_HEALING_WISH
callnative BS_StoreHealingWish
.byte \battler
AsparagusEduardo marked this conversation as resolved.
Show resolved Hide resolved
.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");
Loading