diff --git a/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc b/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc index 4a22bf8eeaeb..a4fcc0237cc2 100644 --- a/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc +++ b/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc @@ -257,14 +257,7 @@ MossdeepCity_SpaceCenter_2F_EventScript_ChoosePartyForMultiBattle:: goto MossdeepCity_SpaceCenter_2F_EventScript_ReadyForBattlePrompt MossdeepCity_SpaceCenter_2F_EventScript_DoStevenMultiBattle:: - special ReducePlayerPartyToSelectedMons - frontier_set FRONTIER_DATA_SELECTED_MON_ORDER - setvar VAR_0x8004, SPECIAL_BATTLE_STEVEN - setvar VAR_0x8005, 0 - special DoSpecialTrainerBattle - waitstate - frontier_saveparty - special LoadPlayerParty + multi_2_vs_2 TRAINER_MAXIE_MOSSDEEP, MossdeepCity_SpaceCenter_2F_Text_JustWantToExpandLand, TRAINER_TABITHA_MOSSDEEP, MossdeepCity_SpaceCenter_Text_TabithaDefeat, PARTNER_STEVEN, TRAINER_BACK_PIC_STEVEN switch VAR_RESULT case 1, MossdeepCity_SpaceCenter_2F_EventScript_DefeatedMaxieTabitha fadescreen FADE_TO_BLACK @@ -336,14 +329,6 @@ MossdeepCity_SpaceCenter_2F_EventScript_StevenFacePlayerWest:: turnobject LOCALID_STEVEN, DIR_EAST return -MossdeepCity_SpaceCenter_2F_EventScript_MaxieTrainer:: - trainerbattle TRAINER_BATTLE_SET_TRAINER_A, TRAINER_MAXIE_MOSSDEEP, 0, MossdeepCity_SpaceCenter_2F_Text_JustWantToExpandLand, MossdeepCity_SpaceCenter_2F_Text_JustWantToExpandLand - end - -MossdeepCity_SpaceCenter_2F_EventScript_TabithaTrainer:: - trainerbattle TRAINER_BATTLE_SET_TRAINER_B, TRAINER_TABITHA_MOSSDEEP, 0, MossdeepCity_SpaceCenter_Text_TabithaDefeat, MossdeepCity_SpaceCenter_Text_TabithaDefeat - end - MossdeepCity_SpaceCenter_2F_EventScript_RivalRayquazaCall:: lockall checkplayergender diff --git a/include/constants/battle_frontier.h b/include/constants/battle_frontier.h index 85c1df085ed4..e4a56b15d147 100644 --- a/include/constants/battle_frontier.h +++ b/include/constants/battle_frontier.h @@ -41,10 +41,9 @@ #define SPECIAL_BATTLE_ARENA 5 #define SPECIAL_BATTLE_FACTORY 6 #define SPECIAL_BATTLE_PIKE_SINGLE 7 -#define SPECIAL_BATTLE_STEVEN 8 -#define SPECIAL_BATTLE_PIKE_DOUBLE 9 -#define SPECIAL_BATTLE_PYRAMID 10 -#define SPECIAL_BATTLE_MULTI 11 +#define SPECIAL_BATTLE_PIKE_DOUBLE 8 +#define SPECIAL_BATTLE_PYRAMID 9 +#define SPECIAL_BATTLE_MULTI 10 #define MAX_BATTLE_FRONTIER_POINTS 9999 #define MAX_STREAK 9999 diff --git a/include/constants/battle_partner.h b/include/constants/battle_partner.h new file mode 100644 index 000000000000..5622349a888c --- /dev/null +++ b/include/constants/battle_partner.h @@ -0,0 +1,8 @@ + +#ifndef GUARD_CONSTANTS_BATTLE_PARTNERS_H +#define GUARD_CONSTANTS_BATTLE_PARTNERS_H + +#define PARTNER_NONE 0 +#define PARTNER_STEVEN 1 + +#endif // GUARD_CONSTANTS_BATTLE_PARTNERS_H diff --git a/include/constants/opponents.h b/include/constants/opponents.h index c9cf9239d851..9e7131077c3b 100644 --- a/include/constants/opponents.h +++ b/include/constants/opponents.h @@ -1,6 +1,8 @@ #ifndef GUARD_CONSTANTS_OPPONENTS_H #define GUARD_CONSTANTS_OPPONENTS_H +#include "constants/battle_partner.h" + #define TRAINER_NONE 0 #define TRAINER_SAWYER_1 1 #define TRAINER_GRUNT_AQUA_HIDEOUT_1 2 @@ -863,5 +865,6 @@ #define TRAINERS_COUNT 855 #define MAX_TRAINERS_COUNT 864 +#define TRAINER_PARTNER(partner) (MAX_TRAINERS_COUNT + partner) #endif // GUARD_CONSTANTS_OPPONENTS_H diff --git a/include/constants/trainers.h b/include/constants/trainers.h index 16904bcd1221..ff7d5b11f393 100644 --- a/include/constants/trainers.h +++ b/include/constants/trainers.h @@ -14,8 +14,6 @@ #define TRAINER_SECRET_BASE 1024 #define TRAINER_LINK_OPPONENT 2048 #define TRAINER_UNION_ROOM 3072 -#define TRAINER_STEVEN_PARTNER 3075 -#define TRAINER_CUSTOM_PARTNER 3076 #define TRAINER_PIC_HIKER 0 #define TRAINER_PIC_AQUA_GRUNT_M 1 diff --git a/include/data.h b/include/data.h index 82b85607c0af..8fc4209d3de3 100644 --- a/include/data.h +++ b/include/data.h @@ -102,6 +102,8 @@ extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; // functionall extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[]; extern const struct Trainer gTrainers[]; +extern const struct Trainer gBattlePartners[]; + extern const u8 gTrainerClassNames[][13]; extern const u8 gMoveNames[MOVES_COUNT_DYNAMAX][MOVE_NAME_LENGTH + 1]; extern const u8 *const gZMoveNames[]; diff --git a/include/event_scripts.h b/include/event_scripts.h index 00b06165cf6b..153935695900 100644 --- a/include/event_scripts.h +++ b/include/event_scripts.h @@ -611,7 +611,6 @@ extern const u8 EventScript_TradeCenter_Chair1[]; extern const u8 EventScript_TradeCenter_Chair0[]; extern const u8 EventScript_ConfirmLeaveCableClubRoom[]; extern const u8 EventScript_TerminateLink[]; - extern const u8 VSSeeker_Text_BatteryNotChargedNeedXSteps[]; extern const u8 VSSeeker_Text_NoTrainersWithinRange[]; extern const u8 VSSeeker_Text_TrainersNotReady[]; diff --git a/src/battle_bg.c b/src/battle_bg.c index b18962af9918..496618f3151a 100644 --- a/src/battle_bg.c +++ b/src/battle_bg.c @@ -26,6 +26,7 @@ #include "constants/songs.h" #include "constants/trainers.h" #include "constants/battle_anim.h" +#include "constants/battle_partner.h" // .rodata static const u16 sUnrefArray[] = {0x0300, 0x0000}; //OamData? @@ -1146,7 +1147,7 @@ void DrawBattleEntryBackground(void) } else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_EREADER_TRAINER)) { - if (!(gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) || gPartnerTrainerId == TRAINER_STEVEN_PARTNER || gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) + if (!(gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) || gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE)) { LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)(BG_CHAR_ADDR(1))); LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)(BG_SCREEN_ADDR(28))); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index cf4d094fc32f..711eef1d1e93 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -31,6 +31,7 @@ #include "util.h" #include "window.h" #include "constants/battle_anim.h" +#include "constants/battle_partner.h" #include "constants/hold_effects.h" #include "constants/items.h" #include "constants/moves.h" @@ -1875,7 +1876,7 @@ static void PlayerHandleDrawTrainerPic(u32 battler) else // First mon, on the left. xPos = 32; - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId != TRAINER_STEVEN_PARTNER && gPartnerTrainerId < TRAINER_CUSTOM_PARTNER) + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId < TRAINER_PARTNER(PARTNER_NONE)) { xPos = 90; yPos = (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 80; @@ -1893,7 +1894,7 @@ static void PlayerHandleDrawTrainerPic(u32 battler) } // Use front pic table for any tag battles unless your partner is Steven or a custom partner. - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId != TRAINER_STEVEN_PARTNER && gPartnerTrainerId < TRAINER_CUSTOM_PARTNER) + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId < TRAINER_PARTNER(PARTNER_NONE)) { trainerPicId = PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender); isFrontPic = TRUE; diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index 5155db49ec57..8f989c677d7b 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -27,6 +27,7 @@ #include "util.h" #include "window.h" #include "constants/battle_anim.h" +#include "constants/battle_partner.h" #include "constants/songs.h" #include "constants/party_menu.h" #include "constants/trainers.h" @@ -296,15 +297,9 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler) s16 xPos, yPos; u32 trainerPicId; - if (gPartnerTrainerId == TRAINER_STEVEN_PARTNER) + if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE)) { - trainerPicId = TRAINER_BACK_PIC_STEVEN; - xPos = 90; - yPos = (8 - gTrainerBackPicCoords[trainerPicId].size) * 4 + 80; - } - else if (gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) - { - trainerPicId = gPartnerSpriteId; + trainerPicId = gBattlePartners[gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic; xPos = 90; yPos = (8 - gTrainerBackPicCoords[trainerPicId].size) * 4 + 80; } @@ -321,8 +316,8 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler) yPos = (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 80; } - // Use back pic only if the partner is Steven or a custom partner. - if (gPartnerTrainerId == TRAINER_STEVEN_PARTNER || gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) + // Use back pic only if the partner Steven or is custom. + if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE)) isFrontPic = FALSE; else isFrontPic = TRUE; @@ -439,9 +434,7 @@ static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler) { const u32 *trainerPal; - if (gPartnerTrainerId == TRAINER_STEVEN_PARTNER) - trainerPal = gTrainerBackPicPaletteTable[TRAINER_STEVEN_PARTNER].data; - else if (gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) // Custom multi battle. + if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE)) trainerPal = gTrainerBackPicPaletteTable[gPartnerSpriteId].data; else if (IsAiVsAiBattle()) trainerPal = gTrainerFrontPicPaletteTable[gTrainers[gPartnerTrainerId].trainerPic].data; diff --git a/src/battle_intro.c b/src/battle_intro.c index 90ff736f003e..463804368fe9 100644 --- a/src/battle_intro.c +++ b/src/battle_intro.c @@ -9,6 +9,7 @@ #include "scanline_effect.h" #include "task.h" #include "trig.h" +#include "constants/battle_partner.h" #include "constants/trainers.h" extern const u8 gBattleAnimBgCntSet[]; @@ -104,7 +105,7 @@ void HandleIntroSlide(u8 terrain) { u8 taskId; - if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) && gPartnerTrainerId != TRAINER_STEVEN_PARTNER && gPartnerTrainerId < TRAINER_CUSTOM_PARTNER) + if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) && gPartnerTrainerId < TRAINER_PARTNER(PARTNER_NONE)) { taskId = CreateTask(BattleIntroSlidePartner, 0); } diff --git a/src/battle_main.c b/src/battle_main.c index 3a81c9915730..4c28f3ffd42c 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -56,6 +56,7 @@ #include "constants/abilities.h" #include "constants/battle_move_effects.h" #include "constants/battle_string_ids.h" +#include "constants/battle_partner.h" #include "constants/hold_effects.h" #include "constants/items.h" #include "constants/moves.h" @@ -512,7 +513,7 @@ static void CB2_InitBattleInternal(void) gBattle_WIN0H = DISPLAY_WIDTH; - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId != TRAINER_STEVEN_PARTNER && gPartnerTrainerId < TRAINER_CUSTOM_PARTNER) + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId < TRAINER_PARTNER(PARTNER_NONE)) { gBattle_WIN0V = DISPLAY_HEIGHT - 1; gBattle_WIN1H = DISPLAY_WIDTH; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index cebbdfb898aa..3e48794eb130 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -50,6 +50,7 @@ #include "constants/battle_anim.h" #include "constants/battle_move_effects.h" #include "constants/battle_string_ids.h" +#include "constants/battle_partner.h" #include "constants/hold_effects.h" #include "constants/items.h" #include "constants/item_effects.h" @@ -4363,7 +4364,7 @@ static bool32 NoAliveMonsForPlayerAndPartner(void) u32 i; u32 HP_count = 0; - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && (gPartnerTrainerId == TRAINER_STEVEN_PARTNER || gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER)) + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE)) { for (i = 0; i < PARTY_SIZE; i++) { @@ -4383,25 +4384,12 @@ bool32 NoAliveMonsForPlayer(void) u32 i; u32 HP_count = 0; - // Get total HP for the player's party to determine if the player has lost - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && (gPartnerTrainerId == TRAINER_STEVEN_PARTNER || gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER)) + for (i = 0; i < PARTY_SIZE; i++) { - // In multi battle with Steven, skip his Pokémon - for (i = 0; i < MULTI_PARTY_SIZE; i++) + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostPlayerMons & gBitTable[i]))) { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) - HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); - } - } - else - { - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) - && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostPlayerMons & gBitTable[i]))) - { - HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); - } + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); } } diff --git a/src/battle_tower.c b/src/battle_tower.c index c30406f79834..015f6d207f34 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -32,15 +32,13 @@ #include "constants/battle_tent_mons.h" #include "constants/battle_tent_trainers.h" #include "constants/battle_tower.h" +#include "constants/battle_partner.h" #include "constants/frontier_util.h" #include "constants/items.h" #include "constants/trainers.h" #include "constants/event_objects.h" #include "constants/moves.h" -extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_MaxieTrainer[]; -extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_TabithaTrainer[]; - // EWRAM vars. EWRAM_DATA const struct BattleFrontierTrainer *gFacilityTrainers = NULL; EWRAM_DATA const struct FacilityMon *gFacilityTrainerMons = NULL; @@ -762,44 +760,11 @@ static const u8 *const *const sPartnerApprenticeTextTables[NUM_APPRENTICES] = sPartnerApprenticeTexts16 }; -struct -{ - u16 species; - u8 fixedIV; - u8 level; - u8 nature; - u8 evs[NUM_STATS]; - u16 moves[MAX_MON_MOVES]; -} static const sStevenMons[MULTI_PARTY_SIZE] = -{ - { - .species = SPECIES_METANG, - .fixedIV = MAX_PER_STAT_IVS, - .level = 42, - .nature = NATURE_BRAVE, - .evs = {0, 252, 252, 0, 6, 0}, - .moves = {MOVE_LIGHT_SCREEN, MOVE_PSYCHIC, MOVE_REFLECT, MOVE_METAL_CLAW} - }, - { - .species = SPECIES_SKARMORY, - .fixedIV = MAX_PER_STAT_IVS, - .level = 43, - .nature = NATURE_IMPISH, - .evs = {252, 0, 0, 0, 6, 252}, - .moves = {MOVE_TOXIC, MOVE_AERIAL_ACE, MOVE_PROTECT, MOVE_STEEL_WING} - }, - { - .species = SPECIES_AGGRON, - .fixedIV = MAX_PER_STAT_IVS, - .level = 44, - .nature = NATURE_ADAMANT, - .evs = {0, 252, 0, 0, 252, 6}, - .moves = {MOVE_THUNDER, MOVE_PROTECT, MOVE_SOLAR_BEAM, MOVE_DRAGON_CLAW} - } -}; - #include "data/battle_frontier/battle_tent.h" +#include "data/partner_parties.h" +#include "data/battle_partners.h" + static void (* const sBattleTowerFuncs[])(void) = { [BATTLE_TOWER_FUNC_INIT] = InitTowerChallenge, @@ -1447,13 +1412,9 @@ u8 GetFrontierOpponentClass(u16 trainerId) { return GetFrontierBrainTrainerClass(); } - else if (trainerId == TRAINER_STEVEN_PARTNER) - { - trainerClass = gTrainers[TRAINER_STEVEN].trainerClass; - } - else if (trainerId >= TRAINER_CUSTOM_PARTNER) + else if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) { - trainerClass = gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].trainerClass; + trainerClass = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass; } else if (trainerId < FRONTIER_TRAINERS_COUNT) { @@ -1531,15 +1492,10 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) CopyFrontierBrainTrainerName(dst); return; } - else if (trainerId == TRAINER_STEVEN_PARTNER) + else if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) { - for (i = 0; i < PLAYER_NAME_LENGTH; i++) - dst[i] = gTrainers[TRAINER_STEVEN].trainerName[i]; - } - else if (trainerId >= TRAINER_CUSTOM_PARTNER) - { - for (i = 0; gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].trainerName[i] != EOS; i++) - dst[i] = gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].trainerName[i]; + for (i = 0; gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName[i] != EOS; i++) + dst[i] = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName[i]; } else if (trainerId < FRONTIER_TRAINERS_COUNT) { @@ -2136,18 +2092,6 @@ void DoSpecialTrainerBattle(void) PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(GetSpecialBattleTransition(B_TRANSITION_GROUP_B_PIKE)); break; - case SPECIAL_BATTLE_STEVEN: - gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER; - FillPartnerParty(TRAINER_STEVEN_PARTNER); - gApproachingTrainerId = 0; - BattleSetup_ConfigureTrainerBattle(MossdeepCity_SpaceCenter_2F_EventScript_MaxieTrainer + 1); - gApproachingTrainerId = 1; - BattleSetup_ConfigureTrainerBattle(MossdeepCity_SpaceCenter_2F_EventScript_TabithaTrainer + 1); - gPartnerTrainerId = TRAINER_STEVEN_PARTNER; - CreateTask(Task_StartBattleAfterTransition, 1); - PlayMapChosenOrBattleBGM(0); - BattleTransition_StartOnField(B_TRANSITION_MAGMA); - break; case SPECIAL_BATTLE_MULTI: if (gSpecialVar_0x8005 & MULTI_BATTLE_2_VS_WILD) // Player + AI against wild mon { @@ -2164,7 +2108,7 @@ void DoSpecialTrainerBattle(void) } gPartnerSpriteId = VarGet(gSpecialVar_0x8007); - gPartnerTrainerId = VarGet(gSpecialVar_0x8006) + TRAINER_CUSTOM_PARTNER; + gPartnerTrainerId = VarGet(gSpecialVar_0x8006) + TRAINER_PARTNER(PARTNER_NONE); FillPartnerParty(gPartnerTrainerId); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); @@ -3003,7 +2947,8 @@ void TryHideBattleTowerReporter(void) static void FillPartnerParty(u16 trainerId) { - s32 i, j; + s32 i, j, k; + u32 firstIdPart = 0, secondIdPart = 0, thirdIdPart = 0; u32 ivs, level, personality; u32 friendship; u16 monId; @@ -3012,47 +2957,38 @@ static void FillPartnerParty(u16 trainerId) s32 ball = -1; SetFacilityPtrsGetLevel(); - if (trainerId == TRAINER_STEVEN_PARTNER) + if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) { - for (i = 0; i < MULTI_PARTY_SIZE; i++) - { - do - { - j = Random32(); - } while (IsShinyOtIdPersonality(STEVEN_OTID, j) || sStevenMons[i].nature != GetNatureFromPersonality(j)); - CreateMon(&gPlayerParty[MULTI_PARTY_SIZE + i], - sStevenMons[i].species, - sStevenMons[i].level, - sStevenMons[i].fixedIV, - TRUE, - #ifdef BUGFIX - j, - #else - i, // BUG: personality was stored in the 'j' variable. As a result, Steven's pokemon do not have the intended natures. - #endif - OT_ID_PRESET, STEVEN_OTID); - for (j = 0; j < PARTY_SIZE; j++) - SetMonData(&gPlayerParty[MULTI_PARTY_SIZE + i], MON_DATA_HP_EV + j, &sStevenMons[i].evs[j]); - for (j = 0; j < MAX_MON_MOVES; j++) - SetMonMoveSlot(&gPlayerParty[MULTI_PARTY_SIZE + i], sStevenMons[i].moves[j], j); - SetMonData(&gPlayerParty[MULTI_PARTY_SIZE + i], MON_DATA_OT_NAME, gTrainers[TRAINER_STEVEN].trainerName); - j = MALE; - SetMonData(&gPlayerParty[MULTI_PARTY_SIZE + i], MON_DATA_OT_GENDER, &j); - CalculateMonStats(&gPlayerParty[MULTI_PARTY_SIZE + i]); - } - } - else if (trainerId >= TRAINER_CUSTOM_PARTNER) - { - otID = Random32(); - for (i = 0; i < 3; i++) ZeroMonData(&gPlayerParty[i + 3]); - for (i = 0; i < 3 && i < gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].partySize; i++) + for (i = 0; i < 3 && i < gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].partySize; i++) { - const struct TrainerMon *partyData = gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].party; - u32 otIdType = OT_ID_RANDOM_NO_SHINY; - do + const struct TrainerMon *partyData = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].party; + const u8 *partnerName = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName; + + for (k = 0; partnerName[k] != EOS && k < 3; k++) + { + if (k == 0) + { + firstIdPart = partnerName[k]; + secondIdPart = partnerName[k]; + thirdIdPart = partnerName[k]; + } + else if (k == 1) + { + secondIdPart = partnerName[k]; + thirdIdPart = partnerName[k]; + } + else if (k == 2) + { + thirdIdPart = partnerName[k]; + } + } + if (trainerId == TRAINER_PARTNER(PARTNER_STEVEN)) + otID = STEVEN_OTID; + else + otID = ((firstIdPart % 72) * 1000) + ((secondIdPart % 23) * 10) + (thirdIdPart % 37) % 65536; { personality = Random32(); } while (IsShinyOtIdPersonality(otID, personality)); @@ -3064,53 +3000,50 @@ static void FillPartnerParty(u16 trainerId) if (partyData[i].nature != 0) ModifyPersonalityForNature(&personality, partyData[i].nature - 1); if (partyData[i].isShiny) - { - otIdType = OT_ID_PRESET; - otID = HIHALF(personality) ^ LOHALF(personality); - } + otID ^= GET_SHINY_VALUE(otID, personality) << 16; - CreateMon(&gPlayerParty[i + 3], partyData[i].species, partyData[i].lvl, 0, TRUE, personality, otIdType, otID); + CreateMon(&gPlayerParty[i + 3], partyData[i].species, partyData[i].lvl, 0, TRUE, personality, OT_ID_PRESET, otID); SetMonData(&gPlayerParty[i + 3], MON_DATA_HELD_ITEM, &partyData[i].heldItem); - CustomTrainerPartyAssignMoves(&gPlayerParty[i+3], &partyData[i]); + CustomTrainerPartyAssignMoves(&gPlayerParty[i + 3], &partyData[i]); - SetMonData(&gPlayerParty[i+3], MON_DATA_IVS, &(partyData[i].iv)); + SetMonData(&gPlayerParty[i + 3], MON_DATA_IVS, &(partyData[i].iv)); if (partyData[i].ev != NULL) { - SetMonData(&gPlayerParty[i+3], MON_DATA_HP_EV, &(partyData[i].ev[0])); - SetMonData(&gPlayerParty[i+3], MON_DATA_ATK_EV, &(partyData[i].ev[1])); - SetMonData(&gPlayerParty[i+3], MON_DATA_DEF_EV, &(partyData[i].ev[2])); - SetMonData(&gPlayerParty[i+3], MON_DATA_SPATK_EV, &(partyData[i].ev[3])); - SetMonData(&gPlayerParty[i+3], MON_DATA_SPDEF_EV, &(partyData[i].ev[4])); - SetMonData(&gPlayerParty[i+3], MON_DATA_SPEED_EV, &(partyData[i].ev[5])); + SetMonData(&gPlayerParty[i + 3], MON_DATA_HP_EV, &(partyData[i].ev[0])); + SetMonData(&gPlayerParty[i + 3], MON_DATA_ATK_EV, &(partyData[i].ev[1])); + SetMonData(&gPlayerParty[i + 3], MON_DATA_DEF_EV, &(partyData[i].ev[2])); + SetMonData(&gPlayerParty[i + 3], MON_DATA_SPATK_EV, &(partyData[i].ev[3])); + SetMonData(&gPlayerParty[i + 3], MON_DATA_SPDEF_EV, &(partyData[i].ev[4])); + SetMonData(&gPlayerParty[i + 3], 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 (j = 0; j < maxAbilities; ++j) + for (j = 0; j < maxAbilities; j++) { if (speciesInfo->abilities[j] == partyData[i].ability) break; } if (j < maxAbilities) - SetMonData(&gPlayerParty[i+3], MON_DATA_ABILITY_NUM, &j); + SetMonData(&gPlayerParty[i + 3], MON_DATA_ABILITY_NUM, &j); } - SetMonData(&gPlayerParty[i+3], MON_DATA_FRIENDSHIP, &(partyData[i].friendship)); + SetMonData(&gPlayerParty[i + 3], MON_DATA_FRIENDSHIP, &(partyData[i].friendship)); if (partyData[i].ball != ITEM_NONE) { ball = partyData[i].ball; - SetMonData(&gPlayerParty[i+3], MON_DATA_POKEBALL, &ball); + SetMonData(&gPlayerParty[i + 3], MON_DATA_POKEBALL, &ball); } if (partyData[i].nickname != NULL) { - SetMonData(&gPlayerParty[i+3], MON_DATA_NICKNAME, partyData[i].nickname); + SetMonData(&gPlayerParty[i + 3], MON_DATA_NICKNAME, partyData[i].nickname); } - CalculateMonStats(&gPlayerParty[i+3]); + CalculateMonStats(&gPlayerParty[i + 3]); - StringCopy(trainerName, gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].trainerName); + StringCopy(trainerName, gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName); SetMonData(&gPlayerParty[i + 3], MON_DATA_OT_NAME, trainerName); - j = gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].encounterMusic_gender >> 7; - SetMonData(&gPlayerParty[i+3], MON_DATA_OT_GENDER, &j); + j = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].encounterMusic_gender >> 7; + SetMonData(&gPlayerParty[i + 3], MON_DATA_OT_GENDER, &j); } } else if (trainerId == TRAINER_EREADER) diff --git a/src/data/battle_partners.h b/src/data/battle_partners.h new file mode 100644 index 000000000000..806a50bdf6e5 --- /dev/null +++ b/src/data/battle_partners.h @@ -0,0 +1,21 @@ +const struct Trainer gBattlePartners[] = { + [PARTNER_NONE] = + { + .party = NULL, + .trainerClass = TRAINER_CLASS_PKMN_TRAINER_1, + .encounterMusic_gender = TRAINER_ENCOUNTER_MUSIC_MALE, + .trainerPic = TRAINER_PIC_HIKER, + .trainerName = _(""), + .items = {}, + }, + + [PARTNER_STEVEN] = + { + .party = TRAINER_PARTY(sParty_StevenPartner), + .trainerClass = TRAINER_CLASS_RIVAL, + .encounterMusic_gender = TRAINER_ENCOUNTER_MUSIC_MALE, + .trainerPic = TRAINER_BACK_PIC_STEVEN, + .trainerName = _("STEVEN"), + }, + +}; diff --git a/src/data/partner_parties.h b/src/data/partner_parties.h new file mode 100644 index 000000000000..fec80c6ca11c --- /dev/null +++ b/src/data/partner_parties.h @@ -0,0 +1,26 @@ +static const struct TrainerMon sParty_StevenPartner[] = { + { + .species = SPECIES_METANG, + .lvl = 42, + .nature = TRAINER_PARTY_NATURE(NATURE_BRAVE), + .iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31), + .ev = TRAINER_PARTY_EVS(0, 252, 252, 0, 6, 0), + .moves = {MOVE_LIGHT_SCREEN, MOVE_PSYCHIC, MOVE_REFLECT, MOVE_METAL_CLAW}, + }, + { + .species = SPECIES_SKARMORY, + .lvl = 43, + .nature = TRAINER_PARTY_NATURE(NATURE_IMPISH), + .iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31), + .ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 6, 252), + .moves = {MOVE_TOXIC, MOVE_AERIAL_ACE, MOVE_PROTECT, MOVE_STEEL_WING}, + }, + { + .species = SPECIES_AGGRON, + .lvl = 44, + .nature = TRAINER_PARTY_NATURE(NATURE_ADAMANT), + .iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31), + .ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 252, 6), + .moves = {MOVE_THUNDER, MOVE_PROTECT, MOVE_SOLAR_BEAM, MOVE_DRAGON_CLAW}, + } +}; diff --git a/src/pokemon.c b/src/pokemon.c index c6b1c0dae68b..721a998bef11 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -43,6 +43,7 @@ #include "constants/battle_frontier.h" #include "constants/battle_move_effects.h" #include "constants/battle_script_commands.h" +#include "constants/battle_partner.h" #include "constants/cries.h" #include "constants/form_change_types.h" #include "constants/hold_effects.h" @@ -858,7 +859,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv); SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv); } - else if (P_LEGENDARY_PERFECT_IVS >= GEN_6 + else if (P_LEGENDARY_PERFECT_IVS >= GEN_6 && (gSpeciesInfo[species].isLegendary || gSpeciesInfo[species].isMythical || gSpeciesInfo[species].isUltraBeast)) @@ -1824,11 +1825,11 @@ void SetMultiuseSpriteTemplateToPokemon(u16 speciesTag, u8 battlerPosition) gMultiuseSpriteTemplate.paletteTag = speciesTag; if (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_PLAYER_RIGHT) gMultiuseSpriteTemplate.anims = gAnims_MonPic; - else + else { if (speciesTag > SPECIES_SHINY_TAG) speciesTag = speciesTag - SPECIES_SHINY_TAG; - + speciesTag = SanitizeSpeciesId(speciesTag); if (gSpeciesInfo[speciesTag].frontAnimFrames != NULL) gMultiuseSpriteTemplate.anims = gSpeciesInfo[speciesTag].frontAnimFrames; @@ -5295,7 +5296,7 @@ const u8 *GetTrainerPartnerName(void) { if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) { - if (gPartnerTrainerId == TRAINER_STEVEN_PARTNER) + if (gPartnerTrainerId == TRAINER_PARTNER(PARTNER_STEVEN)) { return gTrainers[TRAINER_STEVEN].trainerName; } @@ -5518,16 +5519,22 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality) const u8 *GetTrainerClassNameFromId(u16 trainerId) { - if (trainerId >= TRAINERS_COUNT) - trainerId = TRAINER_NONE; - return gTrainerClassNames[gTrainers[trainerId].trainerClass]; + if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) + return gTrainerClassNames[gBattlePartners[trainerId].trainerClass]; + else if (trainerId < TRAINERS_COUNT) + return gTrainerClassNames[gTrainers[trainerId].trainerClass]; + + return gTrainerClassNames[gTrainers[TRAINER_NONE].trainerClass]; } const u8 *GetTrainerNameFromId(u16 trainerId) { - if (trainerId >= TRAINERS_COUNT) - trainerId = TRAINER_NONE; - return gTrainers[trainerId].trainerName; + if (trainerId > TRAINER_PARTNER(PARTNER_NONE)) + return gBattlePartners[trainerId].trainerName; + else if (trainerId < TRAINERS_COUNT) + return gTrainers[trainerId].trainerName; + + return gTrainers[TRAINER_NONE].trainerName; } bool8 HasTwoFramesAnimation(u16 species)