Fix partner difficulty and rework tests (#9419)

This commit is contained in:
FosterProgramming 2026-03-13 15:49:23 +01:00 committed by GitHub
parent 50cfe5847e
commit 976e642137
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 279 additions and 117 deletions

1
.gitignore vendored
View File

@ -55,6 +55,7 @@ src/data/trainers_frlg.h
src/data/debug_trainers.h src/data/debug_trainers.h
src/data/tutor_moves.h src/data/tutor_moves.h
test/battle/trainer_control.h test/battle/trainer_control.h
test/battle/partner_control.h
tools/compresSmol/compresSmol tools/compresSmol/compresSmol
tools/compresSmol/compresSmolTilemap tools/compresSmol/compresSmolTilemap
tools/aif2pcm/aif2pcm tools/aif2pcm/aif2pcm

View File

@ -4,8 +4,6 @@
#include "difficulty.h" #include "difficulty.h"
#include "constants/battle_partner.h" #include "constants/battle_partner.h"
extern const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT];
void FillPartnerParty(u16 trainerId); void FillPartnerParty(u16 trainerId);
#endif // BATTLE_PARTNER_H #endif // BATTLE_PARTNER_H

View File

@ -4,6 +4,8 @@
#define PARTNER_NONE 0 #define PARTNER_NONE 0
#define PARTNER_STEVEN 1 #define PARTNER_STEVEN 1
#define PARTNER_COUNT 2 #define PARTNER_DUMMY 2
#define PARTNER_COUNT 3
//Tests need PARTNER_COUNT to be at least 3 so we add a dummy partner
#endif // GUARD_CONSTANTS_BATTLE_PARTNERS_H #endif // GUARD_CONSTANTS_BATTLE_PARTNERS_H

View File

@ -227,7 +227,7 @@ extern const struct FollowerMsgInfo gFollowerPoisonedMessages[];
static inline bool8 IsPartnerTrainerId(u16 trainerId) static inline bool8 IsPartnerTrainerId(u16 trainerId)
{ {
if (trainerId >= TRAINER_PARTNER(PARTNER_NONE) && trainerId < TRAINER_PARTNER(PARTNER_COUNT)) if (trainerId > TRAINER_PARTNER(PARTNER_NONE) && trainerId < TRAINER_PARTNER(PARTNER_COUNT))
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -255,12 +255,17 @@ static inline const struct Trainer *GetTrainerStructFromId(u16 trainerId)
u32 sanitizedTrainerId = 0; u32 sanitizedTrainerId = 0;
if (gIsDebugBattle) return GetDebugAiTrainer(); if (gIsDebugBattle) return GetDebugAiTrainer();
sanitizedTrainerId = SanitizeTrainerId(trainerId); sanitizedTrainerId = SanitizeTrainerId(trainerId);
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
if (IsPartnerTrainerId(trainerId)) if (IsPartnerTrainerId(trainerId))
{
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(sanitizedTrainerId);
return &gBattlePartners[difficulty][sanitizedTrainerId - TRAINER_PARTNER(PARTNER_NONE)]; return &gBattlePartners[difficulty][sanitizedTrainerId - TRAINER_PARTNER(PARTNER_NONE)];
}
else else
{
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
return &gTrainers[difficulty][sanitizedTrainerId]; return &gTrainers[difficulty][sanitizedTrainerId];
}
} }
static inline const enum TrainerClassID GetTrainerClassFromId(u16 trainerId) static inline const enum TrainerClassID GetTrainerClassFromId(u16 trainerId)

View File

@ -13,10 +13,12 @@
#include "constants/battle_ai.h" #include "constants/battle_ai.h"
#include "data/partner_parties.h" #include "data/partner_parties.h"
#if !TESTING
const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT] = const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT] =
{ {
#include "data/battle_partners.h" #include "data/battle_partners.h"
}; };
#endif
#define STEVEN_OTID 61226 #define STEVEN_OTID 61226

View File

@ -228,6 +228,7 @@ const union AnimCmd *const gAnims_Trainer[] ={
#include "data/trainer_parties.h" #include "data/trainer_parties.h"
#if !TESTING
const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] = const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] =
{ {
#if IS_FRLG #if IS_FRLG
@ -236,5 +237,6 @@ const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] =
#include "data/trainers.h" #include "data/trainers.h"
#endif #endif
}; };
#endif
#include "data/text/follower_messages.h" #include "data/text/follower_messages.h"

View File

@ -44,3 +44,15 @@ EVs: 252 Atk / 252 SpA / 6 SpD
- Protect - Protect
- Solar Beam - Solar Beam
- Dragon Claw - Dragon Claw
=== PARTNER_DUMMY ===
Name:
Class: Pkmn Trainer 1
Pic: Brendan
Gender: Male
Music: Male
Back Pic: Brendan
Party Size: 0
Wynaut

View File

@ -70,6 +70,10 @@ static const u8* const sFrontierTrainerSlides[DIFFICULTY_COUNT][FRONTIER_TRAINER
}, },
}; };
#define TRAINER_RED_TEST 1
#define TRAINER_LEAF_TEST 2
#define PARTNER_STEVEN_TEST 1
static const u8* const sTestTrainerSlides[DIFFICULTY_COUNT][MAX_TRAINERS_COUNT_EMERALD + PARTNER_COUNT][TRAINER_SLIDE_COUNT] = static const u8* const sTestTrainerSlides[DIFFICULTY_COUNT][MAX_TRAINERS_COUNT_EMERALD + PARTNER_COUNT][TRAINER_SLIDE_COUNT] =
{ {
#include "../test/battle/trainer_slides.h" #include "../test/battle/trainer_slides.h"

View File

@ -0,0 +1,84 @@
=== PARTNER_NONE ===
Name:
Class: Pkmn Trainer 1
Pic: Brendan
Gender: Male
Music: Male
Back Pic: Brendan
=== PARTNER_STEVEN_TEST ===
Name: STEVEN
Class: Rival
Pic: Steven
Gender: Male
Music: Male
Back Pic: Steven
AI: Basic Trainer
Metang
Brave Nature
Level: 42
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
EVs: 252 Atk / 252 Def / 6 SpA
- Light Screen
- Psychic
- Reflect
- Metal Claw
Skarmory
Impish Nature
Level: 43
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
EVs: 252 HP / 6 SpA / 252 SpD
- Toxic
- Aerial Ace
- Protect
- Steel Wing
Aggron
Adamant Nature
Level: 44
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
EVs: 252 Atk / 252 SpA / 6 SpD
- Thunder
- Protect
- Solar Beam
- Dragon Claw
=== 2 ===
Name: Test2
Class: Rival
Pic: Steven
Gender: Male
Music: Male
Back Pic: Steven
Difficulty: Normal
Mewtwo
Level: 50
=== 2 ===
Name: Test2
Class: Rival
Pic: Steven
Gender: Male
Music: Male
Back Pic: Steven
Battle Type: Singles
Difficulty: Easy
Metapod
Level: 1
=== 2 ===
Name: Test2
Class: Rival
Pic: Steven
Gender: Male
Music: Male
Back Pic: Steven
Battle Type: Singles
Difficulty: Hard
Arceus
Level: 99

View File

@ -11,33 +11,14 @@
#include "constants/abilities.h" #include "constants/abilities.h"
#include "constants/trainers.h" #include "constants/trainers.h"
#include "constants/battle.h" #include "constants/battle.h"
#include "constants/battle_ai.h"
#define NUM_TEST_TRAINERS 12
static const struct Trainer sTestTrainers[DIFFICULTY_COUNT][NUM_TEST_TRAINERS] =
{
#include "trainer_control.h"
};
enum DifficultyLevel GetTrainerDifficultyLevelTest(u16 trainerId)
{
enum DifficultyLevel difficulty = GetCurrentDifficultyLevel();
if (difficulty == DIFFICULTY_NORMAL)
return DIFFICULTY_NORMAL;
if (sTestTrainers[difficulty][trainerId].party == NULL)
return DIFFICULTY_NORMAL;
return difficulty;
}
TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon") TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 0; u32 currTrainer = 3;
u8 nickBuffer[20]; u8 nickBuffer[20];
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(IsMonShiny(&testParty[0])); EXPECT(IsMonShiny(&testParty[0]));
EXPECT(!IsMonShiny(&testParty[1])); EXPECT(!IsMonShiny(&testParty[1]));
@ -111,9 +92,9 @@ TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
TEST("CreateNPCTrainerPartyForTrainer generates different personalities for different mons") TEST("CreateNPCTrainerPartyForTrainer generates different personalities for different mons")
{ {
enum DifficultyLevel difficulty = GetTrainerDifficultyLevelTest(0);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[difficulty][0], TRUE, BATTLE_TYPE_TRAINER); u32 currTrainer = 3;
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(testParty[0].box.personality != testParty[1].box.personality); EXPECT(testParty[0].box.personality != testParty[1].box.personality);
Free(testParty); Free(testParty);
} }
@ -132,88 +113,108 @@ TEST("ModifyPersonalityForNature can set any nature")
EXPECT_EQ(GetNatureFromPersonality(personality), nature); EXPECT_EQ(GetNatureFromPersonality(personality), nature);
} }
static const struct TrainerMon sTestParty2[] =
{
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
};
TEST("Trainer Class Balls apply to the entire party") TEST("Trainer Class Balls apply to the entire party")
{ {
ASSUME(B_TRAINER_CLASS_POKE_BALLS >= GEN_8); ASSUME(B_TRAINER_CLASS_POKE_BALLS >= GEN_8);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 j; u32 j;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[DIFFICULTY_NORMAL][11], TRUE, BATTLE_TYPE_TRAINER); u32 currTrainer = 14;
const struct Trainer *trainer = GetTrainerStructFromId(currTrainer);
CreateNPCTrainerPartyFromTrainer(testParty, trainer, TRUE, BATTLE_TYPE_TRAINER);
for(j = 0; j < 6; j++) for(j = 0; j < 6; j++)
{ {
EXPECT(GetMonData(&testParty[j], MON_DATA_POKEBALL, 0) == gTrainerClasses[sTestTrainers[DIFFICULTY_NORMAL][11].trainerClass].ball); EXPECT(GetMonData(&testParty[j], MON_DATA_POKEBALL, 0) == gTrainerClasses[trainer->trainerClass].ball);
} }
Free(testParty); Free(testParty);
} }
TEST("Difficulty default to Normal is the trainer doesn't have a member for the current diffuculty") TEST("Difficulty default to Normal if the trainer doesn't have a member for the current difficulty")
{ {
SetCurrentDifficultyLevel(DIFFICULTY_EASY); SetCurrentDifficultyLevel(DIFFICULTY_EASY);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 1; u32 currTrainer = 4;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO);
Free(testParty); Free(testParty);
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL); SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
} }
TEST("Difficulty changes which party if used for NPCs if defined for the difficulty (EASY)") TEST("Difficulty changes which party is used for enemy trainer if defined for the difficulty (EASY)")
{ {
SetCurrentDifficultyLevel(DIFFICULTY_EASY); SetCurrentDifficultyLevel(DIFFICULTY_EASY);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 2; u32 currTrainer = 5;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_METAPOD); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_METAPOD);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 1); EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 1);
Free(testParty); Free(testParty);
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL); SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
} }
TEST("Difficulty changes which party if used for NPCs if defined for the difficulty (HARD)") TEST("Difficulty changes which party is used for enemy trainer if defined for the difficulty (HARD)")
{ {
SetCurrentDifficultyLevel(DIFFICULTY_HARD); SetCurrentDifficultyLevel(DIFFICULTY_HARD);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 2; u32 currTrainer = 5;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_ARCEUS); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_ARCEUS);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 99); EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 99);
Free(testParty); Free(testParty);
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL); SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
} }
TEST("Difficulty changes which party if used for NPCs if defined for the difficulty (NORMAL)") TEST("Difficulty changes which party is used for enemy trainer if defined for the difficulty (NORMAL)")
{ {
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL); SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 2; u32 currTrainer = 5;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 50);
Free(testParty);
}
TEST("Difficulty default to Normal if the partner doesn't have a member for the current difficulty")
{
SetCurrentDifficultyLevel(DIFFICULTY_EASY);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = TRAINER_PARTNER(1);
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_METANG);
Free(testParty);
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
}
TEST("Difficulty changes which party is used for partner if defined for the difficulty (EASY)")
{
SetCurrentDifficultyLevel(DIFFICULTY_EASY);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = TRAINER_PARTNER(2);
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_METAPOD);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 1);
Free(testParty);
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
}
TEST("Difficulty changes which party is used for partner if defined for the difficulty (HARD)")
{
SetCurrentDifficultyLevel(DIFFICULTY_HARD);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = TRAINER_PARTNER(2);
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_ARCEUS);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 99);
Free(testParty);
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
}
TEST("Difficulty changes which party is used for partner if defined for the difficulty (NORMAL)")
{
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = TRAINER_PARTNER(2);
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 50); EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 50);
Free(testParty); Free(testParty);
@ -222,8 +223,8 @@ TEST("Difficulty changes which party if used for NPCs if defined for the difficu
TEST("Trainer Party Pool generates a party from the trainer pool") TEST("Trainer Party Pool generates a party from the trainer pool")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 3; u32 currTrainer = 6;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_EEVEE); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_EEVEE);
Free(testParty); Free(testParty);
} }
@ -231,8 +232,8 @@ TEST("Trainer Party Pool generates a party from the trainer pool")
TEST("Trainer Party Pool picks a random lead and a random ace if tags exist in the pool") TEST("Trainer Party Pool picks a random lead and a random ace if tags exist in the pool")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 4; u32 currTrainer = 7;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_ARON); // Lead EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_ARON); // Lead
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WYNAUT); // Not Lead or Ace EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WYNAUT); // Not Lead or Ace
EXPECT(GetMonData(&testParty[2], MON_DATA_SPECIES) == SPECIES_EEVEE); // Ace EXPECT(GetMonData(&testParty[2], MON_DATA_SPECIES) == SPECIES_EEVEE); // Ace
@ -242,8 +243,8 @@ TEST("Trainer Party Pool picks a random lead and a random ace if tags exist in t
TEST("Trainer Party Pool picks according to custom rules") TEST("Trainer Party Pool picks according to custom rules")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 5; u32 currTrainer = 8;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_TORKOAL); // Lead + Weather Setter EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_TORKOAL); // Lead + Weather Setter
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_BULBASAUR); // Lead + Weather Abuser EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_BULBASAUR); // Lead + Weather Abuser
EXPECT(GetMonData(&testParty[2], MON_DATA_SPECIES) == SPECIES_EEVEE); // Anything else EXPECT(GetMonData(&testParty[2], MON_DATA_SPECIES) == SPECIES_EEVEE); // Anything else
@ -253,8 +254,8 @@ TEST("Trainer Party Pool picks according to custom rules")
TEST("Trainer Party Pool uses standard party creation if pool is illegal") TEST("Trainer Party Pool uses standard party creation if pool is illegal")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 6; u32 currTrainer = 9;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_WYNAUT); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_WYNAUT);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WOBBUFFET); EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WOBBUFFET);
Free(testParty); Free(testParty);
@ -263,8 +264,8 @@ TEST("Trainer Party Pool uses standard party creation if pool is illegal")
TEST("Trainer Party Pool can be pruned before picking") TEST("Trainer Party Pool can be pruned before picking")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 7; u32 currTrainer = 10;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_EEVEE); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_EEVEE);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WYNAUT); EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WYNAUT);
Free(testParty); Free(testParty);
@ -273,8 +274,8 @@ TEST("Trainer Party Pool can be pruned before picking")
TEST("Trainer Party Pool can choose which functions to use for picking mons") TEST("Trainer Party Pool can choose which functions to use for picking mons")
{ {
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u32 currTrainer = 8; u32 currTrainer = 11;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_WYNAUT); EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_WYNAUT);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WOBBUFFET); EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WOBBUFFET);
Free(testParty); Free(testParty);
@ -283,17 +284,19 @@ TEST("Trainer Party Pool can choose which functions to use for picking mons")
TEST("trainerproc supports both Double Battle: Yes and Battle Type: Doubles") TEST("trainerproc supports both Double Battle: Yes and Battle Type: Doubles")
{ {
u32 currTrainer; u32 currTrainer;
PARAMETRIZE { currTrainer = 9; } PARAMETRIZE { currTrainer = 12; }
PARAMETRIZE { currTrainer = 10; } PARAMETRIZE { currTrainer = 13; }
const struct Trainer trainer = sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer]; const struct Trainer *trainer = GetTrainerStructFromId(currTrainer);
EXPECT(trainer.battleType == TRAINER_BATTLE_TYPE_DOUBLES); EXPECT(trainer->battleType == TRAINER_BATTLE_TYPE_DOUBLES);
} }
TEST("CreateNPCTrainerPartyForTrainer generates default moves if no moves are specified") TEST("CreateNPCTrainerPartyForTrainer generates default moves if no moves are specified")
{ {
ASSUME(sTestTrainers[GetTrainerDifficultyLevelTest(1)][1].party[0].moves[0] == MOVE_NONE); u32 currTrainer = 1;
const struct Trainer *trainer = GetTrainerStructFromId(currTrainer);
ASSUME(trainer->party[0].moves[0] == MOVE_NONE);
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon)); struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(1)][1], TRUE, BATTLE_TYPE_TRAINER); CreateNPCTrainerPartyFromTrainer(testParty, trainer, TRUE, BATTLE_TYPE_TRAINER);
EXPECT(GetMonData(&testParty[0], MON_DATA_MOVE1) != MOVE_NONE); EXPECT(GetMonData(&testParty[0], MON_DATA_MOVE1) != MOVE_NONE);
Free(testParty); Free(testParty);
} }

View File

@ -1,4 +1,37 @@
=== 0 === === TRAINER_NONE ===
Name:
Class: Pkmn Trainer 1
Pic: Hiker
Gender: Male
Music: Male
Double Battle: No
=== 1 ===
Name: RED
Class: Rival
Pic: Red
Gender: Male
Music: Male
Double Battle: No
Charmander
Level: 5
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
=== 2 ===
Name: LEAF
Class: Rival
Pic: Leaf
Gender: Female
Music: Male
Double Battle: No
Bulbasaur
Level: 5
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
=== 3 ===
Name: Test1 Name: Test1
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -30,7 +63,7 @@ Wynaut
Level: 5 Level: 5
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
=== 1 === === 4 ===
Name: Test2 Name: Test2
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -42,7 +75,7 @@ Difficulty: Normal
Mewtwo Mewtwo
Level: 5 Level: 5
=== 2 === === 5 ===
Name: Test2 Name: Test2
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -54,7 +87,7 @@ Difficulty: Normal
Mewtwo Mewtwo
Level: 50 Level: 50
=== 2 === === 5 ===
Name: Test2 Name: Test2
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -66,7 +99,7 @@ Difficulty: Easy
Metapod Metapod
Level: 1 Level: 1
=== 2 === === 5 ===
Name: Test2 Name: Test2
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -78,7 +111,7 @@ Difficulty: Hard
Arceus Arceus
Level: 99 Level: 99
=== 3 === === 6 ===
Name: Test3 Name: Test3
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -95,7 +128,7 @@ Eevee
Mew Mew
=== 4 === === 7 ===
Name: Test4 Name: Test4
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -120,7 +153,7 @@ Tags: Ace
Aron Aron
Tags: Lead Tags: Lead
=== 5 === === 8 ===
Name: Test5 Name: Test5
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -158,7 +191,7 @@ Oddish
Eevee Eevee
=== 6 === === 9 ===
Name: Test6 Name: Test6
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -177,7 +210,7 @@ Tags: Lead
Eevee Eevee
Tags: Lead Tags: Lead
=== 7 === === 10 ===
Name: Test1 Name: Test1
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -195,7 +228,7 @@ Tags: Lead
Eevee Eevee
=== 8 === === 11 ===
Name: Test1 Name: Test1
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -214,7 +247,7 @@ Wobbuffet
Eevee Eevee
Tags: Lead Tags: Lead
=== 9 === === 12 ===
Name: Test9 Name: Test9
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -227,7 +260,7 @@ Wynaut
Wobbuffet Wobbuffet
=== 10 === === 13 ===
Name: Test10 Name: Test10
Class: Pkmn Trainer 1 Class: Pkmn Trainer 1
Pic: Red Pic: Red
@ -240,7 +273,7 @@ Wynaut
Wobbuffet Wobbuffet
=== 11 === === 14 ===
Name: Test11 Name: Test11
Class: Black Belt Class: Black Belt
Pic: Red Pic: Red

View File

@ -1,6 +1,6 @@
[DIFFICULTY_NORMAL] = [DIFFICULTY_NORMAL] =
{ {
[TRAINER_LEAF] = [TRAINER_LEAF_TEST] =
{ {
[TRAINER_SLIDE_BEFORE_FIRST_TURN] = COMPOUND_STRING("Trainer A: This message plays before the first turn.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_BEFORE_FIRST_TURN] = COMPOUND_STRING("Trainer A: This message plays before the first turn.{PAUSE_UNTIL_PRESS}"),
[TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer A: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer A: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"),
@ -16,7 +16,7 @@
[TRAINER_SLIDE_Z_MOVE] = COMPOUND_STRING("Trainer A: This message plays before the enemy activates the Z-Move gimmick.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_Z_MOVE] = COMPOUND_STRING("Trainer A: This message plays before the enemy activates the Z-Move gimmick.{PAUSE_UNTIL_PRESS}"),
[TRAINER_SLIDE_DYNAMAX] = COMPOUND_STRING("Trainer A: This message plays before the enemy activates the Dynamax gimmick.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_DYNAMAX] = COMPOUND_STRING("Trainer A: This message plays before the enemy activates the Dynamax gimmick.{PAUSE_UNTIL_PRESS}"),
}, },
[TRAINER_RED] = [TRAINER_RED_TEST] =
{ {
[TRAINER_SLIDE_BEFORE_FIRST_TURN] = COMPOUND_STRING("Trainer B: This message plays before the first turn.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_BEFORE_FIRST_TURN] = COMPOUND_STRING("Trainer B: This message plays before the first turn.{PAUSE_UNTIL_PRESS}"),
[TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer B: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer B: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"),
@ -32,7 +32,7 @@
[TRAINER_SLIDE_Z_MOVE] = COMPOUND_STRING("Trainer B: This message plays before the enemy activates the Z-Move gimmick.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_Z_MOVE] = COMPOUND_STRING("Trainer B: This message plays before the enemy activates the Z-Move gimmick.{PAUSE_UNTIL_PRESS}"),
[TRAINER_SLIDE_DYNAMAX] = COMPOUND_STRING("Trainer B: This message plays before the enemy activates the Dynamax gimmick.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_DYNAMAX] = COMPOUND_STRING("Trainer B: This message plays before the enemy activates the Dynamax gimmick.{PAUSE_UNTIL_PRESS}"),
}, },
[TRAINER_PARTNER(PARTNER_STEVEN)] = [TRAINER_PARTNER(PARTNER_STEVEN_TEST)] =
{ {
[TRAINER_SLIDE_BEFORE_FIRST_TURN] = COMPOUND_STRING("Trainer Partner: This message plays before the first turn.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_BEFORE_FIRST_TURN] = COMPOUND_STRING("Trainer Partner: This message plays before the first turn.{PAUSE_UNTIL_PRESS}"),
[TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer Partner: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"), [TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer Partner: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"),

View File

@ -14,6 +14,7 @@
#include "party_menu.h" #include "party_menu.h"
#include "random.h" #include "random.h"
#include "test/battle.h" #include "test/battle.h"
#include "trainer_pools.h"
#include "window.h" #include "window.h"
#include "constants/characters.h" #include "constants/characters.h"
#include "constants/trainers.h" #include "constants/trainers.h"
@ -48,6 +49,20 @@ static inline bool32 RngSeedNotDefault(const rng_value_t *seed)
#undef Q_4_12 #undef Q_4_12
#define Q_4_12(n) (s32)((n) * 4096) #define Q_4_12(n) (s32)((n) * 4096)
#define TRAINER_RED_TEST 1
#define TRAINER_LEAF_TEST 2
#define PARTNER_STEVEN_TEST 1
const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] =
{
#include "battle/trainer_control.h"
};
const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT] =
{
#include "battle/partner_control.h"
};
// Alias sBackupMapData to avoid using heap. // Alias sBackupMapData to avoid using heap.
struct BattleTestRunnerState *const gBattleTestRunnerState = (void *)sBackupMapData; struct BattleTestRunnerState *const gBattleTestRunnerState = (void *)sBackupMapData;
STATIC_ASSERT(sizeof(struct BattleTestRunnerState) <= sizeof(sBackupMapData), sBackupMapDataSpace); STATIC_ASSERT(sizeof(struct BattleTestRunnerState) <= sizeof(sBackupMapData), sBackupMapDataSpace);
@ -365,14 +380,14 @@ static void BattleTest_Run(void *data)
break; break;
case BATTLE_TEST_AI_SINGLES: case BATTLE_TEST_AI_SINGLES:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER;
DATA.recordedBattle.opponentA = TRAINER_LEAF; DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
DATA.hasAI = TRUE; DATA.hasAI = TRUE;
for (i = 0; i < STATE->battlersCount; i++) for (i = 0; i < STATE->battlersCount; i++)
DATA.currentMonIndexes[i] = i / 2; DATA.currentMonIndexes[i] = i / 2;
break; break;
case BATTLE_TEST_AI_DOUBLES: case BATTLE_TEST_AI_DOUBLES:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE;
DATA.recordedBattle.opponentA = TRAINER_LEAF; DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
DATA.recordedBattle.opponentB = TRAINER_NONE; DATA.recordedBattle.opponentB = TRAINER_NONE;
DATA.hasAI = TRUE; DATA.hasAI = TRUE;
for (i = 0; i < STATE->battlersCount; i++) for (i = 0; i < STATE->battlersCount; i++)
@ -380,9 +395,9 @@ static void BattleTest_Run(void *data)
break; break;
case BATTLE_TEST_AI_MULTI: case BATTLE_TEST_AI_MULTI:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN); DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
DATA.recordedBattle.opponentA = TRAINER_LEAF; DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
DATA.recordedBattle.opponentB = TRAINER_RED; DATA.recordedBattle.opponentB = TRAINER_RED_TEST;
DATA.hasAI = TRUE; DATA.hasAI = TRUE;
DATA.currentMonIndexes[0] = 0; // Player first mon DATA.currentMonIndexes[0] = 0; // Player first mon
DATA.currentMonIndexes[1] = 0; // Opponent A first mon DATA.currentMonIndexes[1] = 0; // Opponent A first mon
@ -391,8 +406,8 @@ static void BattleTest_Run(void *data)
break; break;
case BATTLE_TEST_AI_TWO_VS_ONE: case BATTLE_TEST_AI_TWO_VS_ONE:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI;
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN); DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
DATA.recordedBattle.opponentA = TRAINER_LEAF; DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
DATA.recordedBattle.opponentB = 0xFFFF; DATA.recordedBattle.opponentB = 0xFFFF;
DATA.currentMonIndexes[0] = 0; // Player first mon DATA.currentMonIndexes[0] = 0; // Player first mon
DATA.currentMonIndexes[1] = 0; // Opponent first mon DATA.currentMonIndexes[1] = 0; // Opponent first mon
@ -402,8 +417,8 @@ static void BattleTest_Run(void *data)
break; break;
case BATTLE_TEST_AI_ONE_VS_TWO: case BATTLE_TEST_AI_ONE_VS_TWO:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS;
DATA.recordedBattle.opponentA = TRAINER_LEAF; DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
DATA.recordedBattle.opponentB = TRAINER_RED; DATA.recordedBattle.opponentB = TRAINER_RED_TEST;
DATA.currentMonIndexes[0] = 0; // Player first mon DATA.currentMonIndexes[0] = 0; // Player first mon
DATA.currentMonIndexes[1] = 0; // Opponent A first mon DATA.currentMonIndexes[1] = 0; // Opponent A first mon
DATA.currentMonIndexes[2] = 1; // Player second mon DATA.currentMonIndexes[2] = 1; // Player second mon
@ -425,7 +440,7 @@ static void BattleTest_Run(void *data)
break; break;
case BATTLE_TEST_MULTI: case BATTLE_TEST_MULTI:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN); DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
DATA.recordedBattle.opponentA = TRAINER_LINK_OPPONENT; DATA.recordedBattle.opponentA = TRAINER_LINK_OPPONENT;
DATA.recordedBattle.opponentB = TRAINER_LINK_OPPONENT; DATA.recordedBattle.opponentB = TRAINER_LINK_OPPONENT;
DATA.currentMonIndexes[0] = 0; // Player first mon DATA.currentMonIndexes[0] = 0; // Player first mon
@ -435,7 +450,7 @@ static void BattleTest_Run(void *data)
break; break;
case BATTLE_TEST_TWO_VS_ONE: case BATTLE_TEST_TWO_VS_ONE:
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI; DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI;
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN); DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
DATA.recordedBattle.opponentA = TRAINER_LINK_OPPONENT; DATA.recordedBattle.opponentA = TRAINER_LINK_OPPONENT;
DATA.recordedBattle.opponentB = 0xFFFF; DATA.recordedBattle.opponentB = 0xFFFF;
DATA.currentMonIndexes[0] = 0; // Player first mon DATA.currentMonIndexes[0] = 0; // Player first mon

View File

@ -5,6 +5,7 @@ AUTO_GEN_TARGETS += src/data/trainers.h
AUTO_GEN_TARGETS += src/data/trainers_frlg.h AUTO_GEN_TARGETS += src/data/trainers_frlg.h
AUTO_GEN_TARGETS += src/data/battle_partners.h AUTO_GEN_TARGETS += src/data/battle_partners.h
AUTO_GEN_TARGETS += test/battle/trainer_control.h AUTO_GEN_TARGETS += test/battle/trainer_control.h
AUTO_GEN_TARGETS += test/battle/partner_control.h
AUTO_GEN_TARGETS += src/data/debug_trainers.h AUTO_GEN_TARGETS += src/data/debug_trainers.h
%.h: %.party $(TRAINERPROC) %.h: %.party $(TRAINERPROC)