From 6d995cee9b76f556918e848013b80efd4c2a8323 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 18 Dec 2023 02:19:12 -0500 Subject: [PATCH] Add identifier config settings --- include/config.h | 87 +++++++-- include/core/map.h | 2 +- include/core/parseutil.h | 4 +- include/core/regionmap.h | 9 +- include/project.h | 6 +- src/config.cpp | 135 +++++++++++-- src/core/events.cpp | 21 +- src/core/heallocation.cpp | 2 +- src/core/map.cpp | 5 +- src/core/parseutil.cpp | 6 +- src/core/regionmap.cpp | 28 +-- src/core/tileset.cpp | 8 +- src/mainwindow.cpp | 3 +- src/project.cpp | 266 +++++++++++++++----------- src/ui/draggablepixmapitem.cpp | 3 +- src/ui/newmappopup.cpp | 4 +- src/ui/newtilesetdialog.cpp | 2 +- src/ui/projectsettingseditor.cpp | 48 +++-- src/ui/regionmapeditor.cpp | 11 +- src/ui/regionmapentriespixmapitem.cpp | 2 +- 20 files changed, 439 insertions(+), 213 deletions(-) diff --git a/include/config.h b/include/config.h index 7937361d..cd2b6457 100644 --- a/include/config.h +++ b/include/config.h @@ -170,6 +170,61 @@ enum BaseGameVersion { pokeemerald, }; +enum ProjectIdentifier { + symbol_facing_directions, + symbol_obj_event_gfx_pointers, + symbol_pokemon_icon_table, + symbol_wild_encounters, + symbol_heal_locations, + symbol_spawn_points, + symbol_spawn_maps, + symbol_spawn_npcs, + symbol_attribute_table, + symbol_tilesets_prefix, + define_obj_event_count, + define_min_level, + define_max_level, + define_tiles_primary, + define_tiles_total, + define_metatiles_primary, + define_pals_primary, + define_pals_total, + define_map_size, + define_mask_metatile, + define_mask_collision, + define_mask_elevation, + define_mask_behavior, + define_mask_layer, + define_attribute_behavior, + define_attribute_layer, + define_attribute_terrain, + define_attribute_encounter, + define_metatile_label_prefix, + define_heal_locations_prefix, + define_spawn_prefix, + define_map_prefix, + define_map_dynamic, + define_map_empty, + define_map_section_prefix, + define_map_section_empty, + define_map_section_count, + regex_behaviors, + regex_obj_event_gfx, + regex_items, + regex_flags, + regex_vars, + regex_movement_types, + regex_map_types, + regex_battle_scenes, + regex_weather, + regex_coord_event_weather, + regex_secret_bases, + regex_sign_facing_directions, + regex_trainer_types, + regex_music, + regex_species, +}; + enum ProjectFilePath { data_map_folders, data_scripts_folders, @@ -250,11 +305,12 @@ public: this->blockElevationMask = 0xF000; this->warpBehaviors = defaultWarpBehaviors; this->warpBehaviorWarningDisabled = false; + this->identifiers.clear(); this->readKeys.clear(); } + static const QMap> defaultIdentifiers; static const QMap> defaultPaths; static const QStringList versionStrings; - static const QStringList defaultWarpBehaviors; void reset(BaseGameVersion baseGameVersion); void setBaseGameVersion(BaseGameVersion baseGameVersion); BaseGameVersion getBaseGameVersion(); @@ -299,10 +355,16 @@ public: QString getDefaultSecondaryTileset(); void setDefaultPrimaryTileset(QString tilesetName); void setDefaultSecondaryTileset(QString tilesetName); - void setFilePath(QString pathId, QString path); - void setFilePath(ProjectFilePath pathId, QString path); - QString getFilePath(QString defaultPath, bool customOnly = false); - QString getFilePath(ProjectFilePath pathId, bool customOnly = false); + void setFilePath(const QString &pathId, const QString &path); + void setFilePath(ProjectFilePath pathId, const QString &path); + QString getCustomFilePath(ProjectFilePath pathId); + QString getCustomFilePath(const QString &pathId); + QString getFilePath(ProjectFilePath pathId); + void setIdentifier(ProjectIdentifier id, const QString &text); + void setIdentifier(const QString &id, const QString &text); + QString getCustomIdentifier(ProjectIdentifier id); + QString getCustomIdentifier(const QString &id); + QString getIdentifier(ProjectIdentifier id); void setPrefabFilepath(QString filepath); QString getPrefabFilepath(); void setPrefabImportPrompted(bool prompted); @@ -345,18 +407,6 @@ public: void setWarpBehaviorWarningDisabled(bool disabled); bool getWarpBehaviorWarningDisabled(); - // TODO: Replace these once there's generic support for editing project names - static const QString metatileIdMaskName; - static const QString collisionMaskName; - static const QString elevationMaskName; - static const QString behaviorMaskName; - static const QString layerTypeMaskName; - static const QString behaviorTableName; - static const QString layerTypeTableName; - static const QString terrainTypeTableName; - static const QString encounterTypeTableName; - static const QString attrTableName; - protected: virtual QString getConfigFilepath() override; virtual void parseConfigKeyValue(QString key, QString value) override; @@ -364,8 +414,11 @@ protected: virtual void onNewConfigFileCreated() override; virtual void setUnreadKeys() override; private: + static const QStringList defaultWarpBehaviors; + BaseGameVersion baseGameVersion; QString projectDir; + QMap identifiers; QMap filePaths; bool usePoryScript; bool useCustomBorderSize; diff --git a/include/core/map.h b/include/core/map.h index 779afefe..1668ac08 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -71,7 +71,7 @@ public: QList metatileLayerOrder; QList metatileLayerOpacity; void setName(QString mapName); - static QString mapConstantFromName(QString mapName); + static QString mapConstantFromName(QString mapName, bool includePrefix = true); int getWidth(); int getHeight(); int getBorderWidth(); diff --git a/include/core/parseutil.h b/include/core/parseutil.h index 557787ab..9e00087e 100644 --- a/include/core/parseutil.h +++ b/include/core/parseutil.h @@ -54,8 +54,8 @@ public: QString readCIncbin(const QString &text, const QString &label); QMap readCIncbinMulti(const QString &filepath); QStringList readCIncbinArray(const QString &filename, const QString &label); - QMap readCDefinesByPrefix(const QString &filename, const QStringList &prefixes); - QMap readCDefinesByName(const QString &filename, const QStringList &defineNames); + QMap readCDefinesByPrefix(const QString &filename, QStringList prefixes); + QMap readCDefinesByName(const QString &filename, QStringList names); QStringList readCDefineNames(const QString&, const QStringList&); QMap> readCStructs(const QString &, const QString & = "", const QHash = { }); QList getLabelMacros(const QList&, const QString&); diff --git a/include/core/regionmap.h b/include/core/regionmap.h index 6116849a..bc05a84f 100644 --- a/include/core/regionmap.h +++ b/include/core/regionmap.h @@ -21,7 +21,10 @@ class Project; struct LayoutSquare { - LayoutSquare() : map_section("MAPSEC_NONE"), x(-1), y(-1), has_map(false) {} + LayoutSquare() : x(-1), y(-1), has_map(false) { + const QString prefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix); + map_section = prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_empty); + } QString map_section; int x; int y; @@ -144,6 +147,10 @@ public: void emitDisplay(); + const QString section_prefix; + const QString default_map_section; + const QString count_map_section; + signals: void mapNeedsDisplaying(); diff --git a/include/project.h b/include/project.h index e84694fd..faa8186c 100644 --- a/include/project.h +++ b/include/project.h @@ -26,8 +26,7 @@ struct EventGraphics bool inanimate; }; -// The constant and displayed name of the special map value used by warps with multiple potential destinations -static QString DYNAMIC_MAP_CONSTANT = "MAP_DYNAMIC"; +// The displayed name of the special map value used by warps with multiple potential destinations static QString DYNAMIC_MAP_NAME = "Dynamic"; class Project : public QObject @@ -215,7 +214,7 @@ public: QString getDefaultPrimaryTilesetLabel(); QString getDefaultSecondaryTilesetLabel(); - + QString getDynamicMapDefineName(); void updateTilesetMetatileLabels(Tileset *tileset); QString buildMetatileLabelsText(const QMap defines); QString findMetatileLabelsTileset(QString label); @@ -248,6 +247,7 @@ private: void saveHealLocationsData(Map *map); void saveHealLocationsConstants(); + QString getHealLocationsTableName(); void ignoreWatchedFileTemporarily(QString filepath); diff --git a/src/config.cpp b/src/config.cpp index 7b90a5c0..bc4ba7ae 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -47,16 +47,64 @@ const QStringList ProjectConfig::defaultWarpBehaviors = { "MB_BRIDGE_OVER_OCEAN", }; -const QString ProjectConfig::metatileIdMaskName = "MAPGRID_METATILE_ID_MASK"; -const QString ProjectConfig::collisionMaskName = "MAPGRID_COLLISION_MASK"; -const QString ProjectConfig::elevationMaskName = "MAPGRID_ELEVATION_MASK"; -const QString ProjectConfig::behaviorMaskName = "METATILE_ATTR_BEHAVIOR_MASK"; -const QString ProjectConfig::layerTypeMaskName = "METATILE_ATTR_LAYER_MASK"; -const QString ProjectConfig::behaviorTableName = "METATILE_ATTRIBUTE_BEHAVIOR"; -const QString ProjectConfig::layerTypeTableName = "METATILE_ATTRIBUTE_LAYER_TYPE"; -const QString ProjectConfig::terrainTypeTableName = "METATILE_ATTRIBUTE_TERRAIN"; -const QString ProjectConfig::encounterTypeTableName = "METATILE_ATTRIBUTE_ENCOUNTER_TYPE"; -const QString ProjectConfig::attrTableName = "sMetatileAttrMasks"; +// TODO: symbol_wild_encounters should ultimately be removed from the table below. We can determine this name when we read the project. +const QMap> ProjectConfig::defaultIdentifiers = { + // Symbols + {ProjectIdentifier::symbol_facing_directions, {"symbol_facing_directions", "gInitialMovementTypeFacingDirections"}}, + {ProjectIdentifier::symbol_obj_event_gfx_pointers, {"symbol_obj_event_gfx_pointers", "gObjectEventGraphicsInfoPointers"}}, + {ProjectIdentifier::symbol_pokemon_icon_table, {"symbol_pokemon_icon_table", "gMonIconTable"}}, + {ProjectIdentifier::symbol_wild_encounters, {"symbol_wild_encounters", "gWildMonHeaders"}}, + {ProjectIdentifier::symbol_heal_locations, {"symbol_heal_locations", "sHealLocations"}}, + {ProjectIdentifier::symbol_spawn_points, {"symbol_spawn_points", "sSpawnPoints"}}, + {ProjectIdentifier::symbol_spawn_maps, {"symbol_spawn_maps", "sWhiteoutRespawnHealCenterMapIdxs"}}, + {ProjectIdentifier::symbol_spawn_npcs, {"symbol_spawn_npcs", "sWhiteoutRespawnHealerNpcIds"}}, + {ProjectIdentifier::symbol_attribute_table, {"symbol_attribute_table", "sMetatileAttrMasks"}}, + {ProjectIdentifier::symbol_tilesets_prefix, {"symbol_tilesets_prefix", "gTileset_"}}, + // Defines + {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_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"}}, + {ProjectIdentifier::define_pals_primary, {"define_pals_primary", "NUM_PALS_IN_PRIMARY"}}, + {ProjectIdentifier::define_pals_total, {"define_pals_total", "NUM_PALS_TOTAL"}}, + {ProjectIdentifier::define_map_size, {"define_map_size", "MAX_MAP_DATA_SIZE"}}, + {ProjectIdentifier::define_mask_metatile, {"define_mask_metatile", "MAPGRID_METATILE_ID_MASK"}}, + {ProjectIdentifier::define_mask_collision, {"define_mask_collision", "MAPGRID_COLLISION_MASK"}}, + {ProjectIdentifier::define_mask_elevation, {"define_mask_elevation", "MAPGRID_ELEVATION_MASK"}}, + {ProjectIdentifier::define_mask_behavior, {"define_mask_behavior", "METATILE_ATTR_BEHAVIOR_MASK"}}, + {ProjectIdentifier::define_mask_layer, {"define_mask_layer", "METATILE_ATTR_LAYER_MASK"}}, + {ProjectIdentifier::define_attribute_behavior, {"define_attribute_behavior", "METATILE_ATTRIBUTE_BEHAVIOR"}}, + {ProjectIdentifier::define_attribute_layer, {"define_attribute_layer", "METATILE_ATTRIBUTE_LAYER_TYPE"}}, + {ProjectIdentifier::define_attribute_terrain, {"define_attribute_terrain", "METATILE_ATTRIBUTE_TERRAIN"}}, + {ProjectIdentifier::define_attribute_encounter, {"define_attribute_encounter", "METATILE_ATTRIBUTE_ENCOUNTER_TYPE"}}, + {ProjectIdentifier::define_metatile_label_prefix, {"define_metatile_label_prefix", "METATILE_"}}, + {ProjectIdentifier::define_heal_locations_prefix, {"define_heal_locations_prefix", "HEAL_LOCATION_"}}, + {ProjectIdentifier::define_spawn_prefix, {"define_spawn_prefix", "SPAWN_"}}, + {ProjectIdentifier::define_map_prefix, {"define_map_prefix", "MAP_"}}, + {ProjectIdentifier::define_map_dynamic, {"define_map_dynamic", "DYNAMIC"}}, + {ProjectIdentifier::define_map_empty, {"define_map_empty", "UNDEFINED"}}, + {ProjectIdentifier::define_map_section_prefix, {"define_map_section_prefix", "MAPSEC_"}}, + {ProjectIdentifier::define_map_section_empty, {"define_map_section_empty", "NONE"}}, + {ProjectIdentifier::define_map_section_count, {"define_map_section_count", "COUNT"}}, + // Regex + {ProjectIdentifier::regex_behaviors, {"regex_behaviors", "\\bMB_"}}, + {ProjectIdentifier::regex_obj_event_gfx, {"regex_obj_event_gfx", "\\bOBJ_EVENT_GFX_"}}, + {ProjectIdentifier::regex_items, {"regex_items", "\\bITEM_(?!(B_)?USE_)"}}, // Exclude ITEM_USE_ and ITEM_B_USE_ constants + {ProjectIdentifier::regex_flags, {"regex_flags", "\\bFLAG_"}}, + {ProjectIdentifier::regex_vars, {"regex_vars", "\\bVAR_"}}, + {ProjectIdentifier::regex_movement_types, {"regex_movement_types", "\\bMOVEMENT_TYPE_"}}, + {ProjectIdentifier::regex_map_types, {"regex_map_types", "\\bMAP_TYPE_"}}, + {ProjectIdentifier::regex_battle_scenes, {"regex_battle_scenes", "\\bMAP_BATTLE_SCENE_"}}, + {ProjectIdentifier::regex_weather, {"regex_weather", "\\bWEATHER_"}}, + {ProjectIdentifier::regex_coord_event_weather, {"regex_coord_event_weather", "\\bCOORD_EVENT_WEATHER_"}}, + {ProjectIdentifier::regex_secret_bases, {"regex_secret_bases", "\\bSECRET_BASE_[A-Za-z0-9_]*_[0-9]+"}}, + {ProjectIdentifier::regex_sign_facing_directions, {"regex_sign_facing_directions", "\\bBG_EVENT_PLAYER_FACING_"}}, + {ProjectIdentifier::regex_trainer_types, {"regex_trainer_types", "\\bTRAINER_TYPE_"}}, + {ProjectIdentifier::regex_music, {"regex_music", "\\b(SE|MUS)_"}}, + {ProjectIdentifier::regex_species, {"regex_species", "\\bSPECIES_"}}, +}; const QMap> ProjectConfig::defaultPaths = { {ProjectFilePath::data_map_folders, { "data_map_folders", "data/maps/"}}, @@ -108,6 +156,13 @@ const QMap> ProjectConfig::defaultP {ProjectFilePath::pokemon_gfx, { "pokemon_gfx", "graphics/pokemon/"}}, }; +ProjectIdentifier reverseDefaultIdentifier(QString str) { + for (auto i = ProjectConfig::defaultIdentifiers.cbegin(), end = ProjectConfig::defaultIdentifiers.cend(); i != end; i++) { + if (i.value().first == str) return i.key(); + } + return static_cast(-1); +} + ProjectFilePath reverseDefaultPaths(QString str) { for (auto it = ProjectConfig::defaultPaths.constKeyValueBegin(); it != ProjectConfig::defaultPaths.constKeyValueEnd(); ++it) { if ((*it).second.first == str) return (*it).first; @@ -751,6 +806,13 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { } else { logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); } + } else if (key.startsWith("ident/")) { + auto identifierId = reverseDefaultIdentifier(key.mid(6)); + if (identifierId != static_cast(-1)) { + this->setIdentifier(identifierId, value); + } else { + logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); + } } else if (key == "prefabs_filepath") { this->prefabFilepath = value; } else if (key == "prefabs_import_prompted") { @@ -863,6 +925,10 @@ QMap ProjectConfig::getKeyValueMap() { const QString path = i.value(); if (!path.isEmpty()) map.insert("pokemon_icon_path/" + i.key(), path); } + for (auto i = this->identifiers.cbegin(), end = this->identifiers.cend(); i != end; i++) { + // TODO: Test to ensure empties aren't output in config + map.insert("ident/"+defaultIdentifiers.value(i.key()).first, i.value()); + } map.insert("collision_sheet_path", this->collisionSheetPath); map.insert("collision_sheet_width", QString::number(this->collisionSheetWidth)); map.insert("collision_sheet_height", QString::number(this->collisionSheetHeight)); @@ -909,7 +975,7 @@ QString ProjectConfig::getProjectDir() { return this->projectDir; } -void ProjectConfig::setFilePath(ProjectFilePath pathId, QString path) { +void ProjectConfig::setFilePath(ProjectFilePath pathId, const QString &path) { if (!defaultPaths.contains(pathId)) return; if (path.isEmpty()) { this->filePaths.remove(pathId); @@ -918,18 +984,20 @@ void ProjectConfig::setFilePath(ProjectFilePath pathId, QString path) { } } -void ProjectConfig::setFilePath(QString defaultPath, QString newPath) { - this->setFilePath(reverseDefaultPaths(defaultPath), newPath); +void ProjectConfig::setFilePath(const QString &pathId, const QString &path) { + this->setFilePath(reverseDefaultPaths(pathId), path); } -QString ProjectConfig::getFilePath(ProjectFilePath pathId, bool customOnly) { - const QString customPath = this->filePaths.value(pathId); +QString ProjectConfig::getCustomFilePath(ProjectFilePath pathId) { + return this->filePaths.value(pathId); +} - // When reading custom filepaths for the settings editor we don't care - // about the default path or whether the custom path exists. - if (customOnly) - return customPath; +QString ProjectConfig::getCustomFilePath(const QString &pathId) { + return this->getCustomFilePath(reverseDefaultPaths(pathId)); +} +QString ProjectConfig::getFilePath(ProjectFilePath pathId) { + const QString customPath = this->getCustomFilePath(pathId); if (!customPath.isEmpty()) { // A custom filepath has been specified. If the file/folder exists, use that. const QString absCustomPath = this->projectDir + QDir::separator() + customPath; @@ -943,8 +1011,33 @@ QString ProjectConfig::getFilePath(ProjectFilePath pathId, bool customOnly) { } -QString ProjectConfig::getFilePath(QString defaultPath, bool customOnly) { - return this->getFilePath(reverseDefaultPaths(defaultPath), customOnly); +void ProjectConfig::setIdentifier(ProjectIdentifier id, const QString &text) { + if (!defaultIdentifiers.contains(id)) return; + QString copy(text); + if (copy.isEmpty()) { + this->identifiers.remove(id); + } else { + this->identifiers[id] = copy; + } +} + +void ProjectConfig::setIdentifier(const QString &id, const QString &text) { + this->setIdentifier(reverseDefaultIdentifier(id), text); +} + +QString ProjectConfig::getCustomIdentifier(ProjectIdentifier id) { + return this->identifiers.value(id); +} + +QString ProjectConfig::getCustomIdentifier(const QString &id) { + return this->getCustomIdentifier(reverseDefaultIdentifier(id)); +} + +QString ProjectConfig::getIdentifier(ProjectIdentifier id) { + const QString customText = this->getCustomIdentifier(id); + if (!customText.isEmpty()) + return customText; + return defaultIdentifiers.contains(id) ? defaultIdentifiers[id].second : QString(); } void ProjectConfig::setBaseGameVersion(BaseGameVersion baseGameVersion) { diff --git a/src/core/events.cpp b/src/core/events.cpp index 788d438f..7f160481 100644 --- a/src/core/events.cpp +++ b/src/core/events.cpp @@ -372,13 +372,14 @@ bool CloneObjectEvent::loadFromJson(QJsonObject json, Project *project) { this->setTargetID(ParseUtil::jsonToInt(json["target_local_id"])); // Ensure the target map constant is valid before adding it to the events. + const QString dynamicMapConstant = project->getDynamicMapDefineName(); QString mapConstant = ParseUtil::jsonToQString(json["target_map"]); if (project->mapConstantsToMapNames.contains(mapConstant)) { this->setTargetMap(project->mapConstantsToMapNames.value(mapConstant)); - } else if (mapConstant == DYNAMIC_MAP_CONSTANT) { + } else if (mapConstant == dynamicMapConstant) { this->setTargetMap(DYNAMIC_MAP_NAME); } else { - logWarn(QString("Target Map constant '%1' is invalid. Using default '%2'.").arg(mapConstant).arg(DYNAMIC_MAP_CONSTANT)); + logWarn(QString("Target Map constant '%1' is invalid. Using default '%2'.").arg(mapConstant).arg(dynamicMapConstant)); this->setTargetMap(DYNAMIC_MAP_NAME); } @@ -483,13 +484,14 @@ bool WarpEvent::loadFromJson(QJsonObject json, Project *project) { this->setDestinationWarpID(ParseUtil::jsonToQString(json["dest_warp_id"])); // Ensure the warp destination map constant is valid before adding it to the warps. + const QString dynamicMapConstant = project->getDynamicMapDefineName(); QString mapConstant = ParseUtil::jsonToQString(json["dest_map"]); if (project->mapConstantsToMapNames.contains(mapConstant)) { this->setDestinationMap(project->mapConstantsToMapNames.value(mapConstant)); - } else if (mapConstant == DYNAMIC_MAP_CONSTANT) { + } else if (mapConstant == dynamicMapConstant) { this->setDestinationMap(DYNAMIC_MAP_NAME); } else { - logWarn(QString("Destination Map constant '%1' is invalid. Using default '%2'.").arg(mapConstant).arg(DYNAMIC_MAP_CONSTANT)); + logWarn(QString("Destination Map constant '%1' is invalid. Using default '%2'.").arg(mapConstant).arg(dynamicMapConstant)); this->setDestinationMap(DYNAMIC_MAP_NAME); } @@ -913,15 +915,16 @@ OrderedJson::object HealLocationEvent::buildEventJson(Project *) { } void HealLocationEvent::setDefaultValues(Project *) { - this->setElevation(3); + this->setElevation(projectConfig.getDefaultElevation()); if (!this->getMap()) return; - bool respawnEanbled = projectConfig.getHealLocationRespawnDataEnabled(); - QString mapConstant = Map::mapConstantFromName(this->getMap()->name).remove(0,4); - QString prefix = respawnEanbled ? "SPAWN_" : "HEAL_LOCATION_"; + bool respawnEnabled = projectConfig.getHealLocationRespawnDataEnabled(); + const QString mapConstant = Map::mapConstantFromName(this->getMap()->name, false); + const QString prefix = projectConfig.getIdentifier(respawnEnabled ? ProjectIdentifier::define_spawn_prefix + : ProjectIdentifier::define_heal_locations_prefix); this->setLocationName(mapConstant); this->setIdName(prefix + mapConstant); - if (respawnEanbled) { + if (respawnEnabled) { this->setRespawnMap(this->getMap()->name); this->setRespawnNPC(1); } diff --git a/src/core/heallocation.cpp b/src/core/heallocation.cpp index 0d5e287c..42d444af 100644 --- a/src/core/heallocation.cpp +++ b/src/core/heallocation.cpp @@ -26,7 +26,7 @@ HealLocation HealLocation::fromEvent(Event *fromEvent) { healLocation.y = event->getY(); if (projectConfig.getHealLocationRespawnDataEnabled()) { healLocation.respawnNPC = event->getRespawnNPC(); - healLocation.respawnMap = Map::mapConstantFromName(event->getRespawnMap()).remove(0,4); + healLocation.respawnMap = Map::mapConstantFromName(event->getRespawnMap(), false); } return healLocation; } diff --git a/src/core/map.cpp b/src/core/map.cpp index bc73eb0f..800991e5 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -29,11 +29,12 @@ void Map::setName(QString mapName) { constantName = mapConstantFromName(mapName); } -QString Map::mapConstantFromName(QString mapName) { +QString Map::mapConstantFromName(QString mapName, bool includePrefix) { // Transform map names of the form 'GraniteCave_B1F` into map constants like 'MAP_GRANITE_CAVE_B1F'. static const QRegularExpression caseChange("([a-z])([A-Z])"); QString nameWithUnderscores = mapName.replace(caseChange, "\\1_\\2"); - QString withMapAndUppercase = "MAP_" + nameWithUnderscores.toUpper(); + const QString prefix = includePrefix ? projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix) : ""; + QString withMapAndUppercase = prefix + nameWithUnderscores.toUpper(); static const QRegularExpression underscores("_+"); QString constantName = withMapAndUppercase.replace(underscores, "_"); diff --git a/src/core/parseutil.cpp b/src/core/parseutil.cpp index 21ca8737..cee1dd5f 100644 --- a/src/core/parseutil.cpp +++ b/src/core/parseutil.cpp @@ -425,12 +425,14 @@ QMap ParseUtil::readCDefines(const QString &filename, const QStrin } // Find and evaluate an unknown list of defines with a known name prefix. -QMap ParseUtil::readCDefinesByPrefix(const QString &filename, const QStringList &prefixes) { +QMap ParseUtil::readCDefinesByPrefix(const QString &filename, QStringList prefixes) { + prefixes.removeDuplicates(); return this->readCDefines(filename, prefixes, false); } // Find and evaluate a specific set of defines with known names. -QMap ParseUtil::readCDefinesByName(const QString &filename, const QStringList &names) { +QMap ParseUtil::readCDefinesByName(const QString &filename, QStringList names) { + names.removeDuplicates(); return this->readCDefines(filename, names, true); } diff --git a/src/core/regionmap.cpp b/src/core/regionmap.cpp index f9c1fb9d..68da1fa7 100644 --- a/src/core/regionmap.cpp +++ b/src/core/regionmap.cpp @@ -17,7 +17,11 @@ using std::make_shared; -RegionMap::RegionMap(Project *project) { +RegionMap::RegionMap(Project *project) : + section_prefix(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix)), + default_map_section(section_prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_empty)), + count_map_section(section_prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_count)) +{ this->project = project; } @@ -146,7 +150,7 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) { LayoutSquare square; square.map_section = square_section_name; - square.has_map = (square_section_name != "MAPSEC_NONE" && !square_section_name.isEmpty()); + square.has_map = (square_section_name != this->default_map_section && !square_section_name.isEmpty()); square.x = x; square.y = y; @@ -204,7 +208,7 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) { LayoutSquare square; square.map_section = square_section_name; - square.has_map = (square_section_name != "MAPSEC_NONE" && !square_section_name.isEmpty()); + square.has_map = (square_section_name != this->default_map_section && !square_section_name.isEmpty()); square.x = x; square.y = y; layout.append(square); @@ -228,7 +232,7 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) { this->layout_qualifiers = qualifiers + " " + type; this->layout_array_label = label; - static const QRegularExpression reSec("(?MAPSEC_[A-Za-z0-9_]+)"); + static const QRegularExpression reSec(QString("(?%1[A-Za-z0-9_]+)").arg(this->section_prefix)); QRegularExpressionMatchIterator k = reSec.globalMatch(text); QList layout; @@ -242,7 +246,7 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) { LayoutSquare square; square.map_section = sec; - square.has_map = (sec != "MAPSEC_NONE" && !sec.isEmpty()); + square.has_map = (sec != this->default_map_section && !sec.isEmpty()); square.x = x; square.y = y; layout.append(square); @@ -283,7 +287,7 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) { QString square_section_name = section.trimmed(); LayoutSquare square; square.map_section = square_section_name; - square.has_map = (square_section_name != "MAPSEC_NONE" && !square_section_name.isEmpty()); + square.has_map = (square_section_name != this->default_map_section && !square_section_name.isEmpty()); square.x = x; square.y = y; layout.append(square); @@ -454,7 +458,7 @@ void RegionMap::saveLayout() { } void RegionMap::resetSquare(int index) { - this->layouts[this->current_layer][index].map_section = "MAPSEC_NONE"; + this->layouts[this->current_layer][index].map_section = this->default_map_section; this->layouts[this->current_layer][index].has_map = false; } @@ -473,7 +477,7 @@ void RegionMap::replaceSection(QString oldSection, QString newSection) { for (auto &square : this->layouts[this->current_layer]) { if (square.map_section == oldSection) { square.map_section = newSection; - square.has_map = (newSection != "MAPSEC_NONE"); + square.has_map = (newSection != this->default_map_section); } } } @@ -482,11 +486,11 @@ void RegionMap::swapSections(QString secA, QString secB) { for (auto &square : this->layouts[this->current_layer]) { if (square.map_section == secA) { square.map_section = secB; - square.has_map = (square.map_section != "MAPSEC_NONE"); + square.has_map = (square.map_section != this->default_map_section); } else if (square.map_section == secB) { square.map_section = secA; - square.has_map = (square.map_section != "MAPSEC_NONE"); + square.has_map = (square.map_section != this->default_map_section); } } } @@ -725,7 +729,7 @@ void RegionMap::setSquareMapSection(int index, QString section) { int layoutIndex = tilemapToLayoutIndex(index); if (!(layoutIndex < 0 || !this->layouts.contains(this->current_layer))) { this->layouts[this->current_layer][layoutIndex].map_section = section; - this->layouts[this->current_layer][layoutIndex].has_map = !(section == "MAPSEC_NONE" || section.isEmpty()); + this->layouts[this->current_layer][layoutIndex].has_map = !(section == this->default_map_section || section.isEmpty()); } } @@ -780,7 +784,7 @@ QString RegionMap::fixCase(QString caps) { QString camel; static const QRegularExpression re_braced("({.*})"); - for (auto ch : caps.remove(re_braced).remove("MAPSEC")) { + for (auto ch : caps.remove(re_braced).remove(this->section_prefix)) { if (ch == '_' || ch == ' ') { big = true; continue; diff --git a/src/core/tileset.cpp b/src/core/tileset.cpp index 31d623d5..85fab154 100644 --- a/src/core/tileset.cpp +++ b/src/core/tileset.cpp @@ -168,7 +168,10 @@ QString Tileset::getMetatileLabelPrefix() QString Tileset::getMetatileLabelPrefix(const QString &name) { - return QString("METATILE_%1_").arg(QString(name).replace("gTileset_", "")); + // Default is "gTileset_Name" --> "METATILE_Name_" + const QString tilesetPrefix = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix); + const QString labelPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_metatile_label_prefix); + return QString("%1%2_").arg(labelPrefix).arg(QString(name).replace(tilesetPrefix, "")); } bool Tileset::metatileIsValid(uint16_t metatileId, Tileset *primaryTileset, Tileset *secondaryTileset) { @@ -343,7 +346,8 @@ QString Tileset::getExpectedDir(QString tilesetName, bool isSecondary) static const QRegularExpression re("([a-z])([A-Z0-9])"); const QString category = isSecondary ? "secondary" : "primary"; const QString basePath = projectConfig.getFilePath(ProjectFilePath::data_tilesets_folders) + category + "/"; - return basePath + tilesetName.replace("gTileset_", "").replace(re, "\\1_\\2").toLower(); + const QString prefix = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix); + return basePath + tilesetName.replace(prefix, "").replace(re, "\\1_\\2").toLower(); } // Get the expected positions of the members in struct Tileset. diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f0eb3b65..5b47526b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1867,8 +1867,9 @@ void MainWindow::addNewEvent(Event::Type type) { msgBox.setText("Failed to add new event"); if (Event::typeToGroup(type) == Event::Group::Object) { msgBox.setInformativeText(QString("The limit for object events (%1) has been reached.\n\n" - "This limit can be adjusted with OBJECT_EVENT_TEMPLATES_COUNT in '%2'.") + "This limit can be adjusted with %2 in '%3'.") .arg(editor->project->getMaxObjectEvents()) + .arg(projectConfig.getIdentifier(ProjectIdentifier::define_obj_event_count)) .arg(projectConfig.getFilePath(ProjectFilePath::constants_global))); } msgBox.setDefaultButton(QMessageBox::Ok); diff --git a/src/project.cpp b/src/project.cpp index 71414bbd..54888fc6 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -289,10 +289,12 @@ bool Project::loadMapData(Map* map) { } map->events[Event::Group::Heal].clear(); + + const QString mapPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix); for (auto it = healLocations.begin(); it != healLocations.end(); it++) { HealLocation loc = *it; //if TRUE map is flyable / has healing location - if (loc.mapName == QString(mapNamesToMapConstants.value(map->name)).remove(0,4)) { + if (loc.mapName == Map::mapConstantFromName(map->name, false)) { HealLocationEvent *heal = new HealLocationEvent(); heal->setMap(map); heal->setX(loc.x); @@ -301,12 +303,8 @@ bool Project::loadMapData(Map* map) { heal->setLocationName(loc.mapName); heal->setIdName(loc.idName); heal->setIndex(loc.index); - - // TODO: what is this - // heal->put("destination_map_name", mapConstantsToMapNames.value(map->name)); - if (projectConfig.getHealLocationRespawnDataEnabled()) { - heal->setRespawnMap(mapConstantsToMapNames.value(QString("MAP_" + loc.respawnMap))); + heal->setRespawnMap(mapConstantsToMapNames.value(QString(mapPrefix + loc.respawnMap))); heal->setRespawnNPC(loc.respawnNPC); } map->events[Event::Group::Heal].append(heal); @@ -630,9 +628,8 @@ void Project::saveWildMonData() { OrderedJson::object wildEncountersObject; OrderedJson::array wildEncounterGroups; - // gWildMonHeaders label is not mutable OrderedJson::object monHeadersObject; - monHeadersObject["label"] = "gWildMonHeaders"; + monHeadersObject["label"] = projectConfig.getIdentifier(ProjectIdentifier::symbol_wild_encounters); monHeadersObject["for_maps"] = true; OrderedJson::array fieldsInfoArray; @@ -751,6 +748,12 @@ void Project::saveHealLocations(Map *map) { this->saveHealLocationsConstants(); } +QString Project::getHealLocationsTableName() { + if (projectConfig.getHealLocationRespawnDataEnabled()) + return projectConfig.getIdentifier(ProjectIdentifier::symbol_spawn_points); + return projectConfig.getIdentifier(ProjectIdentifier::symbol_heal_locations); +} + // Saves heal location maps/coords/respawn data in root + /src/data/heal_locations.h void Project::saveHealLocationsData(Map *map) { // Update heal locations from map @@ -774,20 +777,19 @@ void Project::saveHealLocationsData(Map *map) { // Create the definition text for each data table bool respawnEnabled = projectConfig.getHealLocationRespawnDataEnabled(); - QString arrayName = respawnEnabled ? "sSpawnPoints" : "sHealLocations"; const QString qualifiers = QString(healLocationDataQualifiers.isStatic ? "static " : "") + QString(healLocationDataQualifiers.isConst ? "const " : ""); - QString locationTableText = QString("%1struct HealLocation %2[] =\n{\n").arg(qualifiers).arg(arrayName); + QString locationTableText = QString("%1struct HealLocation %2[] =\n{\n").arg(qualifiers).arg(this->getHealLocationsTableName()); QString respawnMapTableText, respawnNPCTableText; if (respawnEnabled) { - respawnMapTableText = QString("\n%1u16 sWhiteoutRespawnHealCenterMapIdxs[][2] =\n{\n").arg(qualifiers); - respawnNPCTableText = QString("\n%1u8 sWhiteoutRespawnHealerNpcIds[] =\n{\n").arg(qualifiers); + respawnMapTableText = QString("\n%1u16 %2[][2] =\n{\n").arg(qualifiers).arg(projectConfig.getIdentifier(ProjectIdentifier::symbol_spawn_maps)); + respawnNPCTableText = QString("\n%1u8 %2[] =\n{\n").arg(qualifiers).arg(projectConfig.getIdentifier(ProjectIdentifier::symbol_spawn_npcs)); } // Populate the data tables with the heal location data int i = 0; - const QString emptyMapName = "UNDEFINED"; // TODO: Use a project-wide constant here? + const QString emptyMapName = projectConfig.getIdentifier(ProjectIdentifier::define_map_empty); for (auto hl : this->healLocations) { // Add numbered suffix for duplicate constants if (healLocationsDupes.keys().contains(hl.idName)) { @@ -1505,7 +1507,7 @@ bool Project::readTilesetMetatileLabels() { QString metatileLabelsFilename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels); fileWatcher.addPath(root + "/" + metatileLabelsFilename); - static const QStringList prefixes = {"METATILE_"}; + const QStringList prefixes = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_metatile_label_prefix))}; QMap defines = parser.readCDefinesByPrefix(metatileLabelsFilename, prefixes); for (QString label : defines.keys()) { @@ -1719,8 +1721,9 @@ bool Project::readMapGroups() { } } - mapConstantsToMapNames.insert(DYNAMIC_MAP_CONSTANT, DYNAMIC_MAP_NAME); - mapNamesToMapConstants.insert(DYNAMIC_MAP_NAME, DYNAMIC_MAP_CONSTANT); + const QString defineName = this->getDynamicMapDefineName(); + mapConstantsToMapNames.insert(defineName, DYNAMIC_MAP_NAME); + mapNamesToMapConstants.insert(DYNAMIC_MAP_NAME, defineName); maps.append(DYNAMIC_MAP_NAME); groupNames = groups; @@ -1862,62 +1865,72 @@ bool Project::readTilesetLabels() { return success; } -// TODO: Names to config bool Project::readTilesetProperties() { - static const QStringList names = { - "NUM_TILES_IN_PRIMARY", - "NUM_TILES_TOTAL", - "NUM_METATILES_IN_PRIMARY", - "NUM_PALS_IN_PRIMARY", - "NUM_PALS_TOTAL", - "MAX_MAP_DATA_SIZE", + const QString numTilesPrimaryName = projectConfig.getIdentifier(ProjectIdentifier::define_tiles_primary); + const QString numTilesTotalName = projectConfig.getIdentifier(ProjectIdentifier::define_tiles_total); + const QString numMetatilesPrimaryName = projectConfig.getIdentifier(ProjectIdentifier::define_metatiles_primary); + const QString numPalsPrimaryName = projectConfig.getIdentifier(ProjectIdentifier::define_pals_primary); + const QString numPalsTotalName = projectConfig.getIdentifier(ProjectIdentifier::define_pals_total); + const QString maxMapSizeName = projectConfig.getIdentifier(ProjectIdentifier::define_map_size); + const QStringList names = { + numTilesPrimaryName, + numTilesTotalName, + numMetatilesPrimaryName, + numPalsPrimaryName, + numPalsTotalName, + maxMapSizeName, }; QString filename = projectConfig.getFilePath(ProjectFilePath::constants_fieldmap); fileWatcher.addPath(root + "/" + filename); QMap defines = parser.readCDefinesByName(filename, names); - auto it = defines.find("NUM_TILES_IN_PRIMARY"); + auto it = defines.find(numTilesPrimaryName); if (it != defines.end()) { Project::num_tiles_primary = it.value(); } else { - logWarn(QString("Value for tileset property 'NUM_TILES_IN_PRIMARY' not found. Using default (%1) instead.") + logWarn(QString("Value for tileset property '%1' not found. Using default (%2) instead.") + .arg(numTilesPrimaryName) .arg(Project::num_tiles_primary)); } - it = defines.find("NUM_TILES_TOTAL"); + it = defines.find(numTilesTotalName); if (it != defines.end()) { Project::num_tiles_total = it.value(); } else { - logWarn(QString("Value for tileset property 'NUM_TILES_TOTAL' not found. Using default (%1) instead.") + logWarn(QString("Value for tileset property '%1' not found. Using default (%2) instead.") + .arg(numTilesTotalName) .arg(Project::num_tiles_total)); } - it = defines.find("NUM_METATILES_IN_PRIMARY"); + it = defines.find(numMetatilesPrimaryName); if (it != defines.end()) { Project::num_metatiles_primary = it.value(); } else { - logWarn(QString("Value for tileset property 'NUM_METATILES_IN_PRIMARY' not found. Using default (%1) instead.") + logWarn(QString("Value for tileset property '%1' not found. Using default (%2) instead.") + .arg(numMetatilesPrimaryName) .arg(Project::num_metatiles_primary)); } - it = defines.find("NUM_PALS_IN_PRIMARY"); + it = defines.find(numPalsPrimaryName); if (it != defines.end()) { Project::num_pals_primary = it.value(); } else { - logWarn(QString("Value for tileset property 'NUM_PALS_IN_PRIMARY' not found. Using default (%1) instead.") + logWarn(QString("Value for tileset property '%1' not found. Using default (%2) instead.") + .arg(numPalsPrimaryName) .arg(Project::num_pals_primary)); } - it = defines.find("NUM_PALS_TOTAL"); + it = defines.find(numPalsTotalName); if (it != defines.end()) { Project::num_pals_total = it.value(); } else { - logWarn(QString("Value for tileset property 'NUM_PALS_TOTAL' not found. Using default (%1) instead.") + logWarn(QString("Value for tileset property '%1' not found. Using default (%2) instead.") + .arg(numPalsTotalName) .arg(Project::num_pals_total)); } - it = defines.find("MAX_MAP_DATA_SIZE"); + it = defines.find(maxMapSizeName); if (it != defines.end()) { int min = getMapDataSize(1, 1); if (it.value() >= min) { @@ -1925,29 +1938,35 @@ bool Project::readTilesetProperties() { calculateDefaultMapSize(); } else { // must be large enough to support a 1x1 map - logWarn(QString("Value for map property 'MAX_MAP_DATA_SIZE' is %1, must be at least %2. Using default (%3) instead.") + logWarn(QString("Value for map property '%1' is %2, must be at least %3. Using default (%4) instead.") + .arg(maxMapSizeName) .arg(it.value()) .arg(min) .arg(Project::max_map_data_size)); } } else { - logWarn(QString("Value for map property 'MAX_MAP_DATA_SIZE' not found. Using default (%1) instead.") + logWarn(QString("Value for map property '%1' not found. Using default (%2) instead.") + .arg(maxMapSizeName) .arg(Project::max_map_data_size)); } return true; } -// TODO: Update for config // Read data masks for Blocks and metatile attributes. bool Project::readFieldmapMasks() { - static const QStringList searchNames = { - ProjectConfig::metatileIdMaskName, - ProjectConfig::collisionMaskName, - ProjectConfig::elevationMaskName, - ProjectConfig::behaviorMaskName, - ProjectConfig::layerTypeMaskName, + const QString metatileIdMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_metatile); + const QString collisionMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_collision); + const QString elevationMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_elevation); + const QString behaviorMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_behavior); + const QString layerTypeMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_layer); + const QStringList searchNames = { + metatileIdMaskName, + collisionMaskName, + elevationMaskName, + behaviorMaskName, + layerTypeMaskName, }; QString globalFieldmap = projectConfig.getFilePath(ProjectFilePath::global_fieldmap); fileWatcher.addPath(root + "/" + globalFieldmap); @@ -1963,57 +1982,63 @@ bool Project::readFieldmapMasks() { projectConfig.setSaveDisabled(true); // Read Block masks - auto it = defines.find(ProjectConfig::metatileIdMaskName); + auto it = defines.find(metatileIdMaskName); if (it != defines.end()) projectConfig.setBlockMetatileIdMask(static_cast(it.value())); - it = defines.find(ProjectConfig::collisionMaskName); + it = defines.find(collisionMaskName); if (it != defines.end()) projectConfig.setBlockCollisionMask(static_cast(it.value())); - it = defines.find(ProjectConfig::elevationMaskName); + it = defines.find(elevationMaskName); if (it != defines.end()) projectConfig.setBlockElevationMask(static_cast(it.value())); // Read RSE metatile attribute masks - it = defines.find(ProjectConfig::behaviorMaskName); + it = defines.find(behaviorMaskName); if (it != defines.end()) projectConfig.setMetatileBehaviorMask(static_cast(it.value())); - it = defines.find(ProjectConfig::layerTypeMaskName); + it = defines.find(layerTypeMaskName); if (it != defines.end()) projectConfig.setMetatileLayerTypeMask(static_cast(it.value())); // pokefirered keeps its attribute masks in a separate table, parse this too. - QString srcFieldmap = projectConfig.getFilePath(ProjectFilePath::fieldmap); - const QMap attrTable = parser.readNamedIndexCArray(srcFieldmap, ProjectConfig::attrTableName); + const QString attrTableName = projectConfig.getIdentifier(ProjectIdentifier::symbol_attribute_table); + const QString srcFieldmap = projectConfig.getFilePath(ProjectFilePath::fieldmap); + const QMap attrTable = parser.readNamedIndexCArray(srcFieldmap, attrTableName); if (!attrTable.isEmpty()) { + const QString terrainTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_behavior); + const QString encounterTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_layer); + const QString behaviorTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_terrain); + const QString layerTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_encounter); fileWatcher.addPath(root + "/" + srcFieldmap); + bool ok; // Read terrain type mask - uint32_t mask = attrTable.value(ProjectConfig::terrainTypeTableName).toUInt(&ok, 0); + uint32_t mask = attrTable.value(terrainTypeTableName).toUInt(&ok, 0); if (ok) { projectConfig.setMetatileTerrainTypeMask(mask); - this->disabledSettingsNames.insert(ProjectConfig::terrainTypeTableName); + this->disabledSettingsNames.insert(terrainTypeTableName); } // Read encounter type mask - mask = attrTable.value(ProjectConfig::encounterTypeTableName).toUInt(&ok, 0); + mask = attrTable.value(encounterTypeTableName).toUInt(&ok, 0); if (ok) { projectConfig.setMetatileEncounterTypeMask(mask); - this->disabledSettingsNames.insert(ProjectConfig::encounterTypeTableName); + this->disabledSettingsNames.insert(encounterTypeTableName); } // If we haven't already parsed behavior and layer type then try those too - if (!this->disabledSettingsNames.contains(ProjectConfig::behaviorMaskName)) { + if (!this->disabledSettingsNames.contains(behaviorMaskName)) { // Read behavior mask - mask = attrTable.value(ProjectConfig::behaviorTableName).toUInt(&ok, 0); + mask = attrTable.value(behaviorTableName).toUInt(&ok, 0); if (ok) { projectConfig.setMetatileBehaviorMask(mask); - this->disabledSettingsNames.insert(ProjectConfig::behaviorTableName); + this->disabledSettingsNames.insert(behaviorTableName); } } - if (!this->disabledSettingsNames.contains(ProjectConfig::layerTypeMaskName)) { + if (!this->disabledSettingsNames.contains(layerTypeMaskName)) { // Read layer type mask - mask = attrTable.value(ProjectConfig::layerTypeTableName).toUInt(&ok, 0); + mask = attrTable.value(layerTypeTableName).toUInt(&ok, 0); if (ok) { projectConfig.setMetatileLayerTypeMask(mask); - this->disabledSettingsNames.insert(ProjectConfig::layerTypeTableName); + this->disabledSettingsNames.insert(layerTypeTableName); } } } @@ -2025,7 +2050,7 @@ bool Project::readRegionMapSections() { this->mapSectionNameToValue.clear(); this->mapSectionValueToName.clear(); - static const QStringList prefixes = {"\\bMAPSEC_"}; + const QStringList prefixes = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))}; QString filename = projectConfig.getFilePath(ProjectFilePath::constants_region_map_sections); fileWatcher.addPath(root + "/" + filename); this->mapSectionNameToValue = parser.readCDefinesByPrefix(filename, prefixes); @@ -2043,7 +2068,10 @@ bool Project::readRegionMapSections() { // Read the constants to preserve any "unused" heal locations when writing the file later bool Project::readHealLocationConstants() { this->healLocationNameToValue.clear(); - static const QStringList prefixes = {"\\bSPAWN_", "\\bHEAL_LOCATION_"}; + const QStringList prefixes = { + QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_heal_locations_prefix)), + QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_spawn_prefix)) + }; QString constantsFilename = projectConfig.getFilePath(ProjectFilePath::constants_heal_locations); fileWatcher.addPath(root + "/" + constantsFilename); this->healLocationNameToValue = parser.readCDefinesByPrefix(constantsFilename, prefixes); @@ -2051,6 +2079,7 @@ bool Project::readHealLocationConstants() { return true; } +// TODO: Simplify using the new C struct parsing functions (and indexed array parsing functions) bool Project::readHealLocations() { this->healLocationDataQualifiers = {}; this->healLocations.clear(); @@ -2069,11 +2098,12 @@ bool Project::readHealLocations() { bool respawnEnabled = projectConfig.getHealLocationRespawnDataEnabled(); // Get data qualifiers for the location data table - QString tableName = respawnEnabled ? "sSpawnPoints" : "sHealLocations"; - this->healLocationDataQualifiers = this->getDataQualifiers(text, tableName); + this->healLocationDataQualifiers = this->getDataQualifiers(text, this->getHealLocationsTableName()); // Create regex pattern for the constants (ex: "SPAWN_PALLET_TOWN" or "HEAL_LOCATION_PETALBURG_CITY") - static const QRegularExpression constantsExpr("(SPAWN|HEAL_LOCATION)_[A-Za-z0-9_]+"); + const QString spawnPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_spawn_prefix); + const QString healLocPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_heal_locations_prefix); + const QRegularExpression constantsExpr(QString("\\b(%1|%2)[A-Za-z0-9_]+").arg(spawnPrefix).arg(healLocPrefix)); // Find all the unique heal location constants used in the data tables. // Porymap doesn't care whether or not a constant appeared in the heal locations constants file. @@ -2133,8 +2163,8 @@ bool Project::readHealLocations() { } bool Project::readItemNames() { - QStringList prefixes("\\bITEM_(?!(B_)?USE_)"); // Exclude ITEM_USE_ and ITEM_B_USE_ constants - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_items); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_items)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_items); fileWatcher.addPath(root + "/" + filename); itemNames = parser.readCDefineNames(filename, prefixes); if (itemNames.isEmpty()) { @@ -2145,8 +2175,8 @@ bool Project::readItemNames() { } bool Project::readFlagNames() { - QStringList prefixes("\\bFLAG_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_flags); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_flags)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_flags); fileWatcher.addPath(root + "/" + filename); flagNames = parser.readCDefineNames(filename, prefixes); if (flagNames.isEmpty()) { @@ -2157,8 +2187,8 @@ bool Project::readFlagNames() { } bool Project::readVarNames() { - QStringList prefixes("\\bVAR_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_vars); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_vars)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_vars); fileWatcher.addPath(root + "/" + filename); varNames = parser.readCDefineNames(filename, prefixes); if (varNames.isEmpty()) { @@ -2169,8 +2199,8 @@ bool Project::readVarNames() { } bool Project::readMovementTypes() { - QStringList prefixes("\\bMOVEMENT_TYPE_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_event_movement); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_movement_types)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_event_movement); fileWatcher.addPath(root + "/" + filename); movementTypes = parser.readCDefineNames(filename, prefixes); if (movementTypes.isEmpty()) { @@ -2183,7 +2213,7 @@ bool Project::readMovementTypes() { bool Project::readInitialFacingDirections() { QString filename = projectConfig.getFilePath(ProjectFilePath::initial_facing_table); fileWatcher.addPath(root + "/" + filename); - facingDirections = parser.readNamedIndexCArray(filename, "gInitialMovementTypeFacingDirections"); + facingDirections = parser.readNamedIndexCArray(filename, projectConfig.getIdentifier(ProjectIdentifier::symbol_facing_directions)); if (facingDirections.isEmpty()) { logError(QString("Failed to read initial movement type facing directions from %1").arg(filename)); return false; @@ -2192,8 +2222,8 @@ bool Project::readInitialFacingDirections() { } bool Project::readMapTypes() { - QStringList prefixes("\\bMAP_TYPE_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_map_types)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); fileWatcher.addPath(root + "/" + filename); mapTypes = parser.readCDefineNames(filename, prefixes); if (mapTypes.isEmpty()) { @@ -2204,8 +2234,8 @@ bool Project::readMapTypes() { } bool Project::readMapBattleScenes() { - QStringList prefixes("\\bMAP_BATTLE_SCENE_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_battle_scenes)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); fileWatcher.addPath(root + "/" + filename); mapBattleScenes = parser.readCDefineNames(filename, prefixes); if (mapBattleScenes.isEmpty()) { @@ -2216,8 +2246,8 @@ bool Project::readMapBattleScenes() { } bool Project::readWeatherNames() { - QStringList prefixes("\\bWEATHER_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_weather)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); fileWatcher.addPath(root + "/" + filename); weatherNames = parser.readCDefineNames(filename, prefixes); if (weatherNames.isEmpty()) { @@ -2231,8 +2261,8 @@ bool Project::readCoordEventWeatherNames() { if (!projectConfig.getEventWeatherTriggerEnabled()) return true; - QStringList prefixes("\\bCOORD_EVENT_WEATHER_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_coord_event_weather)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); fileWatcher.addPath(root + "/" + filename); coordEventWeatherNames = parser.readCDefineNames(filename, prefixes); if (coordEventWeatherNames.isEmpty()) { @@ -2246,8 +2276,8 @@ bool Project::readSecretBaseIds() { if (!projectConfig.getEventSecretBaseEnabled()) return true; - QStringList prefixes("\\bSECRET_BASE_[A-Za-z0-9_]*_[0-9]+"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_secret_bases); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_secret_bases)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_secret_bases); fileWatcher.addPath(root + "/" + filename); secretBaseIds = parser.readCDefineNames(filename, prefixes); if (secretBaseIds.isEmpty()) { @@ -2258,8 +2288,8 @@ bool Project::readSecretBaseIds() { } bool Project::readBgEventFacingDirections() { - QStringList prefixes("\\bBG_EVENT_PLAYER_FACING_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_event_bg); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_sign_facing_directions)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_event_bg); fileWatcher.addPath(root + "/" + filename); bgEventFacingDirections = parser.readCDefineNames(filename, prefixes); if (bgEventFacingDirections.isEmpty()) { @@ -2270,8 +2300,8 @@ bool Project::readBgEventFacingDirections() { } bool Project::readTrainerTypes() { - QStringList prefixes("\\bTRAINER_TYPE_"); - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_trainer_types); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_trainer_types)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_trainer_types); fileWatcher.addPath(root + "/" + filename); trainerTypes = parser.readCDefineNames(filename, prefixes); if (trainerTypes.isEmpty()) { @@ -2285,7 +2315,7 @@ bool Project::readMetatileBehaviors() { this->metatileBehaviorMap.clear(); this->metatileBehaviorMapInverse.clear(); - static const QStringList prefixes = {"\\bMB_"}; + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)}; QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors); fileWatcher.addPath(root + "/" + filename); this->metatileBehaviorMap = parser.readCDefinesByPrefix(filename, prefixes); @@ -2312,22 +2342,22 @@ bool Project::readMetatileBehaviors() { } bool Project::readSongNames() { - QStringList songDefinePrefixes{ "\\bSE_", "\\bMUS_" }; - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_songs); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_music)}; + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_songs); fileWatcher.addPath(root + "/" + filename); - this->songNames = parser.readCDefineNames(filename, songDefinePrefixes); - this->defaultSong = this->songNames.value(0, "MUS_DUMMY"); + this->songNames = parser.readCDefineNames(filename, prefixes); if (this->songNames.isEmpty()) { logError(QString("Failed to read song names from %1.").arg(filename)); return false; } + this->defaultSong = this->songNames.value(0); // Song names don't have a very useful order (esp. if we include SE_* values), so sort them alphabetically. this->songNames.sort(); return true; } bool Project::readObjEventGfxConstants() { - static const QStringList prefixes = {"\\bOBJ_EVENT_GFX_"}; + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_obj_event_gfx)}; QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_events); fileWatcher.addPath(root + "/" + filename); this->gfxDefines = parser.readCDefinesByPrefix(filename, prefixes); @@ -2338,33 +2368,37 @@ bool Project::readObjEventGfxConstants() { return true; } -// TODO: Names to config bool Project::readMiscellaneousConstants() { miscConstants.clear(); if (userConfig.getEncounterJsonActive()) { - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_pokemon); + 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, {"MIN_LEVEL", "MAX_LEVEL"}); - miscConstants.insert("max_level_define", pokemonDefines.value("MAX_LEVEL") > pokemonDefines.value("MIN_LEVEL") ? pokemonDefines.value("MAX_LEVEL") : 100); - miscConstants.insert("min_level_define", pokemonDefines.value("MIN_LEVEL") < pokemonDefines.value("MAX_LEVEL") ? pokemonDefines.value("MIN_LEVEL") : 1); + 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); } - QString filename = projectConfig.getFilePath(ProjectFilePath::constants_global); + const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_global); + const QString maxObjectEventsName = projectConfig.getIdentifier(ProjectIdentifier::define_obj_event_count); fileWatcher.addPath(root + "/" + filename); - QMap defines = parser.readCDefinesByName(filename, {"OBJECT_EVENT_TEMPLATES_COUNT"}); + QMap defines = parser.readCDefinesByName(filename, {maxObjectEventsName}); - auto it = defines.find("OBJECT_EVENT_TEMPLATES_COUNT"); + auto it = defines.find(maxObjectEventsName); if (it != defines.end()) { if (it.value() > 0) { Project::max_object_events = it.value(); } else { - logWarn(QString("Value for 'OBJECT_EVENT_TEMPLATES_COUNT' is %1, must be greater than 0. Using default (%2) instead.") + logWarn(QString("Value for '%1' is %2, must be greater than 0. Using default (%3) instead.") + .arg(maxObjectEventsName) .arg(it.value()) .arg(Project::max_object_events)); } } else { - logWarn(QString("Value for 'OBJECT_EVENT_TEMPLATES_COUNT' not found. Using default (%1) instead.") + logWarn(QString("Value for '%1' not found. Using default (%2) instead.") + .arg(maxObjectEventsName) .arg(Project::max_object_events)); } @@ -2471,7 +2505,9 @@ bool Project::readEventGraphics() { << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables) << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx)); - QMap pointerHash = parser.readNamedIndexCArray(projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_pointers), "gObjectEventGraphicsInfoPointers"); + const QString pointersFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_pointers); + const QString pointersName = projectConfig.getIdentifier(ProjectIdentifier::symbol_obj_event_gfx_pointers); + QMap pointerHash = parser.readNamedIndexCArray(pointersFilepath, pointersName); qDeleteAll(eventGraphicsMap); eventGraphicsMap.clear(); @@ -2479,7 +2515,7 @@ bool Project::readEventGraphics() { // The positions of each of the required members for the gfx info struct. // For backwards compatibility if the struct doesn't use initializers. - const auto gfxInfoMemberMap = QHash{ + static const auto gfxInfoMemberMap = QHash{ {8, "inanimate"}, {11, "oam"}, {12, "subspriteTables"}, @@ -2546,21 +2582,23 @@ bool Project::readSpeciesIconPaths() { // Read map of species constants to icon names const QString srcfilename = projectConfig.getFilePath(ProjectFilePath::pokemon_icon_table); fileWatcher.addPath(root + "/" + srcfilename); - const QMap monIconNames = parser.readNamedIndexCArray(srcfilename, "gMonIconTable"); + const QString tableName = projectConfig.getIdentifier(ProjectIdentifier::symbol_pokemon_icon_table); + const QMap monIconNames = parser.readNamedIndexCArray(srcfilename, tableName); - // Read map of icon names to filepaths. These are spread between two different files + // Read map of icon names to filepaths const QString incfilename = projectConfig.getFilePath(ProjectFilePath::data_pokemon_gfx); fileWatcher.addPath(root + "/" + incfilename); const QMap iconIncbins = parser.readCIncbinMulti(incfilename); // Read species constants. If this fails we can get them from the icon table (but we shouldn't rely on it). - static const QStringList prefixes("\\bSPECIES_"); + const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_species)}; const QString constantsFilename = projectConfig.getFilePath(ProjectFilePath::constants_species); fileWatcher.addPath(root + "/" + constantsFilename); QStringList speciesNames = parser.readCDefineNames(constantsFilename, prefixes); if (speciesNames.isEmpty()) speciesNames = monIconNames.keys(); + // For each species, use the information gathered above to find the icon image. bool missingIcons = false; for (auto species : speciesNames) { QString path = QString(); @@ -2705,7 +2743,8 @@ bool Project::calculateDefaultMapSize(){ // x^2 + 29x + (210 - max), then complete the square and simplify default_map_size = qFloor((qSqrt(4 * getMaxMapDataSize() + 1) - 29) / 2); } else { - logError(QString("'MAX_MAP_DATA_SIZE' of %1 is too small to support a 1x1 map. Must be at least %2.") + logError(QString("'%1' of %2 is too small to support a 1x1 map. Must be at least %3.") + .arg(projectConfig.getIdentifier(ProjectIdentifier::define_map_size)) .arg(max) .arg(getMapDataSize(1, 1))); return false; @@ -2718,6 +2757,11 @@ int Project::getMaxObjectEvents() return Project::max_object_events; } +QString Project::getDynamicMapDefineName() { + const QString prefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix); + return prefix + projectConfig.getIdentifier(ProjectIdentifier::define_map_dynamic); +} + void Project::setImportExportPath(QString filename) { this->importExportPath = QFileInfo(filename).absolutePath(); diff --git a/src/ui/draggablepixmapitem.cpp b/src/ui/draggablepixmapitem.cpp index 13625db4..22511643 100644 --- a/src/ui/draggablepixmapitem.cpp +++ b/src/ui/draggablepixmapitem.cpp @@ -94,9 +94,10 @@ void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) { emit editor->warpEventDoubleClicked(clone->getTargetMap(), clone->getTargetID(), Event::Group::Object); } else if (eventType == Event::Type::SecretBase) { + const QString mapPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix); SecretBaseEvent *base = dynamic_cast(this->event); QString baseId = base->getBaseID(); - QString destMap = editor->project->mapConstantsToMapNames.value("MAP_" + baseId.left(baseId.lastIndexOf("_"))); + QString destMap = editor->project->mapConstantsToMapNames.value(mapPrefix + baseId.left(baseId.lastIndexOf("_"))); emit editor->warpEventDoubleClicked(destMap, 0, Event::Group::Warp); } } diff --git a/src/ui/newmappopup.cpp b/src/ui/newmappopup.cpp index 41c339ec..0239b710 100644 --- a/src/ui/newmappopup.cpp +++ b/src/ui/newmappopup.cpp @@ -258,9 +258,9 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() { newMap->location = this->ui->comboBox_NewMap_Location->currentText(); newMap->song = this->ui->comboBox_NewMap_Song->currentText(); newMap->requiresFlash = false; - newMap->weather = this->project->weatherNames.value(0, "WEATHER_NONE"); + newMap->weather = this->project->weatherNames.value(0); newMap->show_location = this->ui->checkBox_NewMap_Show_Location->isChecked(); - newMap->battle_scene = this->project->mapBattleScenes.value(0, "MAP_BATTLE_SCENE_NORMAL"); + newMap->battle_scene = this->project->mapBattleScenes.value(0); if (this->existingLayout) { layout = this->project->mapLayouts.value(this->layoutId); diff --git a/src/ui/newtilesetdialog.cpp b/src/ui/newtilesetdialog.cpp index afd716d7..e38c499e 100644 --- a/src/ui/newtilesetdialog.cpp +++ b/src/ui/newtilesetdialog.cpp @@ -38,7 +38,7 @@ void NewTilesetDialog::SecondaryChanged(){ void NewTilesetDialog::NameOrSecondaryChanged() { this->friendlyName = this->ui->nameLineEdit->text(); - this->fullSymbolName = "gTileset_" + this->friendlyName; + this->fullSymbolName = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix) + this->friendlyName; this->ui->symbolNameLineEdit->setText(this->fullSymbolName); this->path = Tileset::getExpectedDir(this->fullSymbolName, this->isSecondary); this->ui->pathLineEdit->setText(this->path); diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp index 09a94981..89cce4c3 100644 --- a/src/ui/projectsettingseditor.cpp +++ b/src/ui/projectsettingseditor.cpp @@ -135,32 +135,42 @@ void ProjectSettingsEditor::initUi() { if (project) { const QString maskFilepath = projectConfig.getFilePath(ProjectFilePath::global_fieldmap); const QString attrTableFilepath = projectConfig.getFilePath(ProjectFilePath::fieldmap); + const QString metatileIdMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_metatile); + const QString collisionMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_collision); + const QString elevationMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_elevation); + const QString behaviorMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_behavior); + const QString layerTypeMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_layer); + const QString terrainTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_behavior); + const QString encounterTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_layer); + const QString behaviorTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_terrain); + const QString layerTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_encounter); + const QString attrTableName = projectConfig.getIdentifier(ProjectIdentifier::symbol_attribute_table); // Block masks - if (project->disabledSettingsNames.contains(ProjectConfig::metatileIdMaskName)) - this->disableParsedSetting(ui->spinBox_MetatileIdMask, ProjectConfig::metatileIdMaskName, maskFilepath); - if (project->disabledSettingsNames.contains(ProjectConfig::collisionMaskName)) - this->disableParsedSetting(ui->spinBox_CollisionMask, ProjectConfig::collisionMaskName, maskFilepath); - if (project->disabledSettingsNames.contains(ProjectConfig::elevationMaskName)) - this->disableParsedSetting(ui->spinBox_ElevationMask, ProjectConfig::elevationMaskName, maskFilepath); + if (project->disabledSettingsNames.contains(metatileIdMaskName)) + this->disableParsedSetting(ui->spinBox_MetatileIdMask, metatileIdMaskName, maskFilepath); + if (project->disabledSettingsNames.contains(collisionMaskName)) + this->disableParsedSetting(ui->spinBox_CollisionMask, collisionMaskName, maskFilepath); + if (project->disabledSettingsNames.contains(elevationMaskName)) + this->disableParsedSetting(ui->spinBox_ElevationMask, elevationMaskName, maskFilepath); // Behavior mask - if (project->disabledSettingsNames.contains(ProjectConfig::behaviorMaskName)) - this->disableParsedSetting(ui->spinBox_BehaviorMask, ProjectConfig::behaviorMaskName, maskFilepath); - else if (project->disabledSettingsNames.contains(ProjectConfig::behaviorTableName)) - this->disableParsedSetting(ui->spinBox_BehaviorMask, ProjectConfig::attrTableName, attrTableFilepath); + if (project->disabledSettingsNames.contains(behaviorMaskName)) + this->disableParsedSetting(ui->spinBox_BehaviorMask, behaviorMaskName, maskFilepath); + else if (project->disabledSettingsNames.contains(behaviorTableName)) + this->disableParsedSetting(ui->spinBox_BehaviorMask, attrTableName, attrTableFilepath); // Layer type mask - if (project->disabledSettingsNames.contains(ProjectConfig::layerTypeMaskName)) - this->disableParsedSetting(ui->spinBox_LayerTypeMask, ProjectConfig::layerTypeMaskName, maskFilepath); - else if (project->disabledSettingsNames.contains(ProjectConfig::layerTypeTableName)) - this->disableParsedSetting(ui->spinBox_LayerTypeMask, ProjectConfig::attrTableName, attrTableFilepath); + if (project->disabledSettingsNames.contains(layerTypeMaskName)) + this->disableParsedSetting(ui->spinBox_LayerTypeMask, layerTypeMaskName, maskFilepath); + else if (project->disabledSettingsNames.contains(layerTypeTableName)) + this->disableParsedSetting(ui->spinBox_LayerTypeMask, attrTableName, attrTableFilepath); // Encounter and terrain type masks - if (project->disabledSettingsNames.contains(ProjectConfig::terrainTypeTableName)) - this->disableParsedSetting(ui->spinBox_TerrainTypeMask, ProjectConfig::attrTableName, attrTableFilepath); - if (project->disabledSettingsNames.contains(ProjectConfig::encounterTypeTableName)) - this->disableParsedSetting(ui->spinBox_EncounterTypeMask, ProjectConfig::attrTableName, attrTableFilepath); + if (project->disabledSettingsNames.contains(terrainTypeTableName)) + this->disableParsedSetting(ui->spinBox_TerrainTypeMask, attrTableName, attrTableFilepath); + if (project->disabledSettingsNames.contains(encounterTypeTableName)) + this->disableParsedSetting(ui->spinBox_EncounterTypeMask, attrTableName, attrTableFilepath); } } @@ -440,7 +450,7 @@ void ProjectSettingsEditor::refresh() { ui->lineEdit_BGsIcon->setText(projectConfig.getEventIconPath(Event::Group::Bg)); ui->lineEdit_HealspotsIcon->setText(projectConfig.getEventIconPath(Event::Group::Heal)); for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren()) - lineEdit->setText(projectConfig.getFilePath(lineEdit->objectName(), true)); + lineEdit->setText(projectConfig.getCustomFilePath(lineEdit->objectName())); this->setWarpBehaviorsList(projectConfig.getWarpBehaviors()); this->refreshing = false; // Allow signals diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index 39d79ca7..220f9cca 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -796,14 +796,17 @@ void RegionMapEditor::displayRegionMapEntryOptions() { void RegionMapEditor::updateRegionMapEntryOptions(QString section) { if (!this->region_map->layoutEnabled()) return; - bool enabled = ((section != "MAPSEC_NONE") && (section != "MAPSEC_COUNT")) && (this->region_map_entries.contains(section)); + bool isSpecialSection = (section == this->region_map->default_map_section + || section == this->region_map->count_map_section); + + bool enabled = (!isSpecialSection && this->region_map_entries.contains(section)); this->ui->lineEdit_RM_MapName->setEnabled(enabled); this->ui->spinBox_RM_Entry_x->setEnabled(enabled); this->ui->spinBox_RM_Entry_y->setEnabled(enabled); this->ui->spinBox_RM_Entry_width->setEnabled(enabled); this->ui->spinBox_RM_Entry_height->setEnabled(enabled); - this->ui->pushButton_entryActivate->setEnabled(section != "MAPSEC_NONE" && section != "MAPSEC_COUNT"); + this->ui->pushButton_entryActivate->setEnabled(!isSpecialSection); this->ui->pushButton_entryActivate->setText(enabled ? "Remove" : "Add"); this->ui->lineEdit_RM_MapName->blockSignals(true); @@ -831,7 +834,7 @@ void RegionMapEditor::updateRegionMapEntryOptions(QString section) { void RegionMapEditor::on_pushButton_entryActivate_clicked() { QString section = this->ui->comboBox_RM_Entry_MapSection->currentText(); - if (section == "MAPSEC_NONE") return; + if (section == this->region_map->default_map_section) return; if (this->region_map_entries.contains(section)) { // disable @@ -1297,7 +1300,7 @@ void RegionMapEditor::on_action_RegionMap_ClearLayout_triggered() { QMessageBox::StandardButton result = QMessageBox::question( this, "WARNING", - "This action will reset the entire map layout to MAPSEC_NONE, continue?", + QString("This action will reset the entire map layout to %1, continue?").arg(this->region_map->default_map_section), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes ); diff --git a/src/ui/regionmapentriespixmapitem.cpp b/src/ui/regionmapentriespixmapitem.cpp index 779b73bb..ace3c38d 100644 --- a/src/ui/regionmapentriespixmapitem.cpp +++ b/src/ui/regionmapentriespixmapitem.cpp @@ -8,7 +8,7 @@ void RegionMapEntriesPixmapItem::draw() { int entry_x, entry_y, entry_w, entry_h; - if (!entry.valid || entry.name == "MAPSEC_NONE") { + if (!entry.valid || entry.name == region_map->default_map_section) { entry_x = entry_y = 0; entry_w = entry_h = 1; } else {