From 089e214d2e37414812ae716fb7474f6593ba1d48 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 10 Sep 2022 23:30:28 -0400 Subject: [PATCH] Add new map config options --- docsrc/manual/settings-and-options.rst | 3 + include/config.h | 19 +++- src/config.cpp | 125 ++++++++++++++++++------- src/project.cpp | 30 +++--- 4 files changed, 127 insertions(+), 50 deletions(-) diff --git a/docsrc/manual/settings-and-options.rst b/docsrc/manual/settings-and-options.rst index 4cbe3c57..df8cd0a9 100644 --- a/docsrc/manual/settings-and-options.rst +++ b/docsrc/manual/settings-and-options.rst @@ -47,6 +47,9 @@ determined by this file. ``enable_floor_number``, 1 if ``pokefirered``, project, yes, Adds ``Floor Number`` to map headers ``create_map_text_file``, 1 if not ``pokeemerald``, project, yes, A ``text.inc`` or ``text.pory`` file will be created for any new map ``enable_triple_layer_metatiles``, 0, project, yes, Enables triple-layer metatiles (See https://github.com/pret/pokeemerald/wiki/Triple-layer-metatiles) + ``new_map_metatile``, 1, project, yes, The metatile id that will be used to fill new maps + ``new_map_elevation``, 3, project, yes, The elevation that will be used to fill new maps + ``new_map_border_metatiles``, "``468,469,476,477`` or ``20,21,28,29``", project, yes, The list of metatile ids that will be used to fill the 2x2 border of new maps ``custom_scripts``, , project, yes, A list of script files to load into the scripting engine ``prefabs_filepath``, ``/prefabs.json``, project, yes, The filepath containing prefab JSON data diff --git a/include/config.h b/include/config.h index f8e86fac..af19bbf8 100644 --- a/include/config.h +++ b/include/config.h @@ -9,6 +9,10 @@ #include #include +// In both versions the default new map border is a generic tree +#define DEFAULT_BORDER_RSE (QList{468, 469, 476, 477}) +#define DEFAULT_BORDER_FRLG (QList{20, 21, 28, 29}) + enum MapSortOrder { Group = 0, Area = 1, @@ -28,7 +32,8 @@ protected: virtual QMap getKeyValueMap() = 0; virtual void onNewConfigFileCreated() = 0; virtual void setUnreadKeys() = 0; - void setConfigBool(QString key, bool * field, QString value); + bool getConfigBool(QString key, QString value); + int getConfigInteger(QString key, QString value, int min, int max, int defaultValue); }; class PorymapConfig: public KeyValueConfigBase @@ -157,6 +162,9 @@ public: this->enableFloorNumber = false; this->createMapTextFile = false; this->enableTripleLayerMetatiles = false; + this->newMapMetatileId = 1; + this->newMapElevation = 3; + this->newMapBorderMetatileIds = DEFAULT_BORDER_RSE; this->prefabFilepath = QString(); this->customScripts.clear(); this->readKeys.clear(); @@ -192,6 +200,12 @@ public: bool getCreateMapTextFileEnabled(); void setTripleLayerMetatilesEnabled(bool enable); bool getTripleLayerMetatilesEnabled(); + void setNewMapMetatileId(int metatileId); + int getNewMapMetatileId(); + void setNewMapElevation(int elevation); + int getNewMapElevation(); + void setNewMapBorderMetatileIds(QList metatileIds); + QList getNewMapBorderMetatileIds(); void setCustomScripts(QList scripts); QList getCustomScripts(); void setPrefabFilepath(QString filepath); @@ -218,6 +232,9 @@ private: bool enableFloorNumber; bool createMapTextFile; bool enableTripleLayerMetatiles; + int newMapMetatileId; + int newMapElevation; + QList newMapBorderMetatileIds; QList customScripts; QStringList readKeys; QString prefabFilepath; diff --git a/src/config.cpp b/src/config.cpp index 05e589ba..3cd4b9a7 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,6 +1,7 @@ #include "config.h" #include "log.h" #include "shortcut.h" +#include "map.h" #include #include #include @@ -79,12 +80,23 @@ void KeyValueConfigBase::save() { } } -void KeyValueConfigBase::setConfigBool(QString key, bool * field, QString value) { +bool KeyValueConfigBase::getConfigBool(QString key, QString value) { bool ok; - *field = value.toInt(&ok); - if (!ok) { + int result = value.toInt(&ok); + if (!ok || (result != 0 && result != 1)) { logWarn(QString("Invalid config value for %1: '%2'. Must be 0 or 1.").arg(key).arg(value)); } + return (result != 0); +} + +int KeyValueConfigBase::getConfigInteger(QString key, QString value, int min, int max, int defaultValue) { + bool ok; + int result = value.toInt(&ok); + if (!ok) { + logWarn(QString("Invalid config value for %1: '%2'. Must be an integer.").arg(key).arg(value)); + return defaultValue; + } + return qMin(max, qMax(min, result)); } const QMap mapSortOrderMap = { @@ -117,9 +129,9 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { if (key == "recent_project") { this->recentProject = value; } else if (key == "reopen_on_launch") { - setConfigBool(key, &this->reopenOnLaunch, value); + this->reopenOnLaunch = getConfigBool(key, value); } else if (key == "pretty_cursors") { - setConfigBool(key, &this->prettyCursors, value); + this->prettyCursors = getConfigBool(key, value); } else if (key == "map_sort_order") { QString sortOrder = value.toLower(); if (mapSortOrderReverseMap.contains(sortOrder)) { @@ -137,12 +149,7 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { } else if (key == "main_splitter_state") { this->mainSplitterState = bytesFromString(value); } else if (key == "collision_opacity") { - bool ok; - this->collisionOpacity = qMax(0, qMin(100, value.toInt(&ok))); - if (!ok) { - logWarn(QString("Invalid config value for collision_opacity: '%1'. Must be an integer.").arg(value)); - this->collisionOpacity = 50; - } + this->collisionOpacity = getConfigInteger(key, value, 0, 100, 50); } else if (key == "tileset_editor_geometry") { this->tilesetEditorGeometry = bytesFromString(value); } else if (key == "tileset_editor_state") { @@ -156,22 +163,17 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { } else if (key == "region_map_editor_state") { this->regionMapEditorState = bytesFromString(value); } else if (key == "metatiles_zoom") { - bool ok; - this->metatilesZoom = qMax(10, qMin(100, value.toInt(&ok))); - if (!ok) { - logWarn(QString("Invalid config value for metatiles_zoom: '%1'. Must be an integer.").arg(value)); - this->metatilesZoom = 30; - } + this->metatilesZoom = getConfigInteger(key, value, 10, 100, 30); } else if (key == "show_player_view") { - setConfigBool(key, &this->showPlayerView, value); + this->showPlayerView = getConfigBool(key, value); } else if (key == "show_cursor_tile") { - setConfigBool(key, &this->showCursorTile, value); + this->showCursorTile = getConfigBool(key, value); } else if (key == "show_border") { - setConfigBool(key, &this->showBorder, value); + this->showBorder = getConfigBool(key, value); } else if (key == "show_grid") { - setConfigBool(key, &this->showGrid, value); + this->showGrid = getConfigBool(key, value); } else if (key == "monitor_files") { - setConfigBool(key, &this->monitorFiles, value); + this->monitorFiles = getConfigBool(key, value); } else if (key == "region_map_dimensions") { bool ok1, ok2; QStringList dims = value.split("x"); @@ -471,29 +473,47 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { } else if (key == "recent_map") { this->recentMap = value; } else if (key == "use_encounter_json") { - setConfigBool(key, &this->useEncounterJson, value); + this->useEncounterJson = getConfigBool(key, value); } else if (key == "use_poryscript") { - setConfigBool(key, &this->usePoryScript, value); + this->usePoryScript = getConfigBool(key, value); } else if (key == "use_custom_border_size") { - setConfigBool(key, &this->useCustomBorderSize, value); + this->useCustomBorderSize = getConfigBool(key, value); } else if (key == "enable_event_weather_trigger") { - setConfigBool(key, &this->enableEventWeatherTrigger, value); + this->enableEventWeatherTrigger = getConfigBool(key, value); } else if (key == "enable_event_secret_base") { - setConfigBool(key, &this->enableEventSecretBase, value); + this->enableEventSecretBase = getConfigBool(key, value); } else if (key == "enable_hidden_item_quantity") { - setConfigBool(key, &this->enableHiddenItemQuantity, value); + this->enableHiddenItemQuantity = getConfigBool(key, value); } else if (key == "enable_hidden_item_requires_itemfinder") { - setConfigBool(key, &this->enableHiddenItemRequiresItemfinder, value); + this->enableHiddenItemRequiresItemfinder = getConfigBool(key, value); } else if (key == "enable_heal_location_respawn_data") { - setConfigBool(key, &this->enableHealLocationRespawnData, value); + this->enableHealLocationRespawnData = getConfigBool(key, value); } else if (key == "enable_event_clone_object") { - setConfigBool(key, &this->enableEventCloneObject, value); + this->enableEventCloneObject = getConfigBool(key, value); } else if (key == "enable_floor_number") { - setConfigBool(key, &this->enableFloorNumber, value); + this->enableFloorNumber = getConfigBool(key, value); } else if (key == "create_map_text_file") { - setConfigBool(key, &this->createMapTextFile, value); + this->createMapTextFile = getConfigBool(key, value); } else if (key == "enable_triple_layer_metatiles") { - setConfigBool(key, &this->enableTripleLayerMetatiles, value); + this->enableTripleLayerMetatiles = getConfigBool(key, value); + } else if (key == "new_map_metatile") { + this->newMapMetatileId = getConfigInteger(key, value, 0, 1023, 0); + } else if (key == "new_map_elevation") { + this->newMapElevation = getConfigInteger(key, value, 0, 15, 3); + } else if (key == "new_map_border_metatiles") { + this->newMapBorderMetatileIds.clear(); + QList metatileIds = value.split(","); + const int maxSize = DEFAULT_BORDER_WIDTH * DEFAULT_BORDER_HEIGHT; + const int size = qMin(metatileIds.size(), maxSize); + int i; + for (i = 0; i < size; i++) { + int metatileId = getConfigInteger(key, metatileIds.at(i), 0, 1023, 0); + this->newMapBorderMetatileIds.append(metatileId); + } + for (; i < maxSize; i++) { + // Set any metatiles not provided to 0 + this->newMapBorderMetatileIds.append(0); + } } else if (key == "custom_scripts") { this->customScripts.clear(); QList paths = value.split(","); @@ -523,6 +543,7 @@ void ProjectConfig::setUnreadKeys() { if (!readKeys.contains("enable_event_clone_object")) this->enableEventCloneObject = isPokefirered; if (!readKeys.contains("enable_floor_number")) this->enableFloorNumber = isPokefirered; if (!readKeys.contains("create_map_text_file")) this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald); + if (!readKeys.contains("new_map_border_metatiles")) this->newMapBorderMetatileIds = isPokefirered ? DEFAULT_BORDER_FRLG : DEFAULT_BORDER_RSE; } QMap ProjectConfig::getKeyValueMap() { @@ -541,6 +562,12 @@ QMap ProjectConfig::getKeyValueMap() { map.insert("enable_floor_number", QString::number(this->enableFloorNumber)); map.insert("create_map_text_file", QString::number(this->createMapTextFile)); map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles)); + map.insert("new_map_metatile", QString::number(this->newMapMetatileId)); + map.insert("new_map_elevation", QString::number(this->newMapElevation)); + QStringList metatiles; + for (auto metatile : this->newMapBorderMetatileIds) + metatiles << QString::number(metatile); + map.insert("new_map_border_metatiles", metatiles.join(",")); map.insert("custom_scripts", this->customScripts.join(",")); map.insert("prefabs_filepath", this->prefabFilepath); return map; @@ -585,6 +612,9 @@ void ProjectConfig::onNewConfigFileCreated() { this->useEncounterJson = true; this->usePoryScript = false; this->enableTripleLayerMetatiles = false; + this->newMapMetatileId = 1; + this->newMapElevation = 3; + this->newMapBorderMetatileIds = isPokefirered ? DEFAULT_BORDER_FRLG : DEFAULT_BORDER_RSE; this->customScripts.clear(); } @@ -726,6 +756,33 @@ bool ProjectConfig::getTripleLayerMetatilesEnabled() { return this->enableTripleLayerMetatiles; } +void ProjectConfig::setNewMapMetatileId(int metatileId) { + this->newMapMetatileId = metatileId; + this->save(); +} + +int ProjectConfig::getNewMapMetatileId() { + return this->newMapMetatileId; +} + +void ProjectConfig::setNewMapElevation(int elevation) { + this->newMapElevation = elevation; + this->save(); +} + +int ProjectConfig::getNewMapElevation() { + return this->newMapElevation; +} + +void ProjectConfig::setNewMapBorderMetatileIds(QList metatileIds) { + this->newMapBorderMetatileIds = metatileIds; + this->save(); +} + +QList ProjectConfig::getNewMapBorderMetatileIds() { + return this->newMapBorderMetatileIds; +} + void ProjectConfig::setCustomScripts(QList scripts) { this->customScripts = scripts; this->save(); diff --git a/src/project.cpp b/src/project.cpp index 01d32154..0942c101 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1179,11 +1179,14 @@ bool Project::loadBlockdata(MapLayout *layout) { void Project::setNewMapBlockdata(Map *map) { map->layout->blockdata.clear(); - for (int i = 0; i < map->getWidth() * map->getHeight(); i++) { - map->layout->blockdata.append(qint16(0x3001)); + int width = map->getWidth(); + int height = map->getHeight(); + Block block(projectConfig.getNewMapMetatileId(), 0, projectConfig.getNewMapElevation()); + for (int i = 0; i < width * height; i++) { + map->layout->blockdata.append(block); } map->layout->lastCommitBlocks.blocks = map->layout->blockdata; - map->layout->lastCommitBlocks.mapDimensions = QSize(map->getWidth(), map->getHeight()); + map->layout->lastCommitBlocks.mapDimensions = QSize(width, height); } bool Project::loadLayoutBorder(MapLayout *layout) { @@ -1204,23 +1207,20 @@ bool Project::loadLayoutBorder(MapLayout *layout) { void Project::setNewMapBorder(Map *map) { map->layout->border.clear(); - if (map->getBorderWidth() != DEFAULT_BORDER_WIDTH || map->getBorderHeight() != DEFAULT_BORDER_HEIGHT) { - for (int i = 0; i < map->getBorderWidth() * map->getBorderHeight(); i++) { + int width = map->getBorderWidth(); + int height = map->getBorderHeight(); + if (width != DEFAULT_BORDER_WIDTH || height != DEFAULT_BORDER_HEIGHT) { + for (int i = 0; i < width * height; i++) { map->layout->border.append(0); } - } else if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) { - map->layout->border.append(qint16(0x0014)); - map->layout->border.append(qint16(0x0015)); - map->layout->border.append(qint16(0x001C)); - map->layout->border.append(qint16(0x001D)); } else { - map->layout->border.append(qint16(0x01D4)); - map->layout->border.append(qint16(0x01D5)); - map->layout->border.append(qint16(0x01DC)); - map->layout->border.append(qint16(0x01DD)); + QList metatileIds = projectConfig.getNewMapBorderMetatileIds(); + for (int i = 0; i < DEFAULT_BORDER_WIDTH * DEFAULT_BORDER_HEIGHT; i++) { + map->layout->border.append(qint16(metatileIds.at(i))); + } } map->layout->lastCommitBlocks.border = map->layout->border; - map->layout->lastCommitBlocks.borderDimensions = QSize(map->getBorderWidth(), map->getBorderHeight()); + map->layout->lastCommitBlocks.borderDimensions = QSize(width, height); } void Project::saveLayoutBorder(Map *map) {