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

Wild battle tests + tests for exp points #3342

Merged
merged 6 commits into from
Sep 27, 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
1 change: 1 addition & 0 deletions data/battle_scripts_2.s
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ BattleScript_PrintCaughtMonInfo::
getexp BS_TARGET
sethword gBattle_BG2_X, 0
BattleScript_TryPrintCaughtMonInfo:
jumpifbattletype BATTLE_TYPE_RECORDED, BattleScript_GiveCaughtMonEnd
trysetcaughtmondexflags BattleScript_TryNicknameCaughtMon
printstring STRINGID_PKMNDATAADDEDTODEX
waitstate
Expand Down
1 change: 1 addition & 0 deletions include/battle_controllers.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 up
// player controller
void SetControllerToPlayer(u32 battler);
void SetBattleEndCallbacks(u32 battler);
void PlayerHandleBallThrowAnim(u32 battler);
void PlayerHandleExpUpdate(u32 battler);
u32 LinkPlayerGetTrainerPicId(u32 multiplayerId);
void CB2_SetUpReshowBattleScreenAfterMenu(void);
Expand Down
1 change: 1 addition & 0 deletions include/constants/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
| BATTLE_TYPE_GROUDON | BATTLE_TYPE_KYOGRE | BATTLE_TYPE_RAYQUAZA))

#define WILD_DOUBLE_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER))))
#define RECORDED_WILD_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_RECORDED) && !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FRONTIER)))
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gTrainerBattleOpponent_B == 0xFFFF))
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER | BATTLE_TYPE_INGAME_PARTNER)

Expand Down
1 change: 1 addition & 0 deletions include/recorded_battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ u8 RecordedBattle_BufferNewBattlerData(u8 *dst);
void RecordedBattle_RecordAllBattlerData(u8 *data);
bool32 CanCopyRecordedBattleSaveData(void);
bool32 MoveRecordedBattleToSaveData(void);
void SetPartiesFromRecordedSave(struct RecordedBattleSave *src);
void SetVariablesForRecordedBattle(struct RecordedBattleSave *);
void PlayRecordedBattle(void (*CB2_After)(void));
u8 GetRecordedBattleFrontierFacility(void);
Expand Down
57 changes: 56 additions & 1 deletion include/test/battle.h
mrgriffin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,20 @@
* ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
* target can only be specified for ANIM_TYPE_MOVE.
*
* EXPERIENCE_BAR(battler, [exp: | captureGainedExp:])
* If exp: is used, causes the test to fail if that amount of
* experience is not gained, e.g.:
* EXPERIENCE_BAR(player, exp: 0);
* If captureGainedExp: is used, causes the test to fail if
* the Experience bar does not change, and then writes that change to the
* pointer, e.g.:
* u32 exp;
* EXPERIENCE_BAR(player, captureGainedExp: &exp);
* If none of the above are used, causes the test to fail if the Exp
* does not change at all.
* Please note that due to nature of tests, this command
* is only usable in WILD_BATTLE_TEST and will fail elsewhere.
*
* HP_BAR(battler, [damage: | hp: | captureDamage: | captureHP:])
* If hp: or damage: are used, causes the test to fail if that amount of
* damage is not dealt, e.g.:
Expand Down Expand Up @@ -470,7 +484,7 @@
#define MAX_TURNS 16
#define MAX_QUEUED_EVENTS 25

enum { BATTLE_TEST_SINGLES, BATTLE_TEST_DOUBLES };
enum { BATTLE_TEST_SINGLES, BATTLE_TEST_DOUBLES, BATTLE_TEST_WILD };

typedef void (*SingleBattleTestFunction)(void *, u32, struct BattlePokemon *, struct BattlePokemon *);
typedef void (*DoubleBattleTestFunction)(void *, u32, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *);
Expand All @@ -492,6 +506,7 @@ enum
QUEUED_ABILITY_POPUP_EVENT,
QUEUED_ANIMATION_EVENT,
QUEUED_HP_EVENT,
QUEUED_EXP_EVENT,
QUEUED_MESSAGE_EVENT,
QUEUED_STATUS_EVENT,
};
Expand All @@ -511,6 +526,7 @@ struct QueuedAnimationEvent
};

enum { HP_EVENT_NEW_HP, HP_EVENT_DELTA_HP };
enum { EXP_EVENT_NEW_EXP, EXP_EVENT_DELTA_EXP };

struct QueuedHPEvent
{
Expand All @@ -519,6 +535,13 @@ struct QueuedHPEvent
u32 address:28;
};

struct QueuedExpEvent
{
u32 battlerId:3;
u32 type:1;
u32 address:28;
};

struct QueuedMessageEvent
{
const u8 *pattern;
Expand All @@ -541,6 +564,7 @@ struct QueuedEvent
struct QueuedAbilityEvent ability;
struct QueuedAnimationEvent animation;
struct QueuedHPEvent hp;
struct QueuedExpEvent exp;
struct QueuedMessageEvent message;
struct QueuedStatusEvent status;
} as;
Expand Down Expand Up @@ -676,6 +700,24 @@ extern struct BattleTestRunnerState *gBattleTestRunnerState;
}; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *results, u32 i, struct BattlePokemon *player, struct BattlePokemon *opponent)

#define WILD_BATTLE_TEST(_name, ...) \
struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, u32, struct BattlePokemon *, struct BattlePokemon *); \
__attribute__((section(".tests"))) static const struct Test CAT(sTest, __LINE__) = \
{ \
.name = _name, \
.filename = __FILE__, \
.runner = &gBattleTestRunner, \
.data = (void *)&(const struct BattleTest) \
{ \
.type = BATTLE_TEST_WILD, \
.sourceLine = __LINE__, \
.function = { .singles = (SingleBattleTestFunction)CAT(Test, __LINE__) }, \
.resultsSize = sizeof(struct CAT(Result, __LINE__)), \
}, \
}; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *results, u32 i, struct BattlePokemon *player, struct BattlePokemon *opponent)

#define DOUBLE_BATTLE_TEST(_name, ...) \
struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, u32, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *, struct BattlePokemon *); \
Expand Down Expand Up @@ -741,6 +783,7 @@ struct moveWithPP {
#define MovesWithPP(movewithpp1, ...) MovesWithPP_(__LINE__, (struct moveWithPP[MAX_MON_MOVES]) {movewithpp1, __VA_ARGS__})
#define Friendship(friendship) Friendship_(__LINE__, friendship)
#define Status1(status1) Status1_(__LINE__, status1)
#define OTName(otName) do {static const u8 otName_[] = _(otName); OTName_(__LINE__, otName_);} while (0)

void OpenPokemon(u32 sourceLine, u32 side, u32 species);
void ClosePokemon(u32 sourceLine);
Expand All @@ -762,6 +805,7 @@ void Moves_(u32 sourceLine, const u16 moves[MAX_MON_MOVES]);
void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES]);
void Friendship_(u32 sourceLine, u32 friendship);
void Status1_(u32 sourceLine, u32 status1);
void OTName_(u32 sourceLine, const u8 *otName);

#define PLAYER_PARTY (gBattleTestRunnerState->data.recordedBattle.playerParty)
#define OPPONENT_PARTY (gBattleTestRunnerState->data.recordedBattle.opponentParty)
Expand Down Expand Up @@ -837,6 +881,7 @@ void SendOut(u32 sourceLine, struct BattlePokemon *, u32 partyIndex);
#define ABILITY_POPUP(battler, ...) QueueAbility(__LINE__, battler, (struct AbilityEventContext) { __VA_ARGS__ })
#define ANIMATION(type, id, ...) QueueAnimation(__LINE__, type, id, (struct AnimationEventContext) { __VA_ARGS__ })
#define HP_BAR(battler, ...) QueueHP(__LINE__, battler, (struct HPEventContext) { APPEND_TRUE(__VA_ARGS__) })
#define EXPERIENCE_BAR(battler, ...) QueueExp(__LINE__, battler, (struct ExpEventContext) { APPEND_TRUE(__VA_ARGS__) })
// Static const is needed to make the modern compiler put the pattern variable in the .rodata section, instead of putting it on stack(which can break the game).
#define MESSAGE(pattern) do {static const u8 msg[] = _(pattern); QueueMessage(__LINE__, msg);} while (0)
#define STATUS_ICON(battler, status) QueueStatus(__LINE__, battler, (struct StatusEventContext) { status })
Expand Down Expand Up @@ -872,6 +917,15 @@ struct HPEventContext
bool8 explicitCaptureDamage;
};

struct ExpEventContext
{
u8 _;
u32 exp;
mrgriffin marked this conversation as resolved.
Show resolved Hide resolved
bool8 explicitExp;
s32 *captureGainedExp;
bool8 explicitCaptureGainedExp;
};

struct StatusEventContext
{
u16 status1;
Expand All @@ -891,6 +945,7 @@ void CloseQueueGroup(u32 sourceLine);
void QueueAbility(u32 sourceLine, struct BattlePokemon *battler, struct AbilityEventContext);
void QueueAnimation(u32 sourceLine, u32 type, u32 id, struct AnimationEventContext);
void QueueHP(u32 sourceLine, struct BattlePokemon *battler, struct HPEventContext);
void QueueExp(u32 sourceLine, struct BattlePokemon *battler, struct ExpEventContext);
void QueueMessage(u32 sourceLine, const u8 *pattern);
void QueueStatus(u32 sourceLine, struct BattlePokemon *battler, struct StatusEventContext);

Expand Down
2 changes: 2 additions & 0 deletions include/test_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern const bool8 gTestRunnerSkipIsFail;
void TestRunner_Battle_RecordAbilityPopUp(u32 battlerId, u32 ability);
void TestRunner_Battle_RecordAnimation(u32 animType, u32 animId);
void TestRunner_Battle_RecordHP(u32 battlerId, u32 oldHP, u32 newHP);
void TestRunner_Battle_RecordExp(u32 battlerId, u32 oldExp, u32 newExp);
void TestRunner_Battle_RecordMessage(const u8 *message);
void TestRunner_Battle_RecordStatus1(u32 battlerId, u32 status1);
void TestRunner_Battle_AfterLastTurn(void);
Expand All @@ -23,6 +24,7 @@ u32 TestRunner_Battle_GetForcedAbility(u32 side, u32 partyIndex);
#define TestRunner_Battle_RecordAbilityPopUp(...) (void)0
#define TestRunner_Battle_RecordAnimation(...) (void)0
#define TestRunner_Battle_RecordHP(...) (void)0
#define TestRunner_Battle_RecordExp(...) (void)0
#define TestRunner_Battle_RecordMessage(...) (void)0
#define TestRunner_Battle_RecordStatus1(...) (void)0
#define TestRunner_Battle_AfterLastTurn(...) (void)0
Expand Down
5 changes: 3 additions & 2 deletions src/battle_controller_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "sound.h"
#include "string_util.h"
#include "task.h"
#include "test_runner.h"
#include "text.h"
#include "util.h"
#include "window.h"
Expand All @@ -45,7 +46,6 @@ static void PlayerHandleTrainerSlide(u32 battler);
static void PlayerHandleTrainerSlideBack(u32 battler);
static void PlayerHandlePaletteFade(u32 battler);
static void PlayerHandleSuccessBallThrowAnim(u32 battler);
static void PlayerHandleBallThrowAnim(u32 battler);
static void PlayerHandlePause(u32 battler);
static void PlayerHandleMoveAnimation(u32 battler);
static void PlayerHandlePrintString(u32 battler);
Expand Down Expand Up @@ -1452,6 +1452,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
exp -= currLvlExp;
expToNextLvl = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1] - currLvlExp;
SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], expToNextLvl, exp, -gainedExp);
TestRunner_Battle_RecordExp(battler, exp, -gainedExp);
PlaySE(SE_EXP);
gTasks[taskId].func = Task_GiveExpWithExpBar;
}
Expand Down Expand Up @@ -1850,7 +1851,7 @@ static void PlayerHandleSuccessBallThrowAnim(u32 battler)
BtlController_HandleSuccessBallThrowAnim(battler, gBattlerTarget, B_ANIM_BALL_THROW, TRUE);
}

static void PlayerHandleBallThrowAnim(u32 battler)
void PlayerHandleBallThrowAnim(u32 battler)
{
BtlController_HandleBallThrowAnim(battler, gBattlerTarget, B_ANIM_BALL_THROW, TRUE);
}
Expand Down
22 changes: 1 addition & 21 deletions src/battle_controller_recorded_opponent.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,27 +501,7 @@ static void RecordedOpponentHandleChoosePokemon(u32 battler)

static void RecordedOpponentHandleHealthBarUpdate(u32 battler)
{
s16 hpVal;
s32 maxHP, curHP;

LoadBattleBarGfx(0);
hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);

maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);
curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_HP);

if (hpVal != INSTANT_HP_BAR_DROP)
{
SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal);
TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal)));
}
else
{
SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal);
TestRunner_Battle_RecordHP(battler, curHP, 0);
}

gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar;
BtlController_HandleHealthBarUpdate(battler, FALSE);
}

static void RecordedOpponentHandleStatusIconUpdate(u32 battler)
Expand Down
27 changes: 3 additions & 24 deletions src/battle_controller_recorded_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 ba
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_BALLTHROWANIM] = PlayerHandleBallThrowAnim,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = RecordedPlayerHandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = RecordedPlayerHandlePrintString,
Expand All @@ -78,7 +78,7 @@ static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 ba
[CONTROLLER_CHOOSEPOKEMON] = RecordedPlayerHandleChoosePokemon,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = RecordedPlayerHandleHealthBarUpdate,
[CONTROLLER_EXPUPDATE] = BtlController_Empty,
[CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate,
[CONTROLLER_STATUSICONUPDATE] = RecordedPlayerHandleStatusIconUpdate,
[CONTROLLER_STATUSANIMATION] = RecordedPlayerHandleStatusAnimation,
[CONTROLLER_STATUSXOR] = BtlController_Empty,
Expand Down Expand Up @@ -507,28 +507,7 @@ static void RecordedPlayerHandleChoosePokemon(u32 battler)

static void RecordedPlayerHandleHealthBarUpdate(u32 battler)
{
s16 hpVal;
s32 maxHP, curHP;

LoadBattleBarGfx(0);
hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);

maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);
curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP);

if (hpVal != INSTANT_HP_BAR_DROP)
{
SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal);
TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal)));
}
else
{
SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP);
TestRunner_Battle_RecordHP(battler, curHP, 0);
}

gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar;
BtlController_HandleHealthBarUpdate(battler, TRUE);
}

static void RecordedPlayerHandleStatusIconUpdate(u32 battler)
Expand Down
11 changes: 6 additions & 5 deletions src/battle_controllers.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "string_util.h"
#include "sound.h"
#include "task.h"
#include "test_runner.h"
#include "util.h"
#include "text.h"
#include "constants/abilities.h"
Expand Down Expand Up @@ -2687,26 +2688,26 @@ void BtlController_HandlePrintString(u32 battler, bool32 updateTvData, bool32 ar

void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText)
{
s32 maxHP, curHP;
s16 hpVal;
struct Pokemon *party = GetBattlerParty(battler);

LoadBattleBarGfx(0);
hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);
maxHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);
curHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_HP);

if (hpVal != INSTANT_HP_BAR_DROP)
{
u32 maxHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);
u32 curHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_HP);

SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal);
TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal)));
}
else
{
u32 maxHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);

SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal);
if (updateHpText)
UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP);
TestRunner_Battle_RecordHP(battler, curHP, 0);
}

gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar;
Expand Down
2 changes: 1 addition & 1 deletion src/battle_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -3865,7 +3865,7 @@ void BattlePutTextOnWindow(const u8 *text, u8 windowId)
else
gTextFlags.useAlternateDownArrow = TRUE;

if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED))
if ((gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED)) || gTestRunnerEnabled)
gTextFlags.autoScroll = TRUE;
else
gTextFlags.autoScroll = FALSE;
Expand Down
Loading
Loading