mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 09:55:42 -05:00
Fix partner difficulty and rework tests (#9419)
This commit is contained in:
parent
50cfe5847e
commit
976e642137
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -55,6 +55,7 @@ src/data/trainers_frlg.h
|
|||
src/data/debug_trainers.h
|
||||
src/data/tutor_moves.h
|
||||
test/battle/trainer_control.h
|
||||
test/battle/partner_control.h
|
||||
tools/compresSmol/compresSmol
|
||||
tools/compresSmol/compresSmolTilemap
|
||||
tools/aif2pcm/aif2pcm
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
#include "difficulty.h"
|
||||
#include "constants/battle_partner.h"
|
||||
|
||||
extern const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT];
|
||||
|
||||
void FillPartnerParty(u16 trainerId);
|
||||
|
||||
#endif // BATTLE_PARTNER_H
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#define PARTNER_NONE 0
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ extern const struct FollowerMsgInfo gFollowerPoisonedMessages[];
|
|||
|
||||
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 FALSE;
|
||||
}
|
||||
|
|
@ -255,12 +255,17 @@ static inline const struct Trainer *GetTrainerStructFromId(u16 trainerId)
|
|||
u32 sanitizedTrainerId = 0;
|
||||
if (gIsDebugBattle) return GetDebugAiTrainer();
|
||||
sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
if (IsPartnerTrainerId(trainerId))
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(sanitizedTrainerId);
|
||||
return &gBattlePartners[difficulty][sanitizedTrainerId - TRAINER_PARTNER(PARTNER_NONE)];
|
||||
}
|
||||
else
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
return &gTrainers[difficulty][sanitizedTrainerId];
|
||||
}
|
||||
}
|
||||
|
||||
static inline const enum TrainerClassID GetTrainerClassFromId(u16 trainerId)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@
|
|||
#include "constants/battle_ai.h"
|
||||
|
||||
#include "data/partner_parties.h"
|
||||
#if !TESTING
|
||||
const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT] =
|
||||
{
|
||||
#include "data/battle_partners.h"
|
||||
};
|
||||
#endif
|
||||
|
||||
#define STEVEN_OTID 61226
|
||||
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ const union AnimCmd *const gAnims_Trainer[] ={
|
|||
|
||||
#include "data/trainer_parties.h"
|
||||
|
||||
#if !TESTING
|
||||
const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] =
|
||||
{
|
||||
#if IS_FRLG
|
||||
|
|
@ -236,5 +237,6 @@ const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] =
|
|||
#include "data/trainers.h"
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#include "data/text/follower_messages.h"
|
||||
|
|
|
|||
|
|
@ -44,3 +44,15 @@ EVs: 252 Atk / 252 SpA / 6 SpD
|
|||
- Protect
|
||||
- Solar Beam
|
||||
- Dragon Claw
|
||||
|
||||
=== PARTNER_DUMMY ===
|
||||
Name:
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Brendan
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Back Pic: Brendan
|
||||
Party Size: 0
|
||||
|
||||
Wynaut
|
||||
|
||||
|
|
|
|||
|
|
@ -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] =
|
||||
{
|
||||
#include "../test/battle/trainer_slides.h"
|
||||
|
|
|
|||
84
test/battle/partner_control.party
Normal file
84
test/battle/partner_control.party
Normal 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
|
||||
|
|
@ -11,33 +11,14 @@
|
|||
#include "constants/abilities.h"
|
||||
#include "constants/trainers.h"
|
||||
#include "constants/battle.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;
|
||||
}
|
||||
#include "constants/battle_ai.h"
|
||||
|
||||
TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 0;
|
||||
u32 currTrainer = 3;
|
||||
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[1]));
|
||||
|
||||
|
|
@ -111,9 +92,9 @@ TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
|
|||
|
||||
TEST("CreateNPCTrainerPartyForTrainer generates different personalities for different mons")
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevelTest(0);
|
||||
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);
|
||||
Free(testParty);
|
||||
}
|
||||
|
|
@ -132,88 +113,108 @@ TEST("ModifyPersonalityForNature can set any 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")
|
||||
{
|
||||
ASSUME(B_TRAINER_CLASS_POKE_BALLS >= GEN_8);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 1;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 4;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO);
|
||||
Free(testParty);
|
||||
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);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 2;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 5;
|
||||
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 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);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 2;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 5;
|
||||
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 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);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 2;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 5;
|
||||
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_LEVEL) == 50);
|
||||
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")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 3;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 6;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_EEVEE);
|
||||
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")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 4;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 7;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
|
||||
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[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")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 5;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE);
|
||||
u32 currTrainer = 8;
|
||||
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[1], MON_DATA_SPECIES) == SPECIES_BULBASAUR); // Lead + Weather Abuser
|
||||
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")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 6;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 9;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_WYNAUT);
|
||||
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WOBBUFFET);
|
||||
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")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 7;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 10;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_EEVEE);
|
||||
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WYNAUT);
|
||||
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")
|
||||
{
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 8;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
u32 currTrainer = 11;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, GetTrainerStructFromId(currTrainer), TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_WYNAUT);
|
||||
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES) == SPECIES_WOBBUFFET);
|
||||
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")
|
||||
{
|
||||
u32 currTrainer;
|
||||
PARAMETRIZE { currTrainer = 9; }
|
||||
PARAMETRIZE { currTrainer = 10; }
|
||||
const struct Trainer trainer = sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer];
|
||||
EXPECT(trainer.battleType == TRAINER_BATTLE_TYPE_DOUBLES);
|
||||
PARAMETRIZE { currTrainer = 12; }
|
||||
PARAMETRIZE { currTrainer = 13; }
|
||||
const struct Trainer *trainer = GetTrainerStructFromId(currTrainer);
|
||||
EXPECT(trainer->battleType == TRAINER_BATTLE_TYPE_DOUBLES);
|
||||
}
|
||||
|
||||
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));
|
||||
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);
|
||||
Free(testParty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -30,7 +63,7 @@ Wynaut
|
|||
Level: 5
|
||||
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
||||
|
||||
=== 1 ===
|
||||
=== 4 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -42,7 +75,7 @@ Difficulty: Normal
|
|||
Mewtwo
|
||||
Level: 5
|
||||
|
||||
=== 2 ===
|
||||
=== 5 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -54,7 +87,7 @@ Difficulty: Normal
|
|||
Mewtwo
|
||||
Level: 50
|
||||
|
||||
=== 2 ===
|
||||
=== 5 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -66,7 +99,7 @@ Difficulty: Easy
|
|||
Metapod
|
||||
Level: 1
|
||||
|
||||
=== 2 ===
|
||||
=== 5 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -78,7 +111,7 @@ Difficulty: Hard
|
|||
Arceus
|
||||
Level: 99
|
||||
|
||||
=== 3 ===
|
||||
=== 6 ===
|
||||
Name: Test3
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -95,7 +128,7 @@ Eevee
|
|||
|
||||
Mew
|
||||
|
||||
=== 4 ===
|
||||
=== 7 ===
|
||||
Name: Test4
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -120,7 +153,7 @@ Tags: Ace
|
|||
Aron
|
||||
Tags: Lead
|
||||
|
||||
=== 5 ===
|
||||
=== 8 ===
|
||||
Name: Test5
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -158,7 +191,7 @@ Oddish
|
|||
|
||||
Eevee
|
||||
|
||||
=== 6 ===
|
||||
=== 9 ===
|
||||
Name: Test6
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -177,7 +210,7 @@ Tags: Lead
|
|||
Eevee
|
||||
Tags: Lead
|
||||
|
||||
=== 7 ===
|
||||
=== 10 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -195,7 +228,7 @@ Tags: Lead
|
|||
|
||||
Eevee
|
||||
|
||||
=== 8 ===
|
||||
=== 11 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -214,7 +247,7 @@ Wobbuffet
|
|||
Eevee
|
||||
Tags: Lead
|
||||
|
||||
=== 9 ===
|
||||
=== 12 ===
|
||||
Name: Test9
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -227,7 +260,7 @@ Wynaut
|
|||
|
||||
Wobbuffet
|
||||
|
||||
=== 10 ===
|
||||
=== 13 ===
|
||||
Name: Test10
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
|
|
@ -240,7 +273,7 @@ Wynaut
|
|||
|
||||
Wobbuffet
|
||||
|
||||
=== 11 ===
|
||||
=== 14 ===
|
||||
Name: Test11
|
||||
Class: Black Belt
|
||||
Pic: Red
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[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_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_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_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_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_PLAYER_LANDS_FIRST_CRITICAL_HIT] = COMPOUND_STRING("Trainer Partner: This message plays after the player lands their first critical hit.{PAUSE_UNTIL_PRESS}"),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "party_menu.h"
|
||||
#include "random.h"
|
||||
#include "test/battle.h"
|
||||
#include "trainer_pools.h"
|
||||
#include "window.h"
|
||||
#include "constants/characters.h"
|
||||
#include "constants/trainers.h"
|
||||
|
|
@ -48,6 +49,20 @@ static inline bool32 RngSeedNotDefault(const rng_value_t *seed)
|
|||
#undef Q_4_12
|
||||
#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.
|
||||
struct BattleTestRunnerState *const gBattleTestRunnerState = (void *)sBackupMapData;
|
||||
STATIC_ASSERT(sizeof(struct BattleTestRunnerState) <= sizeof(sBackupMapData), sBackupMapDataSpace);
|
||||
|
|
@ -365,14 +380,14 @@ static void BattleTest_Run(void *data)
|
|||
break;
|
||||
case BATTLE_TEST_AI_SINGLES:
|
||||
DATA.recordedBattle.battleFlags = BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER;
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF;
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
|
||||
DATA.hasAI = TRUE;
|
||||
for (i = 0; i < STATE->battlersCount; i++)
|
||||
DATA.currentMonIndexes[i] = i / 2;
|
||||
break;
|
||||
case BATTLE_TEST_AI_DOUBLES:
|
||||
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.hasAI = TRUE;
|
||||
for (i = 0; i < STATE->battlersCount; i++)
|
||||
|
|
@ -380,9 +395,9 @@ static void BattleTest_Run(void *data)
|
|||
break;
|
||||
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.partnerId = TRAINER_PARTNER(PARTNER_STEVEN);
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF;
|
||||
DATA.recordedBattle.opponentB = TRAINER_RED;
|
||||
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
|
||||
DATA.recordedBattle.opponentB = TRAINER_RED_TEST;
|
||||
DATA.hasAI = TRUE;
|
||||
DATA.currentMonIndexes[0] = 0; // Player first mon
|
||||
DATA.currentMonIndexes[1] = 0; // Opponent A first mon
|
||||
|
|
@ -391,8 +406,8 @@ static void BattleTest_Run(void *data)
|
|||
break;
|
||||
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.partnerId = TRAINER_PARTNER(PARTNER_STEVEN);
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF;
|
||||
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
|
||||
DATA.recordedBattle.opponentB = 0xFFFF;
|
||||
DATA.currentMonIndexes[0] = 0; // Player first mon
|
||||
DATA.currentMonIndexes[1] = 0; // Opponent first mon
|
||||
|
|
@ -402,8 +417,8 @@ static void BattleTest_Run(void *data)
|
|||
break;
|
||||
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.opponentA = TRAINER_LEAF;
|
||||
DATA.recordedBattle.opponentB = TRAINER_RED;
|
||||
DATA.recordedBattle.opponentA = TRAINER_LEAF_TEST;
|
||||
DATA.recordedBattle.opponentB = TRAINER_RED_TEST;
|
||||
DATA.currentMonIndexes[0] = 0; // Player first mon
|
||||
DATA.currentMonIndexes[1] = 0; // Opponent A first mon
|
||||
DATA.currentMonIndexes[2] = 1; // Player second mon
|
||||
|
|
@ -425,7 +440,7 @@ static void BattleTest_Run(void *data)
|
|||
break;
|
||||
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.partnerId = TRAINER_PARTNER(PARTNER_STEVEN);
|
||||
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
|
||||
DATA.recordedBattle.opponentA = TRAINER_LINK_OPPONENT;
|
||||
DATA.recordedBattle.opponentB = TRAINER_LINK_OPPONENT;
|
||||
DATA.currentMonIndexes[0] = 0; // Player first mon
|
||||
|
|
@ -435,7 +450,7 @@ static void BattleTest_Run(void *data)
|
|||
break;
|
||||
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.partnerId = TRAINER_PARTNER(PARTNER_STEVEN);
|
||||
DATA.recordedBattle.partnerId = TRAINER_PARTNER(PARTNER_STEVEN_TEST);
|
||||
DATA.recordedBattle.opponentA = TRAINER_LINK_OPPONENT;
|
||||
DATA.recordedBattle.opponentB = 0xFFFF;
|
||||
DATA.currentMonIndexes[0] = 0; // Player first mon
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ AUTO_GEN_TARGETS += src/data/trainers.h
|
|||
AUTO_GEN_TARGETS += src/data/trainers_frlg.h
|
||||
AUTO_GEN_TARGETS += src/data/battle_partners.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
|
||||
|
||||
%.h: %.party $(TRAINERPROC)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user