refactored trainers

This commit is contained in:
cawtds
2024-05-11 01:30:30 +02:00
parent 6d3a81785f
commit f980e6258d
17 changed files with 3437 additions and 4259 deletions

View File

@@ -34,9 +34,9 @@
#define MOVE_MOST_POWERFUL 2
// script's table id to bit
#define AI_SCRIPT_CHECK_BAD_MOVE (1 << 0)
#define AI_SCRIPT_CHECK_VIABILITY (1 << 1)
#define AI_SCRIPT_TRY_TO_FAINT (1 << 2)
#define AI_FLAG_CHECK_BAD_MOVE (1 << 0)
#define AI_FLAG_CHECK_VIABILITY (1 << 1)
#define AI_FLAG_TRY_TO_FAINT (1 << 2)
#define AI_SCRIPT_SETUP_FIRST_TURN (1 << 3)
#define AI_SCRIPT_RISKY (1 << 4)
#define AI_SCRIPT_PREFER_STRONGEST_MOVE (1 << 5)

View File

@@ -82,6 +82,7 @@
#define WONDER_NEWS_BODY_TEXT_LINES 10
#define TYPE_NAME_LENGTH 6
#define ABILITY_NAME_LENGTH ((B_EXPANDED_ABILITY_NAMES == TRUE) ? 16 : 12)
#define TRAINER_NAME_LENGTH 10
#define MAX_STAMP_CARD_STAMPS 7

View File

@@ -1,6 +1,8 @@
#ifndef GUARD_CONSTANTS_OPPONENTS_H
#define GUARD_CONSTANTS_OPPONENTS_H
#include "constants/battle_partner.h"
#define TRAINER_NONE 0
// Dummy trainers for all the RS trainer classes
#define TRAINER_AQUA_LEADER 1
@@ -752,7 +754,7 @@
// only space for 25 additional trainers before trainer flag space overflows.
// MAX_TRAINERS_COUNT can be increased but will take up additional saveblock space
#define NUM_TRAINERS 744
#define TRAINERS_COUNT 744
#define MAX_TRAINERS_COUNT 769
#define TRAINER_PARTNER(partner) (MAX_TRAINERS_COUNT + partner)

View File

@@ -288,6 +288,8 @@
#define TRAINER_CLASS_LADY 105
#define TRAINER_CLASS_PAINTER 106
#define TRAINER_CLASS_COUNT 107
#define FACILITY_CLASS_AQUA_LEADER_ARCHIE 0
#define FACILITY_CLASS_AQUA_GRUNT_M 1
#define FACILITY_CLASS_AQUA_GRUNT_F 2
@@ -441,6 +443,10 @@
#define F_TRAINER_FEMALE (1 << 7)
// Trainer party defines
#define TRAINER_MON_MALE 1
#define TRAINER_MON_FEMALE 2
// All trainer parties specify the IV, level, and species for each Pokémon in the
// party. Some trainer parties also specify held items and custom moves for each
// Pokémon.

View File

@@ -18,6 +18,8 @@ struct MonCoords
#define MON_COORDS_SIZE(width, height)(DIV_ROUND_UP(width, 8) << 4 | DIV_ROUND_UP(height, 8))
#define GET_MON_COORDS_WIDTH(size)((size >> 4) * 8)
#define GET_MON_COORDS_HEIGHT(size)((size & 0xF) * 8)
#define TRAINER_PARTY_IVS(hp, atk, def, speed, spatk, spdef) (hp | (atk << 5) | (def << 10) | (speed << 15) | (spatk << 20) | (spdef << 25))
#define TRAINER_PARTY_EVS(hp, atk, def, speed, spatk, spdef) ((const u8[6]){hp,atk,def,spatk,spdef,speed})
#define MAX_TRAINER_ITEMS 4
@@ -28,76 +30,51 @@ enum {
BATTLER_AFFINE_RETURN,
};
struct TrainerMonNoItemDefaultMoves
struct TrainerMon
{
u16 iv;
u8 lvl;
u16 species;
};
struct TrainerMonItemDefaultMoves
{
u16 iv;
u8 lvl;
const u8 *nickname;
const u8 *ev;
u32 iv;
u16 moves[4];
u16 species;
u16 heldItem;
};
struct TrainerMonNoItemCustomMoves
{
u16 iv;
u16 ability;
u8 lvl;
u16 species;
u16 moves[MAX_MON_MOVES];
u8 ball;
u8 friendship;
u8 nature:5;
bool8 gender:2;
bool8 isShiny:1;
u8 dynamaxLevel:4;
bool8 gigantamaxFactor:1;
bool8 shouldDynamax:1;
bool8 shouldTerastal:1;
};
struct TrainerMonItemCustomMoves
{
u16 iv;
u8 lvl;
u16 species;
u16 heldItem;
u16 moves[MAX_MON_MOVES];
};
#define NO_ITEM_DEFAULT_MOVES(party) { .NoItemDefaultMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = 0
#define NO_ITEM_CUSTOM_MOVES(party) { .NoItemCustomMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_CUSTOM_MOVESET
#define ITEM_DEFAULT_MOVES(party) { .ItemDefaultMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_HELD_ITEM
#define ITEM_CUSTOM_MOVES(party) { .ItemCustomMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM
union TrainerMonPtr
{
const struct TrainerMonNoItemDefaultMoves *NoItemDefaultMoves;
const struct TrainerMonNoItemCustomMoves *NoItemCustomMoves;
const struct TrainerMonItemDefaultMoves *ItemDefaultMoves;
const struct TrainerMonItemCustomMoves *ItemCustomMoves;
};
#define TRAINER_PARTY(partyArray) partyArray, .partySize = ARRAY_COUNT(partyArray)
struct Trainer
{
/*0x00*/ u8 partyFlags;
/*0x01*/ u8 trainerClass;
/*0x02*/ u8 encounterMusic_gender; // last bit is gender
/*0x03*/ u8 trainerPic;
/*0x04*/ u8 trainerName[12];
/*0x10*/ u16 items[MAX_TRAINER_ITEMS];
/*0x18*/ bool8 doubleBattle;
/*0x1C*/ u32 aiFlags;
/*0x00*/ u32 aiFlags;
/*0x04*/ const struct TrainerMon *party;
/*0x08*/ u16 items[MAX_TRAINER_ITEMS];
/*0x10*/ u8 trainerClass;
/*0x11*/ u8 encounterMusic_gender; // last bit is gender
/*0x12*/ u8 trainerPic;
/*0x13*/ u8 trainerName[TRAINER_NAME_LENGTH + 1];
/*0x1E*/ bool8 doubleBattle:1;
bool8 mugshotEnabled:1;
u8 startingStatus:6; // this trainer starts a battle with a given status. see include/constants/battle.h for values
/*0x1F*/ u8 mugshotColor;
/*0x20*/ u8 partySize;
/*0x24*/ const union TrainerMonPtr party;
};
// extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
// extern const u8 gMoveNames[][MOVE_NAME_LENGTH + 1];
extern const u8 gTrainerClassNames[][13];
static inline u16 SanitizeTrainerId(u16 trainerId)
struct TrainerClass
{
if (trainerId >= NUM_TRAINERS)
return TRAINER_NONE;
return trainerId;
}
u8 name[13];
u8 money;
u16 ball;
};
struct TypeInfo
{
@@ -116,12 +93,6 @@ struct TypeInfo
//u16 arceusForm;
};
// extern const struct MonCoords gMonFrontPicCoords[];
// extern const struct CompressedSpriteSheet gMonFrontPicTable[];
// extern const struct MonCoords gMonBackPicCoords[];
// extern const struct CompressedSpriteSheet gMonBackPicTable[];
// extern const struct CompressedSpritePalette gMonPaletteTable[];
// extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
extern const union AnimCmd *const *const gTrainerFrontAnimsPtrTable[];
extern const struct MonCoords gTrainerFrontPicCoords[];
extern const struct CompressedSpriteSheet gTrainerFrontPicTable[];
@@ -155,16 +126,85 @@ extern const struct SpriteFrameImage gTrainerBackPicTable_RSMay[];
extern const union AnimCmd sAnim_GeneralFrame0[];
extern const struct Trainer gTrainers[];
extern const struct Trainer gBattlePartners[];
extern const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT];
static inline u16 SanitizeTrainerId(u16 trainerId)
{
if (trainerId >= TRAINERS_COUNT)
return TRAINER_NONE;
return trainerId;
}
static inline const struct Trainer *GetTrainerStructFromId(u16 trainerId)
{
return &gTrainers[SanitizeTrainerId(trainerId)];
}
static inline const u8 GetTrainerClassFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].trainerClass;
}
static inline const u8 *GetTrainerClassNameFromId(u16 trainerId)
{
if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
return gTrainerClasses[gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass].name;
return gTrainerClasses[GetTrainerClassFromId(trainerId)].name;
}
static inline const u8 *GetTrainerNameFromId(u16 trainerId)
{
// if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
// return gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName;
if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
return gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName;
return gTrainers[SanitizeTrainerId(trainerId)].trainerName;
}
// static inline const struct TrainerMon *GetTrainerPartyFromId(u16 trainerId)
// {
// return gTrainers[SanitizeTrainerId(trainerId)].party;
// }
static inline const u8 GetTrainerPicFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].trainerPic;
}
static inline const u8 GetTrainerStartingStatusFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].startingStatus;
}
static inline const bool32 IsTrainerDoubleBattle(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].doubleBattle;
}
static inline const u8 GetTrainerPartySizeFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].partySize;
}
static inline const bool32 DoesTrainerHaveMugshot(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].mugshotEnabled;
}
static inline const u8 GetTrainerMugshotColorFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].mugshotColor;
}
static inline const u16 *GetTrainerItemsFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].items;
}
static inline const struct TrainerMon *GetTrainerPartyFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].party;
}
static inline const bool32 GetTrainerAIFlagsFromId(u16 trainerId)
{
return gTrainers[SanitizeTrainerId(trainerId)].aiFlags;
}
#endif // GUARD_DATA_H

View File

@@ -750,6 +750,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
u8 GetItemEffectParamOffset(u32 battler, u16 itemId, u8 effectByte, u8 effectBit);
// const u8 *Battle_PrintStatBoosterEffectMessage(u16 itemId);
u8 GetNature(struct Pokemon *mon);
u8 GetNatureFromPersonality(u32 personality);
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem, struct Pokemon *tradePartner);
u16 NationalPokedexNumToSpecies(u16 nationalNum);
u16 SpeciesToNationalPokedexNum(u16 species);

View File

@@ -379,18 +379,18 @@ void BattleAI_SetupAIData(u32 battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_WILD_SCRIPTED)
{
AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_CHECK_BAD_MOVE;
AI_THINKING_STRUCT->aiFlags = AI_FLAG_CHECK_BAD_MOVE;
return;
}
else if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY_FRLG)
{
AI_THINKING_STRUCT->aiFlags = (AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY);
AI_THINKING_STRUCT->aiFlags = (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY);
return;
}
}
else
{
AI_THINKING_STRUCT->aiFlags = (AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY);
AI_THINKING_STRUCT->aiFlags = (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY);
return;
}
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags;

View File

@@ -66,7 +66,7 @@ static void HandleEndTurn_FinishBattle(void);
static void CB2_InitBattleInternal(void);
static void CB2_PreInitMultiBattle(void);
static void CB2_HandleStartMultiBattle(void);
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum);
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 firstTrainer);
static void CB2_HandleStartBattle(void);
static void TryCorrectShedinjaLanguage(struct Pokemon *mon);
static void BattleMainCB1(void);
@@ -593,28 +593,124 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
*/
};
// extra args are money and ball
#define TRAINER_CLASS(trainerClass, trainerName, ...) \
[TRAINER_CLASS_##trainerClass] = \
{ \
.name = _(trainerName), \
.money = DEFAULT(5, __VA_ARGS__), \
.ball = DEFAULT_2(ITEM_POKE_BALL, __VA_ARGS__), \
}
static const union AnimCmd sAnim_Unused[] =
const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_Unused[] =
{
sAnim_Unused,
};
static const union AffineAnimCmd sAffineAnim_Unused[] =
{
AFFINEANIMCMD_FRAME(-0x10, 0x0, 0, 4),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 0x3C),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_Unused[] =
{
sAffineAnim_Unused,
TRAINER_CLASS(NONE, "{PKMN} TRAINER"),
TRAINER_CLASS(PKMN_TRAINER_UNUSED, "{PKMN} TRAINER"),
TRAINER_CLASS(AQUA_LEADER, "AQUA LEADER"),
TRAINER_CLASS(TEAM_AQUA, "TEAM AQUA"),
TRAINER_CLASS(RS_AROMA_LADY, "AROMA LADY"),
TRAINER_CLASS(RS_RUIN_MANIAC, "RUIN MANIAC"),
TRAINER_CLASS(INTERVIEWER, "INTERVIEWER"),
TRAINER_CLASS(RS_TUBER_F, "TUBER"),
TRAINER_CLASS(RS_TUBER_M, "TUBER"),
TRAINER_CLASS(RS_COOLTRAINER, "COOLTRAINER"),
TRAINER_CLASS(HEX_MANIAC, "HEX MANIAC"),
TRAINER_CLASS(RS_LADY, "LADY"),
TRAINER_CLASS(RS_BEAUTY, "BEAUTY"),
TRAINER_CLASS(RICH_BOY, "RICH BOY"),
TRAINER_CLASS(RS_POKEMANIAC, "POKéMANIAC"),
TRAINER_CLASS(RS_SWIMMER_M, "SWIMMER♂"),
TRAINER_CLASS(RS_BLACK_BELT, "BLACK BELT"),
TRAINER_CLASS(GUITARIST, "GUITARIST"),
TRAINER_CLASS(KINDLER, "KINDLER"),
TRAINER_CLASS(RS_CAMPER, "CAMPER"),
TRAINER_CLASS(BUG_MANIAC, "BUG MANIAC"),
TRAINER_CLASS(RS_PSYCHIC, "PSYCHIC"),
TRAINER_CLASS(RS_GENTLEMAN, "GENTLEMAN"),
TRAINER_CLASS(RS_ELITE_FOUR, "ELITE FOUR"),
TRAINER_CLASS(RS_LEADER, "LEADER"),
TRAINER_CLASS(SCHOOL_KID, "SCHOOL KID"),
TRAINER_CLASS(SR_AND_JR, "SR. AND JR."),
TRAINER_CLASS(POKEFAN, "POKéFAN"),
TRAINER_CLASS(EXPERT, "EXPERT"),
TRAINER_CLASS(RS_YOUNGSTER, "YOUNGSTER"),
TRAINER_CLASS(RS_CHAMPION, "CHAMPION"),
TRAINER_CLASS(RS_FISHERMAN, "FISHERMAN"),
TRAINER_CLASS(TRIATHLETE, "TRIATHLETE"),
TRAINER_CLASS(DRAGON_TAMER, "DRAGON TAMER"),
TRAINER_CLASS(RS_BIRD_KEEPER, "BIRD KEEPER"),
TRAINER_CLASS(NINJA_BOY, "NINJA BOY"),
TRAINER_CLASS(BATTLE_GIRL, "BATTLE GIRL"),
TRAINER_CLASS(PARASOL_LADY, "PARASOL LADY"),
TRAINER_CLASS(RS_SWIMMER_F, "SWIMMER♀"),
TRAINER_CLASS(RS_PICNICKER, "PICNICKER"),
TRAINER_CLASS(RS_TWINS, "TWINS"),
TRAINER_CLASS(RS_SAILOR, "SAILOR"),
TRAINER_CLASS(BOARDER, "BOARDER"),
TRAINER_CLASS(COLLECTOR, "COLLECTOR"),
TRAINER_CLASS(PKMN_TRAINER, "{PKMN} TRAINER"),
TRAINER_CLASS(RS_PKMN_BREEDER, "{PKMN} BREEDER"),
TRAINER_CLASS(RS_PKMN_RANGER, "{PKMN} RANGER"),
TRAINER_CLASS(MAGMA_LEADER, "MAGMA LEADER"),
TRAINER_CLASS(TEAM_MAGMA, "TEAM MAGMA"),
TRAINER_CLASS(RS_LASS, "LASS"),
TRAINER_CLASS(RS_BUG_CATCHER, "BUG CATCHER"),
TRAINER_CLASS(RS_HIKER, "HIKER"),
TRAINER_CLASS(RS_YOUNG_COUPLE, "YOUNG COUPLE"),
TRAINER_CLASS(OLD_COUPLE, "OLD COUPLE"),
TRAINER_CLASS(RS_SIS_AND_BRO, "SIS AND BRO"),
TRAINER_CLASS(AQUA_ADMIN, "AQUA ADMIN"),
TRAINER_CLASS(MAGMA_ADMIN, "MAGMA ADMIN"),
TRAINER_CLASS(YOUNGSTER, "YOUNGSTER"),
TRAINER_CLASS(BUG_CATCHER, "BUG CATCHER"),
TRAINER_CLASS(LASS, "LASS"),
TRAINER_CLASS(SAILOR, "SAILOR"),
TRAINER_CLASS(CAMPER, "CAMPER"),
TRAINER_CLASS(PICNICKER, "PICNICKER"),
TRAINER_CLASS(POKEMANIAC, "POKéMANIAC"),
TRAINER_CLASS(SUPER_NERD, "SUPER NERD"),
TRAINER_CLASS(HIKER, "HIKER"),
TRAINER_CLASS(BIKER, "BIKER"),
TRAINER_CLASS(BURGLAR, "BURGLAR"),
TRAINER_CLASS(ENGINEER, "ENGINEER"),
TRAINER_CLASS(FISHERMAN, "FISHERMAN"),
TRAINER_CLASS(SWIMMER_M, "SWIMMER♂"),
TRAINER_CLASS(CUE_BALL, "CUE BALL"),
TRAINER_CLASS(GAMER, "GAMER"),
TRAINER_CLASS(BEAUTY, "BEAUTY"),
TRAINER_CLASS(SWIMMER_F, "SWIMMER♀"),
TRAINER_CLASS(PSYCHIC, "PSYCHIC"),
TRAINER_CLASS(ROCKER, "ROCKER"),
TRAINER_CLASS(JUGGLER, "JUGGLER"),
TRAINER_CLASS(TAMER, "TAMER"),
TRAINER_CLASS(BIRD_KEEPER, "BIRD KEEPER"),
TRAINER_CLASS(BLACK_BELT, "BLACK BELT"),
TRAINER_CLASS(RIVAL_EARLY, "RIVAL"),
TRAINER_CLASS(SCIENTIST, "SCIENTIST"),
TRAINER_CLASS(BOSS, "BOSS"),
TRAINER_CLASS(LEADER, "LEADER"),
TRAINER_CLASS(TEAM_ROCKET, "TEAM ROCKET"),
TRAINER_CLASS(COOLTRAINER, "COOLTRAINER"),
TRAINER_CLASS(ELITE_FOUR, "ELITE FOUR"),
TRAINER_CLASS(GENTLEMAN, "GENTLEMAN"),
TRAINER_CLASS(RIVAL_LATE, "RIVAL"),
TRAINER_CLASS(CHAMPION, "CHAMPION"),
TRAINER_CLASS(CHANNELER, "CHANNELER"),
TRAINER_CLASS(TWINS, "TWINS"),
TRAINER_CLASS(COOL_COUPLE, "COOL COUPLE"),
TRAINER_CLASS(YOUNG_COUPLE, "YOUNG COUPLE"),
TRAINER_CLASS(CRUSH_KIN, "CRUSH KIN"),
TRAINER_CLASS(SIS_AND_BRO, "SIS AND BRO"),
TRAINER_CLASS(PKMN_PROF, "{PKMN} PROF."),
TRAINER_CLASS(PLAYER, "PLAYER"),
TRAINER_CLASS(CRUSH_GIRL, "CRUSH GIRL"),
TRAINER_CLASS(TUBER, "TUBER"),
TRAINER_CLASS(PKMN_BREEDER, "{PKMN} BREEDER"),
TRAINER_CLASS(PKMN_RANGER, "{PKMN} RANGER"),
TRAINER_CLASS(AROMA_LADY, "AROMA LADY"),
TRAINER_CLASS(RUIN_MANIAC, "RUIN MANIAC"),
TRAINER_CLASS(LADY, "LADY"),
TRAINER_CLASS(PAINTER, "PAINTER"),
};
static const s8 sPlayerThrowXTranslation[] = { -32, -16, -16, -32, -32, 0, 0, 0 };
@@ -865,6 +961,13 @@ static void CB2_InitBattleInternal(void)
gBattleTerrain = BattleSetup_GetTerrainId();
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_TRAINER_TOWER)))
{
gBattleTypeFlags |= (IsTrainerDoubleBattle(gTrainerBattleOpponent_A) ? BATTLE_TYPE_DOUBLE : 0);
}
InitBattleBgsVideo();
LoadBattleTextboxAndBackground();
ResetSpriteData();
@@ -881,7 +984,7 @@ static void CB2_InitBattleInternal(void)
SetMainCallback2(CB2_HandleStartBattle);
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
{
CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A);
CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A, FALSE);
SetWildMonHeldItem();
}
@@ -1743,112 +1846,210 @@ static void SpriteCB_UnusedDebugSprite_Step(struct Sprite *sprite)
}
}
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum)
static u32 Crc32B (const u8 *data, u32 size)
{
u32 nameHash = 0;
u32 personalityValue;
u8 fixedIV;
s32 i, j;
s32 i, j;
u32 byte, crc, mask;
if (trainerNum == TRAINER_SECRET_BASE)
return 0;
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
&& !(gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER_TOWER)))
{
ZeroEnemyPartyMons();
for (i = 0; i < gTrainers[trainerNum].partySize; i++)
i = 0;
crc = 0xFFFFFFFF;
for (i = 0; i < size; ++i)
{
byte = data[i];
crc = crc ^ byte;
for (j = 7; j >= 0; --j)
{
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
if (gTrainers[trainerNum].doubleBattle == TRUE)
static u32 GeneratePartyHash(const struct Trainer *trainer, u32 i)
{
const u8 *buffer = (const u8 *) &trainer->party[i];
u32 n = sizeof(*trainer->party);
return Crc32B(buffer, n);
}
void ModifyPersonalityForNature(u32 *personality, u32 newNature)
{
u32 nature = GetNatureFromPersonality(*personality);
s32 diff = abs((s32)nature - (s32)newNature);
s32 sign = (nature > newNature) ? 1 : -1;
if (diff > NUM_NATURES / 2)
{
diff = NUM_NATURES - diff;
sign *= -1;
}
*personality -= (diff * sign);
}
u32 GeneratePersonalityForGender(u32 gender, u32 species)
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[species];
if (gender == MON_MALE)
return ((255 - speciesInfo->genderRatio) / 2) + speciesInfo->genderRatio;
else
return speciesInfo->genderRatio / 2;
}
void CustomTrainerPartyAssignMoves(struct Pokemon *mon, const struct TrainerMon *partyEntry)
{
bool32 noMoveSet = TRUE;
u32 j;
for (j = 0; j < MAX_MON_MOVES; ++j)
{
if (partyEntry->moves[j] != MOVE_NONE)
noMoveSet = FALSE;
}
if (noMoveSet)
{
// TODO: Figure out a default strategy when moves are not set, to generate a good moveset
return;
}
for (j = 0; j < MAX_MON_MOVES; ++j)
{
SetMonData(mon, MON_DATA_MOVE1 + j, &partyEntry->moves[j]);
SetMonData(mon, MON_DATA_PP1 + j, &gMovesInfo[partyEntry->moves[j]].pp);
}
}
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags)
{
u32 personalityValue;
s32 i;
u8 monsCount;
if (battleTypeFlags & BATTLE_TYPE_TRAINER && !(battleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_TRAINER_TOWER)))
{
if (firstTrainer == TRUE)
ZeroEnemyPartyMons();
if (battleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (trainer->partySize > PARTY_SIZE / 2)
monsCount = PARTY_SIZE / 2;
else
monsCount = trainer->partySize;
}
else
{
monsCount = trainer->partySize;
}
for (i = 0; i < monsCount; i++)
{
s32 ball = -1;
u32 personalityHash = GeneratePartyHash(trainer, i);
const struct TrainerMon *partyData = trainer->party;
u32 otIdType = OT_ID_RANDOM_NO_SHINY;
u32 fixedOtId = 0;
u32 ability = 0;
if (trainer->doubleBattle == TRUE)
personalityValue = 0x80;
else if (gTrainers[trainerNum].encounterMusic_gender & F_TRAINER_FEMALE)
else if (trainer->encounterMusic_gender & F_TRAINER_FEMALE)
personalityValue = 0x78; // Use personality more likely to result in a female Pokémon
else
personalityValue = 0x88; // Use personality more likely to result in a male Pokémon
for (j = 0; gTrainers[trainerNum].trainerName[j] != EOS; j++)
nameHash += gTrainers[trainerNum].trainerName[j];
switch (gTrainers[trainerNum].partyFlags)
personalityValue += personalityHash << 8;
if (partyData[i].gender == TRAINER_MON_MALE)
personalityValue = (personalityValue & 0xFFFFFF00) | GeneratePersonalityForGender(MON_MALE, partyData[i].species);
else if (partyData[i].gender == TRAINER_MON_FEMALE)
personalityValue = (personalityValue & 0xFFFFFF00) | GeneratePersonalityForGender(MON_FEMALE, partyData[i].species);
ModifyPersonalityForNature(&personalityValue, partyData[i].nature);
if (partyData[i].isShiny)
{
case 0:
{
const struct TrainerMonNoItemDefaultMoves *partyData = gTrainers[trainerNum].party.NoItemDefaultMoves;
for (j = 0; gSpeciesInfo[partyData[i].species].speciesName[j] != EOS; j++)
nameHash += gSpeciesInfo[partyData[i].species].speciesName[j];
personalityValue += nameHash << 8;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
break;
otIdType = OT_ID_PRESET;
fixedOtId = HIHALF(personalityValue) ^ LOHALF(personalityValue);
}
case F_TRAINER_PARTY_CUSTOM_MOVESET:
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, 0, TRUE, personalityValue, otIdType, fixedOtId);
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
CustomTrainerPartyAssignMoves(&party[i], &partyData[i]);
SetMonData(&party[i], MON_DATA_IVS, &(partyData[i].iv));
if (partyData[i].ev != NULL)
{
const struct TrainerMonNoItemCustomMoves *partyData = gTrainers[trainerNum].party.NoItemCustomMoves;
for (j = 0; gSpeciesInfo[partyData[i].species].speciesName[j] != EOS; j++)
nameHash += gSpeciesInfo[partyData[i].species].speciesName[j];
personalityValue += nameHash << 8;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
for (j = 0; j < MAX_MON_MOVES; j++)
SetMonData(&party[i], MON_DATA_HP_EV, &(partyData[i].ev[0]));
SetMonData(&party[i], MON_DATA_ATK_EV, &(partyData[i].ev[1]));
SetMonData(&party[i], MON_DATA_DEF_EV, &(partyData[i].ev[2]));
SetMonData(&party[i], MON_DATA_SPATK_EV, &(partyData[i].ev[3]));
SetMonData(&party[i], MON_DATA_SPDEF_EV, &(partyData[i].ev[4]));
SetMonData(&party[i], MON_DATA_SPEED_EV, &(partyData[i].ev[5]));
}
if (partyData[i].ability != ABILITY_NONE)
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[partyData[i].species];
u32 maxAbilities = ARRAY_COUNT(speciesInfo->abilities);
for (ability = 0; ability < maxAbilities; ++ability)
{
SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]);
SetMonData(&party[i], MON_DATA_PP1 + j, &gMovesInfo[partyData[i].moves[j]].pp);
if (speciesInfo->abilities[ability] == partyData[i].ability)
break;
}
break;
if (ability >= maxAbilities)
ability = 0;
}
case F_TRAINER_PARTY_HELD_ITEM:
else if (B_TRAINER_MON_RANDOM_ABILITY)
{
const struct TrainerMonItemDefaultMoves *partyData = gTrainers[trainerNum].party.ItemDefaultMoves;
for (j = 0; gSpeciesInfo[partyData[i].species].speciesName[j] != EOS; j++)
nameHash += gSpeciesInfo[partyData[i].species].speciesName[j];
personalityValue += nameHash << 8;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
break;
}
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemCustomMoves *partyData = gTrainers[trainerNum].party.ItemCustomMoves;
for (j = 0; gSpeciesInfo[partyData[i].species].speciesName[j] != EOS; j++)
nameHash += gSpeciesInfo[partyData[i].species].speciesName[j];
personalityValue += nameHash << 8;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
for (j = 0; j < MAX_MON_MOVES; j++)
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[partyData[i].species];
ability = personalityHash % 3;
while (speciesInfo->abilities[ability] == ABILITY_NONE)
{
SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]);
SetMonData(&party[i], MON_DATA_PP1 + j, &gMovesInfo[partyData[i].moves[j]].pp);
ability--;
}
break;
}
SetMonData(&party[i], MON_DATA_ABILITY_NUM, &ability);
SetMonData(&party[i], MON_DATA_FRIENDSHIP, &(partyData[i].friendship));
if (partyData[i].ball != ITEM_NONE)
{
ball = partyData[i].ball;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);
}
if (partyData[i].nickname != NULL)
{
SetMonData(&party[i], MON_DATA_NICKNAME, partyData[i].nickname);
}
if (partyData[i].isShiny)
{
u32 data = TRUE;
SetMonData(&party[i], MON_DATA_IS_SHINY, &data);
}
if (partyData[i].dynamaxLevel > 0)
{
u32 data = partyData[i].dynamaxLevel;
SetMonData(&party[i], MON_DATA_DYNAMAX_LEVEL, &data);
}
if (partyData[i].gigantamaxFactor)
{
u32 data = partyData[i].gigantamaxFactor;
SetMonData(&party[i], MON_DATA_GIGANTAMAX_FACTOR, &data);
}
CalculateMonStats(&party[i]);
if (B_TRAINER_CLASS_POKE_BALLS >= GEN_7 && ball == -1)
{
ball = gTrainerClasses[trainer->trainerClass].ball ?: ITEM_POKE_BALL;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);
}
}
gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle;
}
return gTrainers[trainerNum].partySize;
return trainer->partySize;
}
// Unused
static void HBlankCB_Battle(void)
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 firstTrainer)
{
if (REG_VCOUNT < DISPLAY_HEIGHT && REG_VCOUNT >= 111)
REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(24) | BGCNT_16COLOR | BGCNT_TXT256x512;
u8 retVal;
if (trainerNum == TRAINER_SECRET_BASE)
return 0;
retVal = CreateNPCTrainerPartyFromTrainer(party, GetTrainerStructFromId(trainerNum), firstTrainer, gBattleTypeFlags);
return retVal;
}
void VBlankCB_Battle(void)

View File

@@ -2827,6 +2827,24 @@ static const u8 *BattleStringGetTrainerName(u8 *text, u8 multiplayerId, u8 battl
return BattleStringGetOpponentName(text, multiplayerId, battler);
}
static const u8 *BattleStringGetOpponentClassByTrainerId(u16 trainerId)
{
const u8 *toCpy;
if (trainerId == TRAINER_UNION_ROOM)
toCpy = gTrainerClasses[GetUnionRoomTrainerClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
toCpy = gTrainerClasses[GetBattleTowerTrainerClassNameId()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
toCpy = gTrainerClasses[GetTrainerTowerOpponentClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
toCpy = gTrainerClasses[GetEreaderTrainerClassId()].name;
else
toCpy = gTrainerClasses[GetTrainerClassFromId(trainerId)].name;
return toCpy;
}
u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
{
u32 dstId = 0; // if they used dstId, why not use srcId as well?
@@ -2876,18 +2894,14 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
toCpy = gBattleTextBuff3;
break;
case B_TXT_TRAINER2_CLASS:
// TODO: trainer name
// toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
toCpy = "TODO";
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
break;
case B_TXT_TRAINER2_NAME:
// TODO: trainer name
// toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, text, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT));
toCpy = "TODO";
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, text, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT));
break;
case B_TXT_PARTNER_CLASS:
// TODO: trainer name
// toCpy = gTrainerClassNames[GetFrontierOpponentClass(gPartnerTrainerId)].name;
// toCpy = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name;
toCpy = "TODO";
break;
case B_TXT_PARTNER_NAME:
@@ -3053,17 +3067,17 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
break;
case B_TXT_TRAINER1_CLASS: // trainer class name
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()];
toCpy = gTrainerClasses[GetSecretBaseTrainerNameIndex()].name;
else if (gTrainerBattleOpponent_A == TRAINER_UNION_ROOM)
toCpy = gTrainerClassNames[GetUnionRoomTrainerClass()];
toCpy = gTrainerClasses[GetUnionRoomTrainerClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
toCpy = gTrainerClassNames[GetBattleTowerTrainerClassNameId()];
toCpy = gTrainerClasses[GetBattleTowerTrainerClassNameId()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
toCpy = gTrainerClassNames[GetTrainerTowerOpponentClass()];
toCpy = gTrainerClasses[GetTrainerTowerOpponentClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
toCpy = gTrainerClassNames[GetEreaderTrainerClassId()];
toCpy = gTrainerClasses[GetEreaderTrainerClassId()].name;
else
toCpy = gTrainerClassNames[gTrainers[gTrainerBattleOpponent_A].trainerClass];
toCpy = gTrainerClasses[gTrainers[gTrainerBattleOpponent_A].trainerClass].name;
break;
case B_TXT_TRAINER1_NAME: // trainer1 name
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
@@ -3199,24 +3213,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
toCpy = BattleStringGetTrainerName(text, multiplayerId, gBattlerAttacker);
break;
case B_TXT_ATK_TRAINER_CLASS:
// TODO: get trainer name
toCpy = "TODO";
// switch (GetBattlerPosition(gBattlerAttacker))
// {
// case B_POSITION_PLAYER_RIGHT:
// if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
// toCpy = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name;
// break;
// case B_POSITION_OPPONENT_LEFT:
// toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
// break;
// case B_POSITION_OPPONENT_RIGHT:
// if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT)
// toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
// else
// toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
// break;
// }
switch (GetBattlerPosition(gBattlerAttacker))
{
case B_POSITION_PLAYER_RIGHT:
// TODO: implement partner trainers?
// if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
// toCpy = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name;
toCpy = gTrainerClasses[TRAINER_CLASS_NONE].name;
break;
case B_POSITION_OPPONENT_LEFT:
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
break;
case B_POSITION_OPPONENT_RIGHT:
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT)
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
else
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
break;
}
break;
case B_TXT_ATK_TEAM1:
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)

View File

@@ -564,49 +564,17 @@ static u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons)
u8 i;
u8 sum;
u32 count = numMons;
const struct TrainerMon *party;
if (GetTrainerPartySizeFromId(opponentId) < count)
count = GetTrainerPartySizeFromId(opponentId);
if (gTrainers[opponentId].partySize < count)
count = gTrainers[opponentId].partySize;
sum = 0;
switch (gTrainers[opponentId].partyFlags)
{
case 0:
{
const struct TrainerMonNoItemDefaultMoves *party;
party = gTrainers[opponentId].party.NoItemDefaultMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_CUSTOM_MOVESET:
{
const struct TrainerMonNoItemCustomMoves *party;
party = GetTrainerPartyFromId(opponentId);
for (i = 0; i < count && party != NULL; i++)
sum += party[i].lvl;
party = gTrainers[opponentId].party.NoItemCustomMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemDefaultMoves *party;
party = gTrainers[opponentId].party.ItemDefaultMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemCustomMoves *party;
party = gTrainers[opponentId].party.ItemCustomMoves;
for (i = 0; i < count; ++i)
sum += party[i].lvl;
}
break;
}
return sum;
}
@@ -628,29 +596,30 @@ static u8 GetTrainerBattleTransition(void)
u8 transitionType;
u8 enemyLevel;
u8 playerLevel;
u32 trainerId = SanitizeTrainerId(gTrainerBattleOpponent_A);
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
if (trainerId == TRAINER_SECRET_BASE)
return B_TRANSITION_BLUE;
if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR)
if (gTrainers[trainerId].trainerClass == TRAINER_CLASS_ELITE_FOUR)
{
if (gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_LORELEI || gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_LORELEI_2)
if (trainerId == TRAINER_ELITE_FOUR_LORELEI || trainerId == TRAINER_ELITE_FOUR_LORELEI_2)
return B_TRANSITION_LORELEI;
if (gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_BRUNO || gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_BRUNO_2)
if (trainerId == TRAINER_ELITE_FOUR_BRUNO || trainerId == TRAINER_ELITE_FOUR_BRUNO_2)
return B_TRANSITION_BRUNO;
if (gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_AGATHA || gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_AGATHA_2)
if (trainerId == TRAINER_ELITE_FOUR_AGATHA || trainerId == TRAINER_ELITE_FOUR_AGATHA_2)
return B_TRANSITION_AGATHA;
if (gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_LANCE || gTrainerBattleOpponent_A == TRAINER_ELITE_FOUR_LANCE_2)
if (trainerId == TRAINER_ELITE_FOUR_LANCE || trainerId == TRAINER_ELITE_FOUR_LANCE_2)
return B_TRANSITION_LANCE;
return B_TRANSITION_BLUE;
}
if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION)
if (gTrainers[trainerId].trainerClass == TRAINER_CLASS_CHAMPION)
return B_TRANSITION_BLUE;
if (gTrainers[gTrainerBattleOpponent_A].doubleBattle == TRUE)
if (gTrainers[trainerId].doubleBattle == TRUE)
minPartyCount = 2; // double battles always at least have 2 pokemon.
else
minPartyCount = 1;
transitionType = GetBattleTransitionTypeByMap();
enemyLevel = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent_A, minPartyCount);
enemyLevel = GetSumOfEnemyPartyLevel(trainerId, minPartyCount);
playerLevel = GetSumOfPlayerPartyLevel(minPartyCount);
if (enemyLevel < playerLevel)
return sBattleTransitionTable_Trainer[transitionType][0];

View File

@@ -290,5 +290,5 @@ const union AnimCmd *const gAnims_MonPic[] =
#include "data/trainer_graphics/back_pic_tables.h"
#include "data/trainer_parties.h"
#include "data/text/trainer_class_names.h"
#include "data/trainers.h"
#include "data/battle_partners.h"

View File

@@ -2,7 +2,7 @@ const struct Trainer gBattlePartners[] = {
[PARTNER_NONE] =
{
.party = NULL,
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
.trainerClass = TRAINER_CLASS_NONE,
.encounterMusic_gender = TRAINER_ENCOUNTER_MUSIC_MALE,
.trainerPic = TRAINER_PIC_HIKER,
.trainerName = _(""),

View File

@@ -1,109 +0,0 @@
const u8 gTrainerClassNames[][13] = {
[TRAINER_CLASS_NONE] = _("{PKMN} TRAINER"),
[TRAINER_CLASS_PKMN_TRAINER_UNUSED] = _("{PKMN} TRAINER"),
[TRAINER_CLASS_AQUA_LEADER] = _("AQUA LEADER"),
[TRAINER_CLASS_TEAM_AQUA] = _("TEAM AQUA"),
[TRAINER_CLASS_RS_AROMA_LADY] = _("AROMA LADY"),
[TRAINER_CLASS_RS_RUIN_MANIAC] = _("RUIN MANIAC"),
[TRAINER_CLASS_INTERVIEWER] = _("INTERVIEWER"),
[TRAINER_CLASS_RS_TUBER_F] = _("TUBER"),
[TRAINER_CLASS_RS_TUBER_M] = _("TUBER"),
[TRAINER_CLASS_RS_COOLTRAINER] = _("COOLTRAINER"),
[TRAINER_CLASS_HEX_MANIAC] = _("HEX MANIAC"),
[TRAINER_CLASS_RS_LADY] = _("LADY"),
[TRAINER_CLASS_RS_BEAUTY] = _("BEAUTY"),
[TRAINER_CLASS_RICH_BOY] = _("RICH BOY"),
[TRAINER_CLASS_RS_POKEMANIAC] = _("POKéMANIAC"),
[TRAINER_CLASS_RS_SWIMMER_M] = _("SWIMMER♂"),
[TRAINER_CLASS_RS_BLACK_BELT] = _("BLACK BELT"),
[TRAINER_CLASS_GUITARIST] = _("GUITARIST"),
[TRAINER_CLASS_KINDLER] = _("KINDLER"),
[TRAINER_CLASS_RS_CAMPER] = _("CAMPER"),
[TRAINER_CLASS_BUG_MANIAC] = _("BUG MANIAC"),
[TRAINER_CLASS_RS_PSYCHIC] = _("PSYCHIC"),
[TRAINER_CLASS_RS_GENTLEMAN] = _("GENTLEMAN"),
[TRAINER_CLASS_RS_ELITE_FOUR] = _("ELITE FOUR"),
[TRAINER_CLASS_RS_LEADER] = _("LEADER"),
[TRAINER_CLASS_SCHOOL_KID] = _("SCHOOL KID"),
[TRAINER_CLASS_SR_AND_JR] = _("SR. AND JR."),
[TRAINER_CLASS_POKEFAN] = _("POKéFAN"),
[TRAINER_CLASS_EXPERT] = _("EXPERT"),
[TRAINER_CLASS_RS_YOUNGSTER] = _("YOUNGSTER"),
[TRAINER_CLASS_RS_CHAMPION] = _("CHAMPION"),
[TRAINER_CLASS_RS_FISHERMAN] = _("FISHERMAN"),
[TRAINER_CLASS_TRIATHLETE] = _("TRIATHLETE"),
[TRAINER_CLASS_DRAGON_TAMER] = _("DRAGON TAMER"),
[TRAINER_CLASS_RS_BIRD_KEEPER] = _("BIRD KEEPER"),
[TRAINER_CLASS_NINJA_BOY] = _("NINJA BOY"),
[TRAINER_CLASS_BATTLE_GIRL] = _("BATTLE GIRL"),
[TRAINER_CLASS_PARASOL_LADY] = _("PARASOL LADY"),
[TRAINER_CLASS_RS_SWIMMER_F] = _("SWIMMER♀"),
[TRAINER_CLASS_RS_PICNICKER] = _("PICNICKER"),
[TRAINER_CLASS_RS_TWINS] = _("TWINS"),
[TRAINER_CLASS_RS_SAILOR] = _("SAILOR"),
[TRAINER_CLASS_BOARDER] = _("BOARDER"),
[TRAINER_CLASS_COLLECTOR] = _("COLLECTOR"),
[TRAINER_CLASS_PKMN_TRAINER] = _("{PKMN} TRAINER"),
[TRAINER_CLASS_RS_PKMN_BREEDER] = _("{PKMN} BREEDER"),
[TRAINER_CLASS_RS_PKMN_RANGER] = _("{PKMN} RANGER"),
[TRAINER_CLASS_MAGMA_LEADER] = _("MAGMA LEADER"),
[TRAINER_CLASS_TEAM_MAGMA] = _("TEAM MAGMA"),
[TRAINER_CLASS_RS_LASS] = _("LASS"),
[TRAINER_CLASS_RS_BUG_CATCHER] = _("BUG CATCHER"),
[TRAINER_CLASS_RS_HIKER] = _("HIKER"),
[TRAINER_CLASS_RS_YOUNG_COUPLE] = _("YOUNG COUPLE"),
[TRAINER_CLASS_OLD_COUPLE] = _("OLD COUPLE"),
[TRAINER_CLASS_RS_SIS_AND_BRO] = _("SIS AND BRO"),
[TRAINER_CLASS_AQUA_ADMIN] = _("AQUA ADMIN"),
[TRAINER_CLASS_MAGMA_ADMIN] = _("MAGMA ADMIN"),
[TRAINER_CLASS_YOUNGSTER] = _("YOUNGSTER"),
[TRAINER_CLASS_BUG_CATCHER] = _("BUG CATCHER"),
[TRAINER_CLASS_LASS] = _("LASS"),
[TRAINER_CLASS_SAILOR] = _("SAILOR"),
[TRAINER_CLASS_CAMPER] = _("CAMPER"),
[TRAINER_CLASS_PICNICKER] = _("PICNICKER"),
[TRAINER_CLASS_POKEMANIAC] = _("POKéMANIAC"),
[TRAINER_CLASS_SUPER_NERD] = _("SUPER NERD"),
[TRAINER_CLASS_HIKER] = _("HIKER"),
[TRAINER_CLASS_BIKER] = _("BIKER"),
[TRAINER_CLASS_BURGLAR] = _("BURGLAR"),
[TRAINER_CLASS_ENGINEER] = _("ENGINEER"),
[TRAINER_CLASS_FISHERMAN] = _("FISHERMAN"),
[TRAINER_CLASS_SWIMMER_M] = _("SWIMMER♂"),
[TRAINER_CLASS_CUE_BALL] = _("CUE BALL"),
[TRAINER_CLASS_GAMER] = _("GAMER"),
[TRAINER_CLASS_BEAUTY] = _("BEAUTY"),
[TRAINER_CLASS_SWIMMER_F] = _("SWIMMER♀"),
[TRAINER_CLASS_PSYCHIC] = _("PSYCHIC"),
[TRAINER_CLASS_ROCKER] = _("ROCKER"),
[TRAINER_CLASS_JUGGLER] = _("JUGGLER"),
[TRAINER_CLASS_TAMER] = _("TAMER"),
[TRAINER_CLASS_BIRD_KEEPER] = _("BIRD KEEPER"),
[TRAINER_CLASS_BLACK_BELT] = _("BLACK BELT"),
[TRAINER_CLASS_RIVAL_EARLY] = _("RIVAL"),
[TRAINER_CLASS_SCIENTIST] = _("SCIENTIST"),
[TRAINER_CLASS_BOSS] = _("BOSS"),
[TRAINER_CLASS_LEADER] = _("LEADER"),
[TRAINER_CLASS_TEAM_ROCKET] = _("TEAM ROCKET"),
[TRAINER_CLASS_COOLTRAINER] = _("COOLTRAINER"),
[TRAINER_CLASS_ELITE_FOUR] = _("ELITE FOUR"),
[TRAINER_CLASS_GENTLEMAN] = _("GENTLEMAN"),
[TRAINER_CLASS_RIVAL_LATE] = _("RIVAL"),
[TRAINER_CLASS_CHAMPION] = _("CHAMPION"),
[TRAINER_CLASS_CHANNELER] = _("CHANNELER"),
[TRAINER_CLASS_TWINS] = _("TWINS"),
[TRAINER_CLASS_COOL_COUPLE] = _("COOL COUPLE"),
[TRAINER_CLASS_YOUNG_COUPLE] = _("YOUNG COUPLE"),
[TRAINER_CLASS_CRUSH_KIN] = _("CRUSH KIN"),
[TRAINER_CLASS_SIS_AND_BRO] = _("SIS AND BRO"),
[TRAINER_CLASS_PKMN_PROF] = _("{PKMN} PROF."),
[TRAINER_CLASS_PLAYER] = _("PLAYER"),
[TRAINER_CLASS_CRUSH_GIRL] = _("CRUSH GIRL"),
[TRAINER_CLASS_TUBER] = _("TUBER"),
[TRAINER_CLASS_PKMN_BREEDER] = _("{PKMN} BREEDER"),
[TRAINER_CLASS_PKMN_RANGER] = _("{PKMN} RANGER"),
[TRAINER_CLASS_AROMA_LADY] = _("AROMA LADY"),
[TRAINER_CLASS_RUIN_MANIAC] = _("RUIN MANIAC"),
[TRAINER_CLASS_LADY] = _("LADY"),
[TRAINER_CLASS_PAINTER] = _("PAINTER"),
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -62,7 +62,6 @@ static EWRAM_DATA struct MonSpritesGfxManager *sMonSpritesGfxManager = NULL;
static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
static bool8 IsShinyOtIdPersonality(u32 otId, u32 personality);
static u8 GetNatureFromPersonality(u32 personality);
static bool8 PartyMonHasStatus(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId);
static bool8 IsPokemonStorageFull(void);
static u8 CopyMonToPC(struct Pokemon *mon);
@@ -3982,7 +3981,7 @@ u8 GetNature(struct Pokemon *mon)
return GetMonData(mon, MON_DATA_PERSONALITY, NULL) % NUM_NATURES;
}
static u8 GetNatureFromPersonality(u32 personality)
u8 GetNatureFromPersonality(u32 personality)
{
return personality % NUM_NATURES;
}
@@ -5590,9 +5589,9 @@ u16 FacilityClassToPicIndex(u16 facilityClass)
u16 PlayerGenderToFrontTrainerPicId(u8 playerGender)
{
if (playerGender != MALE)
return FacilityClassToPicIndex(FACILITY_CLASS_MAY);
return FacilityClassToPicIndex(FACILITY_CLASS_LEAF);
else
return FacilityClassToPicIndex(FACILITY_CLASS_BRENDAN);
return FacilityClassToPicIndex(FACILITY_CLASS_RED);
}
void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)

View File

@@ -4280,7 +4280,7 @@ static void ViewURoomPartnerTrainerCard(u8 *unused, struct WirelessLink_URoom *
DynamicPlaceholderTextUtil_Reset();
StringCopy(uroom->trainerCardStrBuffer[0], gTrainerClassNames[GetUnionRoomTrainerClass()]);
StringCopy(uroom->trainerCardStrBuffer[0], gTrainerClasses[GetUnionRoomTrainerClass()].name);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrBuffer[0]);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, trainerCard->rse.playerName);