diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/new_game.c | 5 | ||||
-rw-r--r-- | src/roamer.c | 226 | ||||
-rw-r--r-- | src/rom4.c | 13 | ||||
-rw-r--r-- | src/wild_encounter.c | 9 |
4 files changed, 241 insertions, 12 deletions
diff --git a/src/new_game.c b/src/new_game.c index e058280af..3b93d37cc 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -9,6 +9,7 @@ #include "pokedex.h" #include "pokemon_size_record.h" #include "rng.h" +#include "roamer.h" #include "rom4.h" #include "rtc.h" #include "script.h" @@ -135,8 +136,8 @@ void NewGameInitData(void) gPlayerPartyCount = 0; ZeroPlayerPartyMons(); sub_80961D8(); - sub_81341F8(); - sub_813420C(); + ClearRoamerData(); + ClearRoamerLocationData(); gSaveBlock1.registeredItem = 0; sub_80A3714(); NewGameInitPCItems(); diff --git a/src/roamer.c b/src/roamer.c new file mode 100644 index 000000000..394f81c75 --- /dev/null +++ b/src/roamer.c @@ -0,0 +1,226 @@ +#include "global.h" +#include "pokemon.h" +#include "rng.h" +#include "roamer.h" +#include "species.h" + +#ifdef SAPPHIRE +#define ROAMER_SPECIES SPECIES_LATIAS +#else +#define ROAMER_SPECIES SPECIES_LATIOS +#endif + +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(&gSaveBlock1.roamer, 0, sizeof(gSaveBlock1.roamer)); +} + +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; +} + +void CreateInitialRoamerMon(void) +{ + struct Roamer *roamer; + CreateMon(&gEnemyParty[0], ROAMER_SPECIES, 40, 0x20, 0, 0, 0, 0); + roamer = &gSaveBlock1.roamer; + roamer->species = ROAMER_SPECIES; + roamer->level = 40; + roamer->status = 0; + roamer->active = TRUE; + roamer->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS); + roamer->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY); + roamer->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP); + roamer->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL); + roamer->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY); + roamer->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE); + roamer->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART); + 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(); +} + +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] = gSaveBlock1.location.mapGroup; + sLocationHistory[0][MAP_NUM] = gSaveBlock1.location.mapNum; +} + +void RoamerMoveToOtherLocationSet(void) +{ + u8 val = 0; + struct Roamer *roamer = &gSaveBlock1.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 = &gSaveBlock1.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 = &gSaveBlock1.roamer; + + if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM]) + return TRUE; + else + return FALSE; +} + +void CreateRoamerMonInstance(void) +{ + struct Pokemon *mon = &gEnemyParty[0]; + struct Roamer *roamer = &gSaveBlock1.roamer; + CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality); + SetMonData(mon, MON_DATA_STATUS, (u8 *)&roamer->status); + SetMonData(mon, MON_DATA_HP, (u8 *)&roamer->hp); + SetMonData(mon, MON_DATA_COOL, (u8 *)&roamer->cool); + SetMonData(mon, MON_DATA_BEAUTY, (u8 *)&roamer->beauty); + SetMonData(mon, MON_DATA_CUTE, (u8 *)&roamer->cute); + SetMonData(mon, MON_DATA_SMART, (u8 *)&roamer->smart); + SetMonData(mon, MON_DATA_TOUGH, (u8 *)&roamer->tough); +} + +bool8 TryStartRoamerEncounter(void) +{ + if (IsRoamerAt(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum) == TRUE && (Random() % 4) == 0) + { + CreateRoamerMonInstance(); + return TRUE; + } + else + { + return FALSE; + } +} + +void UpdateRoamerHPStatus(struct Pokemon *mon) +{ + struct Roamer *roamer; + u16 hp; + u8 status; + + hp = GetMonData(mon, MON_DATA_HP); + + roamer = &gSaveBlock1.roamer; + roamer->hp = hp; + + status = GetMonData(mon, MON_DATA_STATUS); + + roamer->status = status; + + RoamerMoveToOtherLocationSet(); +} + +void SetRoamerInactive(void) +{ + struct Roamer *roamer = &gSaveBlock1.roamer; + roamer->active = FALSE; +} + +void GetRoamerLocation(u8 *mapGroup, u8 *mapNum) +{ + *mapGroup = sRoamerLocation[MAP_GRP]; + *mapNum = sRoamerLocation[MAP_NUM]; +} diff --git a/src/rom4.c b/src/rom4.c index 39c182731..5beb698ab 100644 --- a/src/rom4.c +++ b/src/rom4.c @@ -25,6 +25,7 @@ #include "palette.h" #include "play_time.h" #include "rng.h" +#include "roamer.h" #include "safari_zone.h" #include "script.h" #include "script_pokemon_80C4.h" @@ -164,8 +165,8 @@ void sub_805308C(void) FlagReset(SYS_SAFARI_MODE); sub_8054164(); ResetCyclingRoadChallengeData(); - mapnumbers_history_shift_sav1_0_2_4_out(); - sub_8134348(); + UpdateLocationHistoryForRoamer(); + RoamerMoveToOtherLocationSet(); } void ResetGameStats(void) @@ -531,8 +532,8 @@ void sub_80538F0(u8 mapGroup, u8 mapNum) sub_807D874(i); sub_8072ED0(); - mapnumbers_history_shift_sav1_0_2_4_out(); - sub_8134394(); + UpdateLocationHistoryForRoamer(); + RoamerMove(); DoCurrentWeather(); ResetFieldTasksArgs(); mapheader_run_script_with_tag_x5(); @@ -561,8 +562,8 @@ void sub_8053994(u32 a1) sub_8053C98(); sav1_reset_battle_music_maybe(); mapheader_run_script_with_tag_x3(); - mapnumbers_history_shift_sav1_0_2_4_out(); - sub_8134348(); + UpdateLocationHistoryForRoamer(); + RoamerMoveToOtherLocationSet(); not_trainer_hill_battle_pyramid(); if (a1 != 1 && v3) { diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 408dc69ce..9dfcf0e5c 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -7,6 +7,7 @@ #include "field_player_avatar.h" #include "metatile_behavior.h" #include "rng.h" +#include "roamer.h" #include "rom4.h" #include "safari_zone.h" #include "script.h" @@ -3323,7 +3324,7 @@ bool8 StandardWildEncounter(u16 a, u16 b) if (DoWildEncounterTest(gWildMonHeaders[headerNum].landMonsInfo->encounterRate, 0) == TRUE) { - if (sub_81344CC() == TRUE) + if (TryStartRoamerEncounter() == TRUE) { roamer = &gSaveBlock1.roamer; if (RepelCheck(roamer->level)) @@ -3357,7 +3358,7 @@ bool8 StandardWildEncounter(u16 a, u16 b) if (DoWildEncounterTest(gWildMonHeaders[headerNum].waterMonsInfo->encounterRate, 0) == TRUE) { - if (sub_81344CC() == TRUE) + if (TryStartRoamerEncounter() == TRUE) { roamer = &gSaveBlock1.roamer; if (RepelCheck(roamer->level)) @@ -3425,7 +3426,7 @@ bool8 SweetScentWildEncounter(void) wildPokemonInfo = gWildMonHeaders[headerNum].landMonsInfo; if (wildPokemonInfo == NULL) return FALSE; - if (sub_81344CC() == TRUE) + if (TryStartRoamerEncounter() == TRUE) { StartBattle_Roamer(); return TRUE; @@ -3442,7 +3443,7 @@ bool8 SweetScentWildEncounter(void) wildPokemonInfo = gWildMonHeaders[headerNum].waterMonsInfo; if (wildPokemonInfo == NULL) return FALSE; - if (sub_81344CC() == TRUE) + if (TryStartRoamerEncounter() == TRUE) { StartBattle_Roamer(); return TRUE; |