mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-17 12:07:38 +01:00
219 lines
6.3 KiB
C
219 lines
6.3 KiB
C
|
#include "global.h"
|
||
|
#include "roamer.h"
|
||
|
#include "pokemon.h"
|
||
|
#include "rng.h"
|
||
|
#include "species.h"
|
||
|
#include "event_data.h"
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
MAP_GRP = 0, // map group
|
||
|
MAP_NUM = 1, // map number
|
||
|
};
|
||
|
|
||
|
EWRAM_DATA static u8 sLocationHistory[3][2] = {0};
|
||
|
EWRAM_DATA static u8 sRoamerLocation[2] = {0};
|
||
|
|
||
|
static const u8 sRoamerLocations[][6] =
|
||
|
{
|
||
|
{ 0x19, 0x1A, 0x20, 0x21, 0x31, 0xFF },
|
||
|
{ 0x1A, 0x19, 0x20, 0x21, 0xFF, 0xFF },
|
||
|
{ 0x20, 0x1A, 0x19, 0x21, 0xFF, 0xFF },
|
||
|
{ 0x21, 0x20, 0x19, 0x1A, 0x22, 0x26 },
|
||
|
{ 0x22, 0x21, 0x23, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x23, 0x22, 0x24, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x24, 0x23, 0x25, 0x26, 0xFF, 0xFF },
|
||
|
{ 0x25, 0x24, 0x26, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x26, 0x25, 0x21, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x27, 0x24, 0x28, 0x29, 0xFF, 0xFF },
|
||
|
{ 0x28, 0x27, 0x2A, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x29, 0x27, 0x2A, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x2A, 0x28, 0x29, 0x2B, 0xFF, 0xFF },
|
||
|
{ 0x2B, 0x2A, 0x2C, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x2C, 0x2B, 0x2D, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x2D, 0x2C, 0x2E, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x2E, 0x2D, 0x2F, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x2F, 0x2E, 0x30, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x30, 0x2F, 0x31, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0x31, 0x30, 0x19, 0xFF, 0xFF, 0xFF },
|
||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
|
||
|
};
|
||
|
|
||
|
void ClearRoamerData(void)
|
||
|
{
|
||
|
memset(&gSaveBlock1Ptr->roamer, 0, sizeof(struct Roamer));
|
||
|
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS;
|
||
|
}
|
||
|
|
||
|
void ClearRoamerLocationData(void)
|
||
|
{
|
||
|
u8 i;
|
||
|
|
||
|
for (i = 0; i < 3; i++)
|
||
|
{
|
||
|
sLocationHistory[i][MAP_GRP] = 0;
|
||
|
sLocationHistory[i][MAP_NUM] = 0;
|
||
|
}
|
||
|
|
||
|
sRoamerLocation[MAP_GRP] = 0;
|
||
|
sRoamerLocation[MAP_NUM] = 0;
|
||
|
}
|
||
|
|
||
|
static void CreateInitialRoamerMon(bool16 createLatios)
|
||
|
{
|
||
|
if (!createLatios)
|
||
|
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS;
|
||
|
else
|
||
|
(&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIOS;
|
||
|
|
||
|
CreateMon(&gEnemyParty[0], (&gSaveBlock1Ptr->roamer)->species, 40, 0x20, 0, 0, 0, 0);
|
||
|
(&gSaveBlock1Ptr->roamer)->level = 40;
|
||
|
(&gSaveBlock1Ptr->roamer)->status = 0;
|
||
|
(&gSaveBlock1Ptr->roamer)->active = TRUE;
|
||
|
(&gSaveBlock1Ptr->roamer)->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS);
|
||
|
(&gSaveBlock1Ptr->roamer)->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY);
|
||
|
(&gSaveBlock1Ptr->roamer)->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP);
|
||
|
(&gSaveBlock1Ptr->roamer)->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL);
|
||
|
(&gSaveBlock1Ptr->roamer)->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY);
|
||
|
(&gSaveBlock1Ptr->roamer)->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE);
|
||
|
(&gSaveBlock1Ptr->roamer)->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART);
|
||
|
(&gSaveBlock1Ptr->roamer)->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH);
|
||
|
sRoamerLocation[MAP_GRP] = 0;
|
||
|
sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % 20][0];
|
||
|
}
|
||
|
|
||
|
void InitRoamer(void)
|
||
|
{
|
||
|
ClearRoamerData();
|
||
|
ClearRoamerLocationData();
|
||
|
CreateInitialRoamerMon(gSpecialVar_0x8004);
|
||
|
}
|
||
|
|
||
|
void UpdateLocationHistoryForRoamer(void)
|
||
|
{
|
||
|
sLocationHistory[2][MAP_GRP] = sLocationHistory[1][MAP_GRP];
|
||
|
sLocationHistory[2][MAP_NUM] = sLocationHistory[1][MAP_NUM];
|
||
|
|
||
|
sLocationHistory[1][MAP_GRP] = sLocationHistory[0][MAP_GRP];
|
||
|
sLocationHistory[1][MAP_NUM] = sLocationHistory[0][MAP_NUM];
|
||
|
|
||
|
sLocationHistory[0][MAP_GRP] = gSaveBlock1Ptr->location.mapGroup;
|
||
|
sLocationHistory[0][MAP_NUM] = gSaveBlock1Ptr->location.mapNum;
|
||
|
}
|
||
|
|
||
|
void RoamerMoveToOtherLocationSet(void)
|
||
|
{
|
||
|
u8 val = 0;
|
||
|
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
||
|
|
||
|
if (!roamer->active)
|
||
|
return;
|
||
|
|
||
|
sRoamerLocation[MAP_GRP] = val;
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
val = sRoamerLocations[Random() % 20][0];
|
||
|
if (sRoamerLocation[MAP_NUM] != val)
|
||
|
{
|
||
|
sRoamerLocation[MAP_NUM] = val;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void RoamerMove(void)
|
||
|
{
|
||
|
u8 locSet = 0;
|
||
|
|
||
|
if ((Random() % 16) == 0)
|
||
|
{
|
||
|
RoamerMoveToOtherLocationSet();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
||
|
|
||
|
if (!roamer->active)
|
||
|
return;
|
||
|
|
||
|
while (locSet < 20)
|
||
|
{
|
||
|
if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0])
|
||
|
{
|
||
|
u8 mapNum;
|
||
|
while (1)
|
||
|
{
|
||
|
mapNum = sRoamerLocations[locSet][(Random() % 5) + 1];
|
||
|
if (!(sLocationHistory[2][MAP_GRP] == 0 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF)
|
||
|
break;
|
||
|
}
|
||
|
sRoamerLocation[MAP_NUM] = mapNum;
|
||
|
return;
|
||
|
}
|
||
|
locSet++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
|
||
|
{
|
||
|
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
||
|
|
||
|
if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM])
|
||
|
return TRUE;
|
||
|
else
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void CreateRoamerMonInstance(void)
|
||
|
{
|
||
|
struct Pokemon *mon;
|
||
|
struct Roamer *roamer;
|
||
|
|
||
|
mon = &gEnemyParty[0];
|
||
|
ZeroEnemyPartyMons();
|
||
|
roamer = &gSaveBlock1Ptr->roamer;
|
||
|
CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality);
|
||
|
SetMonData(mon, MON_DATA_STATUS, &gSaveBlock1Ptr->roamer.status);
|
||
|
SetMonData(mon, MON_DATA_HP, &gSaveBlock1Ptr->roamer.hp);
|
||
|
SetMonData(mon, MON_DATA_COOL, &gSaveBlock1Ptr->roamer.cool);
|
||
|
SetMonData(mon, MON_DATA_BEAUTY, &gSaveBlock1Ptr->roamer.beauty);
|
||
|
SetMonData(mon, MON_DATA_CUTE, &gSaveBlock1Ptr->roamer.cute);
|
||
|
SetMonData(mon, MON_DATA_SMART, &gSaveBlock1Ptr->roamer.smart);
|
||
|
SetMonData(mon, MON_DATA_TOUGH, &gSaveBlock1Ptr->roamer.tough);
|
||
|
}
|
||
|
|
||
|
bool8 TryStartRoamerEncounter(void)
|
||
|
{
|
||
|
if (IsRoamerAt(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum) == TRUE && (Random() % 4) == 0)
|
||
|
{
|
||
|
CreateRoamerMonInstance();
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UpdateRoamerHPStatus(struct Pokemon *mon)
|
||
|
{
|
||
|
(&gSaveBlock1Ptr->roamer)->hp = GetMonData(mon, MON_DATA_HP);
|
||
|
(&gSaveBlock1Ptr->roamer)->status = GetMonData(mon, MON_DATA_STATUS);
|
||
|
|
||
|
RoamerMoveToOtherLocationSet();
|
||
|
}
|
||
|
|
||
|
void SetRoamerInactive(void)
|
||
|
{
|
||
|
struct Roamer *roamer = &gSaveBlock1Ptr->roamer;
|
||
|
roamer->active = FALSE;
|
||
|
}
|
||
|
|
||
|
void GetRoamerLocation(u8 *mapGroup, u8 *mapNum)
|
||
|
{
|
||
|
*mapGroup = sRoamerLocation[MAP_GRP];
|
||
|
*mapNum = sRoamerLocation[MAP_NUM];
|
||
|
}
|