Finish documenting special_encounter

Documents the last unknown components of SpecialEncounter. Also some other things, sorry.
This commit is contained in:
TheSylphIsIn 2025-02-04 16:52:48 -05:00
parent 838f47a434
commit 5cfa8894af
53 changed files with 1029 additions and 1026 deletions

View File

@ -145,7 +145,7 @@ When calculating the encounter rate for fishing encounters the abilities Sticky
Hold and Suction Cups are supposed to double the encounter rate. However, due to
a typo, the encounter rate stays unmodified.
**Fix:** Edit the routine `ModifyEncounterRateWithFieldParams` in [`src/overlay006/ov6_02240C9C.c`](https://github.com/pret/pokeplatinum/blob/4fb8a8f567ebbfc99a1d7f2e5f1e8edd9beb4aa7/src/overlay006/ov6_02240C9C.c#L1390)
**Fix:** Edit the routine `ModifyEncounterRateWithFieldParams` in [`src/overlay006/wild_encounters.c`](https://github.com/pret/pokeplatinum/blob/4fb8a8f567ebbfc99a1d7f2e5f1e8edd9beb4aa7/src/overlay006/wild_encounters.c#L1390)
```diff
- v0 * 2; // BUG: Abilities do not Increase Fishing Encounter Rate (see docs/bugs_and_glitches.md)

View File

@ -2,8 +2,8 @@
#define POKEPLATINUM_FIELD_SYSTEM_SUB3_H
typedef struct {
u16 unk_00;
u16 unk_02;
u16 encounterAttempts;
u16 wildMonDefeated;
} FieldSystem_sub3;
#endif // POKEPLATINUM_FIELD_SYSTEM_SUB3_H

View File

@ -1,19 +0,0 @@
#ifndef POKEPLATINUM_OV6_02240C9C_H
#define POKEPLATINUM_OV6_02240C9C_H
#include "field/field_system_decl.h"
#include "overlay006/wild_encounters.h"
#include "field_battle_data_transfer.h"
#include "field_task.h"
void WildEncounters_ReplaceTimedEncounters(const WildEncounters *encounterData, int *param1, int *param2);
BOOL WildEncounter_TryWildEncounter(FieldSystem *fieldSystem);
BOOL WildEncounter_TryFishingEncounter(FieldSystem *fieldSystem, const int param1, FieldBattleDTO **param2);
BOOL ov6_022411C8(FieldSystem *fieldSystem, FieldTask *param1);
BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **param1);
void CreateWildMon_HoneyTree(FieldSystem *fieldSystem, FieldBattleDTO *param1);
void CreateWildMon_Scripted(FieldSystem *fieldSystem, u16 param1, u8 param2, FieldBattleDTO *param3);
BOOL WildEncounter_TileHasEncounterRate(FieldSystem *fieldSystem, u8 param1);
#endif // POKEPLATINUM_OV6_02240C9C_H

View File

@ -1,15 +0,0 @@
#ifndef POKEPLATINUM_OV6_022430C4_H
#define POKEPLATINUM_OV6_022430C4_H
#include "struct_defs/struct_020698E4.h"
#include "field/field_system_decl.h"
int ov6_022430C4(FieldSystem *fieldSystem);
int ov6_022430E8(FieldSystem *fieldSystem, const u8 param1);
int ov6_02243114(FieldSystem *fieldSystem, const u8 param1);
int ov6_02243140(FieldSystem *fieldSystem);
int GetRadarSpecies(FieldSystem *fieldSystem);
void ov6_02243160(UnkStruct_020698E4 *param0);
#endif // POKEPLATINUM_OV6_022430C4_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_OV6_02246034_H
#define POKEPLATINUM_OV6_02246034_H
#include "field/field_system_decl.h"
#include "field_battle_data_transfer.h"
void ov6_02246034(FieldSystem *fieldSystem, FieldBattleDTO *param1);
#endif // POKEPLATINUM_OV6_02246034_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_OV6_02246B74_H
#define POKEPLATINUM_OV6_02246B74_H
int ov6_02246B74(const int param0, const BOOL param1);
#endif // POKEPLATINUM_OV6_02246B74_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_OV6_02246BF4_H
#define POKEPLATINUM_OV6_02246BF4_H
#include "field/field_system_decl.h"
#include "savedata.h"
BOOL ov6_02246BF4(SaveData *param0, FieldSystem *fieldSystem);
#endif // POKEPLATINUM_OV6_02246BF4_H

View File

@ -0,0 +1,15 @@
#ifndef POKEPLATINUM_RADAR_CHAIN_RECORDS_H
#define POKEPLATINUM_RADAR_CHAIN_RECORDS_H
#include "struct_defs/radar_chain_records.h"
#include "field/field_system_decl.h"
int RadarChainRecords_GetNumFilledSlots(FieldSystem *fieldSystem);
int RadarChainRecords_GetSpecies(FieldSystem *fieldSystem, const u8 slot);
int RadarChainRecords_GetChainCount(FieldSystem *fieldSystem, const u8 slot);
int RadarChainRecords_GetActiveChain(FieldSystem *fieldSystem);
int GetRadarSpecies(FieldSystem *fieldSystem);
void RadarChainRecords_SortSavedRecords(RadarChainRecords *recordsData);
#endif // POKEPLATINUM_RADAR_CHAIN_RECORDS_H

View File

@ -0,0 +1,10 @@
#ifndef POKEPLATINUM_REPEL_STEP_UPDATE_H
#define POKEPLATINUM_REPEL_STEP_UPDATE_H
#include "field/field_system_decl.h"
#include "savedata.h"
BOOL Repel_UpdateSteps(SaveData *sDat, FieldSystem *fieldSystem);
#endif // POKEPLATINUM_REPEL_STEP_UPDATE_H

View File

@ -0,0 +1,10 @@
#ifndef POKEPLATINUM_ROAMER_AFTER_BATTLE_H
#define POKEPLATINUM_ROAMER_AFTER_BATTLE_H
#include "field/field_system_decl.h"
#include "field_battle_data_transfer.h"
void RoamerAfterBattle_UpdateRoamers(FieldSystem *fieldSystem, FieldBattleDTO *battleParams);
#endif // POKEPLATINUM_ROAMER_AFTER_BATTLE_H

View File

@ -0,0 +1,6 @@
#ifndef POKEPLATINUM_SPECIAL_DATES_H
#define POKEPLATINUM_SPECIAL_DATES_H
int SpecialDates_ModifyEncounterRate(const int encounterModifier, const BOOL hasTimePenalty);
#endif // POKEPLATINUM_SPECIAL_DATES_H

View File

@ -1,9 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_OV6_022430E8_H
#define POKEPLATINUM_STRUCT_OV6_022430E8_H
typedef struct {
u16 unk_00;
u16 unk_02;
} UnkStruct_ov6_022430E8;
#endif // POKEPLATINUM_STRUCT_OV6_022430E8_H

View File

@ -1,9 +1,9 @@
#ifndef POKEPLATINUM_OV6_02243218_H
#define POKEPLATINUM_OV6_02243218_H
#ifndef POKEPLATINUM_SWARM_H
#define POKEPLATINUM_SWARM_H
#define NUM_SWARMS 22
u32 Swarm_GetMapId(const u32 swarm);
void Swarm_GetMapIdAndSpecies(const u32 swarm, u16 *mapIdDest, u16 *speciesDest);
#endif // POKEPLATINUM_OV6_02243218_H
#endif // POKEPLATINUM_SWARM_H

View File

@ -4,6 +4,6 @@
#include "savedata.h"
void TrophyGarden_AddNewMon(SaveData *saveData);
int TrophyGarden_GetSlot1Species(SaveData *param0);
int TrophyGarden_GetSlot1Species(SaveData *saveData);
#endif // POKEPLATINUM_OV6_022475B0_H

View File

@ -3,6 +3,8 @@
#include "constants/wild_encounters.h"
#include "field/field_system_decl.h"
typedef struct GrassEncounter {
s8 level;
u8 padding_01[3];
@ -46,4 +48,16 @@ typedef struct WildEncounters {
WaterEncounters superRodEncounters;
} WildEncounters;
#include "field_battle_data_transfer.h"
#include "field_task.h"
void WildEncounters_ReplaceTimedEncounters(const WildEncounters *encounterData, int *param1, int *param2);
BOOL WildEncounters_TryWildEncounter(FieldSystem *fieldSystem);
BOOL WildEncounters_TryFishingEncounter(FieldSystem *fieldSystem, const int param1, FieldBattleDTO **param2);
BOOL WildEncounters_TrySweetScentEncounter(FieldSystem *fieldSystem, FieldTask *param1);
BOOL WildEncounters_TryMudEncounter(FieldSystem *fieldSystem, FieldBattleDTO **param1);
void CreateWildMon_HoneyTree(FieldSystem *fieldSystem, FieldBattleDTO *param1);
void CreateWildMon_Scripted(FieldSystem *fieldSystem, u16 param1, u8 param2, FieldBattleDTO *param3);
BOOL WildEncounters_TileHasEncounterRate(FieldSystem *fieldSystem, u8 param1);
#endif // POKEPLATINUM_WILD_ENCOUNTERS_H

View File

@ -1,16 +1,16 @@
#ifndef POKEPLATINUM_ROAMING_POKEMON_H
#define POKEPLATINUM_ROAMING_POKEMON_H
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/special_encounter.h"
#include "savedata.h"
void sub_0206C33C(SpecialEncounter *param0, const u8 param1);
void sub_0206C354(SpecialEncounter *param0);
void sub_0206C37C(SpecialEncounter *param0);
int RoamingPokemon_GetRouteFromId(const u8 param0);
BOOL sub_0206C3E0(SpecialEncounter *param0);
void sub_0206C404(SpecialEncounter *param0, const int param1);
void RoamingPokemon_MoveToRandomMap(SpecialEncounter *speEnc, const u8 roamerSlot);
void RoamingPokemon_RandomizeAllLocations(SpecialEncounter *speEnc);
void RoamingPokemon_MoveAllLocations(SpecialEncounter *speEnc);
int RoamingPokemon_GetRouteFromId(const u8 id);
BOOL RoamingPokemon_AnyRoamersActive(SpecialEncounter *speEnc);
void RoamingPokemon_UpdatePlayerRecentRoutes(SpecialEncounter *speEnc, const int newMap);
void RoamingPokemon_ActivateSlot(SaveData *saveData, const u8 speciesID);
#endif // POKEPLATINUM_ROAMING_POKEMON_H

View File

@ -1,9 +1,8 @@
#ifndef POKEPLATINUM_UNK_0202D7A8_H
#define POKEPLATINUM_UNK_0202D7A8_H
#ifndef POKEPLATINUM_SPECIAL_ENCOUNTER_H
#define POKEPLATINUM_SPECIAL_ENCOUNTER_H
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/struct_020698E4.h"
#include "struct_defs/struct_0206C638.h"
#include "struct_defs/radar_chain_records.h"
#include "struct_defs/special_encounter.h"
#include "savedata.h"
@ -15,6 +14,7 @@
#define TROPHY_GARDEN_SLOT_NONE 0xFFFF
// for Roamer_Get/SetData
#define ROAMER_DATA_MAP_ID 1
#define ROAMER_DATA_IVS 2
#define ROAMER_DATA_PERSONALITY 3
#define ROAMER_DATA_SPECIES 4
@ -24,23 +24,23 @@
#define ROAMER_DATA_ACTIVE 8
int SpecialEncounter_SaveSize(void);
void SpecialEncounter_Init(SpecialEncounter *param0);
void SpecialEncounter_Init(SpecialEncounter *speEnc);
void SpecialEncounter_SetMixedRecordDailies(SpecialEncounter *speEnc, const u32 mixedRecord);
u32 SpecialEncounter_GetDailyMon(SpecialEncounter *param0, const u8 dailyType);
UnkStruct_020698E4 *sub_0202D830(SpecialEncounter *param0);
SpecialEncounter *SaveData_GetSpecialEncounters(SaveData *param0);
HoneyTreeData *SpecialEncounter_GetHoneyTreeData(SpecialEncounter *param0);
RadarChainRecords *SpecialEncounter_GetRadarChainRecords(SpecialEncounter *speEnc);
SpecialEncounter *SaveData_GetSpecialEncounters(SaveData *sDat);
HoneyTreeData *SpecialEncounter_GetHoneyTreeData(SpecialEncounter *speEnc);
const int SpecialEncounter_GetLastSlatheredTreeId(HoneyTreeData *treeDat);
void SpecialEncounter_SetLastSlatheredTreeId(const u8 treeId, HoneyTreeData *treeDat);
HoneyTree *SpecialEncounter_GetHoneyTree(const u8 param0, HoneyTreeData *param1);
void SpecialEncounter_DecrementHoneyTreeTimers(SaveData *param0, const int param1);
void SpecialEncounter_EnableSwarms(SaveData *param0);
u8 SpecialEncounter_IsSwarmEnabled(SpecialEncounter *param0);
void sub_0202D8A4(SpecialEncounter *param0, const int param1);
int sub_0202D8BC(SpecialEncounter *param0);
u8 SpecialEncounter_GetRoamerRouteIndex(SpecialEncounter *param0, const u8 param1);
void SpecialEncounter_SetRoamerRouteIndex(SpecialEncounter *param0, const u8 param1, const u8 param2);
u8 SpecialEncounter_IsRoamerActive(SpecialEncounter *param0, const u8 param1);
u8 SpecialEncounter_IsSwarmEnabled(SpecialEncounter *speEnc);
void SpecialEncounter_UpdateRecentRoutes(SpecialEncounter *speEnc, const int param1);
int SpecialEncounter_GetPlayerPreviousMap(SpecialEncounter *speEnc);
u8 SpecialEncounter_GetRoamerRouteIndex(SpecialEncounter *speEnc, const u8 param1);
void SpecialEncounter_SetRoamerRouteIndex(SpecialEncounter *speEnc, const u8 param1, const u8 param2);
u8 SpecialEncounter_IsRoamerActive(SpecialEncounter *speEnc, const u8 param1);
void SpecialEncounter_ZeroRoamerData(Roamer **param0);
Roamer *SpecialEncounter_GetRoamer(SpecialEncounter *speEnc, const u8 slot);
u32 Roamer_GetData(const Roamer *param0, const u8 param1);
@ -53,4 +53,4 @@ u8 SpecialEncounter_GetFluteFactor(SpecialEncounter *param0);
void SpecialEncounter_GetTrophyGardenMons(SaveData *saveData, u16 *slot1, u16 *slot2);
void TrophyGarden_ShiftSlotsForNewMon(SaveData *saveData, const u16 newMon);
#endif // POKEPLATINUM_UNK_0202D7A8_H
#endif // POKEPLATINUM_SPECIAL_ENCOUNTER_H

View File

@ -0,0 +1,15 @@
#ifndef POKEPLATINUM_STRUCT_RADAR_CHAIN_RECORDS_H
#define POKEPLATINUM_STRUCT_RADAR_CHAIN_RECORDS_H
#define NUM_RADAR_RECORDS 3
typedef struct ChainRecord {
u16 species;
u16 chainCount;
} ChainRecord;
typedef struct RadarChainRecords {
ChainRecord records[NUM_RADAR_RECORDS];
} RadarChainRecords;
#endif // POKEPLATINUM_STRUCT_RADAR_CHAIN_RECORDS_H

View File

@ -1,9 +1,7 @@
#ifndef POKEPLATINUM_STRUCT_0202D7B0_H
#define POKEPLATINUM_STRUCT_0202D7B0_H
#ifndef POKEPLATINUM_STRUCT_SPECIAL_ENCOUNTER_H
#define POKEPLATINUM_STRUCT_SPECIAL_ENCOUNTER_H
#include "struct_defs/struct_0202D7B0_sub2.h"
#include "struct_defs/struct_020698E4.h"
#include "struct_defs/struct_0206C638.h"
#include "struct_defs/radar_chain_records.h"
#include "field/field_system.h"
@ -38,13 +36,29 @@ typedef struct {
HoneyTree honeyTrees[NUM_HONEY_TREES];
} HoneyTreeData;
typedef struct {
int currentMapId;
u32 ivs;
u32 personality;
u16 species;
u16 currentHP;
u8 level;
u8 status;
u8 active;
} Roamer;
typedef struct PlayerRecentRoutes {
int currentMapId;
int previousMapId;
} PlayerRecentRoutes;
typedef struct SpecialEncounter {
int marshDaily; // random number, index of the mon is derived from this in ReplaceGreatMarshDailyEncounters
int swarmDaily; // random number, % NUM_SWARMS to get swarm ID
TrophyGardenMons trophyGarden;
HoneyTreeData treeData;
UnkStruct_020698E4 unk_BC;
SpecialEncounter_sub2 unk_C8;
RadarChainRecords chainRecords;
PlayerRecentRoutes recentRoutes; // Used to prevent roamers from trolling you by moving to the route you just left
Roamer roamers[ROAMING_SLOT_MAX];
u8 roamerRouteIndexes[ROAMING_SLOT_MAX]; // Not a map ID. Actually index into RoamingPokemonRoutes in roaming_pokemon.c
u8 swarmEnabled;
@ -53,4 +67,4 @@ typedef struct SpecialEncounter {
u8 fluteFactor;
} SpecialEncounter;
#endif // POKEPLATINUM_STRUCT_0202D7B0_H
#endif // POKEPLATINUM_STRUCT_SPECIAL_ENCOUNTER_H

View File

@ -1,9 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202D7B0_SUB2_H
#define POKEPLATINUM_STRUCT_0202D7B0_SUB2_H
typedef struct {
int unk_00;
int unk_04;
} SpecialEncounter_sub2;
#endif // POKEPLATINUM_STRUCT_0202D7B0_SUB2_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_020698E4_H
#define POKEPLATINUM_STRUCT_020698E4_H
#include "overlay006/struct_ov6_022430E8.h"
typedef struct {
UnkStruct_ov6_022430E8 unk_00[3];
} UnkStruct_020698E4;
#endif // POKEPLATINUM_STRUCT_020698E4_H

View File

@ -1,15 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0206C638_H
#define POKEPLATINUM_STRUCT_0206C638_H
typedef struct {
int unk_00;
u32 ivs;
u32 personality;
u16 species;
u16 currentHP;
u8 level;
u8 status;
u8 active;
} Roamer;
#endif // POKEPLATINUM_STRUCT_0206C638_H

View File

@ -131,7 +131,7 @@ Static main
Object main.nef.p/src_game_records.c.o
Object main.nef.p/src_unk_0202D05C.c.o
Object main.nef.p/src_unk_0202D778.c.o
Object main.nef.p/src_unk_0202D7A8.c.o
Object main.nef.p/src_special_encounter.c.o
Object main.nef.p/src_unk_0202DA40.c.o
Object main.nef.p/src_unk_0202DAB4.c.o
Object main.nef.p/src_unk_0202DF8C.c.o
@ -564,22 +564,22 @@ Overlay overlay6
{
After overlay5
Object main.nef.p/src_overlay006_ov6_0223E140.c.o
Object main.nef.p/src_overlay006_ov6_02240C9C.c.o
Object main.nef.p/src_overlay006_wild_encounters.c.o
Object main.nef.p/src_overlay006_ov6_022426AC.c.o
Object main.nef.p/src_overlay006_great_marsh_binoculars.c.o
Object main.nef.p/src_overlay006_ov6_02242AF0.c.o
Object main.nef.p/src_overlay006_great_marsh_daily_encounters.c.o
Object main.nef.p/src_overlay006_ov6_02243004.c.o
Object main.nef.p/src_overlay006_ov6_022430C4.c.o
Object main.nef.p/src_overlay006_ov6_02243218.c.o
Object main.nef.p/src_overlay006_radar_chain_records.c.o
Object main.nef.p/src_overlay006_swarm.c.o
Object main.nef.p/src_overlay006_ov6_02243258.c.o
Object main.nef.p/src_overlay006_ov6_02246034.c.o
Object main.nef.p/src_overlay006_roamer_after_battle.c.o
Object main.nef.p/src_overlay006_ov6_02246184.c.o
Object main.nef.p/src_overlay006_ov6_02246444.c.o
Object main.nef.p/src_overlay006_ov6_022465FC.c.o
Object main.nef.p/src_overlay006_ov6_02246A30.c.o
Object main.nef.p/src_overlay006_ov6_02246B74.c.o
Object main.nef.p/src_overlay006_ov6_02246BF4.c.o
Object main.nef.p/src_overlay006_special_dates.c.o
Object main.nef.p/src_overlay006_repel_step_update.c.o
Object main.nef.p/src_overlay006_ov6_02246C24.c.o
Object main.nef.p/src_overlay006_ov6_02246F00.c.o
Object main.nef.p/src_overlay006_ov6_02247078.c.o

View File

@ -15,8 +15,8 @@
#include "struct_defs/struct_0202610C.h"
#include "field/field_system.h"
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/ov6_02246034.h"
#include "overlay006/roamer_after_battle.h"
#include "overlay006/wild_encounters.h"
#include "savedata/save_table.h"
#include "catching_show.h"
@ -421,7 +421,7 @@ static BOOL FieldTask_WildEncounter(FieldTask *task)
break;
case 4:
ov6_02246034(fieldSystem, encounter->dto);
RoamerAfterBattle_UpdateRoamers(fieldSystem, encounter->dto);
FieldTransition_FadeIn(task);
encounter->state++;
break;
@ -949,9 +949,9 @@ static void UpdateJournal(FieldSystem *fieldSystem, FieldBattleDTO *dto)
JournalEntryMon *journalEntryMon;
if (resultMask == BATTLE_RESULT_WIN) {
fieldSystem->unk_78.unk_02++;
fieldSystem->unk_78.wildMonDefeated++;
if (fieldSystem->unk_78.unk_02 >= 5) {
if (fieldSystem->unk_78.wildMonDefeated >= 5) {
caughtMon = Party_GetPokemonBySlotIndex(dto->parties[1], 0);
journalEntryMon = JournalEntry_CreateEventMonDefeated(SaveData_GetPlayTime(fieldSystem->saveData), Pokemon_GetValue(caughtMon, MON_DATA_SPECIES, 0), Pokemon_GetValue(caughtMon, MON_DATA_GENDER, 0), dto->timeOfDay, HEAP_ID_FIELDMAP);
JournalEntry_SaveData(fieldSystem->journalEntry, journalEntryMon, JOURNAL_MON);

View File

@ -287,8 +287,8 @@ void FieldMapChange_UpdateGameData(FieldSystem *fieldSystem, BOOL noWarp)
sub_0203F5C0(fieldSystem, 2);
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.unk_02 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
fieldSystem->unk_78.wildMonDefeated = 0;
}
void FieldMapChange_UpdateGameDataDistortionWorld(FieldSystem *fieldSystem, BOOL param1)
@ -323,8 +323,8 @@ void FieldMapChange_UpdateGameDataDistortionWorld(FieldSystem *fieldSystem, BOOL
}
}
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.unk_02 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
fieldSystem->unk_78.wildMonDefeated = 0;
}
static void FieldMapChange_CreateObjects(FieldSystem *fieldSystem)

View File

@ -121,7 +121,7 @@ pokeplatinum_c = files(
'game_records.c',
'unk_0202D05C.c',
'unk_0202D778.c',
'unk_0202D7A8.c',
'special_encounter.c',
'unk_0202DA40.c',
'unk_0202DAB4.c',
'unk_0202DF8C.c',
@ -453,22 +453,22 @@ pokeplatinum_c = files(
'overlay005/ov5_021FAF40.c',
'overlay005/ov5_021FF6B8.c',
'overlay006/ov6_0223E140.c',
'overlay006/ov6_02240C9C.c',
'overlay006/wild_encounters.c',
'overlay006/ov6_022426AC.c',
'overlay006/great_marsh_binoculars.c',
'overlay006/ov6_02242AF0.c',
'overlay006/great_marsh_daily_encounters.c',
'overlay006/ov6_02243004.c',
'overlay006/ov6_022430C4.c',
'overlay006/ov6_02243218.c',
'overlay006/radar_chain_records.c',
'overlay006/swarm.c',
'overlay006/ov6_02243258.c',
'overlay006/ov6_02246034.c',
'overlay006/roamer_after_battle.c',
'overlay006/ov6_02246184.c',
'overlay006/ov6_02246444.c',
'overlay006/ov6_022465FC.c',
'overlay006/ov6_02246A30.c',
'overlay006/ov6_02246B74.c',
'overlay006/ov6_02246BF4.c',
'overlay006/special_dates.c',
'overlay006/repel_step_update.c',
'overlay006/ov6_02246C24.c',
'overlay006/ov6_02246F00.c',
'overlay006/ov6_02247078.c',

View File

@ -23,8 +23,8 @@
#include "overlay005/ov5_021EF4BC.h"
#include "overlay005/ov5_021F8370.h"
#include "overlay005/vs_seeker.h"
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/ov6_02246BF4.h"
#include "overlay006/repel_step_update.h"
#include "overlay006/wild_encounters.h"
#include "overlay008/ov8_02249960.h"
#include "overlay009/ov9_02249960.h"
#include "overlay023/ov23_02241F74.h"
@ -556,7 +556,7 @@ static BOOL Field_CheckWildEncounter(FieldSystem *fieldSystem)
}
}
return MapHeader_HasWildEncounters(fieldSystem->location->mapId) && WildEncounter_TryWildEncounter(fieldSystem) == TRUE;
return MapHeader_HasWildEncounters(fieldSystem->location->mapId) && WildEncounters_TryWildEncounter(fieldSystem) == TRUE;
}
static BOOL Field_CheckMapTransition(FieldSystem *fieldSystem, const FieldInput *input)
@ -856,7 +856,7 @@ static BOOL Field_UpdatePokeRadar(FieldSystem *fieldSystem)
static BOOL Field_UpdateRepel(FieldSystem *fieldSystem)
{
return ov6_02246BF4(fieldSystem->saveData, fieldSystem);
return Repel_UpdateSteps(fieldSystem->saveData, fieldSystem);
}
static BOOL Field_UpdateFriendship(FieldSystem *fieldSystem)

View File

@ -20,8 +20,8 @@
#include "narc.h"
#include "player_avatar.h"
#include "save_player.h"
#include "special_encounter.h"
#include "trainer_info.h"
#include "unk_0202D7A8.h"
#include "unk_02039C80.h"
#include "unk_02054D00.h"
@ -64,12 +64,14 @@ static const int sHoneyTreeMapIds[NUM_HONEY_TREES] = {
MAP_HEADER_FLOAROMA_MEADOW
};
// Seems they considered having version exclusive Honey Tree encounters.
static const int sEncounterTableIndexes_DPt[] = {
0x2,
0x3,
0x4
};
// These IDs ultimately point to the same encounters.
static const int sEncounterTableIndexes_P_Unused[] = {
0x5,
0x6,
@ -79,22 +81,20 @@ static const int sEncounterTableIndexes_P_Unused[] = {
HoneyTreeShakeData *HoneyTree_ShakeDataInit(void)
{
u8 i;
HoneyTreeShakeData *v1;
HoneyTreeShakeData *data = Heap_AllocFromHeap(HEAP_ID_FIELD, sizeof(HoneyTreeShakeData));
v1 = Heap_AllocFromHeap(HEAP_ID_FIELD, sizeof(HoneyTreeShakeData));
for (i = 0; i < 21; i++) {
v1->shakeData[i].shakeValue = 0;
v1->shakeData[i].isShaking = FALSE;
for (i = 0; i < NUM_HONEY_TREES; i++) {
data->shakeData[i].shakeValue = 0;
data->shakeData[i].isShaking = FALSE;
}
return v1;
return data;
}
void HoneyTree_FreeShakeData(HoneyTreeShakeData **param0)
void HoneyTree_FreeShakeData(HoneyTreeShakeData **data)
{
Heap_FreeToHeap(*param0);
*param0 = NULL;
Heap_FreeToHeap(*data);
*data = NULL;
}
BOOL HoneyTree_TryInteract(FieldSystem *fieldSystem, int *eventId)
@ -158,12 +158,10 @@ void HoneyTree_SlatherTree(FieldSystem *fieldSystem)
tree->minutesRemaining = (24 * 60); // slathering lasts for one day
{
TrainerInfo *trainer = SaveData_GetTrainerInfo(fieldSystem->saveData);
munchlaxTree = IsMunchlaxTree(TrainerInfo_ID(trainer), treeId);
}
TrainerInfo *trainer = SaveData_GetTrainerInfo(fieldSystem->saveData);
munchlaxTree = IsMunchlaxTree(TrainerInfo_ID(trainer), treeId);
// Slathering the same tree twice in succession has a 90% chance to not reset encounter group.
// Slathering the same tree twice in succession has a 90% chance to give the same group again.
if (SpecialEncounter_GetLastSlatheredTreeId(treeDat) == treeId) {
if ((LCRNG_RandMod(100)) < 90) {
GetTreeEncounterSlot(&tree->encounterSlot);
@ -172,30 +170,26 @@ void HoneyTree_SlatherTree(FieldSystem *fieldSystem)
}
}
{
GetTreeEncounterGroup(munchlaxTree, &tree->encounterGroup);
GetTreeEncounterGroup(munchlaxTree, &tree->encounterGroup);
if (tree->encounterGroup != TREE_GROUP_NO_ENCOUNTER) {
GetTreeEncounterSlot(&tree->encounterSlot);
if (tree->encounterGroup != TREE_GROUP_NO_ENCOUNTER) {
GetTreeEncounterSlot(&tree->encounterSlot);
tree->encounterTableIndex = GetEncounterTableFromGroup(tree->encounterGroup);
} else {
tree->encounterTableIndex = 0;
tree->encounterSlot = 0;
tree->minutesRemaining = 0;
}
tree->numShakes = GetShakesFromGroup(tree->encounterGroup);
tree->encounterTableIndex = GetEncounterTableFromGroup(tree->encounterGroup);
} else {
tree->encounterTableIndex = 0;
tree->encounterSlot = 0;
tree->minutesRemaining = 0;
}
tree->numShakes = GetShakesFromGroup(tree->encounterGroup);
SpecialEncounter_SetLastSlatheredTreeId(treeId, treeDat);
}
void HoneyTree_StopShaking(FieldSystem *fieldSystem)
{
u8 treeId;
treeId = GetTreeIdFromMapId(fieldSystem->location->mapId);
u8 treeId = GetTreeIdFromMapId(fieldSystem->location->mapId);
GF_ASSERT(treeId != NUM_HONEY_TREES);
if (fieldSystem->unk_A8->shakeData[treeId].isShaking) {
@ -224,9 +218,7 @@ void HoneyTree_StopShaking(FieldSystem *fieldSystem)
// For normal trees the rates are 10/70/20/0.
static void GetTreeEncounterGroup(const BOOL isMunchlaxTree, u8 *group)
{
int roll;
roll = LCRNG_RandMod(100);
int roll = LCRNG_RandMod(100);
if (isMunchlaxTree) {
if (roll < 1) {
@ -252,9 +244,7 @@ static void GetTreeEncounterGroup(const BOOL isMunchlaxTree, u8 *group)
// Rates per slot are 40, 20, 20, 10, 5, 5
static void GetTreeEncounterSlot(u8 *slot)
{
int roll;
roll = LCRNG_RandMod(100);
int roll = LCRNG_RandMod(100);
if (roll < 5) {
*slot = 5;
@ -271,7 +261,7 @@ static void GetTreeEncounterSlot(u8 *slot)
}
}
// Return value is used to read from the encounter table NARC.
// Return value is used to read from the encounter table NARC. This is effectively group - 1.
// This looks really stupid, but it does sanitize invalid groups to table 0 instead of trying to read data out of bounds. I guess.
static const int GetEncounterTableFromGroup(const u8 group)
{
@ -291,9 +281,7 @@ static const int GetEncounterTableFromGroup(const u8 group)
static const int GetShakesFromGroup(const u8 group)
{
int numShakes;
int roll;
roll = LCRNG_RandMod(100);
int roll = LCRNG_RandMod(100);
if (group == TREE_GROUP_C) {
if (roll < 5) {
@ -407,7 +395,6 @@ static void DoTreeShakingAnimation(FieldSystem *fieldSystem, UnkStruct_ov5_021E1
static u8 GetTreeIdFromMapId(const int mapId)
{
u8 i;
for (i = 0; i < NUM_HONEY_TREES; i++) {
if (mapId == sHoneyTreeMapIds[i]) {
return i;
@ -465,9 +452,7 @@ static BOOL IsMunchlaxTree(const u32 trainerId, const u8 treeId)
int HoneyTree_GetSpecies(FieldSystem *fieldSystem)
{
u8 treeId;
treeId = GetTreeIdFromMapId(fieldSystem->location->mapId);
u8 treeId = GetTreeIdFromMapId(fieldSystem->location->mapId);
GF_ASSERT(treeId != NUM_HONEY_TREES);
{
@ -495,7 +480,6 @@ int HoneyTree_GetSpecies(FieldSystem *fieldSystem)
void ov5_021F0030(void *param0, const int param1, UnkStruct_ov5_021E1608 *const param2)
{
FieldSystem *fieldSystem;
u8 v1;
if (param1 < 0) {
return;
@ -509,9 +493,7 @@ void HoneyTree_Unslather(FieldSystem *fieldSystem)
{
HoneyTreeData *treeDat;
HoneyTree *tree;
u8 treeId;
treeId = GetTreeIdFromMapId(fieldSystem->location->mapId);
u8 treeId = GetTreeIdFromMapId(fieldSystem->location->mapId);
GF_ASSERT(treeId != NUM_HONEY_TREES);
fieldSystem->unk_A8->shakeData[treeId].isShaking = FALSE;

View File

@ -19,9 +19,9 @@
#include "overlay005/ov5_021F2850.h"
#include "overlay005/ov5_021F8560.h"
#include "overlay005/struct_ov5_021D1BEC_decl.h"
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/ov6_02243258.h"
#include "overlay006/ov6_02248050.h"
#include "overlay006/wild_encounters.h"
#include "overlay009/ov9_02249960.h"
#include "overlay009/struct_ov9_0224F6EC_decl.h"
#include "overlay101/struct_ov101_021D5D90_decl.h"
@ -889,7 +889,7 @@ static BOOL ov5_021E0560(FieldTask *param0)
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(param0);
FieldBattleDTO *v9;
if (ov6_022413E4(fieldSystem, &v9) == 1) {
if (WildEncounters_TryMudEncounter(fieldSystem, &v9) == 1) {
PlayerAvatar_SetInDeepSwamp(v0->playerAvatar, 1);
ov5_021E1134(v0);
Encounter_StartVsWild(fieldSystem, param0, v9);

View File

@ -3,13 +3,15 @@
#include <nitro.h>
#include <string.h>
#include "generated/sdat.h"
#include "field/field_system.h"
#include "field/field_system_sub2_t.h"
#include "overlay005/ov5_021D1A94.h"
#include "overlay005/ov5_021D5EB8.h"
#include "overlay005/struct_ov5_021D1BEC_decl.h"
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/struct_ov6_0223E6EC.h"
#include "overlay006/wild_encounters.h"
#include "bg_window.h"
#include "field_task.h"
@ -67,7 +69,7 @@ static void ov5_021F007C(UnkStruct_ov5_021D1BEC *param0, FieldSystem *fieldSyste
Bg_SetPriority(2, 0);
GXLayers_EngineAToggleLayers((GX_PLANEMASK_BG2), 1);
Sound_PlayEffect(1608);
Sound_PlayEffect(SEQ_SE_DP_FW230);
}
static void ov5_021F00BC(UnkStruct_ov5_021D1BEC *param0, FieldSystem *fieldSystem, void *param2)
@ -120,7 +122,7 @@ static void ov5_021F013C(UnkStruct_ov5_021D1BEC *param0, FieldSystem *fieldSyste
Bg_SetPriority(2, 0);
GXLayers_EngineAToggleLayers((GX_PLANEMASK_BG2), 1);
Sound_PlayEffect(1608);
Sound_PlayEffect(SEQ_SE_DP_FW230);
}
static void ov5_021F0188(UnkStruct_ov5_021D1BEC *param0, FieldSystem *fieldSystem, void *param2)
@ -487,7 +489,7 @@ BOOL ov5_021F0488(FieldTask *param0)
v5 = Player_GetZPos(fieldSystem->playerAvatar);
v3 = (u8)FieldSystem_GetTileBehavior(fieldSystem, v4, v5);
if (WildEncounter_TileHasEncounterRate(fieldSystem, v3)) {
if (WildEncounters_TileHasEncounterRate(fieldSystem, v3)) {
v1->unk_0C = 6;
} else {
v1->unk_0C = 4;
@ -539,7 +541,7 @@ BOOL ov5_021F0488(FieldTask *param0)
ov5_021F0374(fieldSystem);
}
v6 = ov6_022411C8(fieldSystem, param0);
v6 = WildEncounters_TrySweetScentEncounter(fieldSystem, param0);
GF_ASSERT(v6);
} break;
case 7:

View File

@ -11,7 +11,7 @@
#include "field/field_system.h"
#include "overlay005/ov5_021DFB54.h"
#include "overlay005/ov5_021F5A10.h"
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/wild_encounters.h"
#include "overlay101/struct_ov101_021D5D90_decl.h"
#include "bg_window.h"
@ -102,7 +102,7 @@ BOOL ov5_021F08F8(FieldTask *taskMan)
case 0:
MapObjectMan_PauseAllMovement(fieldSystem->mapObjMan);
v1->unk_10 = NULL;
v1->unk_08 = WildEncounter_TryFishingEncounter(fieldSystem, v1->unk_0C, &v1->unk_10);
v1->unk_08 = WildEncounters_TryFishingEncounter(fieldSystem, v1->unk_0C, &v1->unk_10);
v1->unk_14 = ov5_021F09B4(fieldSystem, v1->unk_0C, v1->unk_08);
v1->unk_00++;
break;

View File

@ -6,7 +6,6 @@
#include "field/field_system.h"
#include "overlay006/dual_slot_encounters.h"
#include "overlay006/great_marsh_daily_encounters.h"
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/wild_encounters.h"
#include "field_system.h"
@ -18,7 +17,7 @@
#include "narc.h"
#include "player_avatar.h"
#include "pokedex.h"
#include "unk_0202D7A8.h"
#include "special_encounter.h"
#include "unk_02039C80.h"
int GreatMarshBinoculars_GetMonSpecies(FieldSystem *fieldSystem)

View File

@ -1,120 +0,0 @@
#include "overlay006/ov6_022430C4.h"
#include <nitro.h>
#include <string.h>
#include "struct_defs/struct_020698E4.h"
#include "field/field_system.h"
#include "overlay006/struct_ov6_022430E8.h"
#include "pokeradar.h"
#include "unk_0202D7A8.h"
static void ov6_022431A0(UnkStruct_020698E4 *param0, UnkStruct_ov6_022430E8 **param1);
int ov6_022430C4(FieldSystem *fieldSystem)
{
int v0;
int v1;
UnkStruct_020698E4 *v2;
v2 = sub_0202D830(SaveData_GetSpecialEncounters(fieldSystem->saveData));
v1 = 0;
for (v0 = 0; v0 < 3; v0++) {
if (v2->unk_00[0].unk_02) {
v1++;
}
}
return v1;
}
int ov6_022430E8(FieldSystem *fieldSystem, const u8 param1)
{
UnkStruct_020698E4 *v0;
UnkStruct_ov6_022430E8 *v1[3];
GF_ASSERT(param1 < 3);
v0 = sub_0202D830(SaveData_GetSpecialEncounters(fieldSystem->saveData));
ov6_022431A0(v0, v1);
return v1[param1]->unk_00;
}
int ov6_02243114(FieldSystem *fieldSystem, const u8 param1)
{
UnkStruct_020698E4 *v0;
UnkStruct_ov6_022430E8 *v1[3];
GF_ASSERT(param1 < 3);
v0 = sub_0202D830(SaveData_GetSpecialEncounters(fieldSystem->saveData));
ov6_022431A0(v0, v1);
return v1[param1]->unk_02;
}
int ov6_02243140(FieldSystem *fieldSystem)
{
return GetChainCount(fieldSystem);
}
int GetRadarSpecies(FieldSystem *fieldSystem)
{
int species, level;
GetRadarMon(fieldSystem->chain, &species, &level);
return species;
}
void ov6_02243160(UnkStruct_020698E4 *param0)
{
int v0;
UnkStruct_ov6_022430E8 v1[3];
UnkStruct_ov6_022430E8 *v2[3];
ov6_022431A0(param0, v2);
for (v0 = 0; v0 < 3; v0++) {
v1[v0] = *(v2[v0]);
}
for (v0 = 0; v0 < 3; v0++) {
param0->unk_00[v0] = v1[v0];
}
}
static void ov6_022431A0(UnkStruct_020698E4 *param0, UnkStruct_ov6_022430E8 **param1)
{
if (param0->unk_00[0].unk_02 < param0->unk_00[1].unk_02) {
if (param0->unk_00[1].unk_02 < param0->unk_00[2].unk_02) {
param1[0] = &param0->unk_00[2];
param1[1] = &param0->unk_00[1];
param1[2] = &param0->unk_00[0];
} else if (param0->unk_00[0].unk_02 < param0->unk_00[2].unk_02) {
param1[0] = &param0->unk_00[1];
param1[1] = &param0->unk_00[2];
param1[2] = &param0->unk_00[0];
} else {
param1[0] = &param0->unk_00[1];
param1[1] = &param0->unk_00[0];
param1[2] = &param0->unk_00[2];
}
} else {
if (param0->unk_00[0].unk_02 < param0->unk_00[2].unk_02) {
param1[0] = &param0->unk_00[2];
param1[1] = &param0->unk_00[0];
param1[2] = &param0->unk_00[1];
} else if (param0->unk_00[1].unk_02 < param0->unk_00[2].unk_02) {
param1[0] = &param0->unk_00[0];
param1[1] = &param0->unk_00[2];
param1[2] = &param0->unk_00[1];
} else {
param1[0] = &param0->unk_00[0];
param1[1] = &param0->unk_00[1];
param1[2] = &param0->unk_00[2];
}
}
}

View File

@ -1,96 +0,0 @@
#include "overlay006/ov6_02246034.h"
#include <nitro.h>
#include <string.h>
#include "constants/battle.h"
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/struct_0206C638.h"
#include "field/field_system.h"
#include "field_battle_data_transfer.h"
#include "inlines.h"
#include "party.h"
#include "pokemon.h"
#include "roaming_pokemon.h"
#include "unk_0202D7A8.h"
#include "unk_0206AFE0.h"
#include "vars_flags.h"
static void ov6_02246110(SpecialEncounter *param0, const int param1);
static Roamer *ov6_02246148(SpecialEncounter *param0, const int param1);
void ov6_02246034(FieldSystem *fieldSystem, FieldBattleDTO *param1)
{
u16 v0;
u8 v1;
int v2;
SpecialEncounter *v3;
Roamer *v4;
Party *v5;
Pokemon *v6;
v5 = param1->parties[1];
v6 = Party_GetPokemonBySlotIndex(v5, 0);
v3 = SaveData_GetSpecialEncounters(fieldSystem->saveData);
v2 = Pokemon_GetValue(v6, MON_DATA_SPECIES, NULL);
v4 = ov6_02246148(v3, v2);
if (v4 != NULL) {
v0 = (u16)(Pokemon_GetValue(v6, MON_DATA_CURRENT_HP, NULL));
v1 = (u8)(Pokemon_GetValue(v6, MON_DATA_STATUS_CONDITION, NULL));
if ((param1->resultMask == BATTLE_RESULT_WIN) && (v0 == 0)) {
SpecialEncounter_ZeroRoamerData(&v4);
sub_0206B688(SaveData_GetVarsFlags(fieldSystem->saveData), v2, 2);
} else if (param1->resultMask == BATTLE_RESULT_CAPTURED_MON) {
SpecialEncounter_ZeroRoamerData(&v4);
sub_0206B688(SaveData_GetVarsFlags(fieldSystem->saveData), v2, 1);
} else {
Roamer_SetData(v4, ROAMER_DATA_CURRENT_HP, v0);
Roamer_SetData(v4, ROAMER_DATA_STATUS, v1);
}
ov6_02246110(v3, fieldSystem->location->mapId);
} else {
if (LCRNG_RandMod(100) < 30) {
ov6_02246110(v3, fieldSystem->location->mapId);
}
}
}
static void ov6_02246110(SpecialEncounter *param0, const int param1)
{
int v0;
u8 v1;
for (v1 = 0; v1 < 6; v1++) {
if (SpecialEncounter_IsRoamerActive(param0, v1)) {
v0 = RoamingPokemon_GetRouteFromId(SpecialEncounter_GetRoamerRouteIndex(param0, v1));
if (param1 == v0) {
sub_0206C33C(param0, v1);
}
}
}
}
static Roamer *ov6_02246148(SpecialEncounter *param0, const int param1)
{
u8 v0;
Roamer *v1;
for (v0 = 0; v0 < 6; v0++) {
if (SpecialEncounter_IsRoamerActive(param0, v0)) {
v1 = SpecialEncounter_GetRoamer(param0, v0);
if (param1 == Roamer_GetData(v1, ROAMER_DATA_SPECIES)) {
return v1;
}
}
}
return NULL;
}

View File

@ -1,150 +0,0 @@
#include "overlay006/ov6_02246B74.h"
#include <nitro.h>
#include <string.h>
#include "rtc.h"
typedef struct {
int unk_00;
const u16 *unk_04;
} UnkStruct_ov6_0224954C;
static const u16 Unk_ov6_02249522[4] = {
((1 << 8) | (3 & 0xff)),
((11 << 8) | (2 & 0xff)),
((12 << 8) | (4 & 0xff)),
((29 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_02249502[4] = {
((3 << 8) | (2 & 0xff)),
((11 << 8) | (2 & 0xff)),
((14 << 8) | (0 & 0xff)),
((27 << 8) | (4 & 0xff))
};
static const u16 Unk_ov6_022494F4[3] = {
((3 << 8) | (2 & 0xff)),
((18 << 8) | (2 & 0xff)),
((21 << 8) | (3 & 0xff))
};
static const u16 Unk_ov6_0224951A[4] = {
((1 << 8) | (2 & 0xff)),
((25 << 8) | (2 & 0xff)),
((26 << 8) | (1 & 0xff)),
((29 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_0224950A[4] = {
((1 << 8) | (0 & 0xff)),
((3 << 8) | (2 & 0xff)),
((4 << 8) | (0 & 0xff)),
((5 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_022494E0[1] = {
((21 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_022494E8[3] = {
((7 << 8) | (4 & 0xff)),
((18 << 8) | (2 & 0xff)),
((24 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_022494FA[4] = {
((13 << 8) | (1 & 0xff)),
((14 << 8) | (1 & 0xff)),
((15 << 8) | (2 & 0xff)),
((16 << 8) | (1 & 0xff))
};
static const u16 Unk_ov6_0224952A[6] = {
((7 << 8) | (2 & 0xff)),
((12 << 8) | (2 & 0xff)),
((15 << 8) | (2 & 0xff)),
((20 << 8) | (2 & 0xff)),
((23 << 8) | (3 & 0xff)),
((28 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_022494EE[3] = {
((5 << 8) | (2 & 0xff)),
((15 << 8) | (2 & 0xff)),
((30 << 8) | (2 & 0xff))
};
static const u16 Unk_ov6_02249512[4] = {
((3 << 8) | (1 & 0xff)),
((12 << 8) | (2 & 0xff)),
((21 << 8) | (2 & 0xff)),
((23 << 8) | (0 & 0xff))
};
static const u16 Unk_ov6_022494E2[3] = {
((14 << 8) | (2 & 0xff)),
((23 << 8) | (2 & 0xff)),
((31 << 8) | (1 & 0xff))
};
static const UnkStruct_ov6_0224954C Unk_ov6_0224954C[12] = {
{ 0x4, Unk_ov6_02249522 },
{ 0x4, Unk_ov6_02249502 },
{ 0x3, Unk_ov6_022494F4 },
{ 0x4, Unk_ov6_0224951A },
{ 0x4, Unk_ov6_0224950A },
{ 0x1, Unk_ov6_022494E0 },
{ 0x3, Unk_ov6_022494E8 },
{ 0x4, Unk_ov6_022494FA },
{ 0x6, Unk_ov6_0224952A },
{ 0x3, Unk_ov6_022494EE },
{ 0x4, Unk_ov6_02249512 },
{ 0x3, Unk_ov6_022494E2 }
};
static const int Unk_ov6_02249538[] = {
0x0,
-5,
0x5,
-10,
0xA
};
int ov6_02246B74(const int param0, const BOOL param1)
{
u8 v0;
int v1;
RTCDate v2;
const UnkStruct_ov6_0224954C *v3;
if (param1) {
return param0;
}
if (param0 == 0) {
return 0;
}
GetCurrentDate(&v2);
GF_ASSERT(v2.month > 0);
GF_ASSERT(v2.month <= 12);
v3 = &(Unk_ov6_0224954C[v2.month - 1]);
for (v0 = 0; v0 < v3->unk_00; v0++) {
if (v2.day == ((v3->unk_04[v0] >> 8) & 0xff)) {
v1 = param0 + Unk_ov6_02249538[(v3->unk_04[v0] & 0xff)];
if (v1 < 0) {
v1 = 1;
}
return v1;
}
}
return param0;
}

View File

@ -0,0 +1,119 @@
#include "overlay006/radar_chain_records.h"
#include <nitro.h>
#include <string.h>
#include "struct_defs/radar_chain_records.h"
#include "field/field_system.h"
#include "pokeradar.h"
#include "special_encounter.h"
static void SortChainRecords(RadarChainRecords *param0, ChainRecord **param1);
int RadarChainRecords_GetNumFilledSlots(FieldSystem *fieldSystem)
{
int i;
int filledSlots;
RadarChainRecords *recordsData = SpecialEncounter_GetRadarChainRecords(SaveData_GetSpecialEncounters(fieldSystem->saveData));
filledSlots = 0;
for (i = 0; i < NUM_RADAR_RECORDS; i++) {
if (recordsData->records[0].chainCount) {
filledSlots++;
}
}
return filledSlots;
}
int RadarChainRecords_GetSpecies(FieldSystem *fieldSystem, const u8 slot)
{
RadarChainRecords *recordsData;
ChainRecord *records[NUM_RADAR_RECORDS];
GF_ASSERT(slot < NUM_RADAR_RECORDS);
recordsData = SpecialEncounter_GetRadarChainRecords(SaveData_GetSpecialEncounters(fieldSystem->saveData));
SortChainRecords(recordsData, records);
return records[slot]->species;
}
int RadarChainRecords_GetChainCount(FieldSystem *fieldSystem, const u8 slot)
{
RadarChainRecords *recordsData;
ChainRecord *records[NUM_RADAR_RECORDS];
GF_ASSERT(slot < NUM_RADAR_RECORDS);
recordsData = SpecialEncounter_GetRadarChainRecords(SaveData_GetSpecialEncounters(fieldSystem->saveData));
SortChainRecords(recordsData, records);
return records[slot]->chainCount;
}
int RadarChainRecords_GetActiveChain(FieldSystem *fieldSystem)
{
return GetChainCount(fieldSystem);
}
int GetRadarSpecies(FieldSystem *fieldSystem)
{
int species, level;
GetRadarMon(fieldSystem->chain, &species, &level);
return species;
}
void RadarChainRecords_SortSavedRecords(RadarChainRecords *recordsData)
{
int i;
ChainRecord recordsCopy[NUM_RADAR_RECORDS];
ChainRecord *sortedRecords[NUM_RADAR_RECORDS];
SortChainRecords(recordsData, sortedRecords);
for (i = 0; i < NUM_RADAR_RECORDS; i++) {
recordsCopy[i] = *(sortedRecords[i]);
}
for (i = 0; i < NUM_RADAR_RECORDS; i++) {
recordsData->records[i] = recordsCopy[i];
}
}
// Sorts RadarChainRecords data in descending order.
static void SortChainRecords(RadarChainRecords *data, ChainRecord **sorted)
{
if (data->records[0].chainCount < data->records[1].chainCount) {
if (data->records[1].chainCount < data->records[2].chainCount) { // 2 > 1 > 0
sorted[0] = &data->records[2];
sorted[1] = &data->records[1];
sorted[2] = &data->records[0];
} else if (data->records[0].chainCount < data->records[2].chainCount) { // 1 > 2 > 0
sorted[0] = &data->records[1];
sorted[1] = &data->records[2];
sorted[2] = &data->records[0];
} else { // 1 > 0 > 2
sorted[0] = &data->records[1];
sorted[1] = &data->records[0];
sorted[2] = &data->records[2];
}
} else {
if (data->records[0].chainCount < data->records[2].chainCount) { // 2 > 0 > 1
sorted[0] = &data->records[2];
sorted[1] = &data->records[0];
sorted[2] = &data->records[1];
} else if (data->records[1].chainCount < data->records[2].chainCount) { // 0 > 2 > 1
sorted[0] = &data->records[0];
sorted[1] = &data->records[2];
sorted[2] = &data->records[1];
} else { // 0 > 1 > 2
sorted[0] = &data->records[0];
sorted[1] = &data->records[1];
sorted[2] = &data->records[2];
}
}
}

View File

@ -1,4 +1,4 @@
#include "overlay006/ov6_02246BF4.h"
#include "overlay006/repel_step_update.h"
#include <nitro.h>
#include <string.h>
@ -7,13 +7,11 @@
#include "savedata.h"
#include "script_manager.h"
#include "unk_0202D7A8.h"
#include "special_encounter.h"
BOOL ov6_02246BF4(SaveData *saveData, FieldSystem *fieldSystem)
BOOL Repel_UpdateSteps(SaveData *saveData, FieldSystem *fieldSystem)
{
u8 *repelSteps;
repelSteps = SpecialEncounter_GetRepelSteps(SaveData_GetSpecialEncounters(saveData));
u8 *repelSteps = SpecialEncounter_GetRepelSteps(SaveData_GetSpecialEncounters(saveData));
if ((*repelSteps) > 0) {
(*repelSteps)--;

View File

@ -0,0 +1,96 @@
#include "overlay006/roamer_after_battle.h"
#include <nitro.h>
#include <string.h>
#include "constants/battle.h"
#include "struct_defs/special_encounter.h"
#include "field/field_system.h"
#include "field_battle_data_transfer.h"
#include "inlines.h"
#include "party.h"
#include "pokemon.h"
#include "roaming_pokemon.h"
#include "special_encounter.h"
#include "unk_0206AFE0.h"
#include "vars_flags.h"
static void MoveRoamersOffMap(SpecialEncounter *param0, const int param1);
static Roamer *GetBattledRoamer(SpecialEncounter *speEnc, const int species);
void RoamerAfterBattle_UpdateRoamers(FieldSystem *fieldSystem, FieldBattleDTO *battleParams)
{
u16 roamerHP;
u8 roamerStatus;
int wildSpecies;
SpecialEncounter *specialEncounter;
Roamer *roamer;
Party *enemyParty;
Pokemon *enemyMon;
enemyParty = battleParams->parties[1];
enemyMon = Party_GetPokemonBySlotIndex(enemyParty, 0);
specialEncounter = SaveData_GetSpecialEncounters(fieldSystem->saveData);
wildSpecies = Pokemon_GetValue(enemyMon, MON_DATA_SPECIES, NULL);
roamer = GetBattledRoamer(specialEncounter, wildSpecies);
if (roamer != NULL) {
roamerHP = (u16)(Pokemon_GetValue(enemyMon, MON_DATA_CURRENT_HP, NULL));
roamerStatus = (u8)(Pokemon_GetValue(enemyMon, MON_DATA_STATUS_CONDITION, NULL));
if ((battleParams->resultMask == BATTLE_RESULT_WIN) && (roamerHP == 0)) {
SpecialEncounter_ZeroRoamerData(&roamer);
sub_0206B688(SaveData_GetVarsFlags(fieldSystem->saveData), wildSpecies, 2);
} else if (battleParams->resultMask == BATTLE_RESULT_CAPTURED_MON) {
SpecialEncounter_ZeroRoamerData(&roamer);
sub_0206B688(SaveData_GetVarsFlags(fieldSystem->saveData), wildSpecies, 1);
} else {
Roamer_SetData(roamer, ROAMER_DATA_CURRENT_HP, roamerHP);
Roamer_SetData(roamer, ROAMER_DATA_STATUS, roamerStatus);
}
MoveRoamersOffMap(specialEncounter, fieldSystem->location->mapId); // all roamers leave if you encounter one
} else {
if (LCRNG_RandMod(100) < 30) { // 30% chance for roamers to leave even if you don't encounter one
MoveRoamersOffMap(specialEncounter, fieldSystem->location->mapId);
}
}
}
// For all roamers, moves to a random location if they are on the current map
static void MoveRoamersOffMap(SpecialEncounter *speEnc, const int currentMap)
{
int roamerMap;
u8 i;
for (i = 0; i < ROAMING_SLOT_MAX; i++) {
if (SpecialEncounter_IsRoamerActive(speEnc, i)) {
roamerMap = RoamingPokemon_GetRouteFromId(SpecialEncounter_GetRoamerRouteIndex(speEnc, i));
if (currentMap == roamerMap) {
RoamingPokemon_MoveToRandomMap(speEnc, i);
}
}
}
}
static Roamer *GetBattledRoamer(SpecialEncounter *speEnc, const int species)
{
u8 i;
Roamer *roamer;
for (i = 0; i < ROAMING_SLOT_MAX; i++) {
if (SpecialEncounter_IsRoamerActive(speEnc, i)) {
roamer = SpecialEncounter_GetRoamer(speEnc, i);
if (species == Roamer_GetData(roamer, ROAMER_DATA_SPECIES)) {
return roamer;
}
}
}
return NULL;
}

View File

@ -0,0 +1,164 @@
#include "overlay006/special_dates.h"
#include <nitro.h>
#include <string.h>
#include "rtc.h"
typedef struct SpecialDate {
int size;
const u16 *dayModifier; // high byte is day. low byte is index into sEncounterRateModifiers
} SpecialDate;
// Macros for readability.
#define DateMod(day, modifier) ((day << 8) | (modifier & 0xFF))
#define GetDate(element) ((element >> 8) & 0xff)
#define GetModifier(element) (element & 0xff)
#define MODIFIER_MINUS_5 1
#define MODIFIER_PLUS_5 2
#define MODIFIER_MINUS_10 3
#define MODIFIER_PLUS_10 4
static const u16 sJanuaryDays[] = {
DateMod(1, MODIFIER_MINUS_10),
DateMod(11, MODIFIER_PLUS_5),
DateMod(12, MODIFIER_PLUS_10),
DateMod(29, MODIFIER_PLUS_5)
};
static const u16 sFebruaryDays[] = {
DateMod(3, MODIFIER_PLUS_5),
DateMod(11, MODIFIER_PLUS_5),
DateMod(14, 0),
DateMod(27, MODIFIER_PLUS_10)
};
static const u16 sMarchDays[] = {
DateMod(3, MODIFIER_PLUS_5),
DateMod(18, MODIFIER_PLUS_5),
DateMod(21, MODIFIER_MINUS_10)
};
static const u16 sAprilDays[] = {
DateMod(1, MODIFIER_PLUS_5),
DateMod(25, MODIFIER_PLUS_5),
DateMod(26, MODIFIER_MINUS_5),
DateMod(29, MODIFIER_PLUS_5)
};
static const u16 sMayDays[] = {
DateMod(1, 0),
DateMod(3, MODIFIER_PLUS_5),
DateMod(4, 0),
DateMod(5, MODIFIER_PLUS_5)
};
static const u16 sJuneDays[] = {
DateMod(21, MODIFIER_PLUS_5)
};
static const u16 sJulyDays[] = {
DateMod(7, MODIFIER_PLUS_10),
DateMod(18, MODIFIER_PLUS_5),
DateMod(24, MODIFIER_PLUS_5)
};
static const u16 sAugustDays[] = {
DateMod(13, MODIFIER_MINUS_5),
DateMod(14, MODIFIER_MINUS_5),
DateMod(15, MODIFIER_PLUS_5),
DateMod(16, MODIFIER_MINUS_5)
};
static const u16 sSeptemberDays[] = {
DateMod(7, MODIFIER_PLUS_5),
DateMod(12, MODIFIER_PLUS_5),
DateMod(15, MODIFIER_PLUS_5),
DateMod(20, MODIFIER_PLUS_5),
DateMod(23, MODIFIER_MINUS_10),
DateMod(28, MODIFIER_PLUS_5)
};
static const u16 sOctoberDays[] = {
DateMod(5, MODIFIER_PLUS_5),
DateMod(15, MODIFIER_PLUS_5),
DateMod(30, MODIFIER_PLUS_5)
};
static const u16 sNovemberDays[] = {
DateMod(3, MODIFIER_MINUS_5),
DateMod(12, MODIFIER_PLUS_5),
DateMod(21, MODIFIER_PLUS_5),
DateMod(23, 0)
};
static const u16 sDecemberDays[] = {
DateMod(14, MODIFIER_PLUS_5),
DateMod(23, MODIFIER_PLUS_5),
DateMod(31, MODIFIER_MINUS_5)
};
static const SpecialDate sSpecialDates[12] = {
{ sizeof(sJanuaryDays) / 2, sJanuaryDays },
{ sizeof(sFebruaryDays) / 2, sFebruaryDays },
{ sizeof(sMarchDays) / 2, sMarchDays },
{ sizeof(sAprilDays) / 2, sAprilDays },
{ sizeof(sMayDays) / 2, sMayDays },
{ sizeof(sJuneDays) / 2, sJuneDays },
{ sizeof(sJulyDays) / 2, sJulyDays },
{ sizeof(sAugustDays) / 2, sAugustDays },
{ sizeof(sSeptemberDays) / 2, sSeptemberDays },
{ sizeof(sOctoberDays) / 2, sOctoberDays },
{ sizeof(sNovemberDays) / 2, sNovemberDays },
{ sizeof(sDecemberDays) / 2, sDecemberDays }
};
static const int sEncounterRateModifiers[] = {
0,
-5,
+5,
-10,
+10
};
int SpecialDates_ModifyEncounterRate(const int encounterModifier, const BOOL hasTimePenalty)
{
u8 i;
int newModifier;
RTCDate currentDate;
const SpecialDate *dates;
if (hasTimePenalty) { // Exits without applying the date effect if the clock was changed recently.
return encounterModifier;
}
if (encounterModifier == 0) {
return 0;
}
GetCurrentDate(&currentDate);
GF_ASSERT(currentDate.month > 0);
GF_ASSERT(currentDate.month <= 12);
dates = &(sSpecialDates[currentDate.month - 1]);
for (i = 0; i < dates->size; i++) {
if (currentDate.day == GetDate(dates->dayModifier[i])) {
newModifier = encounterModifier + sEncounterRateModifiers[GetModifier(dates->dayModifier[i])];
if (newModifier < 0) {
newModifier = 1;
}
return newModifier;
}
}
return encounterModifier;
}
#undef DateMod
#undef GetDate
#undef GetModifier

View File

@ -1,4 +1,4 @@
#include "overlay006/ov6_02243218.h"
#include "overlay006/swarm.h"
#include <nitro.h>
#include <string.h>
@ -42,9 +42,8 @@ u32 Swarm_GetMapId(const u32 swarm)
void Swarm_GetMapIdAndSpecies(const u32 swarm, u16 *mapIdDest, u16 *speciesDest)
{
WildEncounters encounterData;
u32 mapId;
u32 mapId = Swarm_MapIdTable[(swarm % NUM_SWARMS)];
mapId = Swarm_MapIdTable[(swarm % NUM_SWARMS)];
MapHeaderData_LoadWildEncounters(&encounterData, mapId);
(*speciesDest) = encounterData.swarmEncounters[0];

View File

@ -7,16 +7,14 @@
#include "inlines.h"
#include "narc.h"
#include "savedata.h"
#include "unk_0202D7A8.h"
#include "special_encounter.h"
void TrophyGarden_AddNewMon(SaveData *saveData)
{
u16 newMonIndex;
u16 index1, index2;
int currentMons[2];
int *encData;
encData = NARC_AllocAtEndAndReadWholeMemberByIndexPair(NARC_INDEX_ARC__ENCDATA_EX, 8, HEAP_ID_FIELD);
int *encData = NARC_AllocAtEndAndReadWholeMemberByIndexPair(NARC_INDEX_ARC__ENCDATA_EX, 8, HEAP_ID_FIELD);
SpecialEncounter_GetTrophyGardenMons(saveData, &index1, &index2);

View File

@ -1,4 +1,4 @@
#include "overlay006/ov6_02240C9C.h"
#include "overlay006/wild_encounters.h"
#include <nitro.h>
#include <string.h>
@ -13,8 +13,7 @@
#include "generated/items.h"
#include "generated/species_data_params.h"
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/struct_0206C638.h"
#include "struct_defs/special_encounter.h"
#include "field/field_system.h"
#include "field/field_system_sub2_t.h"
@ -22,8 +21,8 @@
#include "overlay006/dual_slot_encounters.h"
#include "overlay006/feebas_fishing.h"
#include "overlay006/great_marsh_daily_encounters.h"
#include "overlay006/ov6_02243218.h"
#include "overlay006/ov6_02246B74.h"
#include "overlay006/special_dates.h"
#include "overlay006/swarm.h"
#include "overlay006/wild_encounters.h"
#include "encounter.h"
@ -46,10 +45,10 @@
#include "roaming_pokemon.h"
#include "rtc.h"
#include "save_player.h"
#include "special_encounter.h"
#include "system_flags.h"
#include "trainer_data.h"
#include "trainer_info.h"
#include "unk_0202D7A8.h"
#include "unk_02054884.h"
#include "unk_02054D00.h"
#include "unk_020559DC.h"
@ -87,15 +86,15 @@ typedef struct UnownFormsGroup {
static BOOL ShouldGetRandomEncounter(FieldSystem *fieldSystem, const u32 encounterRate, const u8 tileBehavior);
static u8 GetTileEncounterRateAndType(FieldSystem *fieldSystem, u8 tileBehavior, u8 *encounterType);
static BOOL ov6_022418B4(FieldSystem *fieldSystem, u32 param1);
static BOOL CheckEncounterRateSuccess(FieldSystem *fieldSystem, u32 param1);
static BOOL TryGetSlotForTypeMatchAbility(Pokemon *param0, const WildEncounters_FieldParams *param1, const EncounterSlot *param2, const u8 param3, const u8 param4, const u8 param5, u8 *param6);
static BOOL FirstMonAbilityPreventsEncounter(const WildEncounters_FieldParams *param0, Pokemon *param1, const u8 param2);
static BOOL GracePeriodStepsUsed(FieldSystem *fieldSystem, u32 param1);
static BOOL CheckEncounterRateSuccess(FieldSystem *fieldSystem, u32 encounterRate);
static BOOL TryGetSlotForTypeMatchAbility(Pokemon *unused, const WildEncounters_FieldParams *encParams, const EncounterSlot *encTable, const u8 maxEncounters, const u8 type, const u8 ability, u8 *encSlot);
static BOOL FirstMonAbilityPreventsEncounter(const WildEncounters_FieldParams *encParams, Pokemon *firstMon, const u8 wildLevel);
static int GetGrassEncounterRate(FieldSystem *fieldSystem);
static int GetSurfEncounterRate(FieldSystem *fieldSystem);
static int GetFishingEncounterRate(FieldSystem *fieldSystem, const int param1);
static BOOL TryGenerateGrassEncounter_WithRadar(FieldSystem *fieldSystem, Pokemon *param1, FieldBattleDTO *param2, WildEncounters *encounterData, EncounterSlot *param4, const WildEncounters_FieldParams *param5, const RadarEncounterData *param6);
static BOOL TryGenerateGrassEncounter_DoubleBattle(FieldSystem *fieldSystem, Pokemon *param1, FieldBattleDTO *param2, EncounterSlot *param3, const WildEncounters_FieldParams *param4);
static int GetFishingEncounterRate(FieldSystem *fieldSystem, const int rodType);
static BOOL TryGenerateGrassEncounter_WithRadar(FieldSystem *fieldSystem, Pokemon *firstMon, FieldBattleDTO *battleParams, WildEncounters *encounterData, EncounterSlot *encounterTable, const WildEncounters_FieldParams *fieldParams, const RadarEncounterData *radarData);
static BOOL TryGenerateGrassEncounter_DoubleBattle(FieldSystem *fieldSystem, Pokemon *firstMon, FieldBattleDTO *battleParams, EncounterSlot *encounterTable, const WildEncounters_FieldParams *fieldParams);
static BOOL TryGenerateSurfEncounter(FieldSystem *fieldSystem, Pokemon *param1, FieldBattleDTO *param2, EncounterSlot *param3, const WildEncounters_FieldParams *param4);
static BOOL TryGenerateFishingEncounter(FieldSystem *fieldSystem, Pokemon *param1, FieldBattleDTO *param2, EncounterSlot *param3, const WildEncounters_FieldParams *param4, const int param5);
static BOOL TryGenerateWildMon(Pokemon *firstPartyMon, const int fishingRodType, const WildEncounters_FieldParams *fieldParams, const EncounterSlot *encounterTable, const u8 encounterType, const int param5, FieldBattleDTO *param6);
@ -178,6 +177,7 @@ static const UnownFormsGroup WildEncounters_UnownTables[] = {
{ 0x2, UnownOnlyExcQue }
};
// Default encounters are morning. They get replaced by this if it is not morning.
void WildEncounters_ReplaceTimedEncounters(const WildEncounters *encounterData, int *timedSlot1, int *timedSlot2)
{
int timeOfDay = GetTimeOfDay();
@ -227,7 +227,7 @@ static void WildEncounters_ReplaceTrophyGardenEncounters(FieldSystem *fieldSyste
}
}
BOOL WildEncounter_TryWildEncounter(FieldSystem *fieldSystem)
BOOL WildEncounters_TryWildEncounter(FieldSystem *fieldSystem)
{
FieldBattleDTO *battleParams;
Pokemon *firstPartyMon;
@ -293,6 +293,7 @@ BOOL WildEncounter_TryWildEncounter(FieldSystem *fieldSystem)
withPartner = FALSE;
}
// Roamers can't appear in Poke Radar patches or double battles.
if (!withPartner && !radarData.isRadarEncounter) {
Roamer *roamer;
@ -370,12 +371,12 @@ BOOL WildEncounter_TryWildEncounter(FieldSystem *fieldSystem)
FieldBattleDTO_Free(battleParams);
}
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
return gettingEncounter;
}
BOOL WildEncounter_TryFishingEncounter(FieldSystem *fieldSystem, const int fishingRodType, FieldBattleDTO **battleParams)
BOOL WildEncounters_TryFishingEncounter(FieldSystem *fieldSystem, const int fishingRodType, FieldBattleDTO **battleParams)
{
EncounterSlot encounterTable[MAX_GRASS_ENCOUNTERS];
@ -395,9 +396,9 @@ BOOL WildEncounter_TryFishingEncounter(FieldSystem *fieldSystem, const int fishi
return FALSE;
}
BOOL v2 = SystemFlag_CheckSafariGameActive(SaveData_GetVarsFlags(fieldSystem->saveData));
BOOL safariGameActive = SystemFlag_CheckSafariGameActive(SaveData_GetVarsFlags(fieldSystem->saveData));
CreateWildSingleBattle(fieldSystem, v2, battleParams);
CreateWildSingleBattle(fieldSystem, safariGameActive, battleParams);
FieldBattleDTO_Init(*battleParams, fieldSystem);
FieldBattleDTO_SetWaterTerrain(*battleParams);
@ -406,10 +407,10 @@ BOOL WildEncounter_TryFishingEncounter(FieldSystem *fieldSystem, const int fishi
int species;
u8 maxLevel, minLevel;
LoadFeebasLevelRange(&maxLevel, &minLevel);
LoadFeebasLevelRange(&maxLevel, &minLevel); // 10-20
LoadFeebasFromNARC(&species);
for (u8 i = 0; i < MAX_WATER_ENCOUNTERS; i++) {
for (u8 i = 0; i < MAX_WATER_ENCOUNTERS; i++) { // guaranteed to find Feebas if the above checks pass.
encounterTable[i].species = species;
encounterTable[i].maxLevel = maxLevel;
encounterTable[i].minLevel = minLevel;
@ -444,8 +445,8 @@ BOOL WildEncounter_TryFishingEncounter(FieldSystem *fieldSystem, const int fishi
return TRUE;
}
// I think this is GetSweetScentEncounter
BOOL ov6_022411C8(FieldSystem *fieldSystem, FieldTask *param1)
// Same as TryGrassEncounter except it always generates an encounter if they exist
BOOL WildEncounters_TrySweetScentEncounter(FieldSystem *fieldSystem, FieldTask *param1)
{
FieldBattleDTO *battleParams;
Pokemon *firstPartyMon;
@ -459,9 +460,9 @@ BOOL ov6_022411C8(FieldSystem *fieldSystem, FieldTask *param1)
int playerX = Player_GetXPos(fieldSystem->playerAvatar);
int playerZ = Player_GetZPos(fieldSystem->playerAvatar);
u8 v4 = FieldSystem_GetTileBehavior(fieldSystem, playerX, playerZ);
u8 tileBehavior = FieldSystem_GetTileBehavior(fieldSystem, playerX, playerZ);
u8 encounterRate = GetTileEncounterRateAndType(fieldSystem, v4, &encounterType);
u8 encounterRate = GetTileEncounterRateAndType(fieldSystem, tileBehavior, &encounterType);
if (encounterRate == 0) {
return FALSE;
@ -488,7 +489,7 @@ BOOL ov6_022411C8(FieldSystem *fieldSystem, FieldTask *param1)
Roamer *roamer;
if (TryEncounterRoamer(fieldSystem, &roamer)) {
battleParams = FieldBattleDTO_New(11, BATTLE_TYPE_ROAMER);
battleParams = FieldBattleDTO_New(HEAP_ID_FIELDMAP, BATTLE_TYPE_ROAMER);
FieldBattleDTO_Init(battleParams, fieldSystem);
AddRoamerToEnemyParty(encounterFieldParams.trainerID, roamer, battleParams);
@ -549,18 +550,18 @@ BOOL ov6_022411C8(FieldSystem *fieldSystem, FieldTask *param1)
GF_ASSERT(FALSE);
}
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
return TRUE;
}
// something to do with swamp mud?
BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
// seemingly the same as TryGrassEncounter, but doesn't check Surf tables because it's always a grass tile
BOOL WildEncounters_TryMudEncounter(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
{
Pokemon *firstPartyMon;
u8 encounterType;
BOOL v5;
BOOL v6;
BOOL v7;
BOOL gettingEncounter;
BOOL encounterSuccess;
BOOL withPartner;
BOOL safariGameActive;
RadarEncounterData radarData;
EncounterSlot encounterTable[MAX_GRASS_ENCOUNTERS];
@ -570,9 +571,9 @@ BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
int playerX = Player_GetXPos(fieldSystem->playerAvatar);
int playerZ = Player_GetZPos(fieldSystem->playerAvatar);
u8 v3 = FieldSystem_GetTileBehavior(fieldSystem, playerX, playerZ);
u8 tileBehavior = FieldSystem_GetTileBehavior(fieldSystem, playerX, playerZ);
u8 encounterRate = GetTileEncounterRateAndType(fieldSystem, v3, &encounterType);
u8 encounterRate = GetTileEncounterRateAndType(fieldSystem, tileBehavior, &encounterType);
if (encounterRate == 0) {
return FALSE;
@ -596,30 +597,30 @@ BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
ModifyEncounterRateWithFlute(fieldSystem, &encounterRate);
ModifyEncounterRateWithHeldItem(firstPartyMon, &encounterRate);
if (ShouldGetRandomEncounter(fieldSystem, encounterRate, v3)) {
v5 = TRUE;
if (ShouldGetRandomEncounter(fieldSystem, encounterRate, tileBehavior)) {
gettingEncounter = TRUE;
} else {
v5 = FALSE;
gettingEncounter = FALSE;
}
memset(&radarData, 0, sizeof(RadarEncounterData));
radarData.isRadarEncounter = FALSE;
if (SystemFlag_CheckHasPartner(SaveData_GetVarsFlags(fieldSystem->saveData))) {
v7 = TRUE;
withPartner = TRUE;
} else {
v7 = FALSE;
withPartner = FALSE;
}
if (!v7) {
Roamer *v16;
if (!withPartner) {
Roamer *roamer;
if (TryEncounterRoamer(fieldSystem, &v16)) {
if (!RepelPreventsEncounter(Roamer_GetData(v16, ROAMER_DATA_LEVEL), &encounterFieldParams)) {
if (TryEncounterRoamer(fieldSystem, &roamer)) {
if (!RepelPreventsEncounter(Roamer_GetData(roamer, ROAMER_DATA_LEVEL), &encounterFieldParams)) {
*battleParams = FieldBattleDTO_New(11, BATTLE_TYPE_ROAMER);
FieldBattleDTO_Init(*battleParams, fieldSystem);
AddRoamerToEnemyParty(encounterFieldParams.trainerID, v16, *battleParams);
AddRoamerToEnemyParty(encounterFieldParams.trainerID, roamer, *battleParams);
RadarChain_Clear(fieldSystem->chain);
return TRUE;
} else {
@ -628,7 +629,7 @@ BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
}
}
if (!v7) {
if (!withPartner) {
safariGameActive = SystemFlag_CheckSafariGameActive(SaveData_GetVarsFlags(fieldSystem->saveData));
CreateWildSingleBattle(fieldSystem, safariGameActive, battleParams);
} else {
@ -651,16 +652,16 @@ BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
WildEncounters_ReplaceTrophyGardenEncounters(fieldSystem, nationalDexObtained, &encounterTable[6].species, &encounterTable[7].species);
WildEncounters_ReplaceDualSlotEncounters(encounterData, nationalDexObtained, &encounterTable[8].species, &encounterTable[9].species);
if (!v7) {
if (!withPartner) {
WildEncounters_ReplaceGreatMarshDailyEncounters(fieldSystem, safariGameActive, nationalDexObtained, encounterTable);
v6 = TryGenerateGrassEncounter_WithRadar(fieldSystem, firstPartyMon, *battleParams, encounterData, encounterTable, &encounterFieldParams, &radarData);
encounterSuccess = TryGenerateGrassEncounter_WithRadar(fieldSystem, firstPartyMon, *battleParams, encounterData, encounterTable, &encounterFieldParams, &radarData);
} else {
{
(*battleParams)->trainerIDs[2] = sub_0206B034(SaveData_GetVarsFlags(fieldSystem->saveData));
Trainer_Encounter(*battleParams, fieldSystem->saveData, 11);
}
v6 = TryGenerateGrassEncounter_DoubleBattle(fieldSystem, firstPartyMon, *battleParams, encounterTable, &encounterFieldParams);
encounterSuccess = TryGenerateGrassEncounter_DoubleBattle(fieldSystem, firstPartyMon, *battleParams, encounterTable, &encounterFieldParams);
}
} else {
GF_ASSERT(FALSE);
@ -668,30 +669,31 @@ BOOL ov6_022413E4(FieldSystem *fieldSystem, FieldBattleDTO **battleParams)
return FALSE;
}
if (!v6) {
v5 = FALSE;
if (!encounterSuccess) {
gettingEncounter = FALSE;
}
GF_ASSERT(GF_heap_c_dummy_return_true(4));
GF_ASSERT(GF_heap_c_dummy_return_true(11));
if (!v5) {
if (!gettingEncounter) {
FieldBattleDTO_Free(*battleParams);
} else {
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
}
return v5;
return gettingEncounter;
}
static BOOL TryGenerateGrassEncounter_WithRadar(FieldSystem *fieldSystem, Pokemon *firstPartyMon, FieldBattleDTO *battleParams, WildEncounters *encounterData, EncounterSlot *encounterTable, const WildEncounters_FieldParams *encounterFieldParams, const RadarEncounterData *param6)
// If using radar, adds radar encounters to table and tries to preserve the chain
static BOOL TryGenerateGrassEncounter_WithRadar(FieldSystem *fieldSystem, Pokemon *firstPartyMon, FieldBattleDTO *battleParams, WildEncounters *encounterData, EncounterSlot *encounterTable, const WildEncounters_FieldParams *encounterFieldParams, const RadarEncounterData *radarData)
{
BOOL v0;
BOOL encounterSuccess;
if (param6->isRadarEncounter) {
if (radarData->isRadarEncounter) {
int species, level;
if (param6->shakeType == 1) {
if (radarData->shakeType == 1) {
encounterTable[4].species = encounterData->radarEncounters[0];
encounterTable[5].species = encounterData->radarEncounters[1];
encounterTable[10].species = encounterData->radarEncounters[2];
@ -700,14 +702,14 @@ static BOOL TryGenerateGrassEncounter_WithRadar(FieldSystem *fieldSystem, Pokemo
GetRadarMon(fieldSystem->chain, &species, &level);
if (param6->preserveChain == 1) {
if (radarData->preserveChain == 1) {
TrainerInfo *v3 = SaveData_GetTrainerInfo(FieldSystem_GetSaveData(fieldSystem));
v0 = CreateWildMon_FromRadarKeepChain(species, level, 1, param6->isShiny, TrainerInfo_ID(v3), encounterFieldParams, firstPartyMon, battleParams);
encounterSuccess = CreateWildMon_FromRadarKeepChain(species, level, 1, radarData->isShiny, TrainerInfo_ID(v3), encounterFieldParams, firstPartyMon, battleParams);
} else {
v0 = CreateWildMon_FromRadarNoChain(fieldSystem, firstPartyMon, encounterFieldParams, encounterTable, 1, battleParams, species, level);
encounterSuccess = CreateWildMon_FromRadarNoChain(fieldSystem, firstPartyMon, encounterFieldParams, encounterTable, 1, battleParams, species, level);
}
if (v0) {
if (encounterSuccess) {
{
int playerX = Player_GetXPos(fieldSystem->playerAvatar);
int playerZ = Player_GetZPos(fieldSystem->playerAvatar);
@ -716,24 +718,24 @@ static BOOL TryGenerateGrassEncounter_WithRadar(FieldSystem *fieldSystem, Pokemo
}
}
} else {
v0 = TryGenerateWildMon(firstPartyMon, 0xff, encounterFieldParams, encounterTable, ENCOUNTER_TYPE_GRASS, 1, battleParams);
encounterSuccess = TryGenerateWildMon(firstPartyMon, 0xff, encounterFieldParams, encounterTable, ENCOUNTER_TYPE_GRASS, 1, battleParams);
if (v0) {
if (encounterSuccess) {
RadarChain_Clear(fieldSystem->chain);
}
}
return v0;
return encounterSuccess;
}
static BOOL TryGenerateGrassEncounter_DoubleBattle(FieldSystem *fieldSystem, Pokemon *param1, FieldBattleDTO *param2, EncounterSlot *param3, const WildEncounters_FieldParams *param4)
static BOOL TryGenerateGrassEncounter_DoubleBattle(FieldSystem *fieldSystem, Pokemon *firstPartyMon, FieldBattleDTO *battleParams, EncounterSlot *encounterTable, const WildEncounters_FieldParams *fieldParams)
{
if (!TryGenerateWildMon(param1, 0xff, param4, param3, ENCOUNTER_TYPE_GRASS, 1, param2)) {
if (!TryGenerateWildMon(firstPartyMon, 0xff, fieldParams, encounterTable, ENCOUNTER_TYPE_GRASS, 1, battleParams)) {
return FALSE;
}
BOOL v0 = TryGenerateWildMon(param1, 0xff, param4, param3, ENCOUNTER_TYPE_GRASS, 3, param2);
return v0;
BOOL encounterSuccess = TryGenerateWildMon(firstPartyMon, 0xff, fieldParams, encounterTable, ENCOUNTER_TYPE_GRASS, 3, battleParams);
return encounterSuccess;
}
static BOOL TryGenerateSurfEncounter(FieldSystem *fieldSystem, Pokemon *param1, FieldBattleDTO *param2, EncounterSlot *param3, const WildEncounters_FieldParams *param4)
@ -748,31 +750,33 @@ static BOOL TryGenerateFishingEncounter(FieldSystem *fieldSystem, Pokemon *param
static BOOL ShouldGetRandomEncounter(FieldSystem *fieldSystem, const u32 encounterRate, const u8 tileBehavior)
{
u32 v1 = encounterRate << 8;
u32 encRate = encounterRate << 8;
if (!ov6_022418B4(fieldSystem, v1)) {
fieldSystem->unk_78.unk_00++;
// lowers effective encounter rate by 95% for the first few steps after each encounter.
if (!GracePeriodStepsUsed(fieldSystem, encRate)) {
fieldSystem->unk_78.encounterAttempts++;
if (LCRNG_RandMod(100) >= 5) {
return FALSE;
}
}
u8 v0 = 40;
// flat 60% chance for the encounter attempt to fail, which is decreased by long grass, biking, and on certain dates.
u8 flatEncounterRate = 40;
if (TileBehavior_IsVeryTallGrass(tileBehavior)) {
v0 += 30;
flatEncounterRate += 30;
} else if (PlayerAvatar_GetPlayerState(fieldSystem->playerAvatar) == PLAYER_STATE_CYCLING) {
v0 += 30;
flatEncounterRate += 30;
}
v0 = ov6_02246B74(v0, sub_02055C40(fieldSystem));
flatEncounterRate = SpecialDates_ModifyEncounterRate(flatEncounterRate, sub_02055C40(fieldSystem));
if (v0 > 100) {
v0 = 100;
if (flatEncounterRate > 100) {
flatEncounterRate = 100;
}
return LCRNG_RandMod(100) < v0 && CheckEncounterRateSuccess(fieldSystem, encounterRate);
return LCRNG_RandMod(100) < flatEncounterRate && CheckEncounterRateSuccess(fieldSystem, encounterRate);
}
// Returns encounter rate. Assigns encounter type to third parameter.
@ -791,18 +795,18 @@ static u8 GetTileEncounterRateAndType(FieldSystem *fieldSystem, u8 tileBehavior,
return 0;
}
// unk78.unk00 might be "steps without encounter"? So this is suppressing encounters until you've taken (rate / 10) steps?
static BOOL ov6_022418B4(FieldSystem *fieldSystem, u32 param1)
// Suppresses the first few encounter attempts after each map transition or wild battle.
static BOOL GracePeriodStepsUsed(FieldSystem *fieldSystem, u32 encounterRate)
{
param1 = (param1 / 10) >> 8;
encounterRate = (encounterRate / 10) >> 8;
if (param1 > 8) {
param1 = 8;
if (encounterRate > 8) {
encounterRate = 8;
}
param1 = 8 - (param1);
encounterRate = 8 - (encounterRate); // higher encounter rates also lower the grace period.
return fieldSystem->unk_78.unk_00 >= param1;
return fieldSystem->unk_78.encounterAttempts >= encounterRate;
}
static BOOL CheckEncounterRateSuccess(FieldSystem *fieldSystem, u32 encounterRate)
@ -977,7 +981,7 @@ static u8 GetWildMonLevel(const EncounterSlot *slot, const WildEncounters_FieldP
// Creates a mon with a personality that will make it shiny, and complies with Cute Charm/Synchronize.
// It only has to check one or the other, not both, because only one ability can be in effect at a time.
static void CreateWildMonShinyWithGenderOrNature(const u16 species, const u8 level, const int param2, const u32 param3, const WildEncounters_FieldParams *encounterFieldParams, Pokemon *firstPartyMon, FieldBattleDTO *battleParams)
static void CreateWildMonShinyWithGenderOrNature(const u16 species, const u8 level, const int partyId, const u32 param3, const WildEncounters_FieldParams *encounterFieldParams, Pokemon *firstPartyMon, FieldBattleDTO *battleParams)
{
u8 firstMonGender;
u8 firstMonNature;
@ -1037,7 +1041,7 @@ static void CreateWildMonShinyWithGenderOrNature(const u16 species, const u8 lev
Pokemon_InitWith(newEncounter, species, level, 32, TRUE, newEncounterPersonality, OTID_SET, encounterFieldParams->trainerID);
GF_ASSERT(AddWildMonToParty(param2, encounterFieldParams, newEncounter, battleParams));
GF_ASSERT(AddWildMonToParty(partyId, encounterFieldParams, newEncounter, battleParams));
Heap_FreeToHeap(newEncounter);
}
@ -1233,12 +1237,12 @@ void CreateWildMon_Scripted(FieldSystem *fieldSystem, u16 species, u8 level, Fie
return;
}
BOOL WildEncounter_TileHasEncounterRate(FieldSystem *fieldSystem, u8 param1)
BOOL WildEncounters_TileHasEncounterRate(FieldSystem *fieldSystem, u8 tileBehavior)
{
int encounterRate = 0;
if (TileBehavior_HasEncounters(param1)) {
if (TileBehavior_IsSurfable(param1)) {
if (TileBehavior_HasEncounters(tileBehavior)) {
if (TileBehavior_IsSurfable(tileBehavior)) {
encounterRate = GetSurfEncounterRate(fieldSystem);
} else {
encounterRate = GetGrassEncounterRate(fieldSystem);
@ -1374,13 +1378,13 @@ static BOOL FirstMonAbilityPreventsEncounter(const WildEncounters_FieldParams *e
return FALSE;
}
static void CreateWildSingleBattle(FieldSystem *fieldSystem, const BOOL safariGameActive, FieldBattleDTO **param2)
static void CreateWildSingleBattle(FieldSystem *fieldSystem, const BOOL safariGameActive, FieldBattleDTO **battleParams)
{
if (!safariGameActive) {
*param2 = FieldBattleDTO_New(HEAP_ID_FIELDMAP, (0x0 | 0x0));
*battleParams = FieldBattleDTO_New(HEAP_ID_FIELDMAP, (0x0 | 0x0));
} else {
u16 *safariBallsCount = FieldOverworldState_GetSafariBallCount(SaveData_GetFieldOverworldState(fieldSystem->saveData));
*param2 = FieldBattleDTO_NewSafari(HEAP_ID_FIELDMAP, *safariBallsCount);
*battleParams = FieldBattleDTO_NewSafari(HEAP_ID_FIELDMAP, *safariBallsCount);
}
}
@ -1417,7 +1421,7 @@ static void AddRoamerToEnemyParty(const u32 trainerID, Roamer *roamer, FieldBatt
// 50% chance to encounter a roamer if there is one on the current map.
// If there are multiple on the same map, picks one randomly.
static BOOL TryEncounterRoamer(FieldSystem *fieldSystem, Roamer **param1)
static BOOL TryEncounterRoamer(FieldSystem *fieldSystem, Roamer **encounteredRoamer)
{
Roamer *roamers[ROAMING_SLOT_MAX];
@ -1440,9 +1444,9 @@ static BOOL TryEncounterRoamer(FieldSystem *fieldSystem, Roamer **param1)
}
if (numRoamersOnMap > 1) {
*param1 = roamers[LCRNG_RandMod(numRoamersOnMap)];
*encounteredRoamer = roamers[LCRNG_RandMod(numRoamersOnMap)];
} else {
*param1 = roamers[0];
*encounteredRoamer = roamers[0];
}
return TRUE;
@ -1521,7 +1525,7 @@ static void InitEncounterFieldParams(FieldSystem *fieldSystem, Pokemon *firstPar
encounterFieldParams->firstMonAbility = Pokemon_GetValue(firstPartyMon, MON_DATA_ABILITY, NULL);
} else {
encounterFieldParams->isFirstMonEgg = TRUE;
encounterFieldParams->firstMonAbility = 123;
encounterFieldParams->firstMonAbility = 123; // ABILITY_BAD_DREAMS seemingly standing in for ABILITY_NONE. Bad Dreams doesn't have a field effect anyway.
}
encounterFieldParams->firstBattlerLevel = 0;

View File

@ -2,8 +2,7 @@
#include <nitro/sinit.h>
#include <string.h>
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/struct_0206C638.h"
#include "struct_defs/special_encounter.h"
#include "overlay025/poketch_system.h"
#include "overlay047/ov47_02256634.h"
@ -14,9 +13,9 @@
#include "heap.h"
#include "inlines.h"
#include "poketch.h"
#include "special_encounter.h"
#include "sys_task.h"
#include "sys_task_manager.h"
#include "unk_0202D7A8.h"
#include "unk_0206AFE0.h"
#include "vars_flags.h"
@ -33,6 +32,8 @@ typedef struct {
u8 unk_9A;
} UnkStruct_ov47_0225621C;
// This is the Marking Map
static void NitroStaticInit(void);
static BOOL ov47_022561D4(void **param0, PoketchSystem *poketchSys, BgConfig *param2, u32 param3);
@ -322,7 +323,7 @@ static BOOL ov47_02256584(UnkStruct_ov47_0225621C *param0)
}
if (param0->unk_04.unk_3C[v3].unk_00) {
param0->unk_04.unk_3C[v3].unk_04 = Roamer_GetData(param0->unk_7C[v3], 1);
param0->unk_04.unk_3C[v3].unk_04 = Roamer_GetData(param0->unk_7C[v3], ROAMER_DATA_MAP_ID);
v0 = 1;
}
}

View File

@ -3,7 +3,7 @@
#include <string.h>
#include "field/field_system_decl.h"
#include "overlay006/ov6_022430C4.h"
#include "overlay006/radar_chain_records.h"
#include "overlay025/poketch_button.h"
#include "overlay025/poketch_system.h"
#include "overlay053/ov53_02256420.h"
@ -16,6 +16,8 @@
#include "sys_task_manager.h"
#include "touch_screen.h"
// This is the Trainer Counter.
typedef struct {
u8 unk_00;
u8 unk_01;
@ -84,7 +86,7 @@ static BOOL ov53_0225621C(UnkStruct_ov53_0225621C *param0, PoketchSystem *poketc
int v2;
fieldSystem = PoketchSystem_GetFieldSystem(poketchSys);
param0->unk_04.unk_04 = ov6_02243140(fieldSystem);
param0->unk_04.unk_04 = RadarChainRecords_GetActiveChain(fieldSystem);
if (param0->unk_04.unk_04) {
param0->unk_04.unk_00 = GetRadarSpecies(fieldSystem);
@ -93,11 +95,11 @@ static BOOL ov53_0225621C(UnkStruct_ov53_0225621C *param0, PoketchSystem *poketc
}
for (v2 = 0; v2 < 3; v2++) {
param0->unk_04.unk_14[v2] = ov6_02243114(fieldSystem, v2);
param0->unk_04.unk_08[v2] = ov6_022430E8(fieldSystem, v2);
param0->unk_04.unk_14[v2] = RadarChainRecords_GetChainCount(fieldSystem, v2);
param0->unk_04.unk_08[v2] = RadarChainRecords_GetSpecies(fieldSystem, v2);
}
param0->unk_04.unk_20 = ov6_022430C4(fieldSystem);
param0->unk_04.unk_20 = RadarChainRecords_GetNumFilledSlots(fieldSystem);
if (ov53_02256420(&(param0->unk_2C), &(param0->unk_04), param2)) {
param0->unk_00 = 0;
@ -198,7 +200,7 @@ static BOOL ov53_02256370(UnkStruct_ov53_0225621C *param0)
int v1;
fieldSystem = PoketchSystem_GetFieldSystem(param0->poketchSys);
param0->unk_04.unk_04 = ov6_02243140(fieldSystem);
param0->unk_04.unk_04 = RadarChainRecords_GetActiveChain(fieldSystem);
if (param0->unk_04.unk_04 == 0) {
v1 = 0;

View File

@ -5,7 +5,7 @@
#include "constants/field/map_load.h"
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/special_encounter.h"
#include "struct_defs/struct_0207CB08.h"
#include "struct_defs/struct_02099F80.h"
@ -36,6 +36,7 @@
#include "render_text.h"
#include "render_window.h"
#include "save_player.h"
#include "special_encounter.h"
#include "strbuf.h"
#include "string_list.h"
#include "string_template.h"
@ -50,7 +51,6 @@
#include "unk_02017728.h"
#include "unk_0201DBEC.h"
#include "unk_0201E3D8.h"
#include "unk_0202D7A8.h"
#include "unk_020393C8.h"
#include "unk_020683F4.h"
#include "unk_0207CB08.h"

View File

@ -6,12 +6,12 @@
#include "constants/battle.h"
#include "generated/sdat.h"
#include "struct_defs/radar_chain_records.h"
#include "struct_defs/struct_0201CFEC.h"
#include "struct_defs/struct_020698E4.h"
#include "field/field_system.h"
#include "overlay005/ov5_021F2D20.h"
#include "overlay006/ov6_022430C4.h"
#include "overlay006/radar_chain_records.h"
#include "overlay101/struct_ov101_021D5D90_decl.h"
#include "bag.h"
@ -23,9 +23,9 @@
#include "player_avatar.h"
#include "scrcmd.h"
#include "script_manager.h"
#include "special_encounter.h"
#include "unk_02005474.h"
#include "unk_0201CED8.h"
#include "unk_0202D7A8.h"
#include "unk_02039C80.h"
#include "unk_02054D00.h"
#include "unk_020553DC.h"
@ -57,8 +57,8 @@ typedef struct RadarChain {
static BOOL CheckTileIsGrass(FieldSystem *fieldSystem, const fx32 param1, const int param2, const int param3, const u8 param4, const u8 param5, GrassPatch *patch);
static BOOL PlayerStandingInPatch(const RadarChain *chain, const int x, const int z, u8 *patchMatch);
static void sub_020698E4(FieldSystem *fieldSystem, RadarChain *chain);
static u8 sub_0206994C(FieldSystem *fieldSystem);
static void TryReplaceLowestChainRecord(FieldSystem *fieldSystem, RadarChain *chain);
static u8 GetLowestChainRecordSlot(FieldSystem *fieldSystem);
static BOOL CheckPatchContinueChain(const u8 patchRing, const int battleResult);
static BOOL CheckPatchShiny(const int param0);
static void IncWithCap(int *param0);
@ -230,7 +230,7 @@ BOOL PokeRadar_ShouldDoRadarEncounter(const int playerX, const int playerZ, Fiel
IncWithCap(&(chain->count));
*shake = shakeType;
*preserveChain = 1;
sub_020698E4(fieldSystem, chain);
TryReplaceLowestChainRecord(fieldSystem, chain);
*isShiny = chain->patch[patchRing].shiny;
return TRUE;
} else {
@ -239,7 +239,7 @@ BOOL PokeRadar_ShouldDoRadarEncounter(const int playerX, const int playerZ, Fiel
} else {
*shake = shakeType;
chain->unk_14 = 0;
chain->unk_D0 = sub_0206994C(fieldSystem);
chain->unk_D0 = GetLowestChainRecordSlot(fieldSystem);
}
chain->shakeType = *shake;
@ -349,19 +349,19 @@ static BOOL PlayerStandingInPatch(const RadarChain *chain, const int x, const in
return FALSE;
}
static void sub_020698E4(FieldSystem *fieldSystem, RadarChain *chain)
static void TryReplaceLowestChainRecord(FieldSystem *fieldSystem, RadarChain *chain)
{
UnkStruct_020698E4 *v0 = sub_0202D830(SaveData_GetSpecialEncounters(fieldSystem->saveData));
int v1 = v0->unk_00[chain->unk_D0].unk_02;
RadarChainRecords *chainRecordData = SpecialEncounter_GetRadarChainRecords(SaveData_GetSpecialEncounters(fieldSystem->saveData));
int lowestRecord = chainRecordData->records[chain->unk_D0].chainCount;
if (v1 < chain->count) {
v0->unk_00[chain->unk_D0].unk_02 = chain->count;
v0->unk_00[chain->unk_D0].unk_00 = chain->species;
ov6_02243160(v0);
if (v0->unk_00[chain->unk_D0].unk_02 <= chain->count) {
for (int v2 = 0; v2 < 3; v2++) {
if (v0->unk_00[(2 - v2)].unk_02 == chain->count) {
chain->unk_D0 = (2 - v2);
if (lowestRecord < chain->count) {
chainRecordData->records[chain->unk_D0].chainCount = chain->count;
chainRecordData->records[chain->unk_D0].species = chain->species;
RadarChainRecords_SortSavedRecords(chainRecordData);
if (chainRecordData->records[chain->unk_D0].chainCount <= chain->count) {
for (int v2 = 0; v2 < NUM_RADAR_RECORDS; v2++) {
if (chainRecordData->records[((NUM_RADAR_RECORDS - 1) - v2)].chainCount == chain->count) {
chain->unk_D0 = ((NUM_RADAR_RECORDS - 1) - v2);
return;
}
}
@ -370,31 +370,32 @@ static void sub_020698E4(FieldSystem *fieldSystem, RadarChain *chain)
}
}
static u8 sub_0206994C(FieldSystem *fieldSystem)
// Returns the index of the record with the lowest chain, or the first empty slot if there is one.
static u8 GetLowestChainRecordSlot(FieldSystem *fieldSystem)
{
u8 v1;
BOOL v2;
UnkStruct_020698E4 *v0 = sub_0202D830(SaveData_GetSpecialEncounters(fieldSystem->saveData));
u8 slotToReplace;
BOOL lowerChain;
RadarChainRecords *recordsData = SpecialEncounter_GetRadarChainRecords(SaveData_GetSpecialEncounters(fieldSystem->saveData));
for (v1 = 0; v1 < 3; v1++) {
if (v0->unk_00[v1].unk_00 == 0) {
return v1;
for (slotToReplace = 0; slotToReplace < NUM_RADAR_RECORDS; slotToReplace++) {
if (recordsData->records[slotToReplace].species == 0) {
return slotToReplace;
}
}
(v0->unk_00[0].unk_02 < v0->unk_00[1].unk_02) ? (v2 = 1) : (v2 = 0);
if (v2) {
v1 = 0;
(recordsData->records[0].chainCount < recordsData->records[1].chainCount) ? (lowerChain = 1) : (lowerChain = 0);
if (lowerChain) {
slotToReplace = 0;
} else {
v1 = 1;
slotToReplace = 1;
}
(v0->unk_00[v1].unk_02 < v0->unk_00[2].unk_02) ? (v2 = 1) : (v2 = 0);
if (!v2) {
v1 = 2;
(recordsData->records[slotToReplace].chainCount < recordsData->records[2].chainCount) ? (lowerChain = 1) : (lowerChain = 0);
if (!lowerChain) {
slotToReplace = 2;
}
return v1;
return slotToReplace;
}
static BOOL CheckPatchContinueChain(const u8 patchRing, const int battleResult)
@ -488,7 +489,7 @@ static BOOL CheckPatchShiny(const int chainCount)
void RadarChain_Increment(FieldSystem *fieldSystem)
{
IncWithCap(&(fieldSystem->chain->count));
sub_020698E4(fieldSystem, fieldSystem->chain);
TryReplaceLowestChainRecord(fieldSystem, fieldSystem->chain);
}
int GetChainCount(FieldSystem *fieldSystem)

View File

@ -4,211 +4,241 @@
#include <string.h>
#include "constants/species.h"
#include "generated/map_headers.h"
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/struct_0206C638.h"
#include "struct_defs/special_encounter.h"
#include "heap.h"
#include "inlines.h"
#include "pokemon.h"
#include "save_player.h"
#include "savedata.h"
#include "special_encounter.h"
#include "trainer_info.h"
#include "unk_0202D7A8.h"
typedef struct {
u16 unk_00;
u16 unk_02[5];
} UnkStruct_020EFBB8;
enum RoamerRouteIndex {
RI_ROUTE_201 = 0,
RI_ROUTE_202,
RI_ROUTE_203,
RI_ROUTE_204_SOUTH,
RI_ROUTE_204_NORTH,
RI_ROUTE_205_SOUTH,
RI_ROUTE_205_NORTH,
RI_ROUTE_206,
RI_ROUTE_207,
RI_ROUTE_208,
RI_ROUTE_209,
RI_ROUTE_210_SOUTH,
RI_ROUTE_210_NORTH,
RI_ROUTE_211_WEST,
RI_ROUTE_211_EAST,
RI_ROUTE_212_NORTH,
RI_ROUTE_212_SOUTH,
RI_ROUTE_213,
RI_ROUTE_214,
RI_ROUTE_215,
RI_ROUTE_216,
RI_ROUTE_217,
RI_ROUTE_218,
RI_ROUTE_219,
RI_ROUTE_220,
RI_ROUTE_221,
RI_ROUTE_222,
RI_VALLEY_WINDWORKS_OUTSIDE,
RI_FUEGO_IRONWORKS_OUTSIDE,
RI_MAX,
};
static void sub_0206C538(SpecialEncounter *param0, const u8 param1, const int param2);
static void sub_0206C588(SpecialEncounter *param0, const u8 param1, const int param2);
static void sub_0206C638(SpecialEncounter *param0, const u8 param1, const u8 param2, const int param3);
typedef struct NearbyRoutes {
u16 numPossibilities;
u16 adjacentRouteIndexes[5];
} NearbyRoutes;
static const UnkStruct_020EFBB8 Unk_020EFBB8[29] = {
{
0x2,
{ 0x1, 0x17, 0xffff, 0xffff, 0xffff },
static void MoveRoamerRandom(SpecialEncounter *speEnc, const u8 roamerSlot, const int playerPreviousMap);
static void MoveRoamerNearby(SpecialEncounter *param0, const u8 roamerSlot, const int playerPreviousMap);
static void SetNewMapLocation(SpecialEncounter *speEnc, const u8 roamerSlot, const u8 newMapIndex, const int newMapId);
// Includes adjacent routes as well as routes connected to adjacent towns.
// e.g. Route 202's entry includes both routes connected to Sandgem Town and all 3 routes connected to Jubilife City.
static const NearbyRoutes sNearbyRoutes[RI_MAX] = {
[RI_ROUTE_201] = {
2,
{ RI_ROUTE_202, RI_ROUTE_219, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x5,
{ 0x0, 0x2, 0x3, 0x16, 0x17 },
[RI_ROUTE_202] = {
5,
{ RI_ROUTE_201, RI_ROUTE_203, RI_ROUTE_204_SOUTH, RI_ROUTE_218, RI_ROUTE_219 },
},
{
0x4,
{ 0x1, 0x3, 0x8, 0x16, 0xffff },
[RI_ROUTE_203] = {
4,
{ RI_ROUTE_202, RI_ROUTE_204_SOUTH, RI_ROUTE_207, RI_ROUTE_218, 0xFFFF },
},
{
0x4,
{ 0x1, 0x2, 0x4, 0x16, 0xffff },
[RI_ROUTE_204_SOUTH] = {
4,
{ RI_ROUTE_202, RI_ROUTE_203, RI_ROUTE_204_NORTH, RI_ROUTE_218, 0xFFFF },
},
{
0x2,
{ 0x3, 0x5, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_204_NORTH] = {
2,
{ RI_ROUTE_204_SOUTH, RI_ROUTE_205_SOUTH, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x4,
{ 0x4, 0x6, 0x1B, 0x1C, 0xffff },
[RI_ROUTE_205_SOUTH] = {
4,
{ RI_ROUTE_204_NORTH, RI_ROUTE_205_NORTH, RI_VALLEY_WINDWORKS_OUTSIDE, RI_FUEGO_IRONWORKS_OUTSIDE, 0xFFFF },
},
{
0x3,
{ 0x5, 0x7, 0x9, 0xffff, 0xffff },
[RI_ROUTE_205_NORTH] = {
3,
{ RI_ROUTE_205_SOUTH, RI_ROUTE_206, 9, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x6, 0x8, 0xD, 0xffff, 0xffff },
[RI_ROUTE_206] = {
3,
{ RI_ROUTE_205_NORTH, RI_ROUTE_207, RI_ROUTE_211_WEST, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x2, 0x7, 0x9, 0xffff, 0xffff },
[RI_ROUTE_207] = {
3,
{ RI_ROUTE_203, RI_ROUTE_206, RI_ROUTE_208, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x8, 0xA, 0xF, 0xffff, 0xffff },
[RI_ROUTE_208] = {
3,
{ RI_ROUTE_207, RI_ROUTE_209, RI_ROUTE_212_NORTH, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x9, 0xB, 0xF, 0xffff, 0xffff },
[RI_ROUTE_209] = {
3,
{ RI_ROUTE_208, RI_ROUTE_210_SOUTH, RI_ROUTE_212_NORTH, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0xA, 0xC, 0x13, 0xffff, 0xffff },
[RI_ROUTE_210_SOUTH] = {
3,
{ RI_ROUTE_209, RI_ROUTE_210_NORTH, RI_ROUTE_215, 0xFFFF, 0xFFFF },
},
{
0x2,
{ 0xB, 0xE, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_210_NORTH] = {
2,
{ RI_ROUTE_210_SOUTH, RI_ROUTE_211_EAST, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x4,
{ 0x6, 0x7, 0xE, 0x14, 0xffff },
[RI_ROUTE_211_WEST] = {
4,
{ RI_ROUTE_205_NORTH, RI_ROUTE_206, RI_ROUTE_211_EAST, RI_ROUTE_216, 0xFFFF },
},
{
0x3,
{ 0xC, 0xD, 0x14, 0xffff },
[RI_ROUTE_211_EAST] = {
3,
{ RI_ROUTE_210_NORTH, RI_ROUTE_211_WEST, RI_ROUTE_216, 0xFFFF },
},
{
0x3,
{ 0x9, 0xA, 0x10, 0xffff, 0xffff },
[RI_ROUTE_212_NORTH] = {
3,
{ RI_ROUTE_208, RI_ROUTE_209, RI_ROUTE_212_SOUTH, 0xFFFF, 0xFFFF },
},
{
0x2,
{ 0xF, 0x11, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_212_SOUTH] = {
2,
{ RI_ROUTE_212_NORTH, RI_ROUTE_213, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x10, 0x12, 0x1A, 0xffff, 0xffff },
[RI_ROUTE_213] = {
3,
{ RI_ROUTE_212_SOUTH, RI_ROUTE_214, RI_ROUTE_222, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x11, 0x13, 0x1A, 0xffff, 0xffff },
[RI_ROUTE_214] = {
3,
{ RI_ROUTE_213, RI_ROUTE_215, RI_ROUTE_222, 0xFFFF, 0xFFFF },
},
{
0x2,
{ 0xB, 0x12, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_215] = {
2,
{ RI_ROUTE_210_SOUTH, RI_ROUTE_214, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0xD, 0xE, 0x15, 0xffff, 0xffff },
[RI_ROUTE_216] = {
3,
{ RI_ROUTE_211_WEST, RI_ROUTE_211_EAST, RI_ROUTE_217, 0xFFFF, 0xFFFF },
},
{
0x1,
{ 0x14, 0xffff, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_217] = {
1,
{ RI_ROUTE_216, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x1, 0x2, 0x3, 0xffff, 0xffff },
[RI_ROUTE_218] = {
3,
{ RI_ROUTE_202, RI_ROUTE_203, RI_ROUTE_204_SOUTH, 0xFFFF, 0xFFFF },
},
{
0x3,
{ 0x0, 0x1, 0x18, 0xffff, 0xffff },
[RI_ROUTE_219] = {
3,
{ RI_ROUTE_201, RI_ROUTE_202, RI_ROUTE_220, 0xFFFF, 0xFFFF },
},
{
0x2,
{ 0x17, 0x19, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_220] = {
2,
{ RI_ROUTE_219, RI_ROUTE_221, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x1,
{ 0x18, 0xffff, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_221] = {
1,
{ RI_ROUTE_220, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x2,
{ 0x11, 0x12, 0xffff, 0xffff, 0xffff },
[RI_ROUTE_222] = {
2,
{ RI_ROUTE_213, RI_ROUTE_214, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x1,
{ 0x5, 0xffff, 0xffff, 0xffff, 0xffff },
[RI_VALLEY_WINDWORKS_OUTSIDE] = {
1,
{ RI_ROUTE_205_SOUTH, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF },
},
{
0x1,
{ 0x5, 0xffff, 0xffff, 0xffff, 0xffff },
[RI_FUEGO_IRONWORKS_OUTSIDE] = {
1,
{ RI_ROUTE_205_SOUTH, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF },
},
};
static const int RoamingPokemonRoutes[29] = {
0x156,
0x157,
0x158,
0x159,
0x15A,
0x15B,
0x15D,
0x15E,
0x161,
0x162,
0x164,
0x16A,
0x16B,
0x16D,
0x16E,
0x16F,
0x173,
0x175,
0x17C,
0x17E,
0x17F,
0x181,
0x184,
0x187,
0x1D3,
0x188,
0x18B,
0xC8,
0xCC,
// All outdoor areas with encounters on the mainland except Trophy Garden, Great Marsh, and the ones past Sunyshore City
static const int RoamingPokemonRoutes[RI_MAX] = {
[RI_ROUTE_201] = MAP_HEADER_ROUTE_201,
[RI_ROUTE_202] = MAP_HEADER_ROUTE_202,
[RI_ROUTE_203] = MAP_HEADER_ROUTE_203,
[RI_ROUTE_204_SOUTH] = MAP_HEADER_ROUTE_204_SOUTH,
[RI_ROUTE_204_NORTH] = MAP_HEADER_ROUTE_204_NORTH,
[RI_ROUTE_205_SOUTH] = MAP_HEADER_ROUTE_205_SOUTH,
[RI_ROUTE_205_NORTH] = MAP_HEADER_ROUTE_205_NORTH,
[RI_ROUTE_206] = MAP_HEADER_ROUTE_206,
[RI_ROUTE_207] = MAP_HEADER_ROUTE_207,
[RI_ROUTE_208] = MAP_HEADER_ROUTE_208,
[RI_ROUTE_209] = MAP_HEADER_ROUTE_209,
[RI_ROUTE_210_SOUTH] = MAP_HEADER_ROUTE_210_SOUTH,
[RI_ROUTE_210_NORTH] = MAP_HEADER_ROUTE_210_NORTH,
[RI_ROUTE_211_WEST] = MAP_HEADER_ROUTE_211_WEST,
[RI_ROUTE_211_EAST] = MAP_HEADER_ROUTE_211_EAST,
[RI_ROUTE_212_NORTH] = MAP_HEADER_ROUTE_212_NORTH,
[RI_ROUTE_212_SOUTH] = MAP_HEADER_ROUTE_212_SOUTH,
[RI_ROUTE_213] = MAP_HEADER_ROUTE_213,
[RI_ROUTE_214] = MAP_HEADER_ROUTE_214,
[RI_ROUTE_215] = MAP_HEADER_ROUTE_215,
[RI_ROUTE_216] = MAP_HEADER_ROUTE_216,
[RI_ROUTE_217] = MAP_HEADER_ROUTE_217,
[RI_ROUTE_218] = MAP_HEADER_ROUTE_218,
[RI_ROUTE_219] = MAP_HEADER_ROUTE_219,
[RI_ROUTE_220] = MAP_HEADER_ROUTE_220,
[RI_ROUTE_221] = MAP_HEADER_ROUTE_221,
[RI_ROUTE_222] = MAP_HEADER_ROUTE_222,
[RI_VALLEY_WINDWORKS_OUTSIDE] = MAP_HEADER_VALLEY_WINDWORKS_OUTSIDE,
[RI_FUEGO_IRONWORKS_OUTSIDE] = MAP_HEADER_FUEGO_IRONWORKS_OUTSIDE,
};
void sub_0206C33C(SpecialEncounter *param0, const u8 param1)
void RoamingPokemon_MoveToRandomMap(SpecialEncounter *speEnc, const u8 roamerSlot)
{
int v0;
v0 = sub_0202D8BC(param0);
sub_0206C538(param0, param1, v0);
int previousMap = SpecialEncounter_GetPlayerPreviousMap(speEnc);
MoveRoamerRandom(speEnc, roamerSlot, previousMap);
}
void sub_0206C354(SpecialEncounter *param0)
// Used when Teleporting/Flying
void RoamingPokemon_RandomizeAllLocations(SpecialEncounter *speEnc)
{
u8 v0;
for (v0 = 0; v0 < 6; v0++) {
if (SpecialEncounter_IsRoamerActive(param0, v0)) {
sub_0206C33C(param0, v0);
for (u8 i = 0; i < ROAMING_SLOT_MAX; i++) {
if (SpecialEncounter_IsRoamerActive(speEnc, i)) {
RoamingPokemon_MoveToRandomMap(speEnc, i);
}
}
}
void sub_0206C37C(SpecialEncounter *param0)
// Moves all Roamers. For each, it has a 1/16 chance to randomize its location. Otherwise, it will move to a nearby route.
void RoamingPokemon_MoveAllLocations(SpecialEncounter *specialEncounter)
{
u8 v0;
for (v0 = 0; v0 < 6; v0++) {
if (SpecialEncounter_IsRoamerActive(param0, v0)) {
for (u8 i = 0; i < ROAMING_SLOT_MAX; i++) {
if (SpecialEncounter_IsRoamerActive(specialEncounter, i)) {
if (LCRNG_RandMod(16) == 0) {
sub_0206C33C(param0, v0);
RoamingPokemon_MoveToRandomMap(specialEncounter, i);
} else {
{
int v1;
v1 = sub_0202D8BC(param0);
sub_0206C588(param0, v0, v1);
int previousMap = SpecialEncounter_GetPlayerPreviousMap(specialEncounter);
MoveRoamerNearby(specialEncounter, i, previousMap);
}
}
}
@ -217,42 +247,42 @@ void sub_0206C37C(SpecialEncounter *param0)
int RoamingPokemon_GetRouteFromId(const u8 routeId)
{
GF_ASSERT(routeId < 29);
GF_ASSERT(routeId < RI_MAX);
return RoamingPokemonRoutes[routeId];
}
BOOL sub_0206C3E0(SpecialEncounter *param0)
BOOL RoamingPokemon_AnyRoamersActive(SpecialEncounter *speEnc)
{
u8 v0;
for (v0 = 0; v0 < 6; v0++) {
if (SpecialEncounter_IsRoamerActive(param0, v0)) {
return 1;
for (u8 i = 0; i < ROAMING_SLOT_MAX; i++) {
if (SpecialEncounter_IsRoamerActive(speEnc, i)) {
return TRUE;
}
}
return 0;
return FALSE;
}
void sub_0206C404(SpecialEncounter *param0, const int param1)
// Runs when the player changes maps. Roamers cannot move to the map the player just left.
void RoamingPokemon_UpdatePlayerRecentRoutes(SpecialEncounter *speEnc, const int newMap)
{
if (sub_0206C3E0(param0)) {
sub_0202D8A4(param0, param1);
if (RoamingPokemon_AnyRoamersActive(speEnc)) {
SpecialEncounter_UpdateRecentRoutes(speEnc, newMap);
}
}
void RoamingPokemon_ActivateSlot(SaveData *saveData, const u8 slot)
{
Pokemon *v0;
Roamer *v1;
SpecialEncounter *v2;
Pokemon *roamerMonData;
Roamer *newRoamer;
SpecialEncounter *speEnc;
int previouslyVisitedMap;
TrainerInfo *v4;
TrainerInfo *trainer;
int species;
u8 level;
v2 = SaveData_GetSpecialEncounters(saveData);
v1 = SpecialEncounter_GetRoamer(v2, slot);
speEnc = SaveData_GetSpecialEncounters(saveData);
newRoamer = SpecialEncounter_GetRoamer(speEnc, slot);
switch (slot) {
case ROAMING_SLOT_MESPRIT:
@ -284,83 +314,83 @@ void RoamingPokemon_ActivateSlot(SaveData *saveData, const u8 slot)
return;
}
Roamer_SetData(v1, ROAMER_DATA_SPECIES, species);
Roamer_SetData(v1, ROAMER_DATA_LEVEL, level);
Roamer_SetData(newRoamer, ROAMER_DATA_SPECIES, species);
Roamer_SetData(newRoamer, ROAMER_DATA_LEVEL, level);
v4 = SaveData_GetTrainerInfo(saveData);
v0 = Pokemon_New(4);
trainer = SaveData_GetTrainerInfo(saveData);
roamerMonData = Pokemon_New(4);
Pokemon_Init(v0);
Pokemon_InitWith(v0, species, level, 32, FALSE, 0, OTID_SET, TrainerInfo_ID_LowHalf(v4));
Roamer_SetData(v1, ROAMER_DATA_STATUS, 0);
Roamer_SetData(v1, ROAMER_DATA_ACTIVE, 1);
Roamer_SetData(v1, ROAMER_DATA_IVS, Pokemon_GetValue(v0, MON_DATA_COMBINED_IVS, NULL));
Roamer_SetData(v1, ROAMER_DATA_PERSONALITY, Pokemon_GetValue(v0, MON_DATA_PERSONALITY, NULL));
Roamer_SetData(v1, ROAMER_DATA_CURRENT_HP, Pokemon_GetValue(v0, MON_DATA_MAX_HP, NULL));
Heap_FreeToHeap(v0);
Pokemon_Init(roamerMonData);
Pokemon_InitWith(roamerMonData, species, level, 32, FALSE, 0, OTID_SET, TrainerInfo_ID_LowHalf(trainer));
Roamer_SetData(newRoamer, ROAMER_DATA_STATUS, 0);
Roamer_SetData(newRoamer, ROAMER_DATA_ACTIVE, 1);
Roamer_SetData(newRoamer, ROAMER_DATA_IVS, Pokemon_GetValue(roamerMonData, MON_DATA_COMBINED_IVS, NULL));
Roamer_SetData(newRoamer, ROAMER_DATA_PERSONALITY, Pokemon_GetValue(roamerMonData, MON_DATA_PERSONALITY, NULL));
Roamer_SetData(newRoamer, ROAMER_DATA_CURRENT_HP, Pokemon_GetValue(roamerMonData, MON_DATA_MAX_HP, NULL));
Heap_FreeToHeap(roamerMonData);
previouslyVisitedMap = sub_0202D8BC(v2);
sub_0206C538(v2, slot, previouslyVisitedMap);
previouslyVisitedMap = SpecialEncounter_GetPlayerPreviousMap(speEnc);
MoveRoamerRandom(speEnc, slot, previouslyVisitedMap);
}
static void sub_0206C538(SpecialEncounter *param0, const u8 param1, const int param2)
static void MoveRoamerRandom(SpecialEncounter *specialEncounter, const u8 roamerSlot, const int playerPreviousMap)
{
u8 v0;
int v1;
int v2;
u8 newIndex;
int currentRoute;
int newRoute;
v1 = RoamingPokemonRoutes[SpecialEncounter_GetRoamerRouteIndex(param0, param1)];
currentRoute = RoamingPokemonRoutes[SpecialEncounter_GetRoamerRouteIndex(specialEncounter, roamerSlot)];
while (TRUE) {
v0 = LCRNG_RandMod(29);
v2 = RoamingPokemonRoutes[v0];
newIndex = LCRNG_RandMod(RI_MAX);
newRoute = RoamingPokemonRoutes[newIndex];
if ((v2 != param2) && (v2 != v1)) {
sub_0206C638(param0, param1, v0, v2);
if ((newRoute != playerPreviousMap) && (newRoute != currentRoute)) {
SetNewMapLocation(specialEncounter, roamerSlot, newIndex, newRoute);
break;
}
}
}
static void sub_0206C588(SpecialEncounter *param0, const u8 param1, const int param2)
static void MoveRoamerNearby(SpecialEncounter *specialEncounter, const u8 roamerSlot, const int playerPreviousMap)
{
const UnkStruct_020EFBB8 *v0;
u8 v1;
int v2;
const NearbyRoutes *possibleNewRoutes;
u8 newMapIndex;
int newMapId;
v0 = &(Unk_020EFBB8[SpecialEncounter_GetRoamerRouteIndex(param0, param1)]);
possibleNewRoutes = &(sNearbyRoutes[SpecialEncounter_GetRoamerRouteIndex(specialEncounter, roamerSlot)]);
if (v0->unk_00 == 1) {
v1 = v0->unk_02[0];
v2 = RoamingPokemonRoutes[v1];
if (possibleNewRoutes->numPossibilities == 1) {
newMapIndex = possibleNewRoutes->adjacentRouteIndexes[0];
newMapId = RoamingPokemonRoutes[newMapIndex];
if (v2 == param2) {
sub_0206C538(param0, param1, param2);
if (newMapId == playerPreviousMap) {
MoveRoamerRandom(specialEncounter, roamerSlot, playerPreviousMap);
} else {
sub_0206C638(param0, param1, v1, v2);
SetNewMapLocation(specialEncounter, roamerSlot, newMapIndex, newMapId);
}
} else {
u8 v3;
u8 nearbyIndex;
while (TRUE) {
v3 = LCRNG_RandMod(v0->unk_00);
v1 = v0->unk_02[v3];
v2 = RoamingPokemonRoutes[v1];
nearbyIndex = LCRNG_RandMod(possibleNewRoutes->numPossibilities);
newMapIndex = possibleNewRoutes->adjacentRouteIndexes[nearbyIndex];
newMapId = RoamingPokemonRoutes[newMapIndex];
if (v2 != param2) {
sub_0206C638(param0, param1, v1, v2);
if (newMapId != playerPreviousMap) {
SetNewMapLocation(specialEncounter, roamerSlot, newMapIndex, newMapId);
break;
}
}
}
}
static void sub_0206C638(SpecialEncounter *param0, const u8 param1, const u8 param2, const int param3)
static void SetNewMapLocation(SpecialEncounter *specialEncounter, const u8 roamerSlot, const u8 newMapIndex, const int newMapId)
{
Roamer *v0;
Roamer *roamer;
v0 = SpecialEncounter_GetRoamer(param0, param1);
roamer = SpecialEncounter_GetRoamer(specialEncounter, roamerSlot);
SpecialEncounter_SetRoamerRouteIndex(param0, param1, param2);
Roamer_SetData(v0, 1, param3);
SpecialEncounter_SetRoamerRouteIndex(specialEncounter, roamerSlot, newMapIndex);
Roamer_SetData(roamer, ROAMER_DATA_MAP_ID, newMapId);
}

View File

@ -15,6 +15,7 @@
#include "save_player.h"
#include "savedata.h"
#include "savedata_misc.h"
#include "special_encounter.h"
#include "system_data.h"
#include "unk_02014D38.h"
#include "unk_0202602C.h"
@ -29,7 +30,6 @@
#include "unk_0202C9F4.h"
#include "unk_0202CC64.h"
#include "unk_0202D778.h"
#include "unk_0202D7A8.h"
#include "unk_0202DA40.h"
#include "unk_0202DAB4.h"
#include "unk_0202DF8C.h"

View File

@ -31,7 +31,7 @@
#include "struct_decls/struct_02061AB4_decl.h"
#include "struct_decls/struct_020797DC_decl.h"
#include "struct_defs/choose_starter_data.h"
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/special_encounter.h"
#include "struct_defs/struct_0202DF8C.h"
#include "struct_defs/struct_0203D8AC.h"
#include "struct_defs/struct_0203E608.h"
@ -66,7 +66,6 @@
#include "overlay006/ov6_0223E140.h"
#include "overlay006/ov6_02242AF0.h"
#include "overlay006/ov6_02243004.h"
#include "overlay006/ov6_02243218.h"
#include "overlay006/ov6_02243258.h"
#include "overlay006/ov6_02246184.h"
#include "overlay006/ov6_02246C24.h"
@ -77,6 +76,7 @@
#include "overlay006/ov6_02247F5C.h"
#include "overlay006/ov6_02248948.h"
#include "overlay006/struct_ov6_02246204_decl.h"
#include "overlay006/swarm.h"
#include "overlay006/trophy_garden_daily_encounters.h"
#include "overlay007/communication_club.h"
#include "overlay007/ov7_0224B4E8.h"
@ -131,6 +131,7 @@
#include "savedata.h"
#include "scrcmd_system_flags.h"
#include "script_manager.h"
#include "special_encounter.h"
#include "strbuf.h"
#include "string_template.h"
#include "sys_task.h"
@ -149,7 +150,6 @@
#include "unk_020298BC.h"
#include "unk_0202ACE0.h"
#include "unk_0202C9F4.h"
#include "unk_0202D7A8.h"
#include "unk_0202DF8C.h"
#include "unk_02033200.h"
#include "unk_020363E8.h"

View File

@ -1,11 +1,10 @@
#include "unk_0202D7A8.h"
#include "special_encounter.h"
#include <nitro.h>
#include <string.h>
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/struct_020698E4.h"
#include "struct_defs/struct_0206C638.h"
#include "struct_defs/radar_chain_records.h"
#include "struct_defs/special_encounter.h"
#include "math.h"
#include "roaming_pokemon.h"
@ -16,19 +15,19 @@ int SpecialEncounter_SaveSize(void)
return sizeof(SpecialEncounter);
}
void SpecialEncounter_Init(SpecialEncounter *param0)
void SpecialEncounter_Init(SpecialEncounter *specialEncounter)
{
memset(param0, 0, sizeof(SpecialEncounter));
memset(specialEncounter, 0, sizeof(SpecialEncounter));
param0->marshDaily = MTRNG_Next();
param0->swarmDaily = MTRNG_Next();
param0->trophyGarden.unused = 0;
param0->trophyGarden.slot1 = TROPHY_GARDEN_SLOT_NONE;
param0->trophyGarden.slot2 = TROPHY_GARDEN_SLOT_NONE;
specialEncounter->marshDaily = MTRNG_Next();
specialEncounter->swarmDaily = MTRNG_Next();
specialEncounter->trophyGarden.unused = 0;
specialEncounter->trophyGarden.slot1 = TROPHY_GARDEN_SLOT_NONE;
specialEncounter->trophyGarden.slot2 = TROPHY_GARDEN_SLOT_NONE;
{
int i;
HoneyTreeData *v1 = &(param0->treeData);
HoneyTreeData *v1 = &(specialEncounter->treeData);
v1->lastSlatheredTree = NUM_HONEY_TREES;
@ -41,10 +40,10 @@ void SpecialEncounter_Init(SpecialEncounter *param0)
}
}
param0->swarmEnabled = 0;
param0->repelSteps = 0;
param0->radarCharge = 0;
param0->fluteFactor = FLUTE_FACTOR_NONE;
specialEncounter->swarmEnabled = 0;
specialEncounter->repelSteps = 0;
specialEncounter->radarCharge = 0;
specialEncounter->fluteFactor = FLUTE_FACTOR_NONE;
}
void SpecialEncounter_SetMixedRecordDailies(SpecialEncounter *speEnc, const u32 mixedRecord)
@ -53,22 +52,22 @@ void SpecialEncounter_SetMixedRecordDailies(SpecialEncounter *speEnc, const u32
speEnc->swarmDaily = mixedRecord;
}
u32 SpecialEncounter_GetDailyMon(SpecialEncounter *param0, const u8 dailyType)
u32 SpecialEncounter_GetDailyMon(SpecialEncounter *speEnc, const u8 dailyType)
{
switch (dailyType) {
case DAILY_MARSH:
return param0->marshDaily;
return speEnc->marshDaily;
case DAILY_SWARM:
return param0->swarmDaily;
return speEnc->swarmDaily;
default:
GF_ASSERT(0);
return 0;
}
}
UnkStruct_020698E4 *sub_0202D830(SpecialEncounter *param0)
RadarChainRecords *SpecialEncounter_GetRadarChainRecords(SpecialEncounter *speEnc)
{
return &(param0->unk_BC);
return &(speEnc->chainRecords);
}
SpecialEncounter *SaveData_GetSpecialEncounters(SaveData *speEnc)
@ -95,12 +94,11 @@ void SpecialEncounter_SetLastSlatheredTreeId(const u8 treeId, HoneyTreeData *tre
// Inconsistency: Roamers have bounds checking on the IDs used, but Honey Trees don't
HoneyTree *SpecialEncounter_GetHoneyTree(const u8 treeId, HoneyTreeData *treeDat)
{
HoneyTree *tree;
tree = &treeDat->honeyTrees[treeId];
HoneyTree *tree = &treeDat->honeyTrees[treeId];
return tree;
}
// These are minute timers. They start at 24 hours'worth of minutes
void SpecialEncounter_DecrementHoneyTreeTimers(SaveData *save, const int decrement)
{
int i;
@ -126,9 +124,7 @@ void SpecialEncounter_DecrementHoneyTreeTimers(SaveData *save, const int decreme
void SpecialEncounter_EnableSwarms(SaveData *saveData)
{
SpecialEncounter *speEnc;
speEnc = SaveData_GetSpecialEncounters(saveData);
SpecialEncounter *speEnc = SaveData_GetSpecialEncounters(saveData);
speEnc->swarmEnabled = 1;
}
@ -137,17 +133,17 @@ u8 SpecialEncounter_IsSwarmEnabled(SpecialEncounter *speEnc)
return speEnc->swarmEnabled;
}
void sub_0202D8A4(SpecialEncounter *param0, const int param1)
void SpecialEncounter_UpdateRecentRoutes(SpecialEncounter *speEnc, const int newMap)
{
if (param0->unk_C8.unk_00 != param1) {
param0->unk_C8.unk_04 = param0->unk_C8.unk_00;
param0->unk_C8.unk_00 = param1;
if (speEnc->recentRoutes.currentMapId != newMap) {
speEnc->recentRoutes.previousMapId = speEnc->recentRoutes.currentMapId;
speEnc->recentRoutes.currentMapId = newMap;
}
}
int sub_0202D8BC(SpecialEncounter *param0)
int SpecialEncounter_GetPlayerPreviousMap(SpecialEncounter *speEnc)
{
return param0->unk_C8.unk_04;
return speEnc->recentRoutes.previousMapId;
}
u8 SpecialEncounter_GetRoamerRouteIndex(SpecialEncounter *speEnc, const u8 roamerId)
@ -181,11 +177,11 @@ Roamer *SpecialEncounter_GetRoamer(SpecialEncounter *speEnc, const u8 slot)
u32 Roamer_GetData(const Roamer *roamer, const u8 dataType)
{
u32 data;
u32 data; // awesome uninitialized variable with no default case
switch (dataType) {
case 1:
data = roamer->unk_00;
case ROAMER_DATA_MAP_ID:
data = roamer->currentMapId;
break;
case ROAMER_DATA_IVS:
data = roamer->ivs;
@ -215,11 +211,9 @@ u32 Roamer_GetData(const Roamer *roamer, const u8 dataType)
void Roamer_SetData(Roamer *roamer, const u8 dataType, const u32 data)
{
u32 v0;
switch (dataType) {
case 1:
roamer->unk_00 = data;
case ROAMER_DATA_MAP_ID:
roamer->currentMapId = data;
break;
case ROAMER_DATA_IVS:
roamer->ivs = data;
@ -245,22 +239,22 @@ void Roamer_SetData(Roamer *roamer, const u8 dataType, const u32 data)
}
}
u8 *SpecialEncounter_GetRadarCharge(SpecialEncounter *param0)
u8 *SpecialEncounter_GetRadarCharge(SpecialEncounter *speEnc)
{
return &(param0->radarCharge);
return &(speEnc->radarCharge);
}
u8 *SpecialEncounter_GetRepelSteps(SpecialEncounter *param0)
u8 *SpecialEncounter_GetRepelSteps(SpecialEncounter *speEnc)
{
return &(param0->repelSteps);
return &(speEnc->repelSteps);
}
BOOL SpecialEncounter_RepelStepsEmpty(SpecialEncounter *param0)
BOOL SpecialEncounter_RepelStepsEmpty(SpecialEncounter *speEnc)
{
if (!param0->repelSteps) {
return 1;
if (!speEnc->repelSteps) {
return TRUE;
} else {
return 0;
return FALSE;
}
}

View File

@ -15,10 +15,10 @@
#include "record_mixed_rng.h"
#include "rtc.h"
#include "script_manager.h"
#include "special_encounter.h"
#include "system_data.h"
#include "unk_0202854C.h"
#include "unk_0202C858.h"
#include "unk_0202D7A8.h"
#include "unk_0202E2CC.h"
#include "unk_02055C50.h"
#include "unk_0206AFE0.h"

View File

@ -11,7 +11,7 @@
#include "struct_decls/struct_0202440C_decl.h"
#include "struct_decls/struct_02029C68_decl.h"
#include "struct_decls/struct_0202A750_decl.h"
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/special_encounter.h"
#include "struct_defs/struct_0202E7D8.h"
#include "struct_defs/struct_0202E7E4.h"
#include "struct_defs/struct_0202E7F0.h"
@ -21,13 +21,12 @@
#include "struct_defs/struct_0202E81C.h"
#include "struct_defs/struct_0202E828.h"
#include "struct_defs/struct_0202E834.h"
#include "struct_defs/struct_0206C638.h"
#include "field/field_system.h"
#include "field/field_system_sub2_t.h"
#include "overlay006/ov6_02243218.h"
#include "overlay006/ov6_02246444.h"
#include "overlay006/struct_ov6_022465F4_decl.h"
#include "overlay006/swarm.h"
#include "overlay025/poketch_system.h"
#include "savedata/save_table.h"
@ -50,12 +49,12 @@
#include "save_player.h"
#include "savedata.h"
#include "savedata_misc.h"
#include "special_encounter.h"
#include "strbuf.h"
#include "string_template.h"
#include "system_flags.h"
#include "trainer_info.h"
#include "unk_020298BC.h"
#include "unk_0202D7A8.h"
#include "unk_0202E2CC.h"
#include "unk_0203A944.h"
#include "unk_02054884.h"

View File

@ -3,7 +3,7 @@
#include <nitro.h>
#include <string.h>
#include "struct_defs/struct_0202D7B0.h"
#include "struct_defs/special_encounter.h"
#include "struct_defs/struct_020556C4.h"
#include "struct_defs/struct_0205EC34.h"
@ -17,8 +17,8 @@
#include "player_avatar.h"
#include "roaming_pokemon.h"
#include "save_player.h"
#include "special_encounter.h"
#include "system_flags.h"
#include "unk_0202D7A8.h"
#include "unk_0203A7D8.h"
#include "unk_020556C4.h"
#include "unk_0206AFE0.h"
@ -42,14 +42,14 @@ void FieldSystem_InitFlagsOnMapChange(FieldSystem *fieldSystem)
sub_0203A8E8(fieldSystem, fieldSystem->location->mapId);
SpecialEncounter_SetFluteFactor(SaveData_GetSpecialEncounters(fieldSystem->saveData), FLUTE_FACTOR_NONE);
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
if (!SystemFlag_CheckSafariGameActive(SaveData_GetVarsFlags(fieldSystem->saveData))) {
SpecialEncounter *v0;
v0 = SaveData_GetSpecialEncounters(fieldSystem->saveData);
sub_0206C404(v0, fieldSystem->location->mapId);
sub_0206C37C(v0);
RoamingPokemon_UpdatePlayerRecentRoutes(v0, fieldSystem->location->mapId);
RoamingPokemon_MoveAllLocations(v0);
}
}
@ -71,13 +71,13 @@ void FieldSystem_InitFlagsWarp(FieldSystem *fieldSystem)
sub_0203A8E8(fieldSystem, fieldSystem->location->mapId);
SpecialEncounter_SetFluteFactor(SaveData_GetSpecialEncounters(fieldSystem->saveData), FLUTE_FACTOR_NONE);
fieldSystem->unk_78.unk_00 = 0;
fieldSystem->unk_78.encounterAttempts = 0;
{
SpecialEncounter *v0;
v0 = SaveData_GetSpecialEncounters(fieldSystem->saveData);
sub_0206C404(v0, fieldSystem->location->mapId);
RoamingPokemon_UpdatePlayerRecentRoutes(v0, fieldSystem->location->mapId);
}
if (!MapHeader_IsCave(fieldSystem->location->mapId)) {
@ -108,13 +108,13 @@ void FieldSystem_InitFlagsWarp(FieldSystem *fieldSystem)
void sub_0207056C(FieldSystem *fieldSystem)
{
SystemFlag_ClearSafariGameActive(SaveData_GetVarsFlags(fieldSystem->saveData));
sub_0206C354(SaveData_GetSpecialEncounters(fieldSystem->saveData));
RoamingPokemon_RandomizeAllLocations(SaveData_GetSpecialEncounters(fieldSystem->saveData));
}
void FieldSystem_SetTeleportFlags(FieldSystem *fieldSystem)
{
SystemFlag_ClearSafariGameActive(SaveData_GetVarsFlags(fieldSystem->saveData));
sub_0206C354(SaveData_GetSpecialEncounters(fieldSystem->saveData));
RoamingPokemon_RandomizeAllLocations(SaveData_GetSpecialEncounters(fieldSystem->saveData));
}
void FieldSystem_SetEscapeFlags(FieldSystem *fieldSystem)
@ -132,7 +132,7 @@ void sub_020705B4(FieldSystem *fieldSystem)
void sub_020705CC(FieldSystem *fieldSystem)
{
sub_0206C354(SaveData_GetSpecialEncounters(fieldSystem->saveData));
RoamingPokemon_RandomizeAllLocations(SaveData_GetSpecialEncounters(fieldSystem->saveData));
}
static BOOL sub_020705DC(FieldSystem *fieldSystem)