Clean up roamer.c
This commit is contained in:
+93
-72
@@ -5,51 +5,74 @@
|
|||||||
#include "roamer.h"
|
#include "roamer.h"
|
||||||
#include "constants/maps.h"
|
#include "constants/maps.h"
|
||||||
|
|
||||||
|
// Despite having a variable to track it, the roamer is
|
||||||
|
// hard-coded to only ever be in map group 0
|
||||||
|
#define ROAMER_MAP_GROUP 0
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAP_GRP = 0, // map group
|
MAP_GRP, // map group
|
||||||
MAP_NUM = 1, // map number
|
MAP_NUM, // map number
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ROAMER (&gSaveBlock1Ptr->roamer)
|
||||||
EWRAM_DATA static u8 sLocationHistory[3][2] = {0};
|
EWRAM_DATA static u8 sLocationHistory[3][2] = {0};
|
||||||
EWRAM_DATA static u8 sRoamerLocation[2] = {0};
|
EWRAM_DATA static u8 sRoamerLocation[2] = {0};
|
||||||
|
|
||||||
|
#define __ MAP_NUM(UNDEFINED) // For empty spots in the location table
|
||||||
|
|
||||||
|
// Note: There are two potential softlocks that can occur with this table if its maps are
|
||||||
|
// changed in particular ways. They can be avoided by ensuring the following:
|
||||||
|
// - There must be at least 2 location sets that start with a different map,
|
||||||
|
// i.e. every location set cannot start with the same map. This is because of
|
||||||
|
// the while loop in RoamerMoveToOtherLocationSet.
|
||||||
|
// - Each location set must have at least 3 unique maps. This is because of
|
||||||
|
// the while loop in RoamerMove. In this loop the first map in the set is
|
||||||
|
// ignored, and an additional map is ignored if the roamer was there recently.
|
||||||
|
// - Additionally, while not a softlock, it's worth noting that if for any
|
||||||
|
// map in the location table there is not a location set that starts with
|
||||||
|
// that map then the roamer will be significantly less likely to move away
|
||||||
|
// from that map when it lands there.
|
||||||
static const u8 sRoamerLocations[][6] =
|
static const u8 sRoamerLocations[][6] =
|
||||||
{
|
{
|
||||||
{ MAP_NUM(ROUTE110), MAP_NUM(ROUTE111), MAP_NUM(ROUTE117), MAP_NUM(ROUTE118), MAP_NUM(ROUTE134), 0xFF },
|
{ MAP_NUM(ROUTE110), MAP_NUM(ROUTE111), MAP_NUM(ROUTE117), MAP_NUM(ROUTE118), MAP_NUM(ROUTE134), __ },
|
||||||
{ MAP_NUM(ROUTE111), MAP_NUM(ROUTE110), MAP_NUM(ROUTE117), MAP_NUM(ROUTE118), 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE111), MAP_NUM(ROUTE110), MAP_NUM(ROUTE117), MAP_NUM(ROUTE118), __, __ },
|
||||||
{ MAP_NUM(ROUTE117), MAP_NUM(ROUTE111), MAP_NUM(ROUTE110), MAP_NUM(ROUTE118), 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE117), MAP_NUM(ROUTE111), MAP_NUM(ROUTE110), MAP_NUM(ROUTE118), __, __ },
|
||||||
{ MAP_NUM(ROUTE118), MAP_NUM(ROUTE117), MAP_NUM(ROUTE110), MAP_NUM(ROUTE111), MAP_NUM(ROUTE119), MAP_NUM(ROUTE123) },
|
{ MAP_NUM(ROUTE118), MAP_NUM(ROUTE117), MAP_NUM(ROUTE110), MAP_NUM(ROUTE111), MAP_NUM(ROUTE119), MAP_NUM(ROUTE123) },
|
||||||
{ MAP_NUM(ROUTE119), MAP_NUM(ROUTE118), MAP_NUM(ROUTE120), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE119), MAP_NUM(ROUTE118), MAP_NUM(ROUTE120), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE120), MAP_NUM(ROUTE119), MAP_NUM(ROUTE121), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE120), MAP_NUM(ROUTE119), MAP_NUM(ROUTE121), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE121), MAP_NUM(ROUTE120), MAP_NUM(ROUTE122), MAP_NUM(ROUTE123), 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE121), MAP_NUM(ROUTE120), MAP_NUM(ROUTE122), MAP_NUM(ROUTE123), __, __ },
|
||||||
{ MAP_NUM(ROUTE122), MAP_NUM(ROUTE121), MAP_NUM(ROUTE123), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE122), MAP_NUM(ROUTE121), MAP_NUM(ROUTE123), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE123), MAP_NUM(ROUTE122), MAP_NUM(ROUTE118), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE123), MAP_NUM(ROUTE122), MAP_NUM(ROUTE118), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE124), MAP_NUM(ROUTE121), MAP_NUM(ROUTE125), MAP_NUM(ROUTE126), 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE124), MAP_NUM(ROUTE121), MAP_NUM(ROUTE125), MAP_NUM(ROUTE126), __, __ },
|
||||||
{ MAP_NUM(ROUTE125), MAP_NUM(ROUTE124), MAP_NUM(ROUTE127), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE125), MAP_NUM(ROUTE124), MAP_NUM(ROUTE127), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE126), MAP_NUM(ROUTE124), MAP_NUM(ROUTE127), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE126), MAP_NUM(ROUTE124), MAP_NUM(ROUTE127), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE127), MAP_NUM(ROUTE125), MAP_NUM(ROUTE126), MAP_NUM(ROUTE128), 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE127), MAP_NUM(ROUTE125), MAP_NUM(ROUTE126), MAP_NUM(ROUTE128), __, __ },
|
||||||
{ MAP_NUM(ROUTE128), MAP_NUM(ROUTE127), MAP_NUM(ROUTE129), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE128), MAP_NUM(ROUTE127), MAP_NUM(ROUTE129), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE129), MAP_NUM(ROUTE128), MAP_NUM(ROUTE130), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE129), MAP_NUM(ROUTE128), MAP_NUM(ROUTE130), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE130), MAP_NUM(ROUTE129), MAP_NUM(ROUTE131), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE130), MAP_NUM(ROUTE129), MAP_NUM(ROUTE131), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE131), MAP_NUM(ROUTE130), MAP_NUM(ROUTE132), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE131), MAP_NUM(ROUTE130), MAP_NUM(ROUTE132), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE132), MAP_NUM(ROUTE131), MAP_NUM(ROUTE133), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE132), MAP_NUM(ROUTE131), MAP_NUM(ROUTE133), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE133), MAP_NUM(ROUTE132), MAP_NUM(ROUTE134), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE133), MAP_NUM(ROUTE132), MAP_NUM(ROUTE134), __, __, __ },
|
||||||
{ MAP_NUM(ROUTE134), MAP_NUM(ROUTE133), MAP_NUM(ROUTE110), 0xFF, 0xFF, 0xFF },
|
{ MAP_NUM(ROUTE134), MAP_NUM(ROUTE133), MAP_NUM(ROUTE110), __, __, __ },
|
||||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
|
{ __, __, __, __, __, __ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef __
|
||||||
|
#define NUM_LOCATION_SETS (ARRAY_COUNT(sRoamerLocations) - 1)
|
||||||
|
#define NUM_LOCATIONS_PER_SET (ARRAY_COUNT(sRoamerLocations[0]))
|
||||||
|
|
||||||
void ClearRoamerData(void)
|
void ClearRoamerData(void)
|
||||||
{
|
{
|
||||||
memset(&gSaveBlock1Ptr->roamer, 0, sizeof(struct Roamer));
|
memset(ROAMER, 0, sizeof(*ROAMER));
|
||||||
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS;
|
ROAMER->species = SPECIES_LATIAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearRoamerLocationData(void)
|
void ClearRoamerLocationData(void)
|
||||||
{
|
{
|
||||||
u8 i;
|
u8 i;
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < ARRAY_COUNT(sLocationHistory); i++)
|
||||||
{
|
{
|
||||||
sLocationHistory[i][MAP_GRP] = 0;
|
sLocationHistory[i][MAP_GRP] = 0;
|
||||||
sLocationHistory[i][MAP_NUM] = 0;
|
sLocationHistory[i][MAP_NUM] = 0;
|
||||||
@@ -62,26 +85,27 @@ void ClearRoamerLocationData(void)
|
|||||||
static void CreateInitialRoamerMon(bool16 createLatios)
|
static void CreateInitialRoamerMon(bool16 createLatios)
|
||||||
{
|
{
|
||||||
if (!createLatios)
|
if (!createLatios)
|
||||||
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS;
|
ROAMER->species = SPECIES_LATIAS;
|
||||||
else
|
else
|
||||||
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIOS;
|
ROAMER->species = SPECIES_LATIOS;
|
||||||
|
|
||||||
CreateMon(&gEnemyParty[0], (&gSaveBlock1Ptr->roamer)->species, 40, 0x20, 0, 0, OT_ID_PLAYER_ID, 0);
|
CreateMon(&gEnemyParty[0], ROAMER->species, 40, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
|
||||||
(&gSaveBlock1Ptr->roamer)->level = 40;
|
ROAMER->level = 40;
|
||||||
(&gSaveBlock1Ptr->roamer)->status = 0;
|
ROAMER->status = 0;
|
||||||
(&gSaveBlock1Ptr->roamer)->active = TRUE;
|
ROAMER->active = TRUE;
|
||||||
(&gSaveBlock1Ptr->roamer)->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS);
|
ROAMER->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS);
|
||||||
(&gSaveBlock1Ptr->roamer)->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY);
|
ROAMER->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY);
|
||||||
(&gSaveBlock1Ptr->roamer)->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP);
|
ROAMER->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP);
|
||||||
(&gSaveBlock1Ptr->roamer)->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL);
|
ROAMER->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL);
|
||||||
(&gSaveBlock1Ptr->roamer)->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY);
|
ROAMER->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY);
|
||||||
(&gSaveBlock1Ptr->roamer)->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE);
|
ROAMER->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE);
|
||||||
(&gSaveBlock1Ptr->roamer)->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART);
|
ROAMER->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART);
|
||||||
(&gSaveBlock1Ptr->roamer)->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH);
|
ROAMER->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH);
|
||||||
sRoamerLocation[MAP_GRP] = 0;
|
sRoamerLocation[MAP_GRP] = ROAMER_MAP_GROUP;
|
||||||
sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % (ARRAY_COUNT(sRoamerLocations) - 1)][0];
|
sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % NUM_LOCATION_SETS][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gSpecialVar_0x8004 here corresponds to the options in the multichoice MULTI_TV_LATI (0 for 'Red', 1 for 'Blue')
|
||||||
void InitRoamer(void)
|
void InitRoamer(void)
|
||||||
{
|
{
|
||||||
ClearRoamerData();
|
ClearRoamerData();
|
||||||
@@ -104,16 +128,17 @@ void UpdateLocationHistoryForRoamer(void)
|
|||||||
void RoamerMoveToOtherLocationSet(void)
|
void RoamerMoveToOtherLocationSet(void)
|
||||||
{
|
{
|
||||||
u8 mapNum = 0;
|
u8 mapNum = 0;
|
||||||
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
|
||||||
|
if (!ROAMER->active)
|
||||||
if (!roamer->active)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sRoamerLocation[MAP_GRP] = 0;
|
sRoamerLocation[MAP_GRP] = ROAMER_MAP_GROUP;
|
||||||
|
|
||||||
|
// Choose a location set that starts with a map
|
||||||
|
// different from the roamer's current map
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
mapNum = sRoamerLocations[Random() % (ARRAY_COUNT(sRoamerLocations) - 1)][0];
|
mapNum = sRoamerLocations[Random() % NUM_LOCATION_SETS][0];
|
||||||
if (sRoamerLocation[MAP_NUM] != mapNum)
|
if (sRoamerLocation[MAP_NUM] != mapNum)
|
||||||
{
|
{
|
||||||
sRoamerLocation[MAP_NUM] = mapNum;
|
sRoamerLocation[MAP_NUM] = mapNum;
|
||||||
@@ -132,20 +157,23 @@ void RoamerMove(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
if (!ROAMER->active)
|
||||||
|
|
||||||
if (!roamer->active)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (locSet < (ARRAY_COUNT(sRoamerLocations) - 1))
|
while (locSet < NUM_LOCATION_SETS)
|
||||||
{
|
{
|
||||||
|
// Find the location set that starts with the roamer's current map
|
||||||
if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0])
|
if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0])
|
||||||
{
|
{
|
||||||
u8 mapNum;
|
u8 mapNum;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
mapNum = sRoamerLocations[locSet][(Random() % 5) + 1];
|
// Choose a new map (excluding the first) within this set
|
||||||
if (!(sLocationHistory[2][MAP_GRP] == 0 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF)
|
// Also exclude a map if the roamer was there 2 moves ago
|
||||||
|
mapNum = sRoamerLocations[locSet][(Random() % (NUM_LOCATIONS_PER_SET - 1)) + 1];
|
||||||
|
if (!(sLocationHistory[2][MAP_GRP] == ROAMER_MAP_GROUP
|
||||||
|
&& sLocationHistory[2][MAP_NUM] == mapNum)
|
||||||
|
&& mapNum != MAP_NUM(UNDEFINED))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sRoamerLocation[MAP_NUM] = mapNum;
|
sRoamerLocation[MAP_NUM] = mapNum;
|
||||||
@@ -158,9 +186,7 @@ void RoamerMove(void)
|
|||||||
|
|
||||||
bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
|
bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
|
||||||
{
|
{
|
||||||
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
if (ROAMER->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM])
|
||||||
|
|
||||||
if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM])
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -168,20 +194,16 @@ bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
|
|||||||
|
|
||||||
void CreateRoamerMonInstance(void)
|
void CreateRoamerMonInstance(void)
|
||||||
{
|
{
|
||||||
struct Pokemon *mon;
|
struct Pokemon *mon = &gEnemyParty[0];
|
||||||
struct Roamer *roamer;
|
|
||||||
|
|
||||||
mon = &gEnemyParty[0];
|
|
||||||
ZeroEnemyPartyMons();
|
ZeroEnemyPartyMons();
|
||||||
roamer = &gSaveBlock1Ptr->roamer;
|
CreateMonWithIVsPersonality(mon, ROAMER->species, ROAMER->level, ROAMER->ivs, ROAMER->personality);
|
||||||
CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality);
|
SetMonData(mon, MON_DATA_STATUS, &ROAMER->status);
|
||||||
SetMonData(mon, MON_DATA_STATUS, &gSaveBlock1Ptr->roamer.status);
|
SetMonData(mon, MON_DATA_HP, &ROAMER->hp);
|
||||||
SetMonData(mon, MON_DATA_HP, &gSaveBlock1Ptr->roamer.hp);
|
SetMonData(mon, MON_DATA_COOL, &ROAMER->cool);
|
||||||
SetMonData(mon, MON_DATA_COOL, &gSaveBlock1Ptr->roamer.cool);
|
SetMonData(mon, MON_DATA_BEAUTY, &ROAMER->beauty);
|
||||||
SetMonData(mon, MON_DATA_BEAUTY, &gSaveBlock1Ptr->roamer.beauty);
|
SetMonData(mon, MON_DATA_CUTE, &ROAMER->cute);
|
||||||
SetMonData(mon, MON_DATA_CUTE, &gSaveBlock1Ptr->roamer.cute);
|
SetMonData(mon, MON_DATA_SMART, &ROAMER->smart);
|
||||||
SetMonData(mon, MON_DATA_SMART, &gSaveBlock1Ptr->roamer.smart);
|
SetMonData(mon, MON_DATA_TOUGH, &ROAMER->tough);
|
||||||
SetMonData(mon, MON_DATA_TOUGH, &gSaveBlock1Ptr->roamer.tough);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8 TryStartRoamerEncounter(void)
|
bool8 TryStartRoamerEncounter(void)
|
||||||
@@ -199,16 +221,15 @@ bool8 TryStartRoamerEncounter(void)
|
|||||||
|
|
||||||
void UpdateRoamerHPStatus(struct Pokemon *mon)
|
void UpdateRoamerHPStatus(struct Pokemon *mon)
|
||||||
{
|
{
|
||||||
(&gSaveBlock1Ptr->roamer)->hp = GetMonData(mon, MON_DATA_HP);
|
ROAMER->hp = GetMonData(mon, MON_DATA_HP);
|
||||||
(&gSaveBlock1Ptr->roamer)->status = GetMonData(mon, MON_DATA_STATUS);
|
ROAMER->status = GetMonData(mon, MON_DATA_STATUS);
|
||||||
|
|
||||||
RoamerMoveToOtherLocationSet();
|
RoamerMoveToOtherLocationSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRoamerInactive(void)
|
void SetRoamerInactive(void)
|
||||||
{
|
{
|
||||||
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
ROAMER->active = FALSE;
|
||||||
roamer->active = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetRoamerLocation(u8 *mapGroup, u8 *mapNum)
|
void GetRoamerLocation(u8 *mapGroup, u8 *mapNum)
|
||||||
|
|||||||
Reference in New Issue
Block a user