pokeemerald/src/battle_factory.c

897 lines
30 KiB
C
Raw Normal View History

2018-09-02 19:41:33 +02:00
#include "global.h"
#include "battle.h"
#include "battle_factory.h"
2018-11-11 16:44:27 +01:00
#include "battle_factory_screen.h"
2018-09-02 19:41:33 +02:00
#include "event_data.h"
2018-11-11 16:44:27 +01:00
#include "battle_setup.h"
2018-09-02 19:41:33 +02:00
#include "overworld.h"
2018-11-11 16:44:27 +01:00
#include "frontier_util.h"
2018-09-02 19:41:33 +02:00
#include "battle_tower.h"
2018-11-11 16:44:27 +01:00
#include "random.h"
#include "constants/battle_ai.h"
2019-12-02 14:44:34 +01:00
#include "constants/battle_factory.h"
2018-09-02 19:41:33 +02:00
#include "constants/battle_frontier.h"
2020-01-05 16:50:32 +01:00
#include "constants/battle_frontier_mons.h"
2019-11-24 22:58:40 +01:00
#include "constants/frontier_util.h"
2019-01-31 22:51:20 +01:00
#include "constants/layouts.h"
2018-11-11 16:44:27 +01:00
#include "constants/trainers.h"
#include "constants/moves.h"
2018-09-06 23:02:16 +02:00
2018-11-12 00:46:02 +01:00
// IWRAM bss
static bool8 sPerformedRentalSwap;
2018-11-12 00:46:02 +01:00
2018-09-02 19:41:33 +02:00
// This file's functions.
2019-02-07 19:58:09 +01:00
static void InitFactoryChallenge(void);
static void GetBattleFactoryData(void);
static void SetBattleFactoryData(void);
static void SaveFactoryChallenge(void);
static void FactoryDummy1(void);
static void FactoryDummy2(void);
2019-02-07 19:58:09 +01:00
static void SelectInitialRentalMons(void);
static void SwapRentalMons(void);
static void SetPerformedRentalSwap(void);
static void SetRentalsToOpponentParty(void);
static void SetPlayerAndOpponentParties(void);
static void SetOpponentGfxVar(void);
static void GenerateOpponentMons(void);
static void GenerateInitialRentalMons(void);
static void GetOpponentMostCommonMonType(void);
static void GetOpponentBattleStyle(void);
static void RestorePlayerPartyHeldItems(void);
static u16 GetFactoryMonId(u8 lvlMode, u8 challengeNum, bool8 useBetterRange);
2019-02-07 19:58:09 +01:00
static u8 GetMoveBattleStyle(u16 move);
2018-09-05 23:30:15 +02:00
// Number of moves needed on the team to be considered using a certain battle style
static const u8 sRequiredMoveCounts[FACTORY_NUM_STYLES - 1] = {
[FACTORY_STYLE_PREPARATION - 1] = 3,
[FACTORY_STYLE_SLOW_STEADY - 1] = 3,
[FACTORY_STYLE_ENDURANCE - 1] = 3,
[FACTORY_STYLE_HIGH_RISK - 1] = 2,
[FACTORY_STYLE_WEAKENING - 1] = 2,
[FACTORY_STYLE_UNPREDICTABLE - 1] = 2,
[FACTORY_STYLE_WEATHER - 1] = 2
};
2018-09-09 17:06:35 +02:00
2018-11-11 16:44:27 +01:00
static const u16 sMoves_TotalPreparation[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_SWORDS_DANCE, MOVE_GROWTH, MOVE_MEDITATE, MOVE_AGILITY, MOVE_DOUBLE_TEAM, MOVE_HARDEN,
MOVE_MINIMIZE, MOVE_WITHDRAW, MOVE_DEFENSE_CURL, MOVE_BARRIER, MOVE_FOCUS_ENERGY, MOVE_AMNESIA,
MOVE_ACID_ARMOR, MOVE_SHARPEN, MOVE_CONVERSION, MOVE_CONVERSION_2, MOVE_BELLY_DRUM, MOVE_PSYCH_UP,
MOVE_CHARGE, MOVE_SNATCH, MOVE_TAIL_GLOW, MOVE_COSMIC_POWER, MOVE_IRON_DEFENSE, MOVE_HOWL, MOVE_BULK_UP, MOVE_CALM_MIND, MOVE_DRAGON_DANCE,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u16 sMoves_ImpossibleToPredict[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_MIMIC, MOVE_METRONOME, MOVE_MIRROR_MOVE, MOVE_TRANSFORM, MOVE_SUBSTITUTE, MOVE_SKETCH, MOVE_CURSE,
MOVE_PRESENT, MOVE_FOLLOW_ME, MOVE_TRICK, MOVE_ROLE_PLAY, MOVE_ASSIST, MOVE_SKILL_SWAP, MOVE_CAMOUFLAGE,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u16 sMoves_WeakeningTheFoe[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_SAND_ATTACK, MOVE_TAIL_WHIP, MOVE_LEER, MOVE_GROWL, MOVE_STRING_SHOT, MOVE_SCREECH, MOVE_SMOKESCREEN, MOVE_KINESIS,
MOVE_FLASH, MOVE_COTTON_SPORE, MOVE_SPITE, MOVE_SCARY_FACE, MOVE_CHARM, MOVE_KNOCK_OFF, MOVE_SWEET_SCENT, MOVE_FEATHER_DANCE,
MOVE_FAKE_TEARS, MOVE_METAL_SOUND, MOVE_TICKLE,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u16 sMoves_HighRiskHighReturn[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_GUILLOTINE, MOVE_HORN_DRILL, MOVE_DOUBLE_EDGE, MOVE_HYPER_BEAM, MOVE_COUNTER, MOVE_FISSURE,
MOVE_BIDE, MOVE_SELF_DESTRUCT, MOVE_SKY_ATTACK, MOVE_EXPLOSION, MOVE_FLAIL, MOVE_REVERSAL, MOVE_DESTINY_BOND,
MOVE_PERISH_SONG, MOVE_PAIN_SPLIT, MOVE_MIRROR_COAT, MOVE_MEMENTO, MOVE_GRUDGE, MOVE_FACADE, MOVE_FOCUS_PUNCH,
MOVE_BLAST_BURN, MOVE_HYDRO_CANNON, MOVE_OVERHEAT, MOVE_FRENZY_PLANT, MOVE_PSYCHO_BOOST, MOVE_VOLT_TACKLE,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u16 sMoves_Endurance[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_MIST, MOVE_RECOVER, MOVE_LIGHT_SCREEN, MOVE_HAZE, MOVE_REFLECT, MOVE_SOFT_BOILED, MOVE_REST, MOVE_PROTECT,
MOVE_DETECT, MOVE_ENDURE, MOVE_MILK_DRINK, MOVE_HEAL_BELL, MOVE_SAFEGUARD, MOVE_BATON_PASS, MOVE_MORNING_SUN,
MOVE_SYNTHESIS, MOVE_MOONLIGHT, MOVE_SWALLOW, MOVE_WISH, MOVE_INGRAIN, MOVE_MAGIC_COAT, MOVE_RECYCLE, MOVE_REFRESH,
MOVE_MUD_SPORT, MOVE_SLACK_OFF, MOVE_AROMATHERAPY, MOVE_WATER_SPORT,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u16 sMoves_SlowAndSteady[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_SING, MOVE_SUPERSONIC, MOVE_DISABLE, MOVE_LEECH_SEED, MOVE_POISON_POWDER, MOVE_STUN_SPORE, MOVE_SLEEP_POWDER,
MOVE_THUNDER_WAVE, MOVE_TOXIC, MOVE_HYPNOSIS, MOVE_CONFUSE_RAY, MOVE_GLARE, MOVE_POISON_GAS, MOVE_LOVELY_KISS, MOVE_SPORE,
MOVE_SPIDER_WEB, MOVE_SWEET_KISS, MOVE_SPIKES, MOVE_SWAGGER, MOVE_MEAN_LOOK, MOVE_ATTRACT, MOVE_ENCORE, MOVE_TORMENT,
MOVE_FLATTER, MOVE_WILL_O_WISP, MOVE_TAUNT, MOVE_YAWN, MOVE_IMPRISON, MOVE_SNATCH, MOVE_TEETER_DANCE, MOVE_GRASS_WHISTLE, MOVE_BLOCK,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u16 sMoves_DependsOnTheBattlesFlow[] =
2018-09-09 17:06:35 +02:00
{
2018-11-11 16:44:27 +01:00
MOVE_SANDSTORM, MOVE_RAIN_DANCE, MOVE_SUNNY_DAY, MOVE_HAIL, MOVE_WEATHER_BALL,
2019-12-02 14:44:34 +01:00
MOVE_NONE
2018-09-09 17:06:35 +02:00
};
2019-12-02 14:44:34 +01:00
// Excludes FACTORY_STYLE_NONE
static const u16 *const sMoveStyles[FACTORY_NUM_STYLES - 1] =
2018-09-09 17:06:35 +02:00
{
2019-12-02 14:44:34 +01:00
[FACTORY_STYLE_PREPARATION - 1] = sMoves_TotalPreparation,
[FACTORY_STYLE_SLOW_STEADY - 1] = sMoves_SlowAndSteady,
[FACTORY_STYLE_ENDURANCE - 1] = sMoves_Endurance,
[FACTORY_STYLE_HIGH_RISK - 1] = sMoves_HighRiskHighReturn,
[FACTORY_STYLE_WEAKENING - 1] = sMoves_WeakeningTheFoe,
[FACTORY_STYLE_UNPREDICTABLE - 1] = sMoves_ImpossibleToPredict,
[FACTORY_STYLE_WEATHER - 1] = sMoves_DependsOnTheBattlesFlow,
2018-09-09 17:06:35 +02:00
};
2019-02-07 19:58:09 +01:00
static void (* const sBattleFactoryFunctions[])(void) =
2018-09-09 17:06:35 +02:00
{
2019-12-02 14:44:34 +01:00
[BATTLE_FACTORY_FUNC_INIT] = InitFactoryChallenge,
[BATTLE_FACTORY_FUNC_GET_DATA] = GetBattleFactoryData,
[BATTLE_FACTORY_FUNC_SET_DATA] = SetBattleFactoryData,
[BATTLE_FACTORY_FUNC_SAVE] = SaveFactoryChallenge,
[BATTLE_FACTORY_FUNC_NULL] = FactoryDummy1,
[BATTLE_FACTORY_FUNC_NULL2] = FactoryDummy2,
2019-12-02 14:44:34 +01:00
[BATTLE_FACTORY_FUNC_SELECT_RENT_MONS] = SelectInitialRentalMons,
[BATTLE_FACTORY_FUNC_SWAP_RENT_MONS] = SwapRentalMons,
[BATTLE_FACTORY_FUNC_SET_SWAPPED] = SetPerformedRentalSwap,
[BATTLE_FACTORY_FUNC_SET_OPPONENT_MONS] = SetRentalsToOpponentParty,
[BATTLE_FACTORY_FUNC_SET_PARTIES] = SetPlayerAndOpponentParties,
[BATTLE_FACTORY_FUNC_SET_OPPONENT_GFX] = SetOpponentGfxVar,
[BATTLE_FACTORY_FUNC_GENERATE_OPPONENT_MONS] = GenerateOpponentMons,
[BATTLE_FACTORY_FUNC_GENERATE_RENTAL_MONS] = GenerateInitialRentalMons,
[BATTLE_FACTORY_FUNC_GET_OPPONENT_MON_TYPE] = GetOpponentMostCommonMonType,
[BATTLE_FACTORY_FUNC_GET_OPPONENT_STYLE] = GetOpponentBattleStyle,
[BATTLE_FACTORY_FUNC_RESET_HELD_ITEMS] = RestorePlayerPartyHeldItems,
2018-09-09 17:06:35 +02:00
};
2019-11-24 22:58:40 +01:00
static const u32 sWinStreakFlags[][2] =
2018-09-09 17:06:35 +02:00
{
2019-11-24 22:58:40 +01:00
{STREAK_FACTORY_SINGLES_50, STREAK_FACTORY_SINGLES_OPEN},
{STREAK_FACTORY_DOUBLES_50, STREAK_FACTORY_DOUBLES_OPEN},
2018-09-09 17:06:35 +02:00
};
2019-11-24 22:58:40 +01:00
static const u32 sWinStreakMasks[][2] =
2018-09-09 17:06:35 +02:00
{
2019-11-24 22:58:40 +01:00
{~(STREAK_FACTORY_SINGLES_50), ~(STREAK_FACTORY_SINGLES_OPEN)},
{~(STREAK_FACTORY_DOUBLES_50), ~(STREAK_FACTORY_DOUBLES_OPEN)},
2018-09-09 17:06:35 +02:00
};
2018-11-11 16:44:27 +01:00
static const u8 sFixedIVTable[][2] =
{
2018-11-11 16:44:27 +01:00
{3, 6},
{6, 9},
{9, 12},
{12, 15},
{15, 18},
{21, 31},
{31, 31},
{31, 31},
};
2018-09-02 19:41:33 +02:00
static const u16 sInitialRentalMonRanges[][2] =
{
// Level 50
{FRONTIER_MON_GRIMER, FRONTIER_MON_FURRET_1}, // 110 - 199
{FRONTIER_MON_DELCATTY_1, FRONTIER_MON_CLOYSTER_1}, // 162 - 266
{FRONTIER_MON_DELCATTY_2, FRONTIER_MON_CLOYSTER_2}, // 267 - 371
{FRONTIER_MON_DUGTRIO_1, FRONTIER_MON_SLAKING_1}, // 372 - 467
{FRONTIER_MON_DUGTRIO_2, FRONTIER_MON_SLAKING_2}, // 468 - 563
{FRONTIER_MON_DUGTRIO_3, FRONTIER_MON_SLAKING_3}, // 564 - 659
{FRONTIER_MON_DUGTRIO_4, FRONTIER_MON_SLAKING_4}, // 660 - 755
{FRONTIER_MON_DUGTRIO_1, FRONTIER_MONS_HIGH_TIER}, // 372 - 849
// Open level
{FRONTIER_MON_DUGTRIO_1, FRONTIER_MON_SLAKING_1}, // 372 - 467
{FRONTIER_MON_DUGTRIO_2, FRONTIER_MON_SLAKING_2}, // 468 - 563
{FRONTIER_MON_DUGTRIO_3, FRONTIER_MON_SLAKING_3}, // 564 - 659
{FRONTIER_MON_DUGTRIO_4, FRONTIER_MON_SLAKING_4}, // 660 - 755
{FRONTIER_MON_DUGTRIO_1, NUM_FRONTIER_MONS - 1}, // 372 - 881
{FRONTIER_MON_DUGTRIO_1, NUM_FRONTIER_MONS - 1}, // 372 - 881
{FRONTIER_MON_DUGTRIO_1, NUM_FRONTIER_MONS - 1}, // 372 - 881
{FRONTIER_MON_DUGTRIO_1, NUM_FRONTIER_MONS - 1}, // 372 - 881
2018-11-11 16:44:27 +01:00
};
2018-11-11 16:44:27 +01:00
// code
void CallBattleFactoryFunction(void)
{
2019-02-07 19:58:09 +01:00
sBattleFactoryFunctions[gSpecialVar_0x8004]();
}
2019-02-07 19:58:09 +01:00
static void InitFactoryChallenge(void)
{
2018-11-11 16:44:27 +01:00
u8 i;
u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = 0;
2018-11-11 16:44:27 +01:00
gSaveBlock2Ptr->frontier.curChallengeBattleNum = 0;
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = FALSE;
2019-12-14 09:58:20 +01:00
gSaveBlock2Ptr->frontier.disableRecordBattle = FALSE;
2019-11-24 22:58:40 +01:00
if (!(gSaveBlock2Ptr->frontier.winStreakActiveFlags & sWinStreakFlags[battleMode][lvlMode]))
{
2018-11-11 16:44:27 +01:00
gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] = 0;
gSaveBlock2Ptr->frontier.factoryRentsCount[battleMode][lvlMode] = 0;
}
2019-02-07 19:58:09 +01:00
sPerformedRentalSwap = FALSE;
2018-11-11 16:44:27 +01:00
for (i = 0; i < 6; i++)
2019-02-07 19:58:09 +01:00
gSaveBlock2Ptr->frontier.rentalMons[i].monId = 0xFFFF;
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2020-10-07 23:03:46 +02:00
gFrontierTempParty[i] = 0xFFFF;
2018-11-11 16:44:27 +01:00
SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, WARP_ID_NONE);
2018-11-11 16:44:27 +01:00
gTrainerBattleOpponent_A = 0;
}
2019-02-07 19:58:09 +01:00
static void GetBattleFactoryData(void)
{
2019-02-07 19:58:09 +01:00
int lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
int battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
2018-11-11 16:44:27 +01:00
switch (gSpecialVar_0x8005)
{
2019-12-02 14:44:34 +01:00
case FACTORY_DATA_WIN_STREAK:
2018-11-11 16:44:27 +01:00
gSpecialVar_Result = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode];
break;
2019-12-02 14:44:34 +01:00
case FACTORY_DATA_WIN_STREAK_ACTIVE:
2019-11-24 22:58:40 +01:00
gSpecialVar_Result = ((gSaveBlock2Ptr->frontier.winStreakActiveFlags & sWinStreakFlags[battleMode][lvlMode]) != 0);
2018-11-11 16:44:27 +01:00
break;
2019-12-02 14:44:34 +01:00
case FACTORY_DATA_WIN_STREAK_SWAPS:
2018-11-11 16:44:27 +01:00
gSpecialVar_Result = gSaveBlock2Ptr->frontier.factoryRentsCount[battleMode][lvlMode];
break;
}
}
2019-02-07 19:58:09 +01:00
static void SetBattleFactoryData(void)
{
2019-02-07 19:58:09 +01:00
int lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
int battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
2018-11-11 16:44:27 +01:00
switch (gSpecialVar_0x8005)
{
2019-12-02 14:44:34 +01:00
case FACTORY_DATA_WIN_STREAK:
2018-11-11 16:44:27 +01:00
gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] = gSpecialVar_0x8006;
break;
2019-12-02 14:44:34 +01:00
case FACTORY_DATA_WIN_STREAK_ACTIVE:
2018-11-11 16:44:27 +01:00
if (gSpecialVar_0x8006)
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.winStreakActiveFlags |= sWinStreakFlags[battleMode][lvlMode];
2018-11-11 16:44:27 +01:00
else
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.winStreakActiveFlags &= sWinStreakMasks[battleMode][lvlMode];
2018-11-11 16:44:27 +01:00
break;
2019-12-02 14:44:34 +01:00
case FACTORY_DATA_WIN_STREAK_SWAPS:
2019-02-07 19:58:09 +01:00
if (sPerformedRentalSwap == TRUE)
2018-11-11 16:44:27 +01:00
{
gSaveBlock2Ptr->frontier.factoryRentsCount[battleMode][lvlMode] = gSpecialVar_0x8006;
2019-02-07 19:58:09 +01:00
sPerformedRentalSwap = FALSE;
2018-11-11 16:44:27 +01:00
}
break;
}
}
static void SaveFactoryChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
2018-11-11 16:44:27 +01:00
VarSet(VAR_TEMP_0, 0);
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
SaveGameFrontier();
}
static void FactoryDummy1(void)
{
}
static void FactoryDummy2(void)
{
}
2019-02-07 19:58:09 +01:00
static void SelectInitialRentalMons(void)
{
2018-11-11 16:44:27 +01:00
ZeroPlayerPartyMons();
DoBattleFactorySelectScreen();
}
2019-02-07 19:58:09 +01:00
static void SwapRentalMons(void)
{
2018-11-11 16:44:27 +01:00
DoBattleFactorySwapScreen();
}
2019-02-07 19:58:09 +01:00
static void SetPerformedRentalSwap(void)
{
2019-02-07 19:58:09 +01:00
sPerformedRentalSwap = TRUE;
}
2019-02-07 19:58:09 +01:00
static void GenerateOpponentMons(void)
{
2019-02-07 19:58:09 +01:00
int i, j, k;
2019-12-02 14:44:34 +01:00
u16 species[FRONTIER_PARTY_SIZE];
u16 heldItems[FRONTIER_PARTY_SIZE];
2019-02-07 19:58:09 +01:00
int firstMonId = 0;
2018-11-11 16:44:27 +01:00
u16 trainerId = 0;
u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
u32 winStreak = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode];
u32 challengeNum = winStreak / 7;
gFacilityTrainers = gBattleFrontierTrainers;
2018-11-11 16:44:27 +01:00
do
{
2019-12-21 00:52:29 +01:00
trainerId = GetRandomScaledFrontierTrainerId(challengeNum, gSaveBlock2Ptr->frontier.curChallengeBattleNum);
2018-11-11 16:44:27 +01:00
for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++)
{
2019-02-07 18:37:28 +01:00
if (gSaveBlock2Ptr->frontier.trainerIds[i] == trainerId)
2018-11-11 16:44:27 +01:00
break;
}
} while (i != gSaveBlock2Ptr->frontier.curChallengeBattleNum);
gTrainerBattleOpponent_A = trainerId;
if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 6)
2019-02-07 18:37:28 +01:00
gSaveBlock2Ptr->frontier.trainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = trainerId;
2018-11-11 16:44:27 +01:00
i = 0;
2019-12-02 14:44:34 +01:00
while (i != FRONTIER_PARTY_SIZE)
{
u16 monId = GetFactoryMonId(lvlMode, challengeNum, FALSE);
if (gFacilityTrainerMons[monId].species == SPECIES_UNOWN)
2018-11-11 16:44:27 +01:00
continue;
for (j = 0; j < 6; j++)
{
if (gFacilityTrainerMons[monId].species == gFacilityTrainerMons[gSaveBlock2Ptr->frontier.rentalMons[j].monId].species)
2018-11-11 16:44:27 +01:00
break;
}
if (j != 6)
continue;
if (lvlMode == FRONTIER_LVL_50 && monId > FRONTIER_MONS_HIGH_TIER)
2018-11-11 16:44:27 +01:00
continue;
for (k = firstMonId; k < firstMonId + i; k++)
{
if (species[k] == gFacilityTrainerMons[monId].species)
2018-11-11 16:44:27 +01:00
break;
}
if (k != firstMonId + i)
continue;
for (k = firstMonId; k < firstMonId + i; k++)
{
if (heldItems[k] != 0 && heldItems[k] == gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId])
2018-11-11 16:44:27 +01:00
break;
}
if (k != firstMonId + i)
continue;
species[i] = gFacilityTrainerMons[monId].species;
heldItems[i] = gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId];
2020-10-07 23:03:46 +02:00
gFrontierTempParty[i] = monId;
2018-11-11 16:44:27 +01:00
i++;
}
}
2019-02-07 19:58:09 +01:00
static void SetOpponentGfxVar(void)
{
2018-11-11 16:44:27 +01:00
SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0);
}
2018-09-09 13:12:26 +02:00
2019-02-07 19:58:09 +01:00
static void SetRentalsToOpponentParty(void)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
u8 i;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT)
gFacilityTrainerMons = gBattleFrontierMons;
else
gFacilityTrainerMons = gSlateportBattleTentMons;
2018-09-09 13:12:26 +02:00
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2018-11-11 16:44:27 +01:00
{
gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].monId = gFrontierTempParty[i];
gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].ivs = GetBoxMonData(&gEnemyParty[i].box, MON_DATA_ATK_IV, NULL);
gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].personality = GetMonData(&gEnemyParty[i], MON_DATA_PERSONALITY, NULL);
gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].abilityNum = GetBoxMonData(&gEnemyParty[i].box, MON_DATA_ABILITY_NUM, NULL);
2020-10-07 23:03:46 +02:00
SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[gFrontierTempParty[i]].itemTableId]);
2018-11-11 16:44:27 +01:00
}
2018-09-09 13:12:26 +02:00
}
2019-02-07 19:58:09 +01:00
static void SetPlayerAndOpponentParties(void)
2018-09-09 13:12:26 +02:00
{
2019-02-07 19:58:09 +01:00
int i, j, k;
int count = 0;
2018-11-11 16:44:27 +01:00
u8 bits = 0;
u8 monLevel;
u16 monId;
2018-11-11 16:44:27 +01:00
u16 evs;
u8 ivs;
u8 friendship;
if (gSaveBlock2Ptr->frontier.lvlMode == FRONTIER_LVL_TENT)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
gFacilityTrainerMons = gSlateportBattleTentMons;
monLevel = 30;
}
else
{
gFacilityTrainerMons = gBattleFrontierMons;
if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_50)
monLevel = 100;
else
monLevel = 50;
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
if (gSpecialVar_0x8005 < 2)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
ZeroPlayerPartyMons();
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2018-11-11 16:44:27 +01:00
{
monId = gSaveBlock2Ptr->frontier.rentalMons[i].monId;
2019-02-07 19:58:09 +01:00
ivs = gSaveBlock2Ptr->frontier.rentalMons[i].ivs;
2018-11-11 16:44:27 +01:00
CreateMon(&gPlayerParty[i],
gFacilityTrainerMons[monId].species,
2018-11-11 16:44:27 +01:00
monLevel,
ivs,
2019-02-07 19:58:09 +01:00
TRUE, gSaveBlock2Ptr->frontier.rentalMons[i].personality,
2019-08-31 05:06:43 +02:00
OT_ID_PLAYER_ID, 0);
2018-11-11 16:44:27 +01:00
count = 0;
bits = gFacilityTrainerMons[monId].evSpread;
2018-11-11 16:44:27 +01:00
for (j = 0; j < NUM_STATS; bits >>= 1, j++)
{
if (bits & 1)
count++;
}
evs = MAX_TOTAL_EVS / count;
bits = 1;
for (j = 0; j < NUM_STATS; bits <<= 1, j++)
{
if (gFacilityTrainerMons[monId].evSpread & bits)
2018-11-11 16:44:27 +01:00
SetMonData(&gPlayerParty[i], MON_DATA_HP_EV + j, &evs);
}
CalculateMonStats(&gPlayerParty[i]);
friendship = 0;
for (k = 0; k < MAX_MON_MOVES; k++)
SetMonMoveAvoidReturn(&gPlayerParty[i], gFacilityTrainerMons[monId].moves[k], k);
2018-11-11 16:44:27 +01:00
SetMonData(&gPlayerParty[i], MON_DATA_FRIENDSHIP, &friendship);
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]);
2019-05-14 15:22:16 +02:00
SetMonData(&gPlayerParty[i], MON_DATA_ABILITY_NUM, &gSaveBlock2Ptr->frontier.rentalMons[i].abilityNum);
2018-11-11 16:44:27 +01:00
}
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
switch (gSpecialVar_0x8005)
2018-09-09 13:12:26 +02:00
{
case 0:
2018-11-11 16:44:27 +01:00
case 2:
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2018-11-11 16:44:27 +01:00
{
monId = gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].monId;
ivs = gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].ivs;
2018-11-11 16:44:27 +01:00
CreateMon(&gEnemyParty[i],
gFacilityTrainerMons[monId].species,
2018-11-11 16:44:27 +01:00
monLevel,
ivs,
TRUE, gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].personality,
2019-08-31 05:06:43 +02:00
OT_ID_PLAYER_ID, 0);
2018-11-11 16:44:27 +01:00
count = 0;
bits = gFacilityTrainerMons[monId].evSpread;
2018-11-11 16:44:27 +01:00
for (j = 0; j < NUM_STATS; bits >>= 1, j++)
{
if (bits & 1)
count++;
}
evs = MAX_TOTAL_EVS / count;
bits = 1;
for (j = 0; j < NUM_STATS; bits <<= 1, j++)
{
if (gFacilityTrainerMons[monId].evSpread & bits)
2018-11-11 16:44:27 +01:00
SetMonData(&gEnemyParty[i], MON_DATA_HP_EV + j, &evs);
}
CalculateMonStats(&gEnemyParty[i]);
for (k = 0; k < MAX_MON_MOVES; k++)
SetMonMoveAvoidReturn(&gEnemyParty[i], gFacilityTrainerMons[monId].moves[k], k);
SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]);
SetMonData(&gEnemyParty[i], MON_DATA_ABILITY_NUM, &gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].abilityNum);
2018-11-11 16:44:27 +01:00
}
2018-09-09 13:12:26 +02:00
break;
}
}
2019-02-07 19:58:09 +01:00
static void GenerateInitialRentalMons(void)
2018-09-09 13:12:26 +02:00
{
2019-02-07 19:58:09 +01:00
int i, j;
2018-11-11 16:44:27 +01:00
u8 firstMonId;
u8 battleMode;
u8 lvlMode;
u8 challengeNum;
u8 factoryLvlMode;
u8 factoryBattleMode;
u8 rentalRank;
u16 monId;
2018-11-11 16:44:27 +01:00
u16 currSpecies;
u16 species[PARTY_SIZE];
u16 monIds[PARTY_SIZE];
u16 heldItems[PARTY_SIZE];
gFacilityTrainers = gBattleFrontierTrainers;
for (i = 0; i < PARTY_SIZE; i++)
{
species[i] = 0;
monIds[i] = 0;
heldItems[i] = 0;
}
lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7;
if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES)
factoryBattleMode = FRONTIER_MODE_DOUBLES;
2018-09-09 13:12:26 +02:00
else
2018-11-11 16:44:27 +01:00
factoryBattleMode = FRONTIER_MODE_SINGLES;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
gFacilityTrainerMons = gBattleFrontierMons;
if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_50)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
factoryLvlMode = FRONTIER_LVL_OPEN;
firstMonId = 0;
2018-09-09 13:12:26 +02:00
}
else
{
2018-11-11 16:44:27 +01:00
factoryLvlMode = FRONTIER_LVL_50;
firstMonId = 0;
}
rentalRank = GetNumPastRentalsRank(factoryBattleMode, factoryLvlMode);
2018-11-11 16:44:27 +01:00
2018-12-18 15:35:31 +01:00
currSpecies = SPECIES_NONE;
2018-11-11 16:44:27 +01:00
i = 0;
while (i != PARTY_SIZE)
{
if (i < rentalRank) // The more times the player has rented, the more initial rentals are generated from a better set of pokemon
monId = GetFactoryMonId(factoryLvlMode, challengeNum, TRUE);
2018-09-09 13:12:26 +02:00
else
monId = GetFactoryMonId(factoryLvlMode, challengeNum, FALSE);
2018-11-11 16:44:27 +01:00
if (gFacilityTrainerMons[monId].species == SPECIES_UNOWN)
2018-11-11 16:44:27 +01:00
continue;
// Cannot have two pokemon of the same species.
for (j = firstMonId; j < firstMonId + i; j++)
{
u16 existingMonId = monIds[j];
if (existingMonId == monId)
2018-11-11 16:44:27 +01:00
break;
if (species[j] == gFacilityTrainerMons[monId].species)
2018-11-11 16:44:27 +01:00
{
2018-12-18 15:35:31 +01:00
if (currSpecies == SPECIES_NONE)
currSpecies = gFacilityTrainerMons[monId].species;
2018-11-11 16:44:27 +01:00
else
break;
}
}
if (j != firstMonId + i)
continue;
// Cannot have two same held items.
for (j = firstMonId; j < firstMonId + i; j++)
{
if (heldItems[j] != 0 && heldItems[j] == gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId])
2018-11-11 16:44:27 +01:00
{
if (gFacilityTrainerMons[monId].species == currSpecies)
2018-12-18 15:35:31 +01:00
currSpecies = SPECIES_NONE;
2018-11-11 16:44:27 +01:00
break;
}
}
if (j != firstMonId + i)
continue;
gSaveBlock2Ptr->frontier.rentalMons[i].monId = monId;
species[i] = gFacilityTrainerMons[monId].species;
heldItems[i] = gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId];
monIds[i] = monId;
2018-11-11 16:44:27 +01:00
i++;
2018-09-09 13:12:26 +02:00
}
}
// Determines if the upcoming opponent has a single most-common
// type in its party. If there are two different types that are
// tied, then the opponent is deemed to have no preferred type,
// and NUMBER_OF_MON_TYPES is the result.
2019-02-07 19:58:09 +01:00
static void GetOpponentMostCommonMonType(void)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
u8 i;
u8 typeCounts[NUMBER_OF_MON_TYPES];
u8 mostCommonTypes[2];
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
gFacilityTrainerMons = gBattleFrontierMons;
// Count the number of times each type occurs in the opponent's party.
for (i = TYPE_NORMAL; i < NUMBER_OF_MON_TYPES; i++)
typeCounts[i] = 0;
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2018-09-09 13:12:26 +02:00
{
2020-10-07 23:03:46 +02:00
u32 species = gFacilityTrainerMons[gFrontierTempParty[i]].species;
typeCounts[gBaseStats[species].type1]++;
2018-11-11 16:44:27 +01:00
if (gBaseStats[species].type1 != gBaseStats[species].type2)
typeCounts[gBaseStats[species].type2]++;
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
// Determine which are the two most-common types.
// The second most-common type is only updated if
// its count is equal to the most-common type.
mostCommonTypes[0] = TYPE_NORMAL;
mostCommonTypes[1] = TYPE_NORMAL;
for (i = TYPE_FIGHTING; i < NUMBER_OF_MON_TYPES; i++)
2018-09-09 13:12:26 +02:00
{
if (typeCounts[mostCommonTypes[0]] < typeCounts[i])
mostCommonTypes[0] = i;
else if (typeCounts[mostCommonTypes[0]] == typeCounts[i])
mostCommonTypes[1] = i;
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
if (typeCounts[mostCommonTypes[0]] != 0)
{
// The most-common type must be strictly greater than
// the second-most-common type, or the top two must be
// the same type.
if (typeCounts[mostCommonTypes[0]] > typeCounts[mostCommonTypes[1]])
gSpecialVar_Result = mostCommonTypes[0];
else if (mostCommonTypes[0] == mostCommonTypes[1])
gSpecialVar_Result = mostCommonTypes[0];
else
gSpecialVar_Result = NUMBER_OF_MON_TYPES;
}
2018-11-11 16:44:27 +01:00
else
{
2018-11-11 16:44:27 +01:00
gSpecialVar_Result = NUMBER_OF_MON_TYPES;
}
2018-09-09 13:12:26 +02:00
}
2019-02-07 19:58:09 +01:00
static void GetOpponentBattleStyle(void)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
u8 i, j, count;
2019-12-02 14:44:34 +01:00
u8 stylePoints[FACTORY_NUM_STYLES];
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
count = 0;
gFacilityTrainerMons = gBattleFrontierMons;
2019-12-02 14:44:34 +01:00
for (i = 0; i < FACTORY_NUM_STYLES; i++)
2018-11-11 16:44:27 +01:00
stylePoints[i] = 0;
2019-02-07 19:58:09 +01:00
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2018-09-09 13:12:26 +02:00
{
2020-10-07 23:03:46 +02:00
u16 monId = gFrontierTempParty[i];
for (j = 0; j < MAX_MON_MOVES; j++)
2018-11-11 16:44:27 +01:00
{
u8 battleStyle = GetMoveBattleStyle(gFacilityTrainerMons[monId].moves[j]);
2019-02-07 19:58:09 +01:00
stylePoints[battleStyle]++;
2018-11-11 16:44:27 +01:00
}
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
gSpecialVar_Result = FACTORY_STYLE_NONE;
2019-12-02 14:44:34 +01:00
for (i = 1; i < FACTORY_NUM_STYLES; i++)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
if (stylePoints[i] >= sRequiredMoveCounts[i - 1])
{
gSpecialVar_Result = i;
count++;
}
2018-09-09 13:12:26 +02:00
}
2019-02-07 19:58:09 +01:00
2019-12-02 14:44:34 +01:00
// Has no singular style
2018-11-11 16:44:27 +01:00
if (count > 2)
2019-12-02 14:44:34 +01:00
gSpecialVar_Result = FACTORY_NUM_STYLES;
2018-09-09 13:12:26 +02:00
}
2019-02-07 19:58:09 +01:00
static u8 GetMoveBattleStyle(u16 move)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
const u16 *moves;
u8 i, j;
for (i = 0; i < ARRAY_COUNT(sMoveStyles); i++)
2018-09-09 13:12:26 +02:00
{
2019-12-02 14:44:34 +01:00
for (j = 0, moves = sMoveStyles[i]; moves[j] != MOVE_NONE; j++)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
if (moves[j] == move)
return i + 1;
2018-09-09 13:12:26 +02:00
}
}
2019-12-02 14:44:34 +01:00
return FACTORY_STYLE_NONE;
2018-09-09 13:12:26 +02:00
}
2019-02-07 19:58:09 +01:00
bool8 InBattleFactory(void)
2018-09-09 13:12:26 +02:00
{
2019-01-31 22:51:20 +01:00
return gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM
|| gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM;
2018-09-09 13:12:26 +02:00
}
2019-02-07 19:58:09 +01:00
static void RestorePlayerPartyHeldItems(void)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
u8 i;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT)
gFacilityTrainerMons = gBattleFrontierMons;
else
gFacilityTrainerMons = gSlateportBattleTentMons;
2018-09-09 13:12:26 +02:00
2019-12-02 14:44:34 +01:00
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
2018-11-11 16:44:27 +01:00
{
SetMonData(&gPlayerParty[i],
MON_DATA_HELD_ITEM,
2019-02-07 19:58:09 +01:00
&gBattleFrontierHeldItems[gFacilityTrainerMons[gSaveBlock2Ptr->frontier.rentalMons[i].monId].itemTableId]);
2018-11-11 16:44:27 +01:00
}
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
u8 GetFactoryMonFixedIV(u8 arg0, u8 arg1)
2018-09-09 13:12:26 +02:00
{
2018-11-11 16:44:27 +01:00
u8 a1;
u8 a2 = (arg1 != 0) ? 1 : 0;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
if (arg0 > 8)
a1 = 7;
else
a1 = arg0;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
return sFixedIVTable[a1][a2];
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
void FillFactoryBrainParty(void)
2018-09-09 13:12:26 +02:00
{
2019-02-07 19:58:09 +01:00
int i, j, k;
2019-12-02 14:44:34 +01:00
u16 species[FRONTIER_PARTY_SIZE];
u16 heldItems[FRONTIER_PARTY_SIZE];
2018-11-11 16:44:27 +01:00
u8 friendship;
2019-02-07 19:58:09 +01:00
int monLevel;
2018-11-11 16:44:27 +01:00
u8 fixedIV;
u32 otId;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
u8 challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7;
fixedIV = GetFactoryMonFixedIV(challengeNum + 2, 0);
monLevel = SetFacilityPtrsGetLevel();
i = 0;
otId = T1_READ_32(gSaveBlock2Ptr->playerTrainerId);
2018-09-09 13:12:26 +02:00
2019-12-02 14:44:34 +01:00
while (i != FRONTIER_PARTY_SIZE)
2018-11-11 16:44:27 +01:00
{
u16 monId = GetFactoryMonId(lvlMode, challengeNum, FALSE);
2018-09-09 13:12:26 +02:00
if (gFacilityTrainerMons[monId].species == SPECIES_UNOWN)
2018-11-11 16:44:27 +01:00
continue;
if (monLevel == 50 && monId > FRONTIER_MONS_HIGH_TIER)
2018-11-11 16:44:27 +01:00
continue;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
for (j = 0; j < 6; j++)
{
if (monId == gSaveBlock2Ptr->frontier.rentalMons[j].monId)
2018-11-11 16:44:27 +01:00
break;
}
if (j != 6)
continue;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
for (k = 0; k < i; k++)
{
if (species[k] == gFacilityTrainerMons[monId].species)
2018-11-11 16:44:27 +01:00
break;
}
if (k != i)
continue;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
for (k = 0; k < i; k++)
{
if (heldItems[k] != 0 && heldItems[k] == gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId])
2018-11-11 16:44:27 +01:00
break;
}
if (k != i)
continue;
2018-09-09 13:12:26 +02:00
species[i] = gFacilityTrainerMons[monId].species;
heldItems[i] = gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId];
2018-11-11 16:44:27 +01:00
CreateMonWithEVSpreadNatureOTID(&gEnemyParty[i],
gFacilityTrainerMons[monId].species,
2018-11-11 16:44:27 +01:00
monLevel,
gFacilityTrainerMons[monId].nature,
2018-11-11 16:44:27 +01:00
fixedIV,
gFacilityTrainerMons[monId].evSpread,
2018-11-11 16:44:27 +01:00
otId);
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
friendship = 0;
for (k = 0; k < MAX_MON_MOVES; k++)
SetMonMoveAvoidReturn(&gEnemyParty[i], gFacilityTrainerMons[monId].moves[k], k);
2018-11-11 16:44:27 +01:00
SetMonData(&gEnemyParty[i], MON_DATA_FRIENDSHIP, &friendship);
SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]);
2018-11-11 16:44:27 +01:00
i++;
}
2018-09-09 13:12:26 +02:00
}
static u16 GetFactoryMonId(u8 lvlMode, u8 challengeNum, bool8 useBetterRange)
2018-09-09 13:12:26 +02:00
{
u16 numMons, monId;
u16 adder; // Used to skip past early mons for open level
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
if (lvlMode == FRONTIER_LVL_50)
adder = 0;
else
adder = 8;
2018-09-09 13:12:26 +02:00
2018-11-11 16:44:27 +01:00
if (challengeNum < 7)
2018-09-09 13:12:26 +02:00
{
if (useBetterRange)
2018-09-09 13:12:26 +02:00
{
numMons = (sInitialRentalMonRanges[adder + challengeNum + 1][1] - sInitialRentalMonRanges[adder + challengeNum + 1][0]) + 1;
monId = Random() % numMons;
monId += sInitialRentalMonRanges[adder + challengeNum + 1][0];
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
else
2018-09-09 13:12:26 +02:00
{
numMons = (sInitialRentalMonRanges[adder + challengeNum][1] - sInitialRentalMonRanges[adder + challengeNum][0]) + 1;
monId = Random() % numMons;
monId += sInitialRentalMonRanges[adder + challengeNum][0];
2018-09-09 13:12:26 +02:00
}
}
2018-11-11 16:44:27 +01:00
else
2018-09-09 13:12:26 +02:00
{
u16 challenge = challengeNum;
if (challenge != 7)
challenge = 7; // why bother assigning it above at all
numMons = (sInitialRentalMonRanges[adder + challenge][1] - sInitialRentalMonRanges[adder + challenge][0]) + 1;
monId = Random() % numMons;
monId += sInitialRentalMonRanges[adder + challenge][0];
2018-09-09 13:12:26 +02:00
}
2018-11-11 16:44:27 +01:00
return monId;
2018-09-09 13:12:26 +02:00
}
2018-09-09 20:31:51 +02:00
2019-02-07 19:58:09 +01:00
u8 GetNumPastRentalsRank(u8 battleMode, u8 lvlMode)
2018-09-09 20:31:51 +02:00
{
2018-11-11 16:44:27 +01:00
u8 ret;
u8 rents = gSaveBlock2Ptr->frontier.factoryRentsCount[battleMode][lvlMode];
2018-09-09 20:31:51 +02:00
2018-11-11 16:44:27 +01:00
if (rents < 15)
ret = 0;
else if (rents < 22)
ret = 1;
else if (rents < 29)
ret = 2;
else if (rents < 36)
ret = 3;
else if (rents < 43)
ret = 4;
else
ret = 5;
2018-11-11 16:44:27 +01:00
return ret;
}
2018-11-11 16:44:27 +01:00
u32 GetAiScriptsInBattleFactory(void)
{
2019-02-07 19:58:09 +01:00
int lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
2018-11-11 16:44:27 +01:00
if (lvlMode == FRONTIER_LVL_TENT)
{
2018-11-11 16:44:27 +01:00
return 0;
}
2018-11-11 16:44:27 +01:00
else
{
2019-02-07 19:58:09 +01:00
int battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE);
int challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7;
2018-11-11 16:44:27 +01:00
if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN)
return AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY;
else if (challengeNum < 2)
return 0;
else if (challengeNum < 4)
return AI_SCRIPT_CHECK_BAD_MOVE;
else
return AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY;
}
}
2018-11-11 16:44:27 +01:00
void SetMonMoveAvoidReturn(struct Pokemon *mon, u16 moveArg, u8 moveSlot)
{
2018-11-11 16:44:27 +01:00
u16 move = moveArg;
if (moveArg == MOVE_RETURN)
move = MOVE_FRUSTRATION;
SetMonMoveSlot(mon, move, moveSlot);
}