summaryrefslogtreecommitdiff
path: root/src/roamer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/roamer.c')
-rw-r--r--src/roamer.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/src/roamer.c b/src/roamer.c
new file mode 100644
index 000000000..b42855644
--- /dev/null
+++ b/src/roamer.c
@@ -0,0 +1,240 @@
+#include "global.h"
+#include "roamer.h"
+#include "random.h"
+#include "overworld.h"
+#include "field_specials.h"
+#include "constants/species.h"
+#include "constants/maps.h"
+#include "constants/region_map.h"
+
+EWRAM_DATA u8 sLocationHistory[3][2] = {};
+EWRAM_DATA u8 sRoamerLocation[2] = {};
+
+#define saveRoamer (*(&gSaveBlock1Ptr->roamer))
+
+enum
+{
+ MAP_GRP = 0, // map group
+ MAP_NUM = 1, // map number
+};
+
+const u8 sRoamerLocations[][7] = {
+ {MAP_NUM(ROUTE1), MAP_NUM(ROUTE2), MAP_NUM(ROUTE21_NORTH), MAP_NUM(ROUTE22), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE2), MAP_NUM(ROUTE1), MAP_NUM(ROUTE3), MAP_NUM(ROUTE22), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE3), MAP_NUM(ROUTE2), MAP_NUM(ROUTE4), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE4), MAP_NUM(ROUTE3), MAP_NUM(ROUTE5), MAP_NUM(ROUTE9), MAP_NUM(ROUTE24), 0xff, 0xff},
+ {MAP_NUM(ROUTE5), MAP_NUM(ROUTE4), MAP_NUM(ROUTE6), MAP_NUM(ROUTE7), MAP_NUM(ROUTE8), MAP_NUM(ROUTE9), MAP_NUM(ROUTE24)},
+ {MAP_NUM(ROUTE6), MAP_NUM(ROUTE5), MAP_NUM(ROUTE7), MAP_NUM(ROUTE8), MAP_NUM(ROUTE11), 0xff, 0xff},
+ {MAP_NUM(ROUTE7), MAP_NUM(ROUTE5), MAP_NUM(ROUTE6), MAP_NUM(ROUTE8), MAP_NUM(ROUTE16), 0xff, 0xff},
+ {MAP_NUM(ROUTE8), MAP_NUM(ROUTE5), MAP_NUM(ROUTE6), MAP_NUM(ROUTE7), MAP_NUM(ROUTE10), MAP_NUM(ROUTE12), 0xff},
+ {MAP_NUM(ROUTE9), MAP_NUM(ROUTE4), MAP_NUM(ROUTE5), MAP_NUM(ROUTE10), MAP_NUM(ROUTE24), 0xff, 0xff},
+ {MAP_NUM(ROUTE10), MAP_NUM(ROUTE8), MAP_NUM(ROUTE9), MAP_NUM(ROUTE12), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE11), MAP_NUM(ROUTE6), MAP_NUM(ROUTE12), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE12), MAP_NUM(ROUTE10), MAP_NUM(ROUTE11), MAP_NUM(ROUTE13), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE13), MAP_NUM(ROUTE12), MAP_NUM(ROUTE14), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE14), MAP_NUM(ROUTE13), MAP_NUM(ROUTE15), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE15), MAP_NUM(ROUTE14), MAP_NUM(ROUTE18), MAP_NUM(ROUTE19), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE16), MAP_NUM(ROUTE7), MAP_NUM(ROUTE17), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE17), MAP_NUM(ROUTE16), MAP_NUM(ROUTE18), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE18), MAP_NUM(ROUTE15), MAP_NUM(ROUTE17), MAP_NUM(ROUTE19), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE19), MAP_NUM(ROUTE15), MAP_NUM(ROUTE18), MAP_NUM(ROUTE20), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE20), MAP_NUM(ROUTE19), MAP_NUM(ROUTE21_NORTH), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE21_NORTH), MAP_NUM(ROUTE1), MAP_NUM(ROUTE20), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE22), MAP_NUM(ROUTE1), MAP_NUM(ROUTE2), MAP_NUM(ROUTE23), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE23), MAP_NUM(ROUTE22), MAP_NUM(ROUTE2), 0xff, 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE24), MAP_NUM(ROUTE4), MAP_NUM(ROUTE5), MAP_NUM(ROUTE9), 0xff, 0xff, 0xff},
+ {MAP_NUM(ROUTE25), MAP_NUM(ROUTE24), MAP_NUM(ROUTE9), 0xff, 0xff, 0xff, 0xff},
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+};
+
+void ClearRoamerData(void)
+{
+ u32 i;
+ gSaveBlock1Ptr->roamer = (struct Roamer){};
+ sRoamerLocation[MAP_GRP] = 0;
+ sRoamerLocation[MAP_NUM] = 0;
+ for (i = 0; i < 3; i++)
+ {
+ sLocationHistory[i][MAP_GRP] = 0;
+ sLocationHistory[i][MAP_NUM] = 0;
+ }
+}
+
+#define GetRoamerSpecies() ({\
+ u16 a;\
+ switch (ScrSpecial_GetStarter())\
+ {\
+ default:\
+ a = SPECIES_RAIKOU;\
+ break;\
+ case SPECIES_BULBASAUR:\
+ a = SPECIES_ENTEI;\
+ break;\
+ case SPECIES_CHARMANDER:\
+ a = SPECIES_SUICUNE;\
+ break;\
+ }\
+ a;\
+})
+
+void CreateInitialRoamerMon(void)
+{
+ struct Pokemon * tmpMon = &gEnemyParty[0];
+ u16 roamerMon;
+
+ CreateMon(tmpMon, (roamerMon = GetRoamerSpecies()), 50, 0x20, 0, 0, 0, 0);
+ saveRoamer.species = roamerMon;
+ saveRoamer.level = 50;
+ saveRoamer.status = 0;
+ saveRoamer.active = TRUE;
+ saveRoamer.ivs = GetMonData(tmpMon, MON_DATA_IVS);
+ saveRoamer.personality = GetMonData(tmpMon, MON_DATA_PERSONALITY);
+ saveRoamer.hp = GetMonData(tmpMon, MON_DATA_MAX_HP);
+ saveRoamer.cool = GetMonData(tmpMon, MON_DATA_COOL);
+ saveRoamer.beauty = GetMonData(tmpMon, MON_DATA_BEAUTY);
+ saveRoamer.cute = GetMonData(tmpMon, MON_DATA_CUTE);
+ saveRoamer.smart = GetMonData(tmpMon, MON_DATA_SMART);
+ saveRoamer.tough = GetMonData(tmpMon, MON_DATA_TOUGH);
+ sRoamerLocation[MAP_GRP] = 3;
+ sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % (ARRAY_COUNT(sRoamerLocations) - 1)][0];
+}
+
+void InitRoamer(void)
+{
+ ClearRoamerData();
+ CreateInitialRoamerMon();
+}
+
+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 mapNum = 0;
+ struct Roamer *roamer = &saveRoamer;
+
+ if (!roamer->active)
+ return;
+
+ sRoamerLocation[MAP_GRP] = 3;
+
+ while (1)
+ {
+ mapNum = sRoamerLocations[Random() % (ARRAY_COUNT(sRoamerLocations) - 1)][0];
+ if (sRoamerLocation[MAP_NUM] != mapNum)
+ {
+ sRoamerLocation[MAP_NUM] = mapNum;
+ return;
+ }
+ }
+}
+
+
+void RoamerMove(void)
+{
+ u8 locSet = 0;
+
+ if ((Random() % 16) == 0)
+ {
+ RoamerMoveToOtherLocationSet();
+ }
+ else
+ {
+ struct Roamer *roamer = &saveRoamer;
+
+ if (!roamer->active)
+ return;
+
+ while (locSet < (ARRAY_COUNT(sRoamerLocations) - 1))
+ {
+ if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0])
+ {
+ u8 mapNum;
+ while (1)
+ {
+ mapNum = sRoamerLocations[locSet][(Random() % 6) + 1];
+ if (!(sLocationHistory[2][MAP_GRP] == 3 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF)
+ break;
+ }
+ sRoamerLocation[MAP_NUM] = mapNum;
+ return;
+ }
+ locSet++;
+ }
+ }
+}
+
+bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
+{
+ struct Roamer *roamer = &saveRoamer;
+
+ 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 = &saveRoamer;
+ 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)
+{
+ saveRoamer.hp = GetMonData(mon, MON_DATA_HP);
+ saveRoamer.status = GetMonData(mon, MON_DATA_STATUS);
+
+ RoamerMoveToOtherLocationSet();
+}
+
+void SetRoamerInactive(void)
+{
+ struct Roamer *roamer = &saveRoamer;
+ roamer->active = FALSE;
+}
+
+void GetRoamerLocation(u8 *mapGroup, u8 *mapNum)
+{
+ *mapGroup = sRoamerLocation[MAP_GRP];
+ *mapNum = sRoamerLocation[MAP_NUM];
+}
+
+u16 GetRoamerLocationMapSectionId(void)
+{
+ struct Roamer *roamer = &saveRoamer;
+ if (!saveRoamer.active)
+ return MAPSEC_NONE;
+ return get_mapheader_by_bank_and_number(sRoamerLocation[MAP_GRP], sRoamerLocation[MAP_NUM])->regionMapSectionId;
+}