From 38ba41b324e81214d4c57e1101930a00c006386e Mon Sep 17 00:00:00 2001 From: khbsd Date: Fri, 30 May 2025 15:22:05 +0000 Subject: [PATCH] fix: better area mons handling, no longer duplicates `hiddenMons` field (#6945) --- Makefile | 2 +- .../wild_encounters_to_header.py | 93 +++++++++++++------ 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 9f67efc54a..47503834c9 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,7 @@ ALL_LEARNABLES_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_learnables.json 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 +$(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 $(INCLUDE_DIRS)/config/dexnav.h python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@ $(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h diff --git a/tools/wild_encounters/wild_encounters_to_header.py b/tools/wild_encounters/wild_encounters_to_header.py index 3aab5a2632..5de52fbea9 100644 --- a/tools/wild_encounters/wild_encounters_to_header.py +++ b/tools/wild_encounters/wild_encounters_to_header.py @@ -4,6 +4,7 @@ import os IS_ENABLED = False +DEXNAV_ENABLED = False # C string vars define = "#define" @@ -54,8 +55,6 @@ hLabel = "" hForMaps = True headersArray = [headerIndex] - - # debug output control mainSwitch = True printWarningAndInclude = mainSwitch @@ -115,6 +114,9 @@ def ImportWildEncounterFile(): if IsConfigEnabled(): IS_ENABLED = True TIMES_OF_DAY_COUNT = len(TIME_OF_DAY) + + global DEXNAV_ENABLED + DEXNAV_ENABLED = IsDexnavEnabled() global fieldInfoStrings global fieldStrings @@ -160,26 +162,25 @@ def ImportWildEncounterFile(): 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"] fieldCounter = 0 for field in wFields: - fieldData.append({}) - fieldData[fieldCounter]["name"] = field["type"] - fieldData[fieldCounter]["pascalName"] = GetPascalCase(field["type"]) - fieldData[fieldCounter]["snakeName"] = GetSnakeCase(field["type"]) - fieldData[fieldCounter]["encounter_rates"] = field["encounter_rates"] + if not CheckFieldDataDupes(field["type"]): + AddFieldData(fieldCounter, field["type"], field["encounter_rates"]) if "groups" in field: fieldData[fieldCounter]["groups"] = field["groups"] - if fieldCounter == len(wFields) - 1: - fieldData.append({}) - fieldData[fieldCounter + 1]["name"] = "hidden_mons" - fieldData[fieldCounter + 1]["pascalName"] = GetPascalCase("hidden_mons") - fieldData[fieldCounter + 1]["snakeName"] = GetSnakeCase("hidden_mons") + """ + hidden mons need a special bit of logic since they're not in the vanilla + wild_encounters.json file, but the code expects them to be there + """ + hidden_mons = "hidden_mons" + if (fieldCounter == len(wFields) - 1) and not CheckFieldDataDupes(hidden_mons): + hidden_dummy_rates = [1, 0] + AddFieldData(fieldCounter + 1, hidden_mons, hidden_dummy_rates) fieldCounter += 1 @@ -437,25 +438,28 @@ def PrintEncounterRateMacros(): return fieldCounter = 0 - # len(fieldData) - 1 here so we skip hidden_mons - while fieldCounter < len(fieldData) - 1: + while fieldCounter < len(fieldData): tempName = fieldData[fieldCounter]["name"].upper() if "groups" not in fieldData[fieldCounter]: rateCount = 0 - for percent in fieldData[fieldCounter]["encounter_rates"]: - if rateCount == 0: - print(f"{define} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount} {percent}") - else: - print( - f"{define} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount - 1} + {percent}" - ) + if fieldData[fieldCounter]["encounter_rates"]: + for percent in fieldData[fieldCounter]["encounter_rates"]: + if not DEXNAV_ENABLED and tempName == "HIDDEN_MONS": + break - if rateCount + 1 == len(fieldData[fieldCounter]["encounter_rates"]): - print( - f"{define} {ENCOUNTER_CHANCE}_{tempName}_{TOTAL} ({ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount})" - ) + if rateCount == 0: + print(f"{define} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount} {percent}") + else: + print( + f"{define} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount - 1} + {percent}" + ) - rateCount += 1 + if rateCount + 1 == len(fieldData[fieldCounter]["encounter_rates"]): + print( + f"{define} {ENCOUNTER_CHANCE}_{tempName}_{TOTAL} ({ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount})" + ) + + rateCount += 1 else: rates = fieldData[fieldCounter]["encounter_rates"] groups = fieldData[fieldCounter]["groups"] @@ -512,7 +516,7 @@ def GetMapGroupEnum(string, index = 0): """ get copied lhea :^ ) -- next three functions copied almost verbatim from @lhearachel's python scripts in tools/learnset_helpers +- next four functions copied almost verbatim from @lhearachel's python scripts in tools/learnset_helpers """ def PrintGeneratedWarningText(): print("//") @@ -530,6 +534,15 @@ def IsConfigEnabled(): return config_setting is not None and config_setting.group("cfg_val") in ("TRUE", "1") +def IsDexnavEnabled(): + CONFIG_ENABLED_PAT = re.compile(r"#define DEXNAV_ENABLED\s+(?P[^ ]*)") + + with open("./include/config/dexnav.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 GetTimeEnum(): DEFAULT_TIME_PAT = re.compile(r"enum\s+TimeOfDay\s*\{(?P[\s*\w+,\=\d*]+)\s*\}\s*\;") @@ -600,6 +613,21 @@ def GetSnakeCase(string): return snakeString +def CheckFieldDataDupes(name): + for field in fieldData: + if field["name"] == name: + return True + return False + + +def AddFieldData(index, fieldType, fieldRates): + fieldData.append({}) + fieldData[index]["name"] = fieldType + fieldData[index]["pascalName"] = GetPascalCase(fieldType) + fieldData[index]["snakeName"] = GetSnakeCase(fieldType) + fieldData[index]["encounter_rates"] = fieldRates + + def main(): pass @@ -651,6 +679,13 @@ if __name__ == "__main__": #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) +- if DEXNAV_ENABLED is TRUE +- these macros are 1 and 0, respectively if hidden_mons isn't in the encounter + rate list at the top of wild_encounters.json +#define ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_0 1 +#define ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_1 ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_0 + 0 +#define ENCOUNTER_CHANCE_HIDDEN_MONS_TOTAL (ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_1) + const struct WildPokemon gRoute101_LandMons_Day[] = { { 2, 2, SPECIES_WURMPLE },