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

Battle Tests (Feb 19) #2707

Merged
merged 4 commits into from
Feb 21, 2023
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
4 changes: 4 additions & 0 deletions asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2247,3 +2247,7 @@
various \battler, VARIOUS_JUMP_IF_EMERGENCY_EXITED
.4byte \jumpInstr
.endm

.macro hitswitchtargetfailed
various 0, VARIOUS_HIT_SWITCH_TARGET_FAILED
.endm
12 changes: 8 additions & 4 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -2128,9 +2128,14 @@ BattleScript_EffectHitSwitchTarget:
moveendall
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
tryhitswitchtarget BattleScript_EffectHitSwitchTargetMoveEnd
BattleScript_EffectHitSwitchTargetMoveEnd:
end
tryhitswitchtarget BattleScript_MoveEnd
forcerandomswitch BattleScript_HitSwitchTargetForceRandomSwitchFailed
goto BattleScript_MoveEnd

BattleScript_HitSwitchTargetForceRandomSwitchFailed:
hitswitchtargetfailed
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
goto BattleScript_MoveEnd

BattleScript_EffectClearSmog:
setmoveeffect MOVE_EFFECT_CLEAR_SMOG
Expand Down Expand Up @@ -3708,7 +3713,6 @@ BattleScript_EffectRoar::
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_ButItFailed
BattleScript_ForceRandomSwitch::
forcerandomswitch BattleScript_ButItFailed

BattleScript_EffectMultiHit::
Expand Down
1 change: 1 addition & 0 deletions include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ struct BattleStruct
// When using a move which hits multiple opponents which is then bounced by a target, we need to make sure, the move hits both opponents, the one with bounce, and the one without.
u8 attackerBeforeBounce:2;
u8 beatUpSlot:3;
bool8 hitSwitchTargetFailed:1;
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face.
Expand Down
1 change: 0 additions & 1 deletion include/battle_scripts.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,6 @@ extern const u8 BattleScript_WishMegaEvolution[];
extern const u8 BattleScript_MoveEffectRecoilWithStatus[];
extern const u8 BattleScript_EffectWithChance[];
extern const u8 BattleScript_MoveEffectClearSmog[];
extern const u8 BattleScript_ForceRandomSwitch[];
extern const u8 BattleScript_SideStatusWoreOffReturn[];
extern const u8 BattleScript_MoveEffectSmackDown[];
extern const u8 BattleScript_MoveEffectFlameBurst[];
Expand Down
1 change: 1 addition & 0 deletions include/constants/battle_script_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
#define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166
#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167
#define VARIOUS_STORE_HEALING_WISH 168
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 169

// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0
Expand Down
45 changes: 18 additions & 27 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -5968,7 +5968,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_RED_CARD:
if (gBattleMoves[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET
if ((gBattleMoves[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
&& IsBattlerAlive(gBattlerAttacker)
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
Expand Down Expand Up @@ -6199,6 +6199,7 @@ static void Cmd_moveend(void)
gBattleStruct->zmove.active = FALSE;
gBattleStruct->zmove.toBeUsed[gBattlerAttacker] = MOVE_NONE;
gBattleStruct->zmove.effect = EFFECT_HIT;
gBattleStruct->hitSwitchTargetFailed = FALSE;
gBattleScripting.moveendState++;
break;
case MOVEEND_COUNT:
Expand Down Expand Up @@ -9792,7 +9793,7 @@ static void Cmd_various(void)
&& GetBattlerAbility(gBattlerTarget) != ABILITY_GUARD_DOG)
{
gBattleScripting.switchCase = B_SWITCH_HIT;
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
Expand Down Expand Up @@ -11067,6 +11068,13 @@ static void Cmd_various(void)
gBattleStruct->storedHealingWish |= gBitTable[gActiveBattler];
break;
}
case VARIOUS_HIT_SWITCH_TARGET_FAILED:
{
VARIOUS_ARGS();
gBattleStruct->hitSwitchTargetFailed = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
} // End of switch (cmd->id)

gBattlescriptCurrInstr = cmd->nextInstr;
Expand Down Expand Up @@ -12089,8 +12097,8 @@ static void Cmd_forcerandomswitch(void)
s32 lastMonId = 0; // + 1
s32 monsCount;
struct Pokemon *party = NULL;
s32 validMons = 0;
s32 minNeeded;
u8 validMons[PARTY_SIZE];
s32 validMonsCount = 0;

bool32 redCardForcedSwitch = FALSE;

Expand Down Expand Up @@ -12147,7 +12155,6 @@ static void Cmd_forcerandomswitch(void)
firstMonId = 0;
lastMonId = 6;
monsCount = 6;
minNeeded = 2;
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
}
Expand All @@ -12166,7 +12173,6 @@ static void Cmd_forcerandomswitch(void)
lastMonId = PARTY_SIZE / 2;
}
monsCount = PARTY_SIZE / 2;
minNeeded = 1;
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
}
Expand All @@ -12184,7 +12190,6 @@ static void Cmd_forcerandomswitch(void)
lastMonId = PARTY_SIZE / 2;
}
monsCount = PARTY_SIZE / 2;
minNeeded = 1;
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
}
Expand All @@ -12195,7 +12200,6 @@ static void Cmd_forcerandomswitch(void)
firstMonId = 0;
lastMonId = PARTY_SIZE;
monsCount = PARTY_SIZE;
minNeeded = 2; // since there are two opponents, it has to be a double battle
}
else
{
Expand All @@ -12210,7 +12214,6 @@ static void Cmd_forcerandomswitch(void)
lastMonId = PARTY_SIZE / 2;
}
monsCount = PARTY_SIZE / 2;
minNeeded = 1;
}
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
Expand All @@ -12220,7 +12223,6 @@ static void Cmd_forcerandomswitch(void)
firstMonId = 0;
lastMonId = PARTY_SIZE;
monsCount = PARTY_SIZE;
minNeeded = 2;
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
}
Expand All @@ -12229,7 +12231,6 @@ static void Cmd_forcerandomswitch(void)
firstMonId = 0;
lastMonId = PARTY_SIZE;
monsCount = PARTY_SIZE;
minNeeded = 1;
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one pokemon out in single battles
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget];
}
Expand All @@ -12238,33 +12239,23 @@ static void Cmd_forcerandomswitch(void)
{
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& GetMonData(&party[i], MON_DATA_HP) != 0)
&& GetMonData(&party[i], MON_DATA_HP) != 0
&& i != battler1PartyId
&& i != battler2PartyId)
{
validMons++;
validMons[validMonsCount++] = i;
}
}

if (!redCardForcedSwitch && validMons <= minNeeded)
if (validMonsCount == 0)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
*(gBattleStruct->battlerPartyIndexes + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
gBattlescriptCurrInstr = BattleScript_RoarSuccessSwitch;

do
{
i = Random() % monsCount;
i += firstMonId;
}
while (i == battler2PartyId
|| i == battler1PartyId
|| GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE
|| GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE
|| GetMonData(&party[i], MON_DATA_HP) == 0);

*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = i;
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = validMons[Random() % validMonsCount];

if (!IsMultiBattle())
SwitchPartyOrder(gBattlerTarget);
Expand Down
2 changes: 1 addition & 1 deletion test/ability_blaze.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage)
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_GT(results[1].damage, results[0].damage);
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
20 changes: 20 additions & 0 deletions test/ability_overgrow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "global.h"
#include "test_battle.h"

SINGLE_BATTLE_TEST("Overgrow boosts Grass-type moves in a pinch", s16 damage)
{
u16 hp;
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
ASSUME(gBattleMoves[MOVE_VINE_WHIP].type == TYPE_GRASS);
PLAYER(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_VINE_WHIP); }
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
20 changes: 20 additions & 0 deletions test/ability_swarm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "global.h"
#include "test_battle.h"

SINGLE_BATTLE_TEST("Swarm boosts Bug-type moves in a pinch", s16 damage)
{
u16 hp;
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
ASSUME(gBattleMoves[MOVE_BUG_BITE].type == TYPE_BUG);
PLAYER(SPECIES_LEDYBA) { Ability(ABILITY_SWARM); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BUG_BITE); }
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
20 changes: 20 additions & 0 deletions test/ability_torrent.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "global.h"
#include "test_battle.h"

SINGLE_BATTLE_TEST("Torrent boosts Water-type moves in a pinch", s16 damage)
{
u16 hp;
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER);
PLAYER(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BUBBLE); }
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
Loading