diff --git a/docsrc/manual/project-files.rst b/docsrc/manual/project-files.rst index 1da0fbc6..b99e74d7 100644 --- a/docsrc/manual/project-files.rst +++ b/docsrc/manual/project-files.rst @@ -67,6 +67,7 @@ The filepath that Porymap expects for each file can be overridden on the ``Files include/fieldmap.h, yes, no, ``constants_fieldmap``, reads tileset related constants src/fieldmap.c, yes, no, ``fieldmap``, reads ``symbol_attribute_table`` src/event_object_movement.c, yes, no, ``initial_facing_table``, reads ``symbol_facing_directions`` + src/wild_encounter.c, yes, no, ``wild_encounter``, reads ``define_max_encounter_rate`` src/pokemon_icon.c, yes, no, ``pokemon_icon_table``, reads files in ``symbol_pokemon_icon_table`` graphics/pokemon/\*/icon.png, yes, no, ``pokemon_gfx``, to search for Pokémon icons if they aren't found in ``symbol_pokemon_icon_table`` @@ -96,6 +97,7 @@ In addition to these files, there are some specific symbol and macro names that ``define_obj_event_count``, ``OBJECT_EVENT_TEMPLATES_COUNT``, to limit total Object Events ``define_min_level``, ``MIN_LEVEL``, minimum wild encounters level ``define_max_level``, ``MAX_LEVEL``, maximum wild encounters level + ``define_max_encounter_rate``, ``MAX_ENCOUNTER_RATE``, this value / 16 will be the maximum encounter rate on the ``Wild Pokémon`` tab ``define_tiles_primary``, ``NUM_TILES_IN_PRIMARY``, ``define_tiles_total``, ``NUM_TILES_TOTAL``, ``define_metatiles_primary``, ``NUM_METATILES_IN_PRIMARY``, total metatiles are calculated using metatile ID mask diff --git a/include/config.h b/include/config.h index 25138ff8..a2fead2e 100644 --- a/include/config.h +++ b/include/config.h @@ -194,6 +194,7 @@ enum ProjectIdentifier { define_obj_event_count, define_min_level, define_max_level, + define_max_encounter_rate, define_tiles_primary, define_tiles_total, define_metatiles_primary, @@ -281,6 +282,7 @@ enum ProjectFilePath { global_fieldmap, fieldmap, initial_facing_table, + wild_encounter, pokemon_icon_table, pokemon_gfx, }; diff --git a/include/project.h b/include/project.h index 8c08e508..c3fc1677 100644 --- a/include/project.h +++ b/include/project.h @@ -39,7 +39,6 @@ public: QMap mapGroups; QList groupedMapNames; QStringList mapNames; - QMap miscConstants; QList healLocations; QMap healLocationNameToValue; QMap mapConstantsToMapNames; @@ -79,6 +78,9 @@ public: bool usingAsmTilesets; QString importExportPath; QSet disabledSettingsNames; + int pokemonMinLevel; + int pokemonMaxLevel; + int maxEncounterRate; bool wildEncountersLoaded; void set_root(QString); diff --git a/src/config.cpp b/src/config.cpp index 5f1b3bd9..20869171 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -85,6 +85,7 @@ const QMap> ProjectConfig::defaultIde {ProjectIdentifier::define_obj_event_count, {"define_obj_event_count", "OBJECT_EVENT_TEMPLATES_COUNT"}}, {ProjectIdentifier::define_min_level, {"define_min_level", "MIN_LEVEL"}}, {ProjectIdentifier::define_max_level, {"define_max_level", "MAX_LEVEL"}}, + {ProjectIdentifier::define_max_encounter_rate, {"define_max_encounter_rate", "MAX_ENCOUNTER_RATE"}}, {ProjectIdentifier::define_tiles_primary, {"define_tiles_primary", "NUM_TILES_IN_PRIMARY"}}, {ProjectIdentifier::define_tiles_total, {"define_tiles_total", "NUM_TILES_TOTAL"}}, {ProjectIdentifier::define_metatiles_primary, {"define_metatiles_primary", "NUM_METATILES_IN_PRIMARY"}}, @@ -174,6 +175,7 @@ const QMap> ProjectConfig::defaultPaths {ProjectFilePath::fieldmap, { "fieldmap", "src/fieldmap.c"}}, {ProjectFilePath::pokemon_icon_table, { "pokemon_icon_table", "src/pokemon_icon.c"}}, {ProjectFilePath::initial_facing_table, { "initial_facing_table", "src/event_object_movement.c"}}, + {ProjectFilePath::wild_encounter, { "wild_encounter", "src/wild_encounter.c"}}, {ProjectFilePath::pokemon_gfx, { "pokemon_gfx", "graphics/pokemon/"}}, }; diff --git a/src/project.cpp b/src/project.cpp index d1c3f63c..3719917e 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1654,15 +1654,43 @@ void Project::deleteFile(QString path) { } bool Project::readWildMonData() { - extraEncounterGroups.clear(); - wildMonFields.clear(); - wildMonData.clear(); - encounterGroupLabels.clear(); + this->extraEncounterGroups.clear(); + this->wildMonFields.clear(); + this->wildMonData.clear(); + this->encounterGroupLabels.clear(); + this->pokemonMinLevel = 0; + this->pokemonMaxLevel = 100; + this->maxEncounterRate = 2880/16; this->wildEncountersLoaded = false; if (!userConfig.useEncounterJson) { return true; } + // Read max encounter rate. The games multiply the encounter rate value in the map data by 16, so our input limit is the max/16. + const QString encounterRateFile = projectConfig.getFilePath(ProjectFilePath::wild_encounter); + const QString maxEncounterRateName = projectConfig.getIdentifier(ProjectIdentifier::define_max_encounter_rate); + + fileWatcher.addPath(QString("%1/%2").arg(root).arg(encounterRateFile)); + auto defines = parser.readCDefinesByName(encounterRateFile, {maxEncounterRateName}); + if (defines.contains(maxEncounterRateName)) + this->maxEncounterRate = defines.value(maxEncounterRateName)/16; + + // Read min/max level + const QString levelRangeFile = projectConfig.getFilePath(ProjectFilePath::constants_pokemon); + const QString minLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_min_level); + const QString maxLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_max_level); + + fileWatcher.addPath(QString("%1/%2").arg(root).arg(levelRangeFile)); + defines = parser.readCDefinesByName(levelRangeFile, {minLevelName, maxLevelName}); + if (defines.contains(minLevelName)) + this->pokemonMinLevel = defines.value(minLevelName); + if (defines.contains(maxLevelName)) + this->pokemonMaxLevel = defines.value(maxLevelName); + + this->pokemonMinLevel = qMin(this->pokemonMinLevel, this->pokemonMaxLevel); + this->pokemonMaxLevel = qMax(this->pokemonMinLevel, this->pokemonMaxLevel); + + // Read encounter data QString wildMonJsonFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_wild_encounters)); fileWatcher.addPath(wildMonJsonFilepath); @@ -2412,17 +2440,6 @@ bool Project::readObjEventGfxConstants() { } bool Project::readMiscellaneousConstants() { - miscConstants.clear(); - if (userConfig.useEncounterJson) { - const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_pokemon); - const QString minLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_min_level); - const QString maxLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_max_level); - fileWatcher.addPath(root + "/" + filename); - QMap pokemonDefines = parser.readCDefinesByName(filename, {minLevelName, maxLevelName}); - miscConstants.insert("max_level_define", pokemonDefines.value(maxLevelName) > pokemonDefines.value(minLevelName) ? pokemonDefines.value(maxLevelName) : 100); - miscConstants.insert("min_level_define", pokemonDefines.value(minLevelName) < pokemonDefines.value(maxLevelName) ? pokemonDefines.value(minLevelName) : 1); - } - const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_global); const QString maxObjectEventsName = projectConfig.getIdentifier(ProjectIdentifier::define_obj_event_count); fileWatcher.addPath(root + "/" + filename); diff --git a/src/ui/encountertabledelegates.cpp b/src/ui/encountertabledelegates.cpp index 89d0ec89..230abc7b 100644 --- a/src/ui/encountertabledelegates.cpp +++ b/src/ui/encountertabledelegates.cpp @@ -75,15 +75,12 @@ QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewIt int col = index.column(); if (col == EncounterTableModel::ColumnType::MinLevel || col == EncounterTableModel::ColumnType::MaxLevel) { - editor->setMinimum(this->project->miscConstants.value("min_level_define").toInt()); - editor->setMaximum(this->project->miscConstants.value("max_level_define").toInt()); + editor->setMinimum(this->project->pokemonMinLevel); + editor->setMaximum(this->project->pokemonMaxLevel); } else if (col == EncounterTableModel::ColumnType::EncounterRate) { - // The games multiply the encounter rate value provided here by 16, so the input limit is the max/16. - // TODO: Read MAX_ENCOUNTER_RATE? - static const int maxEncounterRate = 2880; editor->setMinimum(0); - editor->setMaximum(maxEncounterRate / 16); + editor->setMaximum(this->project->maxEncounterRate); } return editor;