Add Time-Based Encounters (#6454)
This commit is contained in:
parent
2b417bfeed
commit
26f28103ec
9
Makefile
9
Makefile
@ -171,6 +171,15 @@ LEARNSET_HELPERS_DATA_DIR := $(LEARNSET_HELPERS_DIR)/porymoves_files
|
||||
LEARNSET_HELPERS_BUILD_DIR := $(LEARNSET_HELPERS_DIR)/build
|
||||
ALL_LEARNABLES_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_learnables.json
|
||||
|
||||
# wild_encounters.h is generated by a Python script
|
||||
WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters
|
||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
|
||||
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py $(INCLUDE_DIRS)/config/overworld.h
|
||||
python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@
|
||||
|
||||
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
|
||||
PERL := perl
|
||||
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
|
||||
|
||||
|
||||
@ -103,9 +103,13 @@
|
||||
#define GEN_8_PLA GEN_LATEST + 2
|
||||
|
||||
//Time
|
||||
#define OW_TIMES_OF_DAY GEN_LATEST // Different generations have the times of day change at different times.
|
||||
#define OW_USE_FAKE_RTC FALSE // When TRUE, seconds on the in-game clock will only advance once every 60 playTimeVBlanks (every 60 frames).
|
||||
#define OW_ALTERED_TIME_RATIO GEN_LATEST // In GEN_8_PLA, the time in game moves forward 60 seconds for every second in the RTC. In GEN_9, it is 20 seconds. This has no effect if OW_USE_FAKE_RTC is FALSE.
|
||||
#define OW_TIMES_OF_DAY GEN_LATEST // Different generations have the times of day change at different times.
|
||||
#define OW_USE_FAKE_RTC FALSE // When TRUE, seconds on the in-game clock will only advance once every 60 playTimeVBlanks (every 60 frames).
|
||||
#define OW_ALTERED_TIME_RATIO GEN_LATEST // In GEN_8_PLA, the time in game moves forward 60 seconds for every second in the RTC. In GEN_9, it is 20 seconds. This has no effect if OW_USE_FAKE_RTC is FALSE.
|
||||
#define OW_TIME_OF_DAY_ENCOUNTERS FALSE // If TRUE, will allow the user to define and use different encounter tables based on the time of day.
|
||||
#define OW_TIME_OF_DAY_DISABLE_FALLBACK FALSE // If TRUE, if the encounter table for a specific map and time is empty, the area will have no encounters instead of falling back to the vanilla map and time.
|
||||
#define OW_TIME_OF_DAY_DEFAULT TIME_MORNING // Should be set to whatever is the first value in the TimeOfDay enum in rtc.h
|
||||
#define OW_TIME_OF_DAY_FALLBACK OW_TIME_OF_DAY_DEFAULT // The time of day that encounter tables fall back to. Defaults to whatever OW_TIME_OF_DAY_FALLBACK is set to.
|
||||
|
||||
// Overworld flags
|
||||
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
|
||||
|
||||
@ -1,6 +1,16 @@
|
||||
#ifndef GUARD_POKEDEX_AREA_SCREEN_H
|
||||
#define GUARD_POKEDEX_AREA_SCREEN_H
|
||||
|
||||
void ShowPokedexAreaScreen(u16, u8 *);
|
||||
#include "rtc.h"
|
||||
|
||||
extern u8 gAreaTimeOfDay;
|
||||
|
||||
enum PokedexAreaScreenState
|
||||
{
|
||||
DEX_SHOW_AREA_SCREEN,
|
||||
DEX_UPDATE_AREA_SCREEN
|
||||
};
|
||||
|
||||
void DisplayPokedexAreaScreen(u16 species, u8 *screenSwitchState, enum TimeOfDay timeOfDay, enum PokedexAreaScreenState areaState);
|
||||
|
||||
#endif // GUARD_POKEDEX_AREA_SCREEN_H
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#ifndef GUARD_RTC_UTIL_H
|
||||
#define GUARD_RTC_UTIL_H
|
||||
|
||||
#include "global.h"
|
||||
#include "siirtc.h"
|
||||
#include "config/overworld.h"
|
||||
|
||||
#define RTC_INIT_ERROR 0x0001
|
||||
#define RTC_INIT_WARNING 0x0002
|
||||
@ -83,10 +85,17 @@
|
||||
#define NIGHT_HOUR_END 6
|
||||
#endif
|
||||
|
||||
#define TIME_MORNING 0
|
||||
#define TIME_DAY 1
|
||||
#define TIME_EVENING 2
|
||||
#define TIME_NIGHT 3
|
||||
// TIMES_OF_DAY_COUNT must be last
|
||||
enum TimeOfDay
|
||||
{
|
||||
TIME_MORNING,
|
||||
TIME_DAY,
|
||||
TIME_EVENING,
|
||||
TIME_NIGHT,
|
||||
TIMES_OF_DAY_COUNT,
|
||||
};
|
||||
|
||||
STATIC_ASSERT(OW_TIME_OF_DAY_DEFAULT == 0, TimeOfDayDefaultMustBeFirstElementInTimeOfDayEnum)
|
||||
|
||||
extern struct Time gLocalTime;
|
||||
|
||||
@ -112,12 +121,15 @@ void FormatHexDate(u8 *dest, s32 year, s32 month, s32 day);
|
||||
void RtcCalcTimeDifference(struct SiiRtcInfo *rtc, struct Time *result, struct Time *t);
|
||||
void RtcCalcLocalTime(void);
|
||||
bool8 IsBetweenHours(s32 hours, s32 begin, s32 end);
|
||||
u8 GetTimeOfDay(void);
|
||||
enum TimeOfDay GetTimeOfDay(void);
|
||||
enum TimeOfDay GetTimeOfDayForDex(void);
|
||||
void RtcInitLocalTimeOffset(s32 hour, s32 minute);
|
||||
void RtcCalcLocalTimeOffset(s32 days, s32 hours, s32 minutes, s32 seconds);
|
||||
void CalcTimeDifference(struct Time *result, struct Time *t1, struct Time *t2);
|
||||
u32 RtcGetMinuteCount(void);
|
||||
u32 RtcGetLocalDayCount(void);
|
||||
void FormatDecimalTimeWithoutSeconds(u8 *dest, s8 hour, s8 minute, bool32 is24Hour);
|
||||
enum TimeOfDay TryIncrementTimeOfDay(enum TimeOfDay timeOfDay);
|
||||
enum TimeOfDay TryDecrementTimeOfDay(enum TimeOfDay timeOfDay);
|
||||
|
||||
#endif // GUARD_RTC_UTIL_H
|
||||
|
||||
@ -1,8 +1,19 @@
|
||||
#ifndef GUARD_WILD_ENCOUNTER_H
|
||||
#define GUARD_WILD_ENCOUNTER_H
|
||||
|
||||
#include "rtc.h"
|
||||
#include "constants/wild_encounter.h"
|
||||
|
||||
#define HEADER_NONE 0xFFFF
|
||||
|
||||
enum WildPokemonArea {
|
||||
WILD_AREA_LAND,
|
||||
WILD_AREA_WATER,
|
||||
WILD_AREA_ROCKS,
|
||||
WILD_AREA_FISHING,
|
||||
WILD_AREA_HIDDEN
|
||||
};
|
||||
|
||||
struct WildPokemon
|
||||
{
|
||||
u8 minLevel;
|
||||
@ -16,17 +27,28 @@ struct WildPokemonInfo
|
||||
const struct WildPokemon *wildPokemon;
|
||||
};
|
||||
|
||||
struct WildEncounterTypes
|
||||
{
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
const struct WildPokemonInfo *rockSmashMonsInfo;
|
||||
const struct WildPokemonInfo *fishingMonsInfo;
|
||||
const struct WildPokemonInfo *hiddenMonsInfo;
|
||||
};
|
||||
|
||||
struct WildPokemonHeader
|
||||
{
|
||||
u8 mapGroup;
|
||||
u8 mapNum;
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
const struct WildPokemonInfo *rockSmashMonsInfo;
|
||||
const struct WildPokemonInfo *hiddenMonsInfo;
|
||||
const struct WildPokemonInfo *fishingMonsInfo;
|
||||
|
||||
#if OW_TIME_OF_DAY_ENCOUNTERS
|
||||
const struct WildEncounterTypes encounterTypes[TIMES_OF_DAY_COUNT];
|
||||
#else
|
||||
const struct WildEncounterTypes encounterTypes[1];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
extern const struct WildPokemonHeader gWildMonHeaders[];
|
||||
extern bool8 gIsFishingEncounter;
|
||||
extern bool8 gIsSurfingEncounter;
|
||||
@ -50,5 +72,6 @@ u8 ChooseWildMonIndex_Land(void);
|
||||
u8 ChooseWildMonIndex_WaterRock(void);
|
||||
u8 ChooseHiddenMonIndex(void);
|
||||
bool32 MapHasNoEncounterData(void);
|
||||
enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area);
|
||||
|
||||
#endif // GUARD_WILD_ENCOUNTER_H
|
||||
|
||||
@ -52,6 +52,7 @@ bool32 InitWindows(const struct WindowTemplate *templates);
|
||||
u32 AddWindow(const struct WindowTemplate *template);
|
||||
int AddWindowWithoutTileMap(const struct WindowTemplate *template);
|
||||
void RemoveWindow(u32 windowId);
|
||||
void RemoveAllWindowsOnBg(u32 bgId);
|
||||
void FreeAllWindowBuffers(void);
|
||||
void CopyWindowToVram(u32 windowId, u32 mode);
|
||||
void CopyWindowRectToVram(u32 windowId, u32 mode, u32 x, u32 y, u32 w, u32 h);
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
# JSON files are run through jsonproc, which is a tool that converts JSON data to an output file
|
||||
# based on an Inja template. https://github.com/pantor/inja
|
||||
|
||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(DATA_SRC_SUBDIR)/wild_encounters.json.txt
|
||||
$(JSONPROC) $^ $@
|
||||
|
||||
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
|
||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/region_map/region_map_entries.h
|
||||
$(DATA_SRC_SUBDIR)/region_map/region_map_entries.h: $(DATA_SRC_SUBDIR)/region_map/region_map_sections.json $(DATA_SRC_SUBDIR)/region_map/region_map_sections.json.txt
|
||||
$(JSONPROC) $^ $@
|
||||
|
||||
97
migration_scripts/add_time_based_encounters.py
Normal file
97
migration_scripts/add_time_based_encounters.py
Normal file
@ -0,0 +1,97 @@
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
|
||||
"""
|
||||
- you can change/add to these if you're adding seasons/days of the week, etc
|
||||
- if you're just adding times of the day, make sure they are in the same order
|
||||
as the `TimeOfDay` enum in include/rtc.h.
|
||||
- you don't need to add an entry for `TIMES_OF_DAY_COUNT`
|
||||
"""
|
||||
ENCOUNTER_GROUP_SUFFIX = [
|
||||
"Morning",
|
||||
"Day",
|
||||
"Evening",
|
||||
"Night"
|
||||
]
|
||||
|
||||
ARGS = [
|
||||
"--copy",
|
||||
]
|
||||
|
||||
"""
|
||||
- make sure this number is the same as `OW_TIME_OF_DAY_DEFAULT` in config/overworld.h.
|
||||
- by default in config/overworld.h it is set to `TIME_MORNING`, which is 0 in the
|
||||
`TimeOfDay` enum in include/rtc.h
|
||||
"""
|
||||
OW_TIME_OF_DAY_DEFAULT = 0
|
||||
|
||||
|
||||
def GetWildEncounterFile():
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from the project's root folder.")
|
||||
quit()
|
||||
|
||||
wFile = open("src/data/wild_encounters.json")
|
||||
wData = json.load(wFile)
|
||||
|
||||
wBackupData = json.dumps(wData, indent=2)
|
||||
wBackupFile = open("src/data/wild_encounters.json.bak", mode="w", encoding="utf-8")
|
||||
wBackupFile.write(wBackupData)
|
||||
|
||||
global COPY_FULL_ENCOUNTER
|
||||
COPY_FULL_ENCOUNTER = False
|
||||
|
||||
for arg in ARGS:
|
||||
if len(sys.argv) > 1:
|
||||
if arg in sys.argv[1:3]:
|
||||
if arg == ARGS[0]:
|
||||
COPY_FULL_ENCOUNTER = True
|
||||
|
||||
j = 0
|
||||
for group in wData["wild_encounter_groups"]:
|
||||
wEncounters = wData["wild_encounter_groups"][j]["encounters"]
|
||||
editMap = True
|
||||
|
||||
wEncounters_New = list()
|
||||
for map in wEncounters:
|
||||
for suffix in ENCOUNTER_GROUP_SUFFIX:
|
||||
tempSuffix = "_" + suffix
|
||||
if tempSuffix in map["base_label"]:
|
||||
editMap = False
|
||||
break
|
||||
else:
|
||||
editMap = True
|
||||
|
||||
if editMap:
|
||||
k = 0
|
||||
for suffix in ENCOUNTER_GROUP_SUFFIX:
|
||||
tempDict = dict()
|
||||
if k == OW_TIME_OF_DAY_DEFAULT or COPY_FULL_ENCOUNTER:
|
||||
tempDict = map.copy()
|
||||
|
||||
tempMapLabel = ""
|
||||
if "map" in map:
|
||||
tempMapLabel = map["map"]
|
||||
tempDict["map"] = tempMapLabel
|
||||
|
||||
tempLabel = map["base_label"] + "_" + suffix
|
||||
tempDict["base_label"] = tempLabel
|
||||
wEncounters_New.append(tempDict)
|
||||
if map["base_label"] in wEncounters_New:
|
||||
wEncounters_New[map["base_label"]].pop()
|
||||
|
||||
print(tempLabel + " added")
|
||||
k += 1
|
||||
else:
|
||||
wEncounters_New.append(map.copy())
|
||||
|
||||
wData["wild_encounter_groups"][j]["encounters"] = wEncounters_New
|
||||
j += 1
|
||||
|
||||
wNewData = json.dumps(wData, indent=2)
|
||||
wNewFile = open("src/data/wild_encounters.json", mode="w", encoding="utf-8")
|
||||
wNewFile.write(wNewData)
|
||||
|
||||
|
||||
GetWildEncounterFile()
|
||||
59
src/dexnav.c
59
src/dexnav.c
@ -36,6 +36,7 @@
|
||||
#include "pokemon_summary_screen.h"
|
||||
#include "random.h"
|
||||
#include "region_map.h"
|
||||
#include "rtc.h"
|
||||
#include "scanline_effect.h"
|
||||
#include "script.h"
|
||||
#include "script_pokemon_util.h"
|
||||
@ -1515,10 +1516,8 @@ static u8 DexNavGeneratePotential(u8 searchLevel)
|
||||
|
||||
static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
const struct WildPokemonInfo *landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
const struct WildPokemonInfo *hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay;
|
||||
u8 min = 100;
|
||||
u8 max = 0;
|
||||
u8 i;
|
||||
@ -1526,6 +1525,9 @@ static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
||||
switch (environment)
|
||||
{
|
||||
case ENCOUNTER_TYPE_LAND: // grass
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
const struct WildPokemonInfo *landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
|
||||
if (landMonsInfo == NULL)
|
||||
return MON_LEVEL_NONEXISTENT; //Hidden pokemon should only appear on walkable tiles or surf tiles
|
||||
|
||||
@ -1539,6 +1541,9 @@ static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
||||
}
|
||||
break;
|
||||
case ENCOUNTER_TYPE_WATER: //water
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
if (waterMonsInfo == NULL)
|
||||
return MON_LEVEL_NONEXISTENT; //Hidden pokemon should only appear on walkable tiles or surf tiles
|
||||
|
||||
@ -1552,6 +1557,9 @@ static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
||||
}
|
||||
break;
|
||||
case ENCOUNTER_TYPE_HIDDEN:
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
const struct WildPokemonInfo *hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
|
||||
if (hiddenMonsInfo == NULL)
|
||||
return MON_LEVEL_NONEXISTENT;
|
||||
|
||||
@ -1724,11 +1732,13 @@ static void CreateNoDataIcon(s16 x, s16 y)
|
||||
CreateSprite(&sNoDataIconTemplate, x, y, 0);
|
||||
}
|
||||
|
||||
static bool8 CapturedAllLandMons(u16 headerId)
|
||||
static bool8 CapturedAllLandMons(u32 headerId)
|
||||
{
|
||||
u16 i, species;
|
||||
int count = 0;
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
|
||||
if (landMonsInfo != NULL)
|
||||
{
|
||||
@ -1756,12 +1766,14 @@ static bool8 CapturedAllLandMons(u16 headerId)
|
||||
}
|
||||
|
||||
//Checks if all Pokemon that can be encountered while surfing have been capture
|
||||
static bool8 CapturedAllWaterMons(u16 headerId)
|
||||
static bool8 CapturedAllWaterMons(u32 headerId)
|
||||
{
|
||||
u32 i;
|
||||
u16 species;
|
||||
u8 count = 0;
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
if (waterMonsInfo != NULL)
|
||||
{
|
||||
@ -1787,13 +1799,15 @@ static bool8 CapturedAllWaterMons(u16 headerId)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool8 CapturedAllHiddenMons(u16 headerId)
|
||||
static bool8 CapturedAllHiddenMons(u32 headerId)
|
||||
{
|
||||
u32 i;
|
||||
u16 species;
|
||||
u8 count = 0;
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
|
||||
if (hiddenMonsInfo != NULL)
|
||||
{
|
||||
for (i = 0; i < HIDDEN_WILD_COUNT; ++i)
|
||||
@ -1820,7 +1834,7 @@ static bool8 CapturedAllHiddenMons(u16 headerId)
|
||||
|
||||
static void DexNavLoadCapturedAllSymbols(void)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
|
||||
LoadCompressedSpriteSheetUsingHeap(&sCapturedAllPokemonSpriteSheet);
|
||||
|
||||
@ -1936,11 +1950,16 @@ static void DexNavLoadEncounterData(void)
|
||||
u8 hiddenIndex = 0;
|
||||
u16 species;
|
||||
u32 i;
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
|
||||
// nop struct data
|
||||
memset(sDexNavUiDataPtr->landSpecies, 0, sizeof(sDexNavUiDataPtr->landSpecies));
|
||||
memset(sDexNavUiDataPtr->waterSpecies, 0, sizeof(sDexNavUiDataPtr->waterSpecies));
|
||||
@ -2509,12 +2528,14 @@ bool8 TryFindHiddenPokemon(void)
|
||||
if ((*stepPtr) == 0 && (Random() % 100 < HIDDEN_MON_SEARCH_RATE))
|
||||
{
|
||||
// hidden pokemon
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u8 index;
|
||||
u16 species;
|
||||
u8 environment;
|
||||
u8 taskId;
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
bool8 isHiddenMon = FALSE;
|
||||
|
||||
// while you can still technically find hidden pokemon if there are not hidden-only pokemon on a map,
|
||||
@ -2539,7 +2560,7 @@ bool8 TryFindHiddenPokemon(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
species = gWildMonHeaders[headerId].landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
|
||||
species = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
|
||||
environment = ENCOUNTER_TYPE_LAND;
|
||||
}
|
||||
break;
|
||||
@ -2557,7 +2578,7 @@ bool8 TryFindHiddenPokemon(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
species = gWildMonHeaders[headerId].waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||
species = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||
environment = ENCOUNTER_TYPE_WATER;
|
||||
|
||||
}
|
||||
|
||||
@ -1752,6 +1752,7 @@ static void PopulateSpeciesFromTrainerLocation(int matchCallId, u8 *destStr)
|
||||
int numSpecies;
|
||||
u8 slot;
|
||||
int i = 0;
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
if (gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED)) // ??? This check is nonsense.
|
||||
{
|
||||
@ -1766,18 +1767,20 @@ static void PopulateSpeciesFromTrainerLocation(int matchCallId, u8 *destStr)
|
||||
|
||||
if (gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED))
|
||||
{
|
||||
timeOfDay = GetTimeOfDayForEncounters(i, WILD_AREA_LAND);
|
||||
numSpecies = 0;
|
||||
if (gWildMonHeaders[i].landMonsInfo)
|
||||
if (gWildMonHeaders[i].encounterTypes[timeOfDay].landMonsInfo)
|
||||
{
|
||||
slot = GetLandEncounterSlot();
|
||||
species[numSpecies] = gWildMonHeaders[i].landMonsInfo->wildPokemon[slot].species;
|
||||
species[numSpecies] = gWildMonHeaders[i].encounterTypes[timeOfDay].landMonsInfo->wildPokemon[slot].species;
|
||||
numSpecies++;
|
||||
}
|
||||
|
||||
if (gWildMonHeaders[i].waterMonsInfo)
|
||||
timeOfDay = GetTimeOfDayForEncounters(i, WILD_AREA_WATER);
|
||||
if (gWildMonHeaders[i].encounterTypes[timeOfDay].waterMonsInfo)
|
||||
{
|
||||
slot = GetWaterEncounterSlot();
|
||||
species[numSpecies] = gWildMonHeaders[i].waterMonsInfo->wildPokemon[slot].species;
|
||||
species[numSpecies] = gWildMonHeaders[i].encounterTypes[timeOfDay].waterMonsInfo->wildPokemon[slot].species;
|
||||
numSpecies++;
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "pokedex_area_screen.h"
|
||||
#include "pokedex_cry_screen.h"
|
||||
#include "pokedex_plus_hgss.h"
|
||||
#include "rtc.h"
|
||||
#include "scanline_effect.h"
|
||||
#include "sound.h"
|
||||
#include "sprite.h"
|
||||
@ -255,7 +256,8 @@ static void Task_HandleInfoScreenInput(u8);
|
||||
static void Task_SwitchScreensFromInfoScreen(u8);
|
||||
static void Task_LoadInfoScreenWaitForFade(u8);
|
||||
static void Task_ExitInfoScreen(u8);
|
||||
static void Task_LoadAreaScreen(u8);
|
||||
static void Task_LoadAreaScreen(u8 taskId);
|
||||
static void Task_ReloadAreaScreen(u8 taskId);
|
||||
static void Task_WaitForAreaScreenInput(u8 taskId);
|
||||
static void Task_SwitchScreensFromAreaScreen(u8);
|
||||
static void Task_LoadCryScreen(u8);
|
||||
@ -3245,6 +3247,7 @@ static u8 LoadInfoScreen(struct PokedexListItem *item, u8 monSpriteId)
|
||||
u8 taskId;
|
||||
|
||||
sPokedexListItem = item;
|
||||
gAreaTimeOfDay = GetTimeOfDayForDex();
|
||||
taskId = CreateTask(Task_LoadInfoScreen, 0);
|
||||
gTasks[taskId].tScrolling = FALSE;
|
||||
gTasks[taskId].tMonSpriteDone = TRUE; // Already has sprite from list view
|
||||
@ -3552,7 +3555,7 @@ static void Task_LoadAreaScreen(u8 taskId)
|
||||
gMain.state++;
|
||||
break;
|
||||
case 2:
|
||||
ShowPokedexAreaScreen(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState);
|
||||
DisplayPokedexAreaScreen(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState, gAreaTimeOfDay, DEX_SHOW_AREA_SCREEN);
|
||||
SetVBlankCallback(gPokedexVBlankCB);
|
||||
sPokedexView->screenSwitchState = 0;
|
||||
gMain.state = 0;
|
||||
@ -3561,6 +3564,29 @@ static void Task_LoadAreaScreen(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Task_ReloadAreaScreen(u8 taskId)
|
||||
{
|
||||
switch (gMain.state)
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
sPokedexView->currentPage = PAGE_AREA;
|
||||
gMain.state = 1;
|
||||
break;
|
||||
case 1:
|
||||
LoadPokedexBgPalette(sPokedexView->isSearchResults);
|
||||
SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(13) | BGCNT_16COLOR | BGCNT_TXT256x256);
|
||||
gMain.state++;
|
||||
break;
|
||||
case 2:
|
||||
DisplayPokedexAreaScreen(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState, gAreaTimeOfDay, DEX_UPDATE_AREA_SCREEN);
|
||||
gMain.state = 0;
|
||||
gTasks[taskId].func = Task_WaitForAreaScreenInput;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_WaitForAreaScreenInput(u8 taskId)
|
||||
{
|
||||
// See Task_HandlePokedexAreaScreenInput() in pokedex_area_screen.c
|
||||
@ -3581,6 +3607,9 @@ static void Task_SwitchScreensFromAreaScreen(u8 taskId)
|
||||
case 2:
|
||||
gTasks[taskId].func = Task_LoadCryScreen;
|
||||
break;
|
||||
case 3:
|
||||
gTasks[taskId].func = Task_ReloadAreaScreen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "event_data.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "graphics.h"
|
||||
#include "international_string_util.h"
|
||||
#include "main.h"
|
||||
#include "malloc.h"
|
||||
#include "menu.h"
|
||||
@ -12,11 +13,15 @@
|
||||
#include "pokedex_area_screen.h"
|
||||
#include "region_map.h"
|
||||
#include "roamer.h"
|
||||
#include "rtc.h"
|
||||
#include "sound.h"
|
||||
#include "string_util.h"
|
||||
#include "text.h"
|
||||
#include "text_window.h"
|
||||
#include "trig.h"
|
||||
#include "pokedex_area_region_map.h"
|
||||
#include "wild_encounter.h"
|
||||
#include "window.h"
|
||||
#include "constants/region_map_sections.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "constants/songs.h"
|
||||
@ -55,6 +60,15 @@
|
||||
#define MAX_AREA_HIGHLIGHTS 64 // Maximum number of rectangular route highlights
|
||||
#define MAX_AREA_MARKERS 32 // Maximum number of circular spot highlights
|
||||
|
||||
#define LABEL_WINDOW_BG 1
|
||||
#define NUM_LABEL_WINDOWS 2
|
||||
|
||||
enum PokedexAreaLabels
|
||||
{
|
||||
DEX_AREA_LABEL_TIME_OF_DAY,
|
||||
DEX_AREA_LABEL_AREA_UNKNOWN
|
||||
};
|
||||
|
||||
struct OverworldArea
|
||||
{
|
||||
u8 mapGroup;
|
||||
@ -90,28 +104,41 @@ struct
|
||||
/*0xF70*/ u8 charBuffer[64];
|
||||
/*0xFB0*/ struct Sprite * areaUnknownSprites[3];
|
||||
/*0xFBC*/ u8 areaUnknownGraphicsBuffer[0x600];
|
||||
/*0xFC0*/ u8 areaScreenLabelIds[NUM_LABEL_WINDOWS];
|
||||
/*0xFC8*/ u8 areaState;
|
||||
} static EWRAM_DATA *sPokedexAreaScreen = NULL;
|
||||
|
||||
EWRAM_DATA u8 gAreaTimeOfDay = 0;
|
||||
|
||||
static void FindMapsWithMon(u16);
|
||||
static void BuildAreaGlowTilemap(void);
|
||||
static void SetAreaHasMon(u16, u16);
|
||||
static void SetSpecialMapHasMon(u16, u16);
|
||||
static u16 GetRegionMapSectionId(u8, u8);
|
||||
static bool8 MapHasSpecies(const struct WildPokemonHeader *, u16);
|
||||
static bool8 MapHasSpecies(const struct WildEncounterTypes *, u16);
|
||||
static bool8 MonListHasSpecies(const struct WildPokemonInfo *, u16, u16);
|
||||
static void DoAreaGlow(void);
|
||||
static void Task_ShowPokedexAreaScreen(u8);
|
||||
static void Task_ShowPokedexAreaScreen(u8 taskId);
|
||||
static void Task_UpdatePokedexAreaScreen(u8 taskId);
|
||||
static void CreateAreaMarkerSprites(void);
|
||||
static void LoadAreaUnknownGraphics(void);
|
||||
static void CreateAreaUnknownSprites(void);
|
||||
static void Task_HandlePokedexAreaScreenInput(u8);
|
||||
static void ResetPokedexAreaMapBg(void);
|
||||
static void DestroyAreaScreenSprites(void);
|
||||
static void LoadHGSSScreenSelectBarSubmenu(void);
|
||||
static void AddTimeOfDayLabels(void);
|
||||
static void ShowEncounterInfoLabel(void);
|
||||
static void ShowAreaUnknownLabel(void);
|
||||
static void PrintAreaLabelText(const u8 *text, enum PokedexAreaLabels labelId, int textXPos);
|
||||
static void ClearAreaWindowLabel(enum PokedexAreaLabels labelId);
|
||||
|
||||
bool32 ShouldShowAreaUnknownLabel(void);
|
||||
|
||||
static const u32 sAreaGlow_Pal[] = INCBIN_U32("graphics/pokedex/area_glow.gbapal");
|
||||
static const u32 sAreaGlow_Gfx[] = INCBIN_U32("graphics/pokedex/area_glow.4bpp.lz");
|
||||
|
||||
static const u32 sPokedexPlusHGSS_ScreenSelectBarSubmenu_Tilemap[] = INCBIN_U32("graphics/pokedex/hgss/SelectBar.bin.lz");
|
||||
static void LoadHGSSScreenSelectBarSubmenu(void);
|
||||
|
||||
static const u16 sSpeciesHiddenFromAreaScreen[] = { SPECIES_WYNAUT };
|
||||
|
||||
@ -205,6 +232,32 @@ static const struct SpriteTemplate sAreaUnknownSpriteTemplate =
|
||||
.callback = SpriteCallbackDummy
|
||||
};
|
||||
|
||||
static const u8 sFontColor_AreaInfo[3] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, 5};
|
||||
static const struct WindowTemplate sTimeOfDayWindowLabelTemplates[] =
|
||||
{
|
||||
[DEX_AREA_LABEL_TIME_OF_DAY] =
|
||||
{
|
||||
.bg = LABEL_WINDOW_BG,
|
||||
.tilemapLeft = 22,
|
||||
.tilemapTop = 18,
|
||||
.width = 8,
|
||||
.height = 2,
|
||||
.paletteNum = 0,
|
||||
.baseBlock = 0x16C
|
||||
},
|
||||
|
||||
[DEX_AREA_LABEL_AREA_UNKNOWN] =
|
||||
{
|
||||
.bg = LABEL_WINDOW_BG,
|
||||
.tilemapLeft = 12,
|
||||
.tilemapTop = 18,
|
||||
.width = 10,
|
||||
.height = 2,
|
||||
.paletteNum = 0,
|
||||
.baseBlock = 0x240
|
||||
}
|
||||
};
|
||||
|
||||
static void ResetDrawAreaGlowState(void)
|
||||
{
|
||||
sPokedexAreaScreen->drawAreaGlowState = 0;
|
||||
@ -287,7 +340,7 @@ static void FindMapsWithMon(u16 species)
|
||||
// Add regular species to the area map
|
||||
for (i = 0; gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED); i++)
|
||||
{
|
||||
if (MapHasSpecies(&gWildMonHeaders[i], species))
|
||||
if (MapHasSpecies(&gWildMonHeaders[i].encounterTypes[gAreaTimeOfDay], species))
|
||||
{
|
||||
switch (gWildMonHeaders[i].mapGroup)
|
||||
{
|
||||
@ -373,10 +426,13 @@ static u16 GetRegionMapSectionId(u8 mapGroup, u8 mapNum)
|
||||
return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->regionMapSectionId;
|
||||
}
|
||||
|
||||
static bool8 MapHasSpecies(const struct WildPokemonHeader *info, u16 species)
|
||||
static bool8 MapHasSpecies(const struct WildEncounterTypes *info, u16 species)
|
||||
{
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u8 currentMapGroup = gWildMonHeaders[headerId].mapGroup;
|
||||
u8 currentMapNum = gWildMonHeaders[headerId].mapNum;
|
||||
// If this is a header for Altering Cave, skip it if it's not the current Altering Cave encounter set
|
||||
if (GetRegionMapSectionId(info->mapGroup, info->mapNum) == MAPSEC_ALTERING_CAVE)
|
||||
if (GetRegionMapSectionId(currentMapGroup, currentMapNum) == MAPSEC_ALTERING_CAVE)
|
||||
{
|
||||
sPokedexAreaScreen->alteringCaveCounter++;
|
||||
if (sPokedexAreaScreen->alteringCaveCounter != sPokedexAreaScreen->alteringCaveId + 1)
|
||||
@ -576,17 +632,98 @@ static void DoAreaGlow(void)
|
||||
}
|
||||
}
|
||||
|
||||
static const u8 *GetTimeOfDayTextWithButton(enum TimeOfDay timeOfDay)
|
||||
{
|
||||
static const u8 gText_Morning[] = _("{DPAD_UPDOWN} MORNING");
|
||||
static const u8 gText_Day[] = _("{DPAD_UPDOWN} DAY");
|
||||
static const u8 gText_Evening[] = _("{DPAD_UPDOWN} EVENING");
|
||||
static const u8 gText_Night[] = _("{DPAD_UPDOWN} NIGHT");
|
||||
|
||||
switch (gAreaTimeOfDay)
|
||||
{
|
||||
case TIME_MORNING:
|
||||
return gText_Morning;
|
||||
case TIME_EVENING:
|
||||
return gText_Evening;
|
||||
case TIME_NIGHT:
|
||||
return gText_Night;
|
||||
case TIME_DAY:
|
||||
default:
|
||||
return gText_Day;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddTimeOfDayLabels(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
// clear the background before adding any more windows
|
||||
RemoveAllWindowsOnBg(LABEL_WINDOW_BG);
|
||||
|
||||
for (i = 0; i < NUM_LABEL_WINDOWS; i ++)
|
||||
{
|
||||
sPokedexAreaScreen->areaScreenLabelIds[i] = AddWindow(&sTimeOfDayWindowLabelTemplates[i]);
|
||||
FillWindowPixelBuffer(sPokedexAreaScreen->areaScreenLabelIds[i], PIXEL_FILL(0));
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowEncounterInfoLabel(void)
|
||||
{
|
||||
const u8 *gText_TimeOfDay = GetTimeOfDayTextWithButton(gAreaTimeOfDay);
|
||||
int stringXPos = GetStringCenterAlignXOffset(FONT_NORMAL, gText_TimeOfDay, 64);
|
||||
|
||||
PrintAreaLabelText(gText_TimeOfDay, DEX_AREA_LABEL_TIME_OF_DAY, stringXPos);
|
||||
}
|
||||
|
||||
static void ShowAreaUnknownLabel(void)
|
||||
{
|
||||
static const u8 gText_AreaUnknown[] = _("AREA UNKNOWN");
|
||||
int stringXPos = GetStringCenterAlignXOffset(FONT_NORMAL, gText_AreaUnknown, 80);
|
||||
|
||||
PrintAreaLabelText(gText_AreaUnknown, DEX_AREA_LABEL_AREA_UNKNOWN, stringXPos);
|
||||
}
|
||||
|
||||
static void ClearAreaWindowLabel(enum PokedexAreaLabels labelId)
|
||||
{
|
||||
FillWindowPixelBuffer(sPokedexAreaScreen->areaScreenLabelIds[labelId], PIXEL_FILL(0));
|
||||
ClearWindowTilemap(sPokedexAreaScreen->areaScreenLabelIds[labelId]);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
}
|
||||
|
||||
static void PrintAreaLabelText(const u8 *text, enum PokedexAreaLabels labelId, int textXPos)
|
||||
{
|
||||
ClearAreaWindowLabel(labelId);
|
||||
|
||||
PutWindowTilemap(sPokedexAreaScreen->areaScreenLabelIds[labelId]);
|
||||
FillWindowPixelBuffer(sPokedexAreaScreen->areaScreenLabelIds[labelId], PIXEL_FILL(7));
|
||||
|
||||
AddTextPrinterParameterized4(sPokedexAreaScreen->areaScreenLabelIds[labelId], FONT_NORMAL, textXPos, 0, 0, 0, sFontColor_AreaInfo, TEXT_SKIP_DRAW, text);
|
||||
CopyWindowToVram(sPokedexAreaScreen->areaScreenLabelIds[labelId], COPYWIN_FULL);
|
||||
}
|
||||
|
||||
bool32 ShouldShowAreaUnknownLabel(void)
|
||||
{
|
||||
return !sPokedexAreaScreen->numOverworldAreas && !sPokedexAreaScreen->numSpecialAreas;
|
||||
}
|
||||
|
||||
#define tState data[0]
|
||||
|
||||
void ShowPokedexAreaScreen(u16 species, u8 *screenSwitchState)
|
||||
void DisplayPokedexAreaScreen(u16 species, u8 *screenSwitchState, enum TimeOfDay timeOfDay, enum PokedexAreaScreenState areaState)
|
||||
{
|
||||
u8 taskId;
|
||||
|
||||
sPokedexAreaScreen = AllocZeroed(sizeof(*sPokedexAreaScreen));
|
||||
sPokedexAreaScreen->species = species;
|
||||
sPokedexAreaScreen->screenSwitchState = screenSwitchState;
|
||||
sPokedexAreaScreen->areaState = areaState;
|
||||
gAreaTimeOfDay = timeOfDay;
|
||||
screenSwitchState[0] = 0;
|
||||
taskId = CreateTask(Task_ShowPokedexAreaScreen, 0);
|
||||
|
||||
if (sPokedexAreaScreen->areaState == DEX_UPDATE_AREA_SCREEN)
|
||||
taskId = CreateTask(Task_UpdatePokedexAreaScreen, 0);
|
||||
else
|
||||
taskId = CreateTask(Task_ShowPokedexAreaScreen, 0);
|
||||
|
||||
gTasks[taskId].tState = 0;
|
||||
}
|
||||
|
||||
@ -627,20 +764,29 @@ static void Task_ShowPokedexAreaScreen(u8 taskId)
|
||||
CreateAreaMarkerSprites();
|
||||
break;
|
||||
case 7:
|
||||
LoadAreaUnknownGraphics();
|
||||
if(!OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
LoadAreaUnknownGraphics();
|
||||
break;
|
||||
case 8:
|
||||
CreateAreaUnknownSprites();
|
||||
if(!OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
CreateAreaUnknownSprites();
|
||||
break;
|
||||
case 9:
|
||||
BeginNormalPaletteFade(PALETTES_ALL & ~(0x14), 0, 16, 0, RGB_BLACK);
|
||||
break;
|
||||
case 10:
|
||||
if (POKEDEX_PLUS_HGSS)
|
||||
LoadHGSSScreenSelectBarSubmenu();
|
||||
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_ALL);
|
||||
StartAreaGlow();
|
||||
if (OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
{
|
||||
AddTimeOfDayLabels();
|
||||
ShowEncounterInfoLabel();
|
||||
if (ShouldShowAreaUnknownLabel())
|
||||
ShowAreaUnknownLabel();
|
||||
DoScheduledBgTilemapCopiesToVram();
|
||||
}
|
||||
if (POKEDEX_PLUS_HGSS)
|
||||
LoadHGSSScreenSelectBarSubmenu();
|
||||
ShowBg(2);
|
||||
ShowBg(3); // TryShowPokedexAreaMap will have done this already
|
||||
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON);
|
||||
@ -654,6 +800,58 @@ static void Task_ShowPokedexAreaScreen(u8 taskId)
|
||||
gTasks[taskId].tState++;
|
||||
}
|
||||
|
||||
static void Task_UpdatePokedexAreaScreen(u8 taskId)
|
||||
{
|
||||
switch (gTasks[taskId].tState)
|
||||
{
|
||||
case 0:
|
||||
ClearAreaWindowLabel(DEX_AREA_LABEL_TIME_OF_DAY);
|
||||
ClearAreaWindowLabel(DEX_AREA_LABEL_AREA_UNKNOWN);
|
||||
ResetSpriteData();
|
||||
FreeAllSpritePalettes();
|
||||
ResetDrawAreaGlowState();
|
||||
HideBg(2);
|
||||
HideBg(0);
|
||||
break;
|
||||
case 1:
|
||||
SetBgAttribute(3, BG_ATTR_CHARBASEINDEX, 3);
|
||||
LoadPokedexAreaMapGfx(&sPokedexAreaMapTemplate);
|
||||
PokedexAreaMapChangeBgY(-8);
|
||||
StringFill(sPokedexAreaScreen->charBuffer, CHAR_SPACE, 16);
|
||||
break;
|
||||
case 2:
|
||||
if (TryShowPokedexAreaMap() == TRUE)
|
||||
return;
|
||||
break;
|
||||
case 3:
|
||||
if (DrawAreaGlow())
|
||||
return;
|
||||
break;
|
||||
case 4:
|
||||
ShowRegionMapForPokedexAreaScreen(&sPokedexAreaScreen->regionMap);
|
||||
CreateRegionMapPlayerIcon(1, 1);
|
||||
PokedexAreaScreen_UpdateRegionMapVariablesAndVideoRegs(0, -8);
|
||||
CreateAreaMarkerSprites();
|
||||
break;
|
||||
case 5:
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_ALL);
|
||||
StartAreaGlow();
|
||||
AddTimeOfDayLabels();
|
||||
ShowEncounterInfoLabel();
|
||||
if (ShouldShowAreaUnknownLabel())
|
||||
ShowAreaUnknownLabel();
|
||||
ShowBg(2);
|
||||
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON);
|
||||
break;
|
||||
case 6:
|
||||
gTasks[taskId].func = Task_HandlePokedexAreaScreenInput;
|
||||
gTasks[taskId].tState = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
gTasks[taskId].tState++;
|
||||
}
|
||||
|
||||
static void Task_HandlePokedexAreaScreenInput(u8 taskId)
|
||||
{
|
||||
DoAreaGlow();
|
||||
@ -687,16 +885,42 @@ static void Task_HandlePokedexAreaScreenInput(u8 taskId)
|
||||
gTasks[taskId].data[1] = 2;
|
||||
PlaySE(SE_DEX_PAGE);
|
||||
}
|
||||
else if (JOY_NEW(DPAD_UP) && OW_TIME_OF_DAY_ENCOUNTERS == TRUE)
|
||||
{
|
||||
gTasks[taskId].data[1] = 3;
|
||||
gAreaTimeOfDay = TryDecrementTimeOfDay(gAreaTimeOfDay);
|
||||
sPokedexAreaScreen->areaState = DEX_UPDATE_AREA_SCREEN;
|
||||
PlaySE(SE_DEX_PAGE);
|
||||
}
|
||||
else if (JOY_NEW(DPAD_DOWN) && OW_TIME_OF_DAY_ENCOUNTERS == TRUE)
|
||||
{
|
||||
gTasks[taskId].data[1] = 3;
|
||||
gAreaTimeOfDay = TryIncrementTimeOfDay(gAreaTimeOfDay);
|
||||
sPokedexAreaScreen->areaState = DEX_UPDATE_AREA_SCREEN;
|
||||
PlaySE(SE_DEX_PAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// screen needs to fade if its doing anything except updating the area screen
|
||||
sPokedexAreaScreen->areaState = DEX_SHOW_AREA_SCREEN;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
BeginNormalPaletteFade(PALETTES_ALL & ~(0x14), 0, 0, 16, RGB_BLACK);
|
||||
if (sPokedexAreaScreen->areaState != DEX_UPDATE_AREA_SCREEN)
|
||||
BeginNormalPaletteFade(PALETTES_ALL & ~(0x14), 0, 0, 16, RGB_BLACK);
|
||||
break;
|
||||
case 3:
|
||||
if (gPaletteFade.active)
|
||||
return;
|
||||
DestroyAreaScreenSprites();
|
||||
if (OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
{
|
||||
ClearAreaWindowLabel(DEX_AREA_LABEL_TIME_OF_DAY);
|
||||
ClearAreaWindowLabel(DEX_AREA_LABEL_AREA_UNKNOWN);
|
||||
RemoveAllWindowsOnBg(LABEL_WINDOW_BG);
|
||||
}
|
||||
|
||||
sPokedexAreaScreen->screenSwitchState[0] = gTasks[taskId].data[1];
|
||||
ResetPokedexAreaMapBg();
|
||||
DestroyTask(taskId);
|
||||
@ -755,13 +979,16 @@ static void DestroyAreaScreenSprites(void)
|
||||
for (i = 0; i < sPokedexAreaScreen->numAreaMarkerSprites; i++)
|
||||
DestroySprite(sPokedexAreaScreen->areaMarkerSprites[i]);
|
||||
|
||||
// Destroy "Area Unknown" sprites
|
||||
FreeSpriteTilesByTag(TAG_AREA_UNKNOWN);
|
||||
FreeSpritePaletteByTag(TAG_AREA_UNKNOWN);
|
||||
for (i = 0; i < ARRAY_COUNT(sPokedexAreaScreen->areaUnknownSprites); i++)
|
||||
if (!OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
{
|
||||
if (sPokedexAreaScreen->areaUnknownSprites[i])
|
||||
DestroySprite(sPokedexAreaScreen->areaUnknownSprites[i]);
|
||||
// Destroy "Area Unknown" sprites
|
||||
FreeSpriteTilesByTag(TAG_AREA_UNKNOWN);
|
||||
FreeSpritePaletteByTag(TAG_AREA_UNKNOWN);
|
||||
for (i = 0; i < ARRAY_COUNT(sPokedexAreaScreen->areaUnknownSprites); i++)
|
||||
{
|
||||
if (sPokedexAreaScreen->areaUnknownSprites[i])
|
||||
DestroySprite(sPokedexAreaScreen->areaUnknownSprites[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "region_map.h"
|
||||
#include "pokemon.h"
|
||||
#include "reset_rtc_screen.h"
|
||||
#include "rtc.h"
|
||||
#include "scanline_effect.h"
|
||||
#include "shop.h"
|
||||
#include "sound.h"
|
||||
@ -526,7 +527,8 @@ static void Task_HandleInfoScreenInput(u8);
|
||||
static void Task_SwitchScreensFromInfoScreen(u8);
|
||||
static void Task_LoadInfoScreenWaitForFade(u8);
|
||||
static void Task_ExitInfoScreen(u8);
|
||||
static void Task_LoadAreaScreen(u8);
|
||||
static void Task_LoadAreaScreen(u8 taskId);
|
||||
static void Task_ReloadAreaScreen(u8 taskId);
|
||||
static void Task_WaitForAreaScreenInput(u8 taskId);
|
||||
static void Task_SwitchScreensFromAreaScreen(u8);
|
||||
static void Task_LoadCryScreen(u8);
|
||||
@ -3736,6 +3738,7 @@ static u8 LoadInfoScreen(struct PokedexListItem *item, u8 monSpriteId)
|
||||
u8 taskId;
|
||||
|
||||
sPokedexListItem = item;
|
||||
gAreaTimeOfDay = GetTimeOfDayForDex();
|
||||
taskId = CreateTask(Task_LoadInfoScreen, 0);
|
||||
gTasks[taskId].tScrolling = FALSE;
|
||||
gTasks[taskId].tMonSpriteDone = TRUE; // Already has sprite from list view
|
||||
@ -3994,7 +3997,7 @@ static void Task_LoadAreaScreen(u8 taskId)
|
||||
gMain.state++;
|
||||
break;
|
||||
case 2:
|
||||
ShowPokedexAreaScreen(NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState);
|
||||
DisplayPokedexAreaScreen(NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState, gAreaTimeOfDay, DEX_SHOW_AREA_SCREEN);
|
||||
SetVBlankCallback(gPokedexVBlankCB);
|
||||
sPokedexView->screenSwitchState = 0;
|
||||
gMain.state = 0;
|
||||
@ -4003,6 +4006,28 @@ static void Task_LoadAreaScreen(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_ReloadAreaScreen(u8 taskId)
|
||||
{
|
||||
switch (gMain.state)
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
sPokedexView->currentPage = PAGE_AREA;
|
||||
gMain.state = 1;
|
||||
break;
|
||||
case 1:
|
||||
LoadPokedexBgPalette(sPokedexView->isSearchResults);
|
||||
SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(13) | BGCNT_16COLOR | BGCNT_TXT256x256);
|
||||
gMain.state++;
|
||||
break;
|
||||
case 2:
|
||||
DisplayPokedexAreaScreen(NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState, gAreaTimeOfDay, DEX_UPDATE_AREA_SCREEN);
|
||||
gMain.state = 0;
|
||||
gTasks[taskId].func = Task_WaitForAreaScreenInput;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_WaitForAreaScreenInput(u8 taskId)
|
||||
{
|
||||
// See Task_HandlePokedexAreaScreenInput() in pokedex_area_screen.c
|
||||
@ -4026,6 +4051,9 @@ static void Task_SwitchScreensFromAreaScreen(u8 taskId)
|
||||
else
|
||||
gTasks[taskId].func = Task_LoadStatsScreen;
|
||||
break;
|
||||
case 3:
|
||||
gTasks[taskId].func = Task_ReloadAreaScreen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
src/rtc.c
19
src/rtc.c
@ -1,4 +1,6 @@
|
||||
#include "global.h"
|
||||
#include "battle_pike.h"
|
||||
#include "battle_pyramid.h"
|
||||
#include "rtc.h"
|
||||
#include "string_util.h"
|
||||
#include "strings.h"
|
||||
@ -325,7 +327,7 @@ bool8 IsBetweenHours(s32 hours, s32 begin, s32 end)
|
||||
return hours >= begin && hours < end;
|
||||
}
|
||||
|
||||
u8 GetTimeOfDay(void)
|
||||
enum TimeOfDay GetTimeOfDay(void)
|
||||
{
|
||||
RtcCalcLocalTime();
|
||||
if (IsBetweenHours(gLocalTime.hours, MORNING_HOUR_BEGIN, MORNING_HOUR_END))
|
||||
@ -337,6 +339,11 @@ u8 GetTimeOfDay(void)
|
||||
return TIME_DAY;
|
||||
}
|
||||
|
||||
enum TimeOfDay GetTimeOfDayForDex(void)
|
||||
{
|
||||
return OW_TIME_OF_DAY_ENCOUNTERS ? GetTimeOfDay() : OW_TIME_OF_DAY_DEFAULT;
|
||||
}
|
||||
|
||||
void RtcInitLocalTimeOffset(s32 hour, s32 minute)
|
||||
{
|
||||
RtcCalcLocalTimeOffset(0, hour, minute, 0);
|
||||
@ -418,3 +425,13 @@ void FormatDecimalTimeWithoutSeconds(u8 *txtPtr, s8 hour, s8 minute, bool32 is24
|
||||
*txtPtr++ = EOS;
|
||||
*txtPtr = EOS;
|
||||
}
|
||||
|
||||
enum TimeOfDay TryIncrementTimeOfDay(enum TimeOfDay timeOfDay)
|
||||
{
|
||||
return timeOfDay == TIME_NIGHT ? TIME_MORNING : timeOfDay + 1;
|
||||
}
|
||||
|
||||
enum TimeOfDay TryDecrementTimeOfDay(enum TimeOfDay timeOfDay)
|
||||
{
|
||||
return timeOfDay == TIME_MORNING ? TIME_NIGHT : timeOfDay - 1;
|
||||
}
|
||||
|
||||
@ -37,25 +37,16 @@ extern const u8 EventScript_SprayWoreOff[];
|
||||
#define NUM_FISHING_SPOTS_3 149
|
||||
#define NUM_FISHING_SPOTS (NUM_FISHING_SPOTS_1 + NUM_FISHING_SPOTS_2 + NUM_FISHING_SPOTS_3)
|
||||
|
||||
enum {
|
||||
WILD_AREA_LAND,
|
||||
WILD_AREA_WATER,
|
||||
WILD_AREA_ROCKS,
|
||||
WILD_AREA_FISHING,
|
||||
};
|
||||
|
||||
#define WILD_CHECK_REPEL (1 << 0)
|
||||
#define WILD_CHECK_KEEN_EYE (1 << 1)
|
||||
|
||||
#define HEADER_NONE 0xFFFF
|
||||
|
||||
static u16 FeebasRandom(void);
|
||||
static void FeebasSeedRng(u16 seed);
|
||||
static void UpdateChainFishingStreak();
|
||||
static bool8 IsWildLevelAllowedByRepel(u8 level);
|
||||
static void ApplyFluteEncounterRateMod(u32 *encRate);
|
||||
static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
|
||||
static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 species, u8 area);
|
||||
static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 species, enum WildPokemonArea area);
|
||||
#ifdef BUGFIX
|
||||
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u16 ability, u8 *monIndex, u32 size);
|
||||
#else
|
||||
@ -305,7 +296,7 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
|
||||
return wildMonIndex;
|
||||
}
|
||||
|
||||
static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon, u8 wildMonIndex, u8 area)
|
||||
static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon, u8 wildMonIndex, enum WildPokemonArea area)
|
||||
{
|
||||
u8 min;
|
||||
u8 max;
|
||||
@ -384,6 +375,87 @@ u16 GetCurrentMapWildMonHeaderId(void)
|
||||
return HEADER_NONE;
|
||||
}
|
||||
|
||||
enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area)
|
||||
{
|
||||
const struct WildPokemonInfo *wildMonInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDay();
|
||||
|
||||
if (!OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
return OW_TIME_OF_DAY_DEFAULT;
|
||||
|
||||
if (InBattlePike())
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
default:
|
||||
case WILD_AREA_LAND:
|
||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_WATER:
|
||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_ROCKS:
|
||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_FISHING:
|
||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_HIDDEN:
|
||||
wildMonInfo = gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (InBattlePyramid())
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
default:
|
||||
case WILD_AREA_LAND:
|
||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_WATER:
|
||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_ROCKS:
|
||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_FISHING:
|
||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_HIDDEN:
|
||||
wildMonInfo = gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
default:
|
||||
case WILD_AREA_LAND:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_WATER:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_ROCKS:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_FISHING:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_HIDDEN:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (wildMonInfo == NULL && !OW_TIME_OF_DAY_DISABLE_FALLBACK)
|
||||
return OW_TIME_OF_DAY_FALLBACK;
|
||||
else
|
||||
return timeOfDay;
|
||||
}
|
||||
|
||||
u8 PickWildMonNature(void)
|
||||
{
|
||||
u8 i;
|
||||
@ -459,7 +531,7 @@ void CreateWildMon(u16 species, u8 level)
|
||||
#define TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildPokemon, type, ability, ptr, count) TryGetAbilityInfluencedWildMonIndex(wildPokemon, type, ability, ptr)
|
||||
#endif
|
||||
|
||||
static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 area, u8 flags)
|
||||
static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, enum WildPokemonArea area, u8 flags)
|
||||
{
|
||||
u8 wildMonIndex = 0;
|
||||
u8 level;
|
||||
@ -501,6 +573,10 @@ static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 ar
|
||||
case WILD_AREA_ROCKS:
|
||||
wildMonIndex = ChooseWildMonIndex_WaterRock();
|
||||
break;
|
||||
default:
|
||||
case WILD_AREA_FISHING:
|
||||
case WILD_AREA_HIDDEN:
|
||||
break;
|
||||
}
|
||||
|
||||
level = ChooseWildMonLevel(wildMonInfo->wildPokemon, wildMonIndex, area);
|
||||
@ -621,7 +697,8 @@ static bool8 AreLegendariesInSootopolisPreventingEncounters(void)
|
||||
|
||||
bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
{
|
||||
u16 headerId;
|
||||
u32 headerId;
|
||||
enum TimeOfDay timeOfDay;
|
||||
struct Roamer *roamer;
|
||||
|
||||
if (sWildEncountersDisabled == TRUE)
|
||||
@ -633,11 +710,13 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS)
|
||||
{
|
||||
headerId = GetBattlePikeWildMonHeaderId();
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (prevMetatileBehavior != curMetatileBehavior && !AllowWildCheckOnNewMetatile())
|
||||
return FALSE;
|
||||
else if (WildEncounterCheck(gBattlePikeWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
else if (WildEncounterCheck(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
return FALSE;
|
||||
else if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
|
||||
else if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
|
||||
return FALSE;
|
||||
else if (!TryGenerateBattlePikeWildMon(TRUE))
|
||||
return FALSE;
|
||||
@ -648,11 +727,13 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR)
|
||||
{
|
||||
headerId = gSaveBlock2Ptr->frontier.curChallengeBattleNum;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (prevMetatileBehavior != curMetatileBehavior && !AllowWildCheckOnNewMetatile())
|
||||
return FALSE;
|
||||
else if (WildEncounterCheck(gBattlePyramidWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
else if (WildEncounterCheck(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
return FALSE;
|
||||
else if (TryGenerateWildMon(gBattlePyramidWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
|
||||
else if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
GenerateBattlePyramidWildMon();
|
||||
@ -664,11 +745,13 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
{
|
||||
if (MetatileBehavior_IsLandWildEncounter(curMetatileBehavior) == TRUE)
|
||||
{
|
||||
if (gWildMonHeaders[headerId].landMonsInfo == NULL)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo == NULL)
|
||||
return FALSE;
|
||||
else if (prevMetatileBehavior != curMetatileBehavior && !AllowWildCheckOnNewMetatile())
|
||||
return FALSE;
|
||||
else if (WildEncounterCheck(gWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
else if (WildEncounterCheck(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
if (TryStartRoamerEncounter())
|
||||
@ -689,12 +772,12 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
}
|
||||
|
||||
// try a regular wild land encounter
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
|
||||
{
|
||||
if (TryDoDoubleWildBattle())
|
||||
{
|
||||
struct Pokemon mon1 = gEnemyParty[0];
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE);
|
||||
gEnemyParty[1] = mon1;
|
||||
BattleSetup_StartDoubleWildBattle();
|
||||
}
|
||||
@ -711,13 +794,15 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
else if (MetatileBehavior_IsWaterWildEncounter(curMetatileBehavior) == TRUE
|
||||
|| (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridgeOverWater(curMetatileBehavior) == TRUE))
|
||||
{
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
|
||||
if (AreLegendariesInSootopolisPreventingEncounters() == TRUE)
|
||||
return FALSE;
|
||||
else if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
|
||||
else if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo == NULL)
|
||||
return FALSE;
|
||||
else if (prevMetatileBehavior != curMetatileBehavior && !AllowWildCheckOnNewMetatile())
|
||||
return FALSE;
|
||||
else if (WildEncounterCheck(gWildMonHeaders[headerId].waterMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
else if (WildEncounterCheck(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
if (TryStartRoamerEncounter())
|
||||
@ -731,13 +816,13 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
}
|
||||
else // try a regular surfing encounter
|
||||
{
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
|
||||
{
|
||||
gIsSurfingEncounter = TRUE;
|
||||
if (TryDoDoubleWildBattle())
|
||||
{
|
||||
struct Pokemon mon1 = gEnemyParty[0];
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_KEEN_EYE);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_KEEN_EYE);
|
||||
gEnemyParty[1] = mon1;
|
||||
BattleSetup_StartDoubleWildBattle();
|
||||
}
|
||||
@ -758,11 +843,14 @@ bool8 StandardWildEncounter(u16 curMetatileBehavior, u16 prevMetatileBehavior)
|
||||
|
||||
void RockSmashWildEncounter(void)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
if (headerId != HEADER_NONE)
|
||||
{
|
||||
const struct WildPokemonInfo *wildPokemonInfo = gWildMonHeaders[headerId].rockSmashMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_ROCKS);
|
||||
|
||||
const struct WildPokemonInfo *wildPokemonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
||||
|
||||
if (wildPokemonInfo == NULL)
|
||||
{
|
||||
@ -788,7 +876,8 @@ void RockSmashWildEncounter(void)
|
||||
bool8 SweetScentWildEncounter(void)
|
||||
{
|
||||
s16 x, y;
|
||||
u16 headerId;
|
||||
u32 headerId;
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
headerId = GetCurrentMapWildMonHeaderId();
|
||||
@ -797,7 +886,9 @@ bool8 SweetScentWildEncounter(void)
|
||||
if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS)
|
||||
{
|
||||
headerId = GetBattlePikeWildMonHeaderId();
|
||||
if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
TryGenerateBattlePikeWildMon(FALSE);
|
||||
@ -807,7 +898,9 @@ bool8 SweetScentWildEncounter(void)
|
||||
if (gMapHeader.mapLayoutId == LAYOUT_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR)
|
||||
{
|
||||
headerId = gSaveBlock2Ptr->frontier.curChallengeBattleNum;
|
||||
if (TryGenerateWildMon(gBattlePyramidWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (TryGenerateWildMon(gBattlePyramidWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
GenerateBattlePyramidWildMon();
|
||||
@ -819,7 +912,9 @@ bool8 SweetScentWildEncounter(void)
|
||||
{
|
||||
if (MetatileBehavior_IsLandWildEncounter(MapGridGetMetatileBehaviorAt(x, y)) == TRUE)
|
||||
{
|
||||
if (gWildMonHeaders[headerId].landMonsInfo == NULL)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (TryStartRoamerEncounter())
|
||||
@ -831,16 +926,18 @@ bool8 SweetScentWildEncounter(void)
|
||||
if (DoMassOutbreakEncounterTest() == TRUE)
|
||||
SetUpMassOutbreakEncounter(0);
|
||||
else
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, 0);
|
||||
|
||||
BattleSetup_StartWildBattle();
|
||||
return TRUE;
|
||||
}
|
||||
else if (MetatileBehavior_IsWaterWildEncounter(MapGridGetMetatileBehaviorAt(x, y)) == TRUE)
|
||||
{
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
|
||||
if (AreLegendariesInSootopolisPreventingEncounters() == TRUE)
|
||||
return FALSE;
|
||||
if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (TryStartRoamerEncounter())
|
||||
@ -849,7 +946,7 @@ bool8 SweetScentWildEncounter(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, 0);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo, WILD_AREA_WATER, 0);
|
||||
BattleSetup_StartWildBattle();
|
||||
return TRUE;
|
||||
}
|
||||
@ -860,9 +957,10 @@ bool8 SweetScentWildEncounter(void)
|
||||
|
||||
bool8 DoesCurrentMapHaveFishingMons(void)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_FISHING);
|
||||
|
||||
if (headerId != HEADER_NONE && gWildMonHeaders[headerId].fishingMonsInfo != NULL)
|
||||
if (headerId != HEADER_NONE && gWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo != NULL)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@ -887,6 +985,8 @@ static void UpdateChainFishingStreak()
|
||||
void FishingWildEncounter(u8 rod)
|
||||
{
|
||||
u16 species;
|
||||
u32 headerId;
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
gIsFishingEncounter = TRUE;
|
||||
if (CheckFeebas() == TRUE)
|
||||
@ -898,7 +998,9 @@ void FishingWildEncounter(u8 rod)
|
||||
}
|
||||
else
|
||||
{
|
||||
species = GenerateFishingWildMon(gWildMonHeaders[GetCurrentMapWildMonHeaderId()].fishingMonsInfo, rod);
|
||||
headerId = GetCurrentMapWildMonHeaderId();
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_FISHING);
|
||||
species = GenerateFishingWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo, rod);
|
||||
}
|
||||
|
||||
IncrementGameStat(GAME_STAT_FISHING_ENCOUNTERS);
|
||||
@ -908,7 +1010,8 @@ void FishingWildEncounter(u8 rod)
|
||||
|
||||
u16 GetLocalWildMon(bool8 *isWaterMon)
|
||||
{
|
||||
u16 headerId;
|
||||
u32 headerId;
|
||||
enum TimeOfDay timeOfDay;
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
|
||||
@ -916,8 +1019,13 @@ u16 GetLocalWildMon(bool8 *isWaterMon)
|
||||
headerId = GetCurrentMapWildMonHeaderId();
|
||||
if (headerId == HEADER_NONE)
|
||||
return SPECIES_NONE;
|
||||
landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
// Neither
|
||||
if (landMonsInfo == NULL && waterMonsInfo == NULL)
|
||||
return SPECIES_NONE;
|
||||
@ -944,11 +1052,14 @@ u16 GetLocalWildMon(bool8 *isWaterMon)
|
||||
|
||||
u16 GetLocalWaterMon(void)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
if (headerId != HEADER_NONE)
|
||||
{
|
||||
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
|
||||
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
if (waterMonsInfo)
|
||||
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||
@ -1053,7 +1164,7 @@ static bool8 TryGetRandomWildMonIndexByType(const struct WildPokemon *wildMon, u
|
||||
|
||||
#include "data.h"
|
||||
|
||||
static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 species, u8 area)
|
||||
static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 species, enum WildPokemonArea area)
|
||||
{
|
||||
u8 i, maxLevel = 0, numMon = 0;
|
||||
|
||||
@ -1068,6 +1179,9 @@ static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16
|
||||
case WILD_AREA_ROCKS:
|
||||
numMon = ROCK_WILD_COUNT;
|
||||
break;
|
||||
default:
|
||||
case WILD_AREA_FISHING:
|
||||
case WILD_AREA_HIDDEN:
|
||||
}
|
||||
|
||||
for (i = 0; i < numMon; i++)
|
||||
@ -1127,8 +1241,10 @@ bool8 TryDoDoubleWildBattle(void)
|
||||
|
||||
bool8 StandardWildEncounter_Debug(void)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
DoStandardWildBattle_Debug();
|
||||
|
||||
14
src/window.c
14
src/window.c
@ -240,6 +240,20 @@ void RemoveWindow(u32 windowId)
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveAllWindowsOnBg(u32 bgId)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
if (bgId > NUM_BACKGROUNDS)
|
||||
return;
|
||||
|
||||
for (i = 0; i < WINDOWS_MAX; i++)
|
||||
{
|
||||
if (gWindows[i].window.bg == bgId)
|
||||
RemoveWindow(i);
|
||||
}
|
||||
}
|
||||
|
||||
void FreeAllWindowBuffers(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
673
tools/wild_encounters/wild_encounters_to_header.py
Normal file
673
tools/wild_encounters/wild_encounters_to_header.py
Normal file
@ -0,0 +1,673 @@
|
||||
import json
|
||||
import re
|
||||
import os
|
||||
|
||||
|
||||
IS_ENABLED = False
|
||||
|
||||
# C string vars
|
||||
define = "#define"
|
||||
ENCOUNTER_CHANCE = "ENCOUNTER_CHANCE"
|
||||
SLOT = "SLOT"
|
||||
TOTAL = "TOTAL"
|
||||
NULL = "NULL"
|
||||
UNDEFINED = "UNDEFINED"
|
||||
MAP_UNDEFINED = "MAP_UNDEFINED"
|
||||
|
||||
# encounter group header types, filled out programmatically
|
||||
MON_HEADERS = []
|
||||
|
||||
# mon encounter group types
|
||||
LAND_MONS = "land_mons"
|
||||
LAND_MONS_LABEL = "LandMons"
|
||||
LAND_MONS_INDEX = 0
|
||||
WATER_MONS = "water_mons"
|
||||
WATER_MONS_LABEL = "WaterMons"
|
||||
WATER_MONS_INDEX = 1
|
||||
ROCK_SMASH_MONS = "rock_smash_mons"
|
||||
ROCK_SMASH_MONS_LABEL = "RockSmashMons"
|
||||
ROCK_SMASH_MONS_INDEX = 2
|
||||
FISHING_MONS = "fishing_mons"
|
||||
FISHING_MONS_LABEL = "FishingMons"
|
||||
FISHING_MONS_INDEX = 3
|
||||
HIDDEN_MONS = "hidden_mons"
|
||||
HIDDEN_MONS_LABEL = "HiddenMons"
|
||||
HIDDEN_MONS_INDEX = 4
|
||||
MONS_INFO_TOTAL = HIDDEN_MONS_INDEX + 1
|
||||
|
||||
# fishing encounter data
|
||||
GOOD_ROD = "good_rod"
|
||||
GOOD_ROD_FIRST_INDEX = 2
|
||||
GOOD_ROD_LAST_INDEX = 4
|
||||
OLD_ROD = "old_rod"
|
||||
OLD_ROD_FIRST_INDEX = 0
|
||||
OLD_ROD_LAST_INDEX = 1
|
||||
SUPER_ROD = "super_rod"
|
||||
SUPER_ROD_FIRST_INDEX = 5
|
||||
SUPER_ROD_LAST_INDEX = 9
|
||||
|
||||
# time of day encounter data
|
||||
TIME_DEFAULT = "OW_TIME_OF_DAY_DEFAULT"
|
||||
TIME_DEFAULT_LABEL = ""
|
||||
TIME_DEFAULT_INDEX = 0
|
||||
TIME_MORNING = "time_morning"
|
||||
TIME_MORNING_LABEL = "Morning"
|
||||
TIME_MORNING_INDEX = 0
|
||||
TIME_DAY = "time_day"
|
||||
TIME_DAY_LABEL = "Day"
|
||||
TIME_DAY_INDEX = 1
|
||||
TIME_EVENING = "time_evening"
|
||||
TIME_EVENING_LABEL = "Evening"
|
||||
TIME_EVENING_INDEX = 2
|
||||
TIME_NIGHT = "time_night"
|
||||
TIME_NIGHT_LABEL = "Night"
|
||||
TIME_NIGHT_INDEX = 3
|
||||
TOTAL_TIME_STAGES = TIME_NIGHT_INDEX + 1
|
||||
|
||||
# struct building blocks
|
||||
baseStruct = "const struct WildPokemon"
|
||||
structLabel = ""
|
||||
structMonType = ""
|
||||
structTime = ""
|
||||
structMap = ""
|
||||
|
||||
structInfo = "Info"
|
||||
structHeader = "Header"
|
||||
structArrayAssign = "[] ="
|
||||
|
||||
baseStructLabel = ""
|
||||
baseStructContent = []
|
||||
infoStructString = ""
|
||||
infoStructRate = 0
|
||||
infoStructContent = []
|
||||
headerStructLabel = ""
|
||||
headerStructContent = {}
|
||||
headerStructTable = {}
|
||||
headerIndex = 0
|
||||
|
||||
# map header data variables
|
||||
hLabel = ""
|
||||
hForMaps = True
|
||||
headersArray = [headerIndex]
|
||||
|
||||
# headersArrayItems
|
||||
landMonsInfo = ""
|
||||
waterMonsInfo = ""
|
||||
rockSmashMonsInfo = ""
|
||||
fishingMonsInfo = ""
|
||||
|
||||
# encounter rate variables
|
||||
eLandMons = []
|
||||
eWaterMons = []
|
||||
eRockSmashMons = []
|
||||
eFishingMons = []
|
||||
|
||||
|
||||
# debug output control
|
||||
printEncounterHeaders = True
|
||||
printEncounterRateMacros = True
|
||||
printEncounterStructsInfoString = True
|
||||
printEncounterStructs = True
|
||||
|
||||
|
||||
def ImportWildEncounterFile():
|
||||
# make sure we're in the right directory before anything else
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from the project's root folder.")
|
||||
quit()
|
||||
|
||||
global MON_HEADERS
|
||||
global landMonsInfo
|
||||
global waterMonsInfo
|
||||
global rockSmashMonsInfo
|
||||
global fishingMonsInfo
|
||||
global hiddenMonsInfo
|
||||
global structLabel
|
||||
global structMonType
|
||||
global structTime
|
||||
global structMap
|
||||
global baseStructLabel
|
||||
global baseStructContent
|
||||
global infoStructString
|
||||
global infoStructRate
|
||||
global headerStructLabel
|
||||
global headerStructContent
|
||||
global hLabel
|
||||
global headersArray
|
||||
global eLandMons
|
||||
global eWaterMons
|
||||
global eRockSmashMons
|
||||
global eFishingMons
|
||||
global encounterTotalCount
|
||||
global encounterCount
|
||||
global headerIndex
|
||||
global tabStr
|
||||
tabStr = " "
|
||||
|
||||
global IS_ENABLED
|
||||
IS_ENABLED = IsConfigEnabled()
|
||||
|
||||
wFile = open("src/data/wild_encounters.json")
|
||||
wData = json.load(wFile)
|
||||
|
||||
encounterTotalCount = []
|
||||
encounterCount = []
|
||||
groupCount = 0
|
||||
while groupCount < len(wData["wild_encounter_groups"]):
|
||||
encounterTotalCount.append(0)
|
||||
encounterCount.append(0)
|
||||
groupCount += 1
|
||||
|
||||
for data in wData["wild_encounter_groups"]:
|
||||
wEncounters = wData["wild_encounter_groups"][headerIndex]["encounters"]
|
||||
headerSuffix = structHeader + "s"
|
||||
|
||||
if data["label"]:
|
||||
hLabel = wData["wild_encounter_groups"][headerIndex]["label"]
|
||||
if headerSuffix in hLabel:
|
||||
hLabel = hLabel[:len(hLabel) - len(headerSuffix)]
|
||||
MON_HEADERS.append(hLabel)
|
||||
|
||||
if data["for_maps"]:
|
||||
hForMaps = wData["wild_encounter_groups"][headerIndex]["for_maps"]
|
||||
|
||||
# for the encounter rate macros, so we don't worry about hidden mons here
|
||||
if headerIndex == 0:
|
||||
wFields = wData["wild_encounter_groups"][headerIndex]["fields"]
|
||||
for field in wFields:
|
||||
if field["type"] == LAND_MONS:
|
||||
eLandMons = field["encounter_rates"]
|
||||
elif field["type"] == WATER_MONS:
|
||||
eWaterMons = field["encounter_rates"]
|
||||
elif field["type"] == ROCK_SMASH_MONS:
|
||||
eRockSmashMons = field["encounter_rates"]
|
||||
elif field["type"] == FISHING_MONS:
|
||||
eFishingMons = field["encounter_rates"]
|
||||
eFishingMons.append(field["groups"])
|
||||
|
||||
PrintGeneratedWarningText()
|
||||
|
||||
print('#include "rtc.h"')
|
||||
print("\n")
|
||||
|
||||
PrintEncounterRateMacros()
|
||||
print("\n")
|
||||
|
||||
for encounter in wEncounters:
|
||||
if "map" in encounter:
|
||||
structMap = encounter["map"]
|
||||
else:
|
||||
structMap = encounter["base_label"]
|
||||
structLabel = encounter["base_label"]
|
||||
|
||||
if encounterTotalCount[headerIndex] != len(wEncounters):
|
||||
encounterTotalCount[headerIndex] = len(wEncounters)
|
||||
encounterCount[headerIndex] += 1
|
||||
headersArray = []
|
||||
|
||||
if not IS_ENABLED:
|
||||
structTime = TIME_DEFAULT_LABEL
|
||||
elif TIME_MORNING_LABEL in structLabel:
|
||||
structTime = TIME_MORNING_LABEL
|
||||
elif TIME_DAY_LABEL in structLabel:
|
||||
structTime = TIME_DAY_LABEL
|
||||
elif TIME_EVENING_LABEL in structLabel:
|
||||
structTime = TIME_EVENING_LABEL
|
||||
elif TIME_NIGHT_LABEL in structLabel:
|
||||
structTime = TIME_NIGHT_LABEL
|
||||
else:
|
||||
structTime = TIME_MORNING_LABEL
|
||||
structLabel = structLabel + "_Morning"
|
||||
|
||||
landMonsInfo = ""
|
||||
waterMonsInfo = ""
|
||||
rockSmashMonsInfo = ""
|
||||
fishingMonsInfo = ""
|
||||
hiddenMonsInfo = ""
|
||||
for areaTable in encounter:
|
||||
if LAND_MONS in areaTable:
|
||||
structMonType = LAND_MONS_LABEL
|
||||
landMonsInfo = f"{structLabel}_{structMonType}{structInfo}"
|
||||
elif WATER_MONS in areaTable:
|
||||
structMonType = WATER_MONS_LABEL
|
||||
waterMonsInfo = f"{structLabel}_{structMonType}{structInfo}"
|
||||
elif ROCK_SMASH_MONS in areaTable:
|
||||
structMonType = ROCK_SMASH_MONS_LABEL
|
||||
rockSmashMonsInfo = f"{structLabel}_{structMonType}{structInfo}"
|
||||
elif FISHING_MONS in areaTable:
|
||||
structMonType = FISHING_MONS_LABEL
|
||||
fishingMonsInfo = f"{structLabel}_{structMonType}{structInfo}"
|
||||
elif HIDDEN_MONS in areaTable:
|
||||
structMonType = HIDDEN_MONS_LABEL
|
||||
hiddenMonsInfo = f"{structLabel}_{structMonType}{structInfo}"
|
||||
else:
|
||||
structMonType = ""
|
||||
continue
|
||||
|
||||
baseStructContent = []
|
||||
for group in encounter[areaTable]:
|
||||
if "mons" in group:
|
||||
for mon in encounter[areaTable][group]:
|
||||
baseStructContent.append(list(mon.values()))
|
||||
|
||||
if "encounter_rate" in group:
|
||||
infoStructRate = encounter[areaTable][group]
|
||||
|
||||
baseStructLabel = f"{baseStruct} {structLabel}_{structMonType}{structArrayAssign}"
|
||||
if printEncounterStructs:
|
||||
print()
|
||||
print(baseStructLabel)
|
||||
print("{")
|
||||
PrintStructContent(baseStructContent)
|
||||
print("};")
|
||||
|
||||
if printEncounterStructsInfoString:
|
||||
infoStructString = f"{baseStruct}{structInfo} {structLabel}_{structMonType}{structInfo} = {{ {infoStructRate}, {structLabel}_{structMonType} }};"
|
||||
print(infoStructString)
|
||||
|
||||
AssembleMonHeaderContent()
|
||||
headerIndex += 1
|
||||
PrintWildMonHeadersContent()
|
||||
|
||||
|
||||
def PrintStructContent(contentList):
|
||||
for monList in contentList:
|
||||
print(f"{tabStr}{{ {monList[0]}, {monList[1]}, {monList[2]} }},")
|
||||
return
|
||||
|
||||
|
||||
def GetStructLabelWithoutTime(label):
|
||||
labelLength = len(label)
|
||||
timeLength = 0
|
||||
|
||||
if not IS_ENABLED:
|
||||
return label
|
||||
elif TIME_MORNING_LABEL in label:
|
||||
timeLength = len(TIME_MORNING_LABEL)
|
||||
elif TIME_DAY_LABEL in label:
|
||||
timeLength = len(TIME_DAY_LABEL)
|
||||
elif TIME_EVENING_LABEL in label:
|
||||
timeLength = len(TIME_EVENING_LABEL)
|
||||
elif TIME_NIGHT_LABEL in label:
|
||||
timeLength = len(TIME_NIGHT_LABEL)
|
||||
return label[:(labelLength - (timeLength + 1))]
|
||||
|
||||
|
||||
def AssembleMonHeaderContent():
|
||||
global structLabel
|
||||
|
||||
SetupMonInfoVars()
|
||||
|
||||
tempHeaderLabel = GetWildMonHeadersLabel()
|
||||
tempHeaderTimeIndex = GetTimeIndexFromString(structTime)
|
||||
structLabelNoTime = GetStructLabelWithoutTime(structLabel)
|
||||
|
||||
if tempHeaderLabel not in headerStructTable:
|
||||
headerStructTable[tempHeaderLabel] = {}
|
||||
headerStructTable[tempHeaderLabel]["groupNum"] = headerIndex
|
||||
|
||||
if structLabelNoTime not in headerStructTable[tempHeaderLabel]:
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime] = {}
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["headerType"] = GetWildMonHeadersLabel()
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["mapGroup"] = structMap
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["mapNum"] = structMap
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounterTotalCount"] = encounterTotalCount[headerIndex]
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"] = []
|
||||
|
||||
timeStart = TIME_DEFAULT_INDEX
|
||||
timeEnd = TIME_NIGHT_INDEX if IS_ENABLED else TIME_DEFAULT_INDEX
|
||||
while timeStart <= timeEnd:
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"].append([])
|
||||
timeStart += 1
|
||||
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"][tempHeaderTimeIndex].append(landMonsInfo)
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"][tempHeaderTimeIndex].append(waterMonsInfo)
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"][tempHeaderTimeIndex].append(rockSmashMonsInfo)
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"][tempHeaderTimeIndex].append(fishingMonsInfo)
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"][tempHeaderTimeIndex].append(hiddenMonsInfo)
|
||||
|
||||
|
||||
def SetupMonInfoVars():
|
||||
global landMonsInfo
|
||||
global waterMonsInfo
|
||||
global rockSmashMonsInfo
|
||||
global fishingMonsInfo
|
||||
global hiddenMonsInfo
|
||||
|
||||
if landMonsInfo == "":
|
||||
landMonsInfo = NULL
|
||||
else:
|
||||
landMonsInfo = f"&{landMonsInfo}"
|
||||
|
||||
if waterMonsInfo == "":
|
||||
waterMonsInfo = NULL
|
||||
else:
|
||||
waterMonsInfo = f"&{waterMonsInfo}"
|
||||
|
||||
if rockSmashMonsInfo == "":
|
||||
rockSmashMonsInfo = NULL
|
||||
else:
|
||||
rockSmashMonsInfo = f"&{rockSmashMonsInfo}"
|
||||
|
||||
if fishingMonsInfo == "":
|
||||
fishingMonsInfo = NULL
|
||||
else:
|
||||
fishingMonsInfo = f"&{fishingMonsInfo}"
|
||||
|
||||
if hiddenMonsInfo == "":
|
||||
hiddenMonsInfo = NULL
|
||||
else:
|
||||
hiddenMonsInfo = f"&{hiddenMonsInfo}"
|
||||
|
||||
|
||||
def PrintWildMonHeadersContent():
|
||||
global tabStr
|
||||
|
||||
groupCount = 0
|
||||
for group in headerStructTable:
|
||||
labelCount = 0
|
||||
for label in headerStructTable[group]:
|
||||
if label != "groupNum":
|
||||
if labelCount == 0:
|
||||
PrintEncounterHeaders("\n")
|
||||
PrintEncounterHeaders(headerStructTable[group][label]["headerType"])
|
||||
|
||||
PrintEncounterHeaders(tabStr + "{")
|
||||
|
||||
for stat in headerStructTable[group][label]:
|
||||
mapData = headerStructTable[group][label][stat]
|
||||
|
||||
if stat == "mapGroup":
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapGroup = {GetMapGroupEnum(mapData)},")
|
||||
elif stat == "mapNum":
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapNum = {GetMapGroupEnum(mapData, labelCount + 1)},")
|
||||
|
||||
if type(headerStructTable[group][label][stat]) == list:
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.encounterTypes =")
|
||||
PrintEncounterHeaders(TabStr(2) + "{")
|
||||
|
||||
infoCount = 0
|
||||
for monInfo in headerStructTable[group][label][stat]:
|
||||
PrintEncounterHeaders(f"{TabStr(3)}[{GetTimeStrFromIndex(infoCount)}] = ")
|
||||
|
||||
infoIndex = 0
|
||||
while infoIndex <= MONS_INFO_TOTAL - 1:
|
||||
if infoIndex == 0:
|
||||
PrintEncounterHeaders(TabStr(3) + "{")
|
||||
|
||||
if len(monInfo) == 0:
|
||||
PrintEncounterHeaders(f"{TabStr(4)}{GetIMonInfoStringFromIndex(infoIndex)} = NULL,")
|
||||
else:
|
||||
PrintEncounterHeaders(f"{TabStr(4)}{GetIMonInfoStringFromIndex(infoIndex)} = {monInfo[infoIndex]},")
|
||||
|
||||
if infoIndex == MONS_INFO_TOTAL - 1:
|
||||
PrintEncounterHeaders(TabStr(3) + "},")
|
||||
|
||||
infoIndex += 1
|
||||
infoCount += 1
|
||||
PrintEncounterHeaders(TabStr(2) + "},")
|
||||
PrintEncounterHeaders(tabStr + "},")
|
||||
|
||||
if labelCount + 1 == headerStructTable[group][label]["encounterTotalCount"]:
|
||||
PrintEncounterHeaders(tabStr + "{")
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapGroup = {GetMapGroupEnum(MAP_UNDEFINED)},")
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapNum = {GetMapGroupEnum(MAP_UNDEFINED, labelCount + 1)},")
|
||||
|
||||
timeEnd = TIME_NIGHT_INDEX if IS_ENABLED else TIME_DEFAULT_INDEX
|
||||
nullCount = 0
|
||||
while nullCount <= timeEnd:
|
||||
if nullCount == 0:
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.encounterTypes =")
|
||||
PrintEncounterHeaders(TabStr(2)+ "{")
|
||||
|
||||
PrintEncounterHeaders(f"{TabStr(3)}[{GetTimeStrFromIndex(nullCount)}] = ")
|
||||
|
||||
nullIndex = 0
|
||||
while nullIndex <= MONS_INFO_TOTAL - 1:
|
||||
if nullIndex == 0:
|
||||
PrintEncounterHeaders(TabStr(3) + "{")
|
||||
|
||||
PrintEncounterHeaders(f"{TabStr(4)}{GetIMonInfoStringFromIndex(nullIndex)} = NULL,")
|
||||
|
||||
if nullIndex == MONS_INFO_TOTAL - 1:
|
||||
PrintEncounterHeaders(TabStr(3) + "},")
|
||||
|
||||
nullIndex += 1
|
||||
nullCount += 1
|
||||
PrintEncounterHeaders(TabStr(2) + "},")
|
||||
PrintEncounterHeaders(tabStr + "},")
|
||||
labelCount += 1
|
||||
groupCount += 1
|
||||
PrintEncounterHeaders("};")
|
||||
|
||||
|
||||
def GetWildMonHeadersLabel():
|
||||
return f"{baseStruct}{structHeader} {MON_HEADERS[headerIndex]}{structHeader}s{structArrayAssign}" + "\n{"
|
||||
|
||||
|
||||
def PrintEncounterHeaders(content):
|
||||
if printEncounterHeaders:
|
||||
print(content)
|
||||
|
||||
|
||||
def PrintEncounterRateMacros():
|
||||
if not printEncounterRateMacros:
|
||||
return
|
||||
|
||||
rateCount = 0
|
||||
for percent in eLandMons:
|
||||
if rateCount == 0:
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{LAND_MONS.upper()}_{SLOT}_{rateCount} {percent}")
|
||||
else:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{LAND_MONS.upper()}_{SLOT}_{rateCount} {ENCOUNTER_CHANCE}_{LAND_MONS.upper()}_{SLOT}_{rateCount - 1} + {percent}"
|
||||
)
|
||||
|
||||
if rateCount + 1 == len(eLandMons):
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{LAND_MONS.upper()}_{TOTAL} ({ENCOUNTER_CHANCE}_{LAND_MONS.upper()}_{SLOT}_{rateCount})"
|
||||
)
|
||||
rateCount += 1
|
||||
|
||||
rateCount = 0
|
||||
for percent in eWaterMons:
|
||||
if rateCount == 0:
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{WATER_MONS.upper()}_{SLOT}_{rateCount} {percent}")
|
||||
else:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{WATER_MONS.upper()}_{SLOT}_{rateCount} {ENCOUNTER_CHANCE}_{WATER_MONS.upper()}_{SLOT}_{rateCount - 1} + {percent}"
|
||||
)
|
||||
|
||||
if rateCount + 1 == len(eWaterMons):
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{WATER_MONS.upper()}_{TOTAL} ({ENCOUNTER_CHANCE}_{WATER_MONS.upper()}_{SLOT}_{rateCount})"
|
||||
)
|
||||
rateCount += 1
|
||||
|
||||
rateCount = 0
|
||||
for percent in eRockSmashMons:
|
||||
if rateCount == 0:
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{ROCK_SMASH_MONS.upper()}_{SLOT}_{rateCount} {percent}")
|
||||
else:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{ROCK_SMASH_MONS.upper()}_{SLOT}_{rateCount} {ENCOUNTER_CHANCE}_{ROCK_SMASH_MONS.upper()}_{SLOT}_{rateCount - 1} + {percent}"
|
||||
)
|
||||
|
||||
if rateCount + 1 == len(eRockSmashMons):
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{ROCK_SMASH_MONS.upper()}_{TOTAL} ({ENCOUNTER_CHANCE}_{ROCK_SMASH_MONS.upper()}_{SLOT}_{rateCount})"
|
||||
)
|
||||
rateCount += 1
|
||||
|
||||
for rodRate in eFishingMons[-1]:
|
||||
for rodPercentIndex in eFishingMons[-1][rodRate]:
|
||||
if rodPercentIndex == OLD_ROD_FIRST_INDEX or rodPercentIndex == GOOD_ROD_FIRST_INDEX or rodPercentIndex == SUPER_ROD_FIRST_INDEX:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{FISHING_MONS.upper()}_{rodRate.upper()}_{SLOT}_{rodPercentIndex} {eFishingMons[rodPercentIndex]}"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{FISHING_MONS.upper()}_{rodRate.upper()}_{SLOT}_{rodPercentIndex} {ENCOUNTER_CHANCE}_{FISHING_MONS.upper()}_{rodRate.upper()}_{SLOT}_{rodPercentIndex - 1} + {eFishingMons[rodPercentIndex]}"
|
||||
)
|
||||
|
||||
if rodPercentIndex == OLD_ROD_LAST_INDEX or rodPercentIndex == GOOD_ROD_LAST_INDEX or rodPercentIndex == SUPER_ROD_LAST_INDEX:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{FISHING_MONS.upper()}_{rodRate.upper()}_{TOTAL} ({ENCOUNTER_CHANCE}_{FISHING_MONS.upper()}_{rodRate.upper()}_{SLOT}_{rodPercentIndex})"
|
||||
)
|
||||
|
||||
|
||||
def GetTimeStrFromIndex(index):
|
||||
if not IS_ENABLED:
|
||||
return TIME_DEFAULT
|
||||
elif index == TIME_MORNING_INDEX:
|
||||
return TIME_MORNING.upper()
|
||||
elif index == TIME_DAY_INDEX:
|
||||
return TIME_DAY.upper()
|
||||
elif index == TIME_EVENING_INDEX:
|
||||
return TIME_EVENING.upper()
|
||||
elif index == TIME_NIGHT_INDEX:
|
||||
return TIME_NIGHT.upper()
|
||||
return index
|
||||
|
||||
|
||||
def GetTimeIndexFromString(string):
|
||||
if not IS_ENABLED:
|
||||
return TIME_DEFAULT_INDEX
|
||||
elif string.lower() == TIME_MORNING or string == TIME_MORNING_LABEL:
|
||||
return TIME_MORNING_INDEX
|
||||
elif string.lower() == TIME_DAY or string == TIME_DAY_LABEL:
|
||||
return TIME_DAY_INDEX
|
||||
elif string.lower() == TIME_EVENING or string == TIME_EVENING_LABEL:
|
||||
return TIME_EVENING_INDEX
|
||||
elif string.lower() == TIME_NIGHT or string == TIME_NIGHT_LABEL:
|
||||
return TIME_NIGHT_INDEX
|
||||
return string
|
||||
|
||||
|
||||
def GetIMonInfoStringFromIndex(index):
|
||||
if index == LAND_MONS_INDEX:
|
||||
return ".landMonsInfo"
|
||||
elif index == WATER_MONS_INDEX:
|
||||
return ".waterMonsInfo"
|
||||
elif index == ROCK_SMASH_MONS_INDEX:
|
||||
return ".rockSmashMonsInfo"
|
||||
elif index == FISHING_MONS_INDEX:
|
||||
return ".fishingMonsInfo"
|
||||
elif index == HIDDEN_MONS_INDEX:
|
||||
return ".hiddenMonsInfo"
|
||||
return index
|
||||
|
||||
|
||||
def GetMapGroupEnum(string, index = 0):
|
||||
if "MAP_" in string and index == 0:
|
||||
return "MAP_GROUP(" + string[4:len(string)] + ")"
|
||||
elif "MAP_" in string and index != 0:
|
||||
return "MAP_NUM(" + string[4:len(string)] + ")"
|
||||
return index
|
||||
|
||||
|
||||
"""
|
||||
get copied lhea :^ )
|
||||
- next two functions copied almost verbatim from @lhearachel's python scripts in tools/learnset_helpers
|
||||
"""
|
||||
def PrintGeneratedWarningText():
|
||||
print("//")
|
||||
print("// DO NOT MODIFY THIS FILE! It is auto-generated by tools/wild_encounters/wild_encounters_to_header.py")
|
||||
print("//")
|
||||
print("\n")
|
||||
|
||||
|
||||
def IsConfigEnabled():
|
||||
CONFIG_ENABLED_PAT = re.compile(r"#define OW_TIME_OF_DAY_ENCOUNTERS\s+(?P<cfg_val>[^ ]*)")
|
||||
|
||||
with open("./include/config/overworld.h", "r") as overworld_config_file:
|
||||
config_overworld = overworld_config_file.read()
|
||||
config_setting = CONFIG_ENABLED_PAT.search(config_overworld)
|
||||
return config_setting is not None and config_setting.group("cfg_val") in ("TRUE", "1")
|
||||
|
||||
|
||||
def TabStr(amount):
|
||||
global tabStr
|
||||
return tabStr * amount
|
||||
|
||||
|
||||
ImportWildEncounterFile()
|
||||
|
||||
|
||||
"""
|
||||
!!!! EXAMPLE OUTPUT !!!!
|
||||
- when OW_TIME_OF DAY_ENCOUNTERS is FALSE in configoverworld.h
|
||||
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 20
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 + 20
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 + 5
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 + 5
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 + 4
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 + 4
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_10 ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 + 1
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_11 ENCOUNTER_CHANCE_LAND_MONS_SLOT_10 + 1
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_TOTAL (ENCOUNTER_CHANCE_LAND_MONS_SLOT_11)
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 60
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 + 30
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 + 5
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_3 ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 + 4
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_4 ENCOUNTER_CHANCE_WATER_MONS_SLOT_3 + 1
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_TOTAL (ENCOUNTER_CHANCE_WATER_MONS_SLOT_4)
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_0 60
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_1 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_0 + 30
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_2 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_1 + 5
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_3 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_2 + 4
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_4 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_3 + 1
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_TOTAL (ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_4)
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2 60
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2 + 20
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4 ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 + 20
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_TOTAL (ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4)
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_0 70
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_1 ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_0 + 30
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_TOTAL (ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_1)
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5 40
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_6 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5 + 40
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_7 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_6 + 15
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_7 + 4
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 + 1
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_TOTAL (ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9)
|
||||
|
||||
const struct WildPokemon gRoute101_LandMons_Day[] =
|
||||
{
|
||||
{ 2, 2, SPECIES_WURMPLE },
|
||||
{ 2, 2, SPECIES_POOCHYENA },
|
||||
{ 2, 2, SPECIES_WURMPLE },
|
||||
{ 3, 3, SPECIES_WURMPLE },
|
||||
{ 3, 3, SPECIES_POOCHYENA },
|
||||
{ 3, 3, SPECIES_POOCHYENA },
|
||||
{ 3, 3, SPECIES_WURMPLE },
|
||||
{ 3, 3, SPECIES_POOCHYENA },
|
||||
{ 2, 2, SPECIES_ZIGZAGOON },
|
||||
{ 2, 2, SPECIES_ZIGZAGOON },
|
||||
{ 3, 3, SPECIES_ZIGZAGOON },
|
||||
{ 3, 3, SPECIES_ZIGZAGOON },
|
||||
};
|
||||
|
||||
const struct WildPokemonInfo gRoute101_Day_LandMonsInfo= { 20, gRoute101_Day_LandMons };
|
||||
const struct WildPokemonHeader gWildMonHeaders[] =
|
||||
{
|
||||
{
|
||||
.mapGroup = MAP(ROUTE101),
|
||||
.mapNum = MAP_NUM(ROUTE101),
|
||||
.encounterTypes =
|
||||
[OW_TIME_OF_DAY_DEFAULT] =
|
||||
{
|
||||
.landMonsInfo = &gRoute101_LandMonsInfo,
|
||||
.waterMonsInfo = NULL,
|
||||
.rockSmashMonsInfo = NULL,
|
||||
.fishingMonsInfo = NULL,
|
||||
.hiddenMonsInfo = NULL,
|
||||
}
|
||||
},
|
||||
}
|
||||
"""
|
||||
Loading…
x
Reference in New Issue
Block a user