pokeemerald/src/battle_tent.c

422 lines
13 KiB
C
Raw Normal View History

#include "global.h"
#include "battle_tent.h"
#include "overworld.h"
#include "event_data.h"
#include "region_map.h"
#include "battle.h"
#include "battle_setup.h"
#include "battle_tower.h"
#include "random.h"
#include "item.h"
2018-11-11 16:44:27 +01:00
#include "battle_factory_screen.h"
2018-10-30 22:17:03 +01:00
#include "frontier_util.h"
2018-11-19 17:36:39 +01:00
#include "string_util.h"
2019-12-02 20:49:22 +01:00
#include "constants/battle_tent.h"
#include "constants/items.h"
2019-01-31 22:51:20 +01:00
#include "constants/layouts.h"
2018-06-30 14:22:09 +02:00
#include "constants/region_map_sections.h"
2018-12-18 15:35:31 +01:00
#include "constants/species.h"
#include "constants/trainers.h"
2018-08-25 18:46:15 +02:00
// This file's functions.
static void InitVerdanturfTentChallenge(void);
static void GetVerdanturfTentPrize(void);
static void SetVerdanturfTentPrize(void);
static void SetVerdanturfTentTrainerGfx(void);
static void BufferVerdanturfTentTrainerIntro(void);
static void SaveVerdanturfTentChallenge(void);
static void SetRandomVerdanturfTentPrize(void);
static void GiveVerdanturfTentPrize(void);
static void InitFallarborTentChallenge(void);
static void GetFallarborTentPrize(void);
static void SetFallarborTentPrize(void);
static void SaveFallarborTentChallenge(void);
static void SetRandomFallarborTentPrize(void);
static void GiveFallarborTentPrize(void);
static void BufferFallarborTentTrainerName(void);
static void InitSlateportTentChallenge(void);
static void GetSlateportTentPrize(void);
static void SetSlateportTentPrize(void);
static void SaveSlateportTentChallenge(void);
static void SetRandomSlateportTentPrize(void);
static void GiveSlateportTentPrize(void);
static void SelectInitialRentalMons(void);
static void SwapRentalMons(void);
2019-12-02 20:49:22 +01:00
static void GenerateOpponentMons(void);
static void GenerateInitialRentalMons(void);
/*
* Battle Tents are mini versions of particular Battle Frontier facilities
* As such they each share some scripts and functions with their counterpart
*
* Verdanturf Battle Tent: Battle Palace
* Fallarbor Battle Tent: Battle Arena
* Slateport Battle Tent: Battle Factory
*
*/
// IWRAM bss
static u16 sRandMonSetId;
// const rom data
2019-11-24 22:58:40 +01:00
void static (*const sVerdanturfTentFuncs[])(void) =
{
2019-12-02 20:49:22 +01:00
[VERDANTURF_TENT_FUNC_INIT] = InitVerdanturfTentChallenge,
[VERDANTURF_TENT_FUNC_GET_PRIZE] = GetVerdanturfTentPrize,
[VERDANTURF_TENT_FUNC_SET_PRIZE] = SetVerdanturfTentPrize,
[VERDANTURF_TENT_FUNC_SET_OPPONENT_GFX] = SetVerdanturfTentTrainerGfx,
[VERDANTURF_TENT_FUNC_GET_OPPONENT_INTRO] = BufferVerdanturfTentTrainerIntro,
[VERDANTURF_TENT_FUNC_SAVE] = SaveVerdanturfTentChallenge,
[VERDANTURF_TENT_FUNC_SET_RANDOM_PRIZE] = SetRandomVerdanturfTentPrize,
[VERDANTURF_TENT_FUNC_GIVE_PRIZE] = GiveVerdanturfTentPrize
};
2018-08-26 15:27:06 +02:00
static const u16 sVerdanturfTentRewards[] = {ITEM_NEST_BALL};
2019-11-24 22:58:40 +01:00
void static (*const sFallarborTentFuncs[])(void) =
{
2019-12-02 20:49:22 +01:00
[FALLARBOR_TENT_FUNC_INIT] = InitFallarborTentChallenge,
[FALLARBOR_TENT_FUNC_GET_PRIZE] = GetFallarborTentPrize,
[FALLARBOR_TENT_FUNC_SET_PRIZE] = SetFallarborTentPrize,
[FALLARBOR_TENT_FUNC_SAVE] = SaveFallarborTentChallenge,
[FALLARBOR_TENT_FUNC_SET_RANDOM_PRIZE] = SetRandomFallarborTentPrize,
[FALLARBOR_TENT_FUNC_GIVE_PRIZE] = GiveFallarborTentPrize,
[FALLARBOR_TENT_FUNC_GET_OPPONENT_NAME] = BufferFallarborTentTrainerName
};
2018-08-26 15:27:06 +02:00
static const u16 sFallarborTentRewards[] = {ITEM_HYPER_POTION};
2019-11-24 22:58:40 +01:00
void static (*const sSlateportTentFuncs[])(void) =
{
2019-12-02 20:49:22 +01:00
[SLATEPORT_TENT_FUNC_INIT] = InitSlateportTentChallenge,
[SLATEPORT_TENT_FUNC_GET_PRIZE] = GetSlateportTentPrize,
[SLATEPORT_TENT_FUNC_SET_PRIZE] = SetSlateportTentPrize,
[SLATEPORT_TENT_FUNC_SAVE] = SaveSlateportTentChallenge,
[SLATEPORT_TENT_FUNC_SET_RANDOM_PRIZE] = SetRandomSlateportTentPrize,
[SLATEPORT_TENT_FUNC_GIVE_PRIZE] = GiveSlateportTentPrize,
[SLATEPORT_TENT_FUNC_SELECT_RENT_MONS] = SelectInitialRentalMons,
[SLATEPORT_TENT_FUNC_SWAP_RENT_MONS] = SwapRentalMons,
[SLATEPORT_TENT_FUNC_GENERATE_OPPONENT_MONS] = GenerateOpponentMons,
[SLATEPORT_TENT_FUNC_GENERATE_RENTAL_MONS] = GenerateInitialRentalMons
};
2018-08-26 15:27:06 +02:00
static const u16 sSlateportTentRewards[] = {ITEM_FULL_HEAL};
// code
2019-11-24 22:58:40 +01:00
void CallVerdanturfTentFunction(void)
{
2019-11-24 22:58:40 +01:00
sVerdanturfTentFuncs[gSpecialVar_0x8004]();
}
static void InitVerdanturfTentChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = 0;
2018-10-21 00:06:42 +02:00
gSaveBlock2Ptr->frontier.curChallengeBattleNum = 0;
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = FALSE;
2018-12-27 23:30:47 +01:00
SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1);
}
static void GetVerdanturfTentPrize(void)
{
gSpecialVar_Result = gSaveBlock2Ptr->frontier.verdanturfTentPrize;
}
static void SetVerdanturfTentPrize(void)
{
gSaveBlock2Ptr->frontier.verdanturfTentPrize = gSpecialVar_0x8006;
}
static void SetVerdanturfTentTrainerGfx(void)
{
gTrainerBattleOpponent_A = (u32)((Random() % 255) * 5) / 64;
2018-10-21 00:06:42 +02:00
SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0);
}
static void BufferVerdanturfTentTrainerIntro(void)
{
if (gTrainerBattleOpponent_A < TRAINER_RECORD_MIXING_FRIEND)
2018-10-21 20:13:12 +02:00
FrontierSpeechToString(gFacilityTrainers[gTrainerBattleOpponent_A].speechBefore);
}
static void SaveVerdanturfTentChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_0, 0);
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
SaveGameFrontier();
}
static void SetRandomVerdanturfTentPrize(void)
{
gSaveBlock2Ptr->frontier.verdanturfTentPrize = sVerdanturfTentRewards[Random() % ARRAY_COUNT(sVerdanturfTentRewards)];
}
static void GiveVerdanturfTentPrize(void)
{
if (AddBagItem(gSaveBlock2Ptr->frontier.verdanturfTentPrize, 1) == TRUE)
{
CopyItemName(gSaveBlock2Ptr->frontier.verdanturfTentPrize, gStringVar1);
gSaveBlock2Ptr->frontier.verdanturfTentPrize = ITEM_NONE;
gSpecialVar_Result = TRUE;
}
else
{
gSpecialVar_Result = FALSE;
}
}
2019-11-24 22:58:40 +01:00
void CallFallarborTentFunction(void)
{
2019-11-24 22:58:40 +01:00
sFallarborTentFuncs[gSpecialVar_0x8004]();
}
static void InitFallarborTentChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = 0;
2018-10-21 00:06:42 +02:00
gSaveBlock2Ptr->frontier.curChallengeBattleNum = 0;
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = FALSE;
2018-12-27 23:30:47 +01:00
SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1);
}
static void GetFallarborTentPrize(void)
{
gSpecialVar_Result = gSaveBlock2Ptr->frontier.fallarborTentPrize;
}
static void SetFallarborTentPrize(void)
{
gSaveBlock2Ptr->frontier.fallarborTentPrize = gSpecialVar_0x8006;
}
static void SaveFallarborTentChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_0, 0);
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
SaveGameFrontier();
}
static void SetRandomFallarborTentPrize(void)
{
gSaveBlock2Ptr->frontier.fallarborTentPrize = sFallarborTentRewards[Random() % ARRAY_COUNT(sFallarborTentRewards)];
}
static void GiveFallarborTentPrize(void)
{
if (AddBagItem(gSaveBlock2Ptr->frontier.fallarborTentPrize, 1) == TRUE)
{
CopyItemName(gSaveBlock2Ptr->frontier.fallarborTentPrize, gStringVar1);
gSaveBlock2Ptr->frontier.fallarborTentPrize = ITEM_NONE;
gSpecialVar_Result = TRUE;
}
else
{
gSpecialVar_Result = FALSE;
}
}
static void BufferFallarborTentTrainerName(void)
{
GetFrontierTrainerName(gStringVar1, gTrainerBattleOpponent_A);
}
2019-11-24 22:58:40 +01:00
void CallSlateportTentFunction(void)
{
2019-11-24 22:58:40 +01:00
sSlateportTentFuncs[gSpecialVar_0x8004]();
}
static void InitSlateportTentChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = 0;
2018-10-21 00:06:42 +02:00
gSaveBlock2Ptr->frontier.curChallengeBattleNum = 0;
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = FALSE;
2018-12-27 23:30:47 +01:00
SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1);
}
static void GetSlateportTentPrize(void)
{
gSpecialVar_Result = gSaveBlock2Ptr->frontier.slateportTentPrize;
}
static void SetSlateportTentPrize(void)
{
gSaveBlock2Ptr->frontier.slateportTentPrize = gSpecialVar_0x8006;
}
static void SaveSlateportTentChallenge(void)
{
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_0, 0);
2019-11-24 22:58:40 +01:00
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
SaveGameFrontier();
}
static void SetRandomSlateportTentPrize(void)
{
gSaveBlock2Ptr->frontier.slateportTentPrize = sSlateportTentRewards[Random() % ARRAY_COUNT(sSlateportTentRewards)];
}
static void GiveSlateportTentPrize(void)
{
if (AddBagItem(gSaveBlock2Ptr->frontier.slateportTentPrize, 1) == TRUE)
{
CopyItemName(gSaveBlock2Ptr->frontier.slateportTentPrize, gStringVar1);
gSaveBlock2Ptr->frontier.slateportTentPrize = ITEM_NONE;
gSpecialVar_Result = TRUE;
}
else
{
gSpecialVar_Result = FALSE;
}
}
static void SelectInitialRentalMons(void)
{
ZeroPlayerPartyMons();
DoBattleFactorySelectScreen();
}
static void SwapRentalMons(void)
{
DoBattleFactorySwapScreen();
}
bool8 InSlateportBattleTent(void)
{
2019-01-31 22:51:20 +01:00
return gMapHeader.regionMapSectionId == MAPSEC_SLATEPORT_CITY
&& (gMapHeader.mapLayoutId == LAYOUT_BATTLE_TENT_CORRIDOR || gMapHeader.mapLayoutId == LAYOUT_BATTLE_TENT_BATTLE_ROOM);
}
2018-08-26 15:27:06 +02:00
2019-12-02 20:49:22 +01:00
static void GenerateInitialRentalMons(void)
2018-08-26 15:27:06 +02:00
{
s32 i, j;
2018-11-11 16:44:27 +01:00
u8 firstMonId;
u16 monSetId;
u16 currSpecies;
2018-08-26 15:27:06 +02:00
u16 species[PARTY_SIZE];
u16 monIds[PARTY_SIZE];
u16 heldItems[PARTY_SIZE];
2018-11-11 16:44:27 +01:00
firstMonId = 0;
2018-08-26 15:27:06 +02:00
gFacilityTrainers = gSlateportBattleTentTrainers;
for (i = 0; i < PARTY_SIZE; i++)
{
species[i] = 0;
monIds[i] = 0;
heldItems[i] = 0;
}
gFacilityTrainerMons = gSlateportBattleTentMons;
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)
2018-08-26 15:27:06 +02:00
{
// Cannot have two pokemon of the same species.
2018-11-11 16:44:27 +01:00
monSetId = Random() % 70;
for (j = firstMonId; j < firstMonId + i; j++)
2018-08-26 15:27:06 +02:00
{
2018-11-11 16:44:27 +01:00
u16 monId = monIds[j];
if (monIds[j] == monSetId)
2018-08-29 20:38:54 +02:00
break;
2018-11-11 16:44:27 +01:00
if (species[j] == gFacilityTrainerMons[monSetId].species)
2018-08-26 15:27:06 +02:00
{
2018-12-18 15:35:31 +01:00
if (currSpecies == SPECIES_NONE)
2018-11-11 16:44:27 +01:00
currSpecies = gFacilityTrainerMons[monSetId].species;
2018-08-26 15:27:06 +02:00
else
break;
}
}
2018-11-11 16:44:27 +01:00
if (j != i + firstMonId)
2018-08-26 15:27:06 +02:00
continue;
// Cannot have two same held items.
2018-11-11 16:44:27 +01:00
for (j = firstMonId; j < i + firstMonId; j++)
2018-08-26 15:27:06 +02:00
{
2018-11-11 16:44:27 +01:00
if (heldItems[j] != 0 && heldItems[j] == gBattleFrontierHeldItems[gFacilityTrainerMons[monSetId].itemTableId])
2018-08-26 15:27:06 +02:00
{
2018-11-11 16:44:27 +01:00
if (gFacilityTrainerMons[monSetId].species == currSpecies)
2018-12-18 15:35:31 +01:00
currSpecies = SPECIES_NONE;
2018-11-11 16:44:27 +01:00
break;
2018-08-26 15:27:06 +02:00
}
}
2018-11-11 16:44:27 +01:00
if (j != i + firstMonId)
2018-08-26 15:27:06 +02:00
continue;
2019-02-07 19:58:09 +01:00
gSaveBlock2Ptr->frontier.rentalMons[i].monId = monSetId;
2018-11-11 16:44:27 +01:00
species[i] = gFacilityTrainerMons[monSetId].species;
heldItems[i] = gBattleFrontierHeldItems[gFacilityTrainerMons[monSetId].itemTableId];
monIds[i] = monSetId;
2018-08-26 15:27:06 +02:00
i++;
}
}
2019-12-02 20:49:22 +01:00
static void GenerateOpponentMons(void)
{
u16 trainerId;
s32 i, j, k;
2018-11-11 16:44:27 +01:00
register const u16 *monSets asm("r9"); // Fix me. Compiler insists on moving that variable into stack.
2019-12-02 20:49:22 +01:00
u16 species[FRONTIER_PARTY_SIZE];
u16 heldItems[FRONTIER_PARTY_SIZE];
2018-11-11 16:44:27 +01:00
s32 setsCount = 0;
gFacilityTrainers = gSlateportBattleTentTrainers;
gFacilityTrainerMons = gSlateportBattleTentMons;
while (1)
{
do
{
trainerId = Random() % 30;
2018-10-21 00:06:42 +02:00
for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++)
{
2019-02-07 18:37:28 +01:00
if (gSaveBlock2Ptr->frontier.trainerIds[i] == trainerId)
break;
}
2018-10-21 00:06:42 +02:00
} while (i != gSaveBlock2Ptr->frontier.curChallengeBattleNum);
gTrainerBattleOpponent_A = trainerId;
2018-11-11 16:44:27 +01:00
while (gFacilityTrainers[gTrainerBattleOpponent_A].monSets[setsCount] != 0xFFFF)
setsCount++;
if (setsCount > 8)
break;
2018-11-11 16:44:27 +01:00
setsCount = 0;
}
2018-10-21 00:06:42 +02:00
if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 2)
2019-02-07 18:37:28 +01:00
gSaveBlock2Ptr->frontier.trainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A;
2018-11-11 16:44:27 +01:00
monSets = gFacilityTrainers[gTrainerBattleOpponent_A].monSets;
i = 0;
2019-12-02 20:49:22 +01:00
while (i != FRONTIER_PARTY_SIZE)
{
2018-11-11 16:44:27 +01:00
sRandMonSetId = monSets[Random() % setsCount];
for (j = 0; j < 6; j++)
{
2019-02-07 19:58:09 +01:00
if (gFacilityTrainerMons[sRandMonSetId].species == gFacilityTrainerMons[gSaveBlock2Ptr->frontier.rentalMons[j].monId].species)
break;
}
if (j != 6)
continue;
for (k = 0; k < i; k++)
{
if (species[k] == gFacilityTrainerMons[sRandMonSetId].species)
break;
}
if (k != i)
continue;
for (k = 0; k < i; k++)
{
if (heldItems[k] != 0 && heldItems[k] == gBattleFrontierHeldItems[gFacilityTrainerMons[sRandMonSetId].itemTableId])
break;
}
if (k != i)
continue;
species[i] = gFacilityTrainerMons[sRandMonSetId].species;
heldItems[i] = gBattleFrontierHeldItems[gFacilityTrainerMons[sRandMonSetId].itemTableId];
gUnknown_03006298[i] = sRandMonSetId;
i++;
}
}