diff --git a/docsrc/manual/project-files.rst b/docsrc/manual/project-files.rst index 46554bb5..4c3685c6 100644 --- a/docsrc/manual/project-files.rst +++ b/docsrc/manual/project-files.rst @@ -33,16 +33,19 @@ to a file, it probably is not a good idea to edit yourself unless otherwise note include/constants/flags.h, yes, no, include/constants/vars.h, yes, no, include/constants/weather.h, yes, no, + include/constants/songs.h, yes, no, include/constants/heal_locations.h, no, yes, include/constants/pokemon.h, yes, no, reads min and max level constants include/constants/map_types.h, yes, no, include/constants/trainer_types.h, yes, no, include/constants/secret_bases.h, yes, no, pokeemerald and pokeruby only include/constants/event_object_movement.h, yes, no, + include/constants/event_objects.h, yes, no, include/constants/event_bg.h, yes, no, include/constants/region_map_sections.h, yes, no, include/constants/metatile_labels.h, yes, yes, include/constants/metatile_behaviors.h, yes, no, include/fieldmap.h, yes, no, reads tileset related constants + src/event_object_movement.c, yes, no, diff --git a/docsrc/manual/settings-and-options.rst b/docsrc/manual/settings-and-options.rst index 09eb610f..aba880c8 100644 --- a/docsrc/manual/settings-and-options.rst +++ b/docsrc/manual/settings-and-options.rst @@ -10,7 +10,11 @@ A global settings file is stored in a platform-dependent location for app config A config file is also created when opening a project in porymap for the first time. It is stored in your project root as ``porymap.project.cfg``. There are several project-specific settings that are -determined by this file. +determined by this file. You may want to check in this file so that other users will have your +porject settings. + +A second config file is created for user-specific settings. It is stored in +your project root as ``porymap.user.cfg``. You should add this file to your gitignore. .. csv-table:: :header: Setting,Default,Location,Can Edit?,Description @@ -18,7 +22,7 @@ determined by this file. ``recent_project``, , global, yes, The project that will be opened on launch ``reopen_on_launch``, 1, global, yes, Whether the most recent project should be opened on launch - ``recent_map``, , global, yes, The map that will be opened on launch + ``recent_map``, , user, yes, The map that will be opened on launch ``pretty_cursors``, 1, global, yes, Whether to use custom crosshair cursors ``map_sort_order``, group, global, yes, The order map list is sorted in ``window_geometry``, , global, no, For restoring window sizes @@ -34,7 +38,7 @@ determined by this file. ``text_editor_goto_line``, , global, yes, The command that will be executed when clicking the button next the ``Script`` combo-box. ``text_editor_open_directory``, , global, yes, The command that will be executed when clicking ``Open Project in Text Editor``. ``base_game_version``, , project, no, The base pret repo for this project - ``use_encounter_json``, 1, project, yes, Enables wild encounter table editing + ``use_encounter_json``, 1, user, yes, Enables wild encounter table editing ``use_poryscript``, 0, project, yes, Whether to open .pory files for scripts ``use_custom_border_size``, 0, project, yes, Whether to allow variable border sizes ``enable_event_weather_trigger``, 1 if not ``pokefirered``, project, yes, Allows adding Weather Trigger events @@ -49,7 +53,7 @@ determined by this file. ``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 + ``custom_scripts``, , user, yes, A list of script files to load into the scripting engine ``prefabs_filepath``, ``/prefabs.json``, project, yes, The filepath containing prefab JSON data Some of these settings can be toggled manually in porymap via the *Options* menu. diff --git a/include/config.h b/include/config.h index 408206c1..e916ba7a 100644 --- a/include/config.h +++ b/include/config.h @@ -13,6 +13,8 @@ #define DEFAULT_BORDER_RSE (QList{468, 469, 476, 477}) #define DEFAULT_BORDER_FRLG (QList{20, 21, 28, 29}) +#define CONFIG_BACKWARDS_COMPATABILITY + enum MapSortOrder { Group = 0, Area = 1, @@ -138,6 +140,50 @@ enum BaseGameVersion { pokeemerald, }; +enum ProjectFilePath { + data_map_folders, + data_scripts_folders, + data_layouts_folders, + data_event_scripts, + json_map_groups, + json_layouts, + json_wild_encounters, + json_region_map_entries, + json_region_porymap_cfg, + tilesets_headers, + tilesets_graphics, + tilesets_metatiles, + data_obj_event_gfx_pointers, + data_obj_event_gfx_info, + data_obj_event_pic_tables, + data_obj_event_gfx, + data_pokemon_gfx, + data_heal_locations, + data_region_map_entries, + constants_global, + constants_map_groups, + constants_items, + constants_opponents, + constants_flags, + constants_vars, + constants_weather, + constants_songs, + constants_heal_locations, + constants_pokemon, + constants_map_types, + constants_trainer_types, + constants_secret_bases, + constants_obj_event_movement, + constants_obj_events, + constants_event_bg, + constants_region_map_sections, + constants_metatile_labels, + constants_metatile_behaviors, + constants_fieldmap, + path_initial_facing_table, + path_pokemon_icon_table, +}; + class ProjectConfig: public KeyValueConfigBase { public: @@ -146,8 +192,6 @@ public: } virtual void reset() override { this->baseGameVersion = BaseGameVersion::pokeemerald; - this->recentMap = QString(); - this->useEncounterJson = true; this->useCustomBorderSize = false; this->enableEventWeatherTrigger = true; this->enableEventSecretBase = true; @@ -163,16 +207,12 @@ public: this->newMapBorderMetatileIds = DEFAULT_BORDER_RSE; this->prefabFilepath = QString(); this->prefabImportPrompted = false; - this->customScripts.clear(); + this->filePaths.clear(); this->readKeys.clear(); } void setBaseGameVersion(BaseGameVersion baseGameVersion); BaseGameVersion getBaseGameVersion(); QString getBaseGameVersionString(); - void setRecentMap(const QString &map); - QString getRecentMap(); - void setEncounterJsonActive(bool active); - bool getEncounterJsonActive(); void setUsePoryScript(bool usePoryScript); bool getUsePoryScript(); void setProjectDir(QString projectDir); @@ -203,8 +243,8 @@ public: int getNewMapElevation(); void setNewMapBorderMetatileIds(QList metatileIds); QList getNewMapBorderMetatileIds(); - void setCustomScripts(QList scripts); - QList getCustomScripts(); + void setFilePath(ProjectFilePath pathId, QString path); + QString getFilePath(ProjectFilePath pathId); void setPrefabFilepath(QString filepath); QString getPrefabFilepath(bool setIfEmpty); void setPrefabImportPrompted(bool prompted); @@ -218,8 +258,7 @@ protected: private: BaseGameVersion baseGameVersion; QString projectDir; - QString recentMap; - bool useEncounterJson; + QMap filePaths; bool usePoryScript; bool useCustomBorderSize; bool enableEventWeatherTrigger; @@ -234,7 +273,6 @@ private: int newMapMetatileId; int newMapElevation; QList newMapBorderMetatileIds; - QList customScripts; QStringList readKeys; QString prefabFilepath; bool prefabImportPrompted; @@ -242,6 +280,45 @@ private: extern ProjectConfig projectConfig; +class UserConfig: public KeyValueConfigBase +{ +public: + UserConfig() { + reset(); + } + virtual void reset() override { + this->recentMap = QString(); + this->useEncounterJson = true; + this->customScripts.clear(); + this->readKeys.clear(); + } + void setRecentMap(const QString &map); + QString getRecentMap(); + void setEncounterJsonActive(bool active); + bool getEncounterJsonActive(); + void setProjectDir(QString projectDir); + QString getProjectDir(); + void setCustomScripts(QList scripts); + QList getCustomScripts(); +protected: + virtual QString getConfigFilepath() override; + virtual void parseConfigKeyValue(QString key, QString value) override; + virtual QMap getKeyValueMap() override; + virtual void onNewConfigFileCreated() override; + virtual void setUnreadKeys() override; +#ifdef CONFIG_BACKWARDS_COMPATABILITY + friend class ProjectConfig; +#endif +private: + QString projectDir; + QString recentMap; + bool useEncounterJson; + QList customScripts; + QStringList readKeys; +}; + +extern UserConfig userConfig; + class QAction; class Shortcut; diff --git a/src/config.cpp b/src/config.cpp index 04d8bbf7..5d508351 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -16,6 +16,57 @@ #include #include +const QMap> defaultPaths = { + {ProjectFilePath::data_map_folders, { "data_map_folders", "data/maps/"}}, + {ProjectFilePath::data_scripts_folders, { "data_scripts_folders", "data/scripts/"}}, + {ProjectFilePath::data_layouts_folders, { "data_layouts_folders", "data/layouts/"}}, + {ProjectFilePath::data_event_scripts, { "data_event_scripts", "data/event_scripts.s"}}, + {ProjectFilePath::json_map_groups, { "json_map_groups", "data/maps/map_groups.json"}}, + {ProjectFilePath::json_layouts, { "json_layouts", "data/layouts/layouts.json"}}, + {ProjectFilePath::json_wild_encounters, { "json_wild_encounters", "src/data/wild_encounters.json"}}, + {ProjectFilePath::json_region_map_entries, { "json_region_map_entries", "src/data/region_map/region_map_sections.json"}}, + {ProjectFilePath::json_region_porymap_cfg, { "json_region_porymap_cfg", "src/data/region_map/porymap_config.json"}}, + {ProjectFilePath::tilesets_headers, { "tilesets_headers", "data/tilesets/headers.inc"}}, + {ProjectFilePath::tilesets_graphics, { "tilesets_graphics", "data/tilesets/graphics.inc"}}, + {ProjectFilePath::tilesets_metatiles, { "tilesets_metatiles", "data/tilesets/metatiles.inc"}}, + {ProjectFilePath::data_obj_event_gfx_pointers, { "data_obj_event_gfx_pointers", "src/data/object_events/object_event_graphics_info_pointers.h"}}, + {ProjectFilePath::data_obj_event_gfx_info, { "data_obj_event_gfx_info", "src/data/object_events/object_event_graphics_info.h"}}, + {ProjectFilePath::data_obj_event_pic_tables, { "data_obj_event_pic_tables", "src/data/object_events/object_event_pic_tables.h"}}, + {ProjectFilePath::data_obj_event_gfx, { "data_obj_event_gfx", "src/data/object_events/object_event_graphics.h"}}, + {ProjectFilePath::data_pokemon_gfx, { "data_pokemon_gfx", "src/data/graphics/pokemon.h"}}, + {ProjectFilePath::data_heal_locations, { "data_heal_locations", "src/data/heal_locations.h"}}, + {ProjectFilePath::data_region_map_entries, { "data_region_map_entries", "src/data/region_map/region_map_entries.h"}}, + {ProjectFilePath::constants_global, { "constants_global", "include/constants/global.h"}}, + {ProjectFilePath::constants_map_groups, { "constants_map_groups", "include/constants/map_groups.h"}}, + {ProjectFilePath::constants_items, { "constants_items", "include/constants/items.h"}}, + {ProjectFilePath::constants_opponents, { "constants_opponents", "include/constants/opponents.h"}}, + {ProjectFilePath::constants_flags, { "constants_flags", "include/constants/flags.h"}}, + {ProjectFilePath::constants_vars, { "constants_vars", "include/constants/vars.h"}}, + {ProjectFilePath::constants_weather, { "constants_weather", "include/constants/weather.h"}}, + {ProjectFilePath::constants_songs, { "constants_songs", "include/constants/songs.h"}}, + {ProjectFilePath::constants_heal_locations, { "constants_heal_locations", "include/constants/heal_locations.h"}}, + {ProjectFilePath::constants_pokemon, { "constants_pokemon", "include/constants/pokemon.h"}}, + {ProjectFilePath::constants_map_types, { "constants_map_types", "include/constants/map_types.h"}}, + {ProjectFilePath::constants_trainer_types, { "constants_trainer_types", "include/constants/trainer_types.h"}}, + {ProjectFilePath::constants_secret_bases, { "constants_secret_bases", "include/constants/secret_bases.h"}}, + {ProjectFilePath::constants_obj_event_movement, { "constants_obj_event_movement", "include/constants/event_object_movement.h"}}, + {ProjectFilePath::constants_obj_events, { "constants_obj_events", "include/constants/event_objects.h"}}, + {ProjectFilePath::constants_event_bg, { "constants_event_bg", "include/constants/event_bg.h"}}, + {ProjectFilePath::constants_region_map_sections, { "constants_region_map_sections", "include/constants/region_map_sections.h"}}, + {ProjectFilePath::constants_metatile_labels, { "constants_metatile_labels", "include/constants/metatile_labels.h"}}, + {ProjectFilePath::constants_metatile_behaviors, { "constants_metatile_behaviors", "include/constants/metatile_behaviors.h"}}, + {ProjectFilePath::constants_fieldmap, { "constants_fieldmap", "include/fieldmap.h"}}, + {ProjectFilePath::path_pokemon_icon_table, { "path_pokemon_icon_table", "src/pokemon_icon.c"}}, + {ProjectFilePath::path_initial_facing_table, { "path_initial_facing_table", "src/event_object_movement.c"}}, +}; + +ProjectFilePath reverseDefaultPaths(QString str) { + for (auto it = defaultPaths.constKeyValueBegin(); it != defaultPaths.constKeyValueEnd(); ++it) { + if ((*it).second.first == str) return (*it).first; + } + return static_cast(-1); +} + KeyValueConfigBase::~KeyValueConfigBase() { } @@ -57,7 +108,7 @@ void KeyValueConfigBase::load() { continue; } - this->parseConfigKeyValue(match.captured("key").toLower(), match.captured("value")); + this->parseConfigKeyValue(match.captured("key").trimmed().toLower(), match.captured("value").trimmed()); } this->setUnreadKeys(); @@ -211,6 +262,7 @@ QMap PorymapConfig::getKeyValueMap() { map.insert("theme", this->theme); map.insert("text_editor_open_directory", this->textEditorOpenFolder); map.insert("text_editor_goto_line", this->textEditorGotoLine); + return map; } @@ -449,10 +501,6 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { this->baseGameVersion = BaseGameVersion::pokeemerald; logWarn(QString("Invalid config value for base_game_version: '%1'. Must be 'pokeruby', 'pokefirered' or 'pokeemerald'.").arg(value)); } - } else if (key == "recent_map") { - this->recentMap = value; - } else if (key == "use_encounter_json") { - this->useEncounterJson = getConfigBool(key, value); } else if (key == "use_poryscript") { this->usePoryScript = getConfigBool(key, value); } else if (key == "use_custom_border_size") { @@ -493,15 +541,28 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { // Set any metatiles not provided to 0 this->newMapBorderMetatileIds.append(0); } +#ifdef CONFIG_BACKWARDS_COMPATABILITY + } else if (key == "recent_map") { + userConfig.setRecentMap(value); + } else if (key == "use_encounter_json") { + userConfig.useEncounterJson = getConfigBool(key, value); } else if (key == "custom_scripts") { - this->customScripts.clear(); + userConfig.customScripts.clear(); QList paths = value.split(","); paths.removeDuplicates(); for (QString script : paths) { if (!script.isEmpty()) { - this->customScripts.append(script); + userConfig.customScripts.append(script); } } +#endif + } else if (key.startsWith("path/")) { + auto k = reverseDefaultPaths(key.mid(5)); + if (k != static_cast(-1)) { + this->setFilePath(k, 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") { @@ -530,8 +591,6 @@ void ProjectConfig::setUnreadKeys() { QMap ProjectConfig::getKeyValueMap() { QMap map; map.insert("base_game_version", baseGameVersionMap.value(this->baseGameVersion)); - map.insert("recent_map", this->recentMap); - map.insert("use_encounter_json", QString::number(this->useEncounterJson)); map.insert("use_poryscript", QString::number(this->usePoryScript)); map.insert("use_custom_border_size", QString::number(this->useCustomBorderSize)); map.insert("enable_event_weather_trigger", QString::number(this->enableEventWeatherTrigger)); @@ -549,9 +608,11 @@ QMap ProjectConfig::getKeyValueMap() { 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); map.insert("prefabs_import_prompted", QString::number(this->prefabImportPrompted)); + for (auto it = this->filePaths.constKeyValueBegin(); it != this->filePaths.constKeyValueEnd(); ++it) { + map.insert("path/"+defaultPaths[(*it).first].first, (*it).second); + } return map; } @@ -591,13 +652,11 @@ void ProjectConfig::onNewConfigFileCreated() { this->enableEventCloneObject = isPokefirered; this->enableFloorNumber = isPokefirered; this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald); - 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(); } void ProjectConfig::setProjectDir(QString projectDir) { @@ -608,6 +667,21 @@ QString ProjectConfig::getProjectDir() { return this->projectDir; } +void ProjectConfig::setFilePath(ProjectFilePath pathId, QString path) { + if (!defaultPaths.contains(pathId)) return; + this->filePaths[pathId] = path; +} + +QString ProjectConfig::getFilePath(ProjectFilePath pathId) { + if (this->filePaths.contains(pathId)) { + return this->filePaths[pathId]; + } else if (defaultPaths.contains(pathId)) { + return defaultPaths[pathId].second; + } else { + return QString(); + } +} + void ProjectConfig::setBaseGameVersion(BaseGameVersion baseGameVersion) { this->baseGameVersion = baseGameVersion; this->save(); @@ -621,24 +695,6 @@ QString ProjectConfig::getBaseGameVersionString() { return baseGameVersionMap.value(this->baseGameVersion); } -void ProjectConfig::setRecentMap(const QString &map) { - this->recentMap = map; - this->save(); -} - -QString ProjectConfig::getRecentMap() { - return this->recentMap; -} - -void ProjectConfig::setEncounterJsonActive(bool active) { - this->useEncounterJson = active; - this->save(); -} - -bool ProjectConfig::getEncounterJsonActive() { - return this->useEncounterJson; -} - void ProjectConfig::setUsePoryScript(bool usePoryScript) { this->usePoryScript = usePoryScript; this->save(); @@ -765,15 +821,6 @@ QList ProjectConfig::getNewMapBorderMetatileIds() { return this->newMapBorderMetatileIds; } -void ProjectConfig::setCustomScripts(QList scripts) { - this->customScripts = scripts; - this->save(); -} - -QList ProjectConfig::getCustomScripts() { - return this->customScripts; -} - void ProjectConfig::setPrefabFilepath(QString filepath) { this->prefabFilepath = filepath; this->save(); @@ -795,6 +842,86 @@ bool ProjectConfig::getPrefabImportPrompted() { return this->prefabImportPrompted; } + +UserConfig userConfig; + +QString UserConfig::getConfigFilepath() { + // porymap config file is in the same directory as porymap itself. + return QDir(this->projectDir).filePath("porymap.user.cfg"); +} + +void UserConfig::parseConfigKeyValue(QString key, QString value) { + if (key == "recent_map") { + this->recentMap = value; + } else if (key == "use_encounter_json") { + this->useEncounterJson = getConfigBool(key, value); + } else if (key == "custom_scripts") { + this->customScripts.clear(); + QList paths = value.split(","); + paths.removeDuplicates(); + for (QString script : paths) { + if (!script.isEmpty()) { + this->customScripts.append(script); + } + } + } else { + logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); + } + readKeys.append(key); +} + +void UserConfig::setUnreadKeys() { +} + +QMap UserConfig::getKeyValueMap() { + QMap map; + map.insert("recent_map", this->recentMap); + map.insert("use_encounter_json", QString::number(this->useEncounterJson)); + map.insert("custom_scripts", this->customScripts.join(",")); + return map; +} + +void UserConfig::onNewConfigFileCreated() { + QString dirName = QDir(this->projectDir).dirName().toLower(); + this->useEncounterJson = true; + this->customScripts.clear(); +} + +void UserConfig::setProjectDir(QString projectDir) { + this->projectDir = projectDir; +} + +QString UserConfig::getProjectDir() { + return this->projectDir; +} + +void UserConfig::setRecentMap(const QString &map) { + this->recentMap = map; + this->save(); +} + +QString UserConfig::getRecentMap() { + return this->recentMap; +} + +void UserConfig::setEncounterJsonActive(bool active) { + this->useEncounterJson = active; + this->save(); +} + +bool UserConfig::getEncounterJsonActive() { + return this->useEncounterJson; +} + +void UserConfig::setCustomScripts(QList scripts) { + this->customScripts = scripts; + this->save(); +} + +QList UserConfig::getCustomScripts() { + return this->customScripts; +} + ShortcutsConfig shortcutsConfig; QString ShortcutsConfig::getConfigFilepath() { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b2bd0b1e..f915f045 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -359,7 +359,7 @@ void MainWindow::setWildEncountersUIEnabled(bool enabled) { void MainWindow::setProjectSpecificUIVisibility() { ui->actionUse_Poryscript->setChecked(projectConfig.getUsePoryScript()); - this->setWildEncountersUIEnabled(projectConfig.getEncounterJsonActive()); + this->setWildEncountersUIEnabled(userConfig.getEncounterJsonActive()); switch (projectConfig.getBaseGameVersion()) { @@ -511,6 +511,8 @@ bool MainWindow::openProject(QString dir) { this->statusBar()->showMessage(QString("Opening project %1").arg(nativeDir)); bool success = true; + userConfig.setProjectDir(dir); + userConfig.load(); projectConfig.setProjectDir(dir); projectConfig.load(); @@ -571,7 +573,7 @@ QString MainWindow::getDefaultMap() { if (editor && editor->project) { QList names = editor->project->groupedMapNames; if (!names.isEmpty()) { - QString recentMap = projectConfig.getRecentMap(); + QString recentMap = userConfig.getRecentMap(); if (!recentMap.isNull() && recentMap.length() > 0) { for (int i = 0; i < names.length(); i++) { if (names.value(i).contains(recentMap)) { @@ -598,8 +600,8 @@ QString MainWindow::getExistingDirectory(QString dir) { void MainWindow::on_action_Open_Project_triggered() { QString recent = "."; - if (!projectConfig.getRecentMap().isEmpty()) { - recent = projectConfig.getRecentMap(); + if (!userConfig.getRecentMap().isEmpty()) { + recent = userConfig.getRecentMap(); } QString dir = getExistingDirectory(recent); if (!dir.isEmpty()) { @@ -744,7 +746,7 @@ void MainWindow::openWarpMap(QString map_name, QString event_id, QString event_g } void MainWindow::setRecentMap(QString mapName) { - projectConfig.setRecentMap(mapName); + userConfig.setRecentMap(mapName); } void MainWindow::displayMapProperties() { @@ -1726,7 +1728,7 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index) editor->setEditingConnections(); } if (index != 4) { - if (projectConfig.getEncounterJsonActive()) + if (userConfig.getEncounterJsonActive()) editor->saveEncounterTabData(); } if (index != 1) { @@ -1777,7 +1779,7 @@ void MainWindow::on_actionUse_Encounter_Json_triggered(bool checked) warning.setText("You must reload the project for this setting to take effect."); warning.setIcon(QMessageBox::Information); warning.exec(); - projectConfig.setEncounterJsonActive(checked); + userConfig.setEncounterJsonActive(checked); } void MainWindow::on_actionMonitor_Project_Files_triggered(bool checked) @@ -1882,8 +1884,9 @@ void MainWindow::addNewEvent(QString event_type) msgBox.setText("Failed to add new event"); if (Event::typeToGroup(event_type) == EventGroup::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 'include/constants/global.h'.") - .arg(editor->project->getMaxObjectEvents())); + "This limit can be adjusted with OBJECT_EVENT_TEMPLATES_COUNT in '%2'.") + .arg(editor->project->getMaxObjectEvents()) + .arg(projectConfig.getFilePath(ProjectFilePath::constants_global))); } msgBox.setDefaultButton(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Icon::Warning); @@ -3248,6 +3251,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { } } projectConfig.save(); + userConfig.save(); } porymapConfig.setMainGeometry( diff --git a/src/project.cpp b/src/project.cpp index 62f12185..c94b646d 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -183,7 +183,7 @@ bool Project::loadMapData(Map* map) { return true; } - QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map->name); + QString mapFilepath = QString("%1/%3%2/map.json").arg(root).arg(map->name).arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)); QJsonDocument mapDoc; if (!parser.tryParseJsonFile(&mapDoc, mapFilepath)) { logError(QString("Failed to read map data from %1").arg(mapFilepath)); @@ -425,7 +425,7 @@ QString Project::readMapLayoutId(QString map_name) { return mapCache.value(map_name)->layoutId; } - QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name); + QString mapFilepath = QString("%1/%3%2/map.json").arg(root).arg(map_name).arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)); QJsonDocument mapDoc; if (!parser.tryParseJsonFile(&mapDoc, mapFilepath)) { logError(QString("Failed to read map layout id from %1").arg(mapFilepath)); @@ -441,7 +441,7 @@ QString Project::readMapLocation(QString map_name) { return mapCache.value(map_name)->location; } - QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name); + QString mapFilepath = QString("%1/%3%2/map.json").arg(root).arg(map_name).arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)); QJsonDocument mapDoc; if (!parser.tryParseJsonFile(&mapDoc, mapFilepath)) { logError(QString("Failed to read map's region map section from %1").arg(mapFilepath)); @@ -508,7 +508,7 @@ bool Project::readMapLayouts() { mapLayouts.clear(); mapLayoutsTable.clear(); - QString layoutsFilepath = QString("%1/data/layouts/layouts.json").arg(root); + QString layoutsFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_layouts)); fileWatcher.addPath(layoutsFilepath); QJsonDocument layoutsDoc; if (!parser.tryParseJsonFile(&layoutsDoc, layoutsFilepath)) { @@ -627,7 +627,7 @@ bool Project::readMapLayouts() { } void Project::saveMapLayouts() { - QString layoutsFilepath = QString("%1/data/layouts/layouts.json").arg(root); + QString layoutsFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_layouts)); QFile layoutsFile(layoutsFilepath); if (!layoutsFile.open(QIODevice::WriteOnly)) { logError(QString("Error: Could not open %1 for writing").arg(layoutsFilepath)); @@ -679,8 +679,8 @@ void Project::setNewMapLayout(Map* map) { layout->height = QString::number(getDefaultMapSize()); layout->border_width = QString::number(DEFAULT_BORDER_WIDTH); layout->border_height = QString::number(DEFAULT_BORDER_HEIGHT); - layout->border_path = QString("data/layouts/%1/border.bin").arg(map->name); - layout->blockdata_path = QString("data/layouts/%1/map.bin").arg(map->name); + layout->border_path = QString("%2%1/border.bin").arg(map->name).arg(projectConfig.getFilePath(ProjectFilePath::data_layouts_folders)); + layout->blockdata_path = QString("%2%1/map.bin").arg(map->name).arg(projectConfig.getFilePath(ProjectFilePath::data_layouts_folders)); layout->tileset_primary_label = tilesetLabels["primary"].value(0, "gTileset_General"); layout->tileset_secondary_label = tilesetLabels["secondary"].value(0, projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered ? "gTileset_PalletTown" : "gTileset_Petalburg"); map->layout = layout; @@ -692,7 +692,7 @@ void Project::setNewMapLayout(Map* map) { } void Project::saveMapGroups() { - QString mapGroupsFilepath = QString("%1/data/maps/map_groups.json").arg(root); + QString mapGroupsFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_map_groups)); QFile mapGroupsFile(mapGroupsFilepath); if (!mapGroupsFile.open(QIODevice::WriteOnly)) { logError(QString("Error: Could not open %1 for writing").arg(mapGroupsFilepath)); @@ -727,9 +727,9 @@ void Project::saveMapGroups() { } void Project::saveWildMonData() { - if (!projectConfig.getEncounterJsonActive()) return; + if (!userConfig.getEncounterJsonActive()) return; - QString wildEncountersJsonFilepath = QString("%1/src/data/wild_encounters.json").arg(root); + QString wildEncountersJsonFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_wild_encounters)); QFile wildEncountersFile(wildEncountersJsonFilepath); if (!wildEncountersFile.open(QIODevice::WriteOnly)) { logError(QString("Error: Could not open %1 for writing").arg(wildEncountersJsonFilepath)); @@ -849,7 +849,7 @@ void Project::saveMapConstantsHeader() { text += QString("#define MAP_GROUPS_COUNT %1\n\n").arg(groupNum); text += QString("#endif // GUARD_CONSTANTS_MAP_GROUPS_H\n"); - QString mapGroupFilepath = root + "/include/constants/map_groups.h"; + QString mapGroupFilepath = root + "/" + projectConfig.getFilePath(ProjectFilePath::constants_map_groups); ignoreWatchedFileTemporarily(mapGroupFilepath); saveTextFile(mapGroupFilepath, text); } @@ -953,11 +953,11 @@ void Project::saveHealLocationStruct(Map *map) { data_text += QString("};\n"); constants_text += QString("\n#endif // GUARD_CONSTANTS_HEAL_LOCATIONS_H\n"); - QString healLocationFilepath = root + "/src/data/heal_locations.h"; + QString healLocationFilepath = root + "/" + projectConfig.getFilePath(ProjectFilePath::data_heal_locations); ignoreWatchedFileTemporarily(healLocationFilepath); saveTextFile(healLocationFilepath, data_text); - QString healLocationConstantsFilepath = root + "/include/constants/heal_locations.h"; + QString healLocationConstantsFilepath = root + "/" + projectConfig.getFilePath(ProjectFilePath::constants_heal_locations); ignoreWatchedFileTemporarily(healLocationConstantsFilepath); saveTextFile(healLocationConstantsFilepath, constants_text); } @@ -981,7 +981,7 @@ void Project::saveTilesetMetatileLabels(Tileset *primaryTileset, Tileset *second QMap defines; bool definesFileModified = false; - QString metatileLabelsFilename = "include/constants/metatile_labels.h"; + QString metatileLabelsFilename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels); defines = parser.readCDefines(metatileLabelsFilename, (QStringList() << "METATILE_")); // Purge old entries from the file. @@ -1635,7 +1635,7 @@ void Project::loadTilesetMetatiles(Tileset* tileset) { void Project::loadTilesetMetatileLabels(Tileset* tileset) { QString tilesetPrefix = QString("METATILE_%1_").arg(QString(tileset->name).replace("gTileset_", "")); - QString metatileLabelsFilename = "include/constants/metatile_labels.h"; + QString metatileLabelsFilename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels); fileWatcher.addPath(root + "/" + metatileLabelsFilename); QMap labels = parser.readCDefines(metatileLabelsFilename, QStringList() << tilesetPrefix); @@ -1721,18 +1721,18 @@ bool Project::readWildMonData() { wildMonFields.clear(); wildMonData.clear(); encounterGroupLabels.clear(); - if (!projectConfig.getEncounterJsonActive()) { + if (!userConfig.getEncounterJsonActive()) { return true; } - QString wildMonJsonFilepath = QString("%1/src/data/wild_encounters.json").arg(root); + QString wildMonJsonFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_wild_encounters)); fileWatcher.addPath(wildMonJsonFilepath); OrderedJson::object wildMonObj; if (!parser.tryParseOrderedJsonFile(&wildMonObj, wildMonJsonFilepath)) { // Failing to read wild encounters data is not a critical error, just disable the // encounter editor and log a warning in case the user intended to have this data. - projectConfig.setEncounterJsonActive(false); + userConfig.setEncounterJsonActive(false); emit disableWildEncountersUI(); logWarn(QString("Failed to read wild encounters from %1").arg(wildMonJsonFilepath)); return true; @@ -1949,7 +1949,7 @@ QMap Project::getTilesetLabels() { bool Project::readTilesetProperties() { QStringList definePrefixes; definePrefixes << "\\bNUM_"; - QString filename = "include/fieldmap.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_fieldmap); fileWatcher.addPath(root + "/" + filename); QMap defines = parser.readCDefines(filename, definePrefixes); @@ -2007,7 +2007,7 @@ bool Project::readTilesetProperties() { bool Project::readMaxMapDataSize() { QStringList definePrefixes; definePrefixes << "\\bMAX_"; - QString filename = "include/fieldmap.h"; // already in fileWatcher from readTilesetProperties + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_fieldmap); // already in fileWatcher from readTilesetProperties QMap defines = parser.readCDefines(filename, definePrefixes); auto it = defines.find("MAX_MAP_DATA_SIZE"); @@ -2036,7 +2036,7 @@ bool Project::readRegionMapSections() { this->mapSectionValueToName.clear(); QStringList prefixes = (QStringList() << "\\bMAPSEC_"); - QString filename = "include/constants/region_map_sections.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_region_map_sections); fileWatcher.addPath(root + "/" + filename); this->mapSectionNameToValue = parser.readCDefines(filename, prefixes); if (this->mapSectionNameToValue.isEmpty()) { @@ -2053,7 +2053,7 @@ bool Project::readRegionMapSections() { bool Project::readHealLocations() { dataQualifiers.clear(); healLocations.clear(); - QString filename = "src/data/heal_locations.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::data_heal_locations); fileWatcher.addPath(root + "/" + filename); QString text = parser.readTextFile(root + "/" + filename); text.replace(QRegularExpression("//.*?(\r\n?|\n)|/\\*.*?\\*/", QRegularExpression::DotMatchesEverythingOption), ""); @@ -2100,7 +2100,7 @@ bool Project::readHealLocations() { bool Project::readItemNames() { QStringList prefixes("\\bITEM_(?!(B_)?USE_)"); // Exclude ITEM_USE_ and ITEM_B_USE_ constants - QString filename = "include/constants/items.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_items); fileWatcher.addPath(root + "/" + filename); itemNames = parser.readCDefinesSorted(filename, prefixes); if (itemNames.isEmpty()) { @@ -2113,12 +2113,12 @@ bool Project::readItemNames() { bool Project::readFlagNames() { // First read MAX_TRAINERS_COUNT, used to skip over trainer flags // If this fails flags may simply be out of order, no need to check for success - QString opponentsFilename = "include/constants/opponents.h"; + QString opponentsFilename = projectConfig.getFilePath(ProjectFilePath::constants_opponents); fileWatcher.addPath(root + "/" + opponentsFilename); QMap maxTrainers = parser.readCDefines(opponentsFilename, QStringList() << "\\bMAX_"); // Parse flags QStringList prefixes("\\bFLAG_"); - QString flagsFilename = "include/constants/flags.h"; + QString flagsFilename = projectConfig.getFilePath(ProjectFilePath::constants_flags); fileWatcher.addPath(root + "/" + flagsFilename); flagNames = parser.readCDefinesSorted(flagsFilename, prefixes, maxTrainers); if (flagNames.isEmpty()) { @@ -2130,7 +2130,7 @@ bool Project::readFlagNames() { bool Project::readVarNames() { QStringList prefixes("\\bVAR_"); - QString filename = "include/constants/vars.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_vars); fileWatcher.addPath(root + "/" + filename); varNames = parser.readCDefinesSorted(filename, prefixes); if (varNames.isEmpty()) { @@ -2142,7 +2142,7 @@ bool Project::readVarNames() { bool Project::readMovementTypes() { QStringList prefixes("\\bMOVEMENT_TYPE_"); - QString filename = "include/constants/event_object_movement.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_event_movement); fileWatcher.addPath(root + "/" + filename); movementTypes = parser.readCDefinesSorted(filename, prefixes); if (movementTypes.isEmpty()) { @@ -2153,7 +2153,7 @@ bool Project::readMovementTypes() { } bool Project::readInitialFacingDirections() { - QString filename = "src/event_object_movement.c"; + QString filename = projectConfig.getFilePath(ProjectFilePath::path_initial_facing_table); fileWatcher.addPath(root + "/" + filename); facingDirections = parser.readNamedIndexCArray(filename, "gInitialMovementTypeFacingDirections"); if (facingDirections.isEmpty()) { @@ -2165,7 +2165,7 @@ bool Project::readInitialFacingDirections() { bool Project::readMapTypes() { QStringList prefixes("\\bMAP_TYPE_"); - QString filename = "include/constants/map_types.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); fileWatcher.addPath(root + "/" + filename); mapTypes = parser.readCDefinesSorted(filename, prefixes); if (mapTypes.isEmpty()) { @@ -2177,9 +2177,9 @@ bool Project::readMapTypes() { bool Project::readMapBattleScenes() { QStringList prefixes("\\bMAP_BATTLE_SCENE_"); - QString filename = "include/constants/map_types.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); fileWatcher.addPath(root + "/" + filename); - mapBattleScenes = parser.readCDefinesSorted("include/constants/map_types.h", prefixes); + mapBattleScenes = parser.readCDefinesSorted(filename, prefixes); if (mapBattleScenes.isEmpty()) { logError(QString("Failed to read map battle scene constants from %1").arg(filename)); return false; @@ -2189,7 +2189,7 @@ bool Project::readMapBattleScenes() { bool Project::readWeatherNames() { QStringList prefixes("\\bWEATHER_"); - QString filename = "include/constants/weather.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); fileWatcher.addPath(root + "/" + filename); weatherNames = parser.readCDefinesSorted(filename, prefixes); if (weatherNames.isEmpty()) { @@ -2204,7 +2204,7 @@ bool Project::readCoordEventWeatherNames() { return true; QStringList prefixes("\\bCOORD_EVENT_WEATHER_"); - QString filename = "include/constants/weather.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); fileWatcher.addPath(root + "/" + filename); coordEventWeatherNames = parser.readCDefinesSorted(filename, prefixes); if (coordEventWeatherNames.isEmpty()) { @@ -2224,7 +2224,7 @@ bool Project::readSecretBaseIds() { knownDefines.insert("SECRET_BASE_GROUP", 0); QStringList prefixes("\\bSECRET_BASE_[A-Za-z0-9_]*_[0-9]+"); - QString filename = "include/constants/secret_bases.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_secret_bases); fileWatcher.addPath(root + "/" + filename); secretBaseIds = parser.readCDefinesSorted(filename, prefixes, knownDefines); if (secretBaseIds.isEmpty()) { @@ -2236,7 +2236,7 @@ bool Project::readSecretBaseIds() { bool Project::readBgEventFacingDirections() { QStringList prefixes("\\bBG_EVENT_PLAYER_FACING_"); - QString filename = "include/constants/event_bg.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_event_bg); fileWatcher.addPath(root + "/" + filename); bgEventFacingDirections = parser.readCDefinesSorted(filename, prefixes); if (bgEventFacingDirections.isEmpty()) { @@ -2248,7 +2248,7 @@ bool Project::readBgEventFacingDirections() { bool Project::readTrainerTypes() { QStringList prefixes("\\bTRAINER_TYPE_"); - QString filename = "include/constants/trainer_types.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_trainer_types); fileWatcher.addPath(root + "/" + filename); trainerTypes = parser.readCDefinesSorted(filename, prefixes); if (trainerTypes.isEmpty()) { @@ -2263,7 +2263,7 @@ bool Project::readMetatileBehaviors() { this->metatileBehaviorMapInverse.clear(); QStringList prefixes("\\bMB_"); - QString filename = "include/constants/metatile_behaviors.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors); fileWatcher.addPath(root + "/" + filename); this->metatileBehaviorMap = parser.readCDefines(filename, prefixes); if (this->metatileBehaviorMap.isEmpty()) { @@ -2279,7 +2279,7 @@ bool Project::readMetatileBehaviors() { bool Project::readSongNames() { QStringList songDefinePrefixes{ "\\bSE_", "\\bMUS_" }; - QString filename = "include/constants/songs.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_songs); fileWatcher.addPath(root + "/" + filename); QMap songDefines = parser.readCDefines(filename, songDefinePrefixes); this->songNames = songDefines.keys(); @@ -2293,7 +2293,7 @@ bool Project::readSongNames() { bool Project::readObjEventGfxConstants() { QStringList objEventGfxPrefixes("\\bOBJ_EVENT_GFX_"); - QString filename = "include/constants/event_objects.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_events); fileWatcher.addPath(root + "/" + filename); this->gfxDefines = parser.readCDefines(filename, objEventGfxPrefixes); if (this->gfxDefines.isEmpty()) { @@ -2305,15 +2305,15 @@ bool Project::readObjEventGfxConstants() { bool Project::readMiscellaneousConstants() { miscConstants.clear(); - if (projectConfig.getEncounterJsonActive()) { - QString filename = "include/constants/pokemon.h"; + if (userConfig.getEncounterJsonActive()) { + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_pokemon); fileWatcher.addPath(root + "/" + filename); QMap pokemonDefines = parser.readCDefines(filename, { "MIN_", "MAX_" }); 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); } - QString filename = "include/constants/global.h"; + QString filename = projectConfig.getFilePath(ProjectFilePath::constants_global); fileWatcher.addPath(root + "/" + filename); QStringList definePrefixes("\\bOBJECT_"); QMap defines = parser.readCDefines(filename, definePrefixes); @@ -2376,7 +2376,7 @@ QString Project::getScriptDefaultString(bool usePoryScript, QString mapName) con QString Project::getMapScriptsFilePath(const QString &mapName) const { const bool usePoryscript = projectConfig.getUsePoryScript(); - auto path = QDir::cleanPath(root + "/data/maps/" + mapName + "/scripts"); + auto path = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_map_folders) + "/" + mapName + "/scripts"); auto extension = getScriptFileExtension(usePoryscript); if (usePoryscript && !QFile::exists(path + extension)) extension = getScriptFileExtension(false); @@ -2385,9 +2385,9 @@ QString Project::getMapScriptsFilePath(const QString &mapName) const { } QStringList Project::getEventScriptsFilePaths() const { - QStringList filePaths(QDir::cleanPath(root + "/data/event_scripts.s")); - const QString scriptsDir = QDir::cleanPath(root + "/data/scripts"); - const QString mapsDir = QDir::cleanPath(root + "/data/maps"); + QStringList filePaths(QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts))); + const QString scriptsDir = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_scripts_folders)); + const QString mapsDir = QDir::cleanPath(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_map_folders)); const bool usePoryscript = projectConfig.getUsePoryScript(); if (usePoryscript) { @@ -2473,12 +2473,12 @@ void Project::setEventPixmap(Event * event, bool forceLoad) { } bool Project::readEventGraphics() { - fileWatcher.addPaths(QStringList() << root + "/" + "src/data/object_events/object_event_graphics_info_pointers.h" - << root + "/" + "src/data/object_events/object_event_graphics_info.h" - << root + "/" + "src/data/object_events/object_event_pic_tables.h" - << root + "/" + "src/data/object_events/object_event_graphics.h"); + fileWatcher.addPaths(QStringList() << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_pointers) + << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info) + << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables) + << root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx)); - QMap pointerHash = parser.readNamedIndexCArray("src/data/object_events/object_event_graphics_info_pointers.h", "gObjectEventGraphicsInfoPointers"); + QMap pointerHash = parser.readNamedIndexCArray(projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_pointers), "gObjectEventGraphicsInfoPointers"); qDeleteAll(eventGraphicsMap); eventGraphicsMap.clear(); @@ -2498,9 +2498,9 @@ bool Project::readEventGraphics() { QString dimensions_label = gfxInfoAttributes.value("oam"); QString subsprites_label = gfxInfoAttributes.value("subspriteTables"); - QString gfx_label = parser.readCArray("src/data/object_events/object_event_pic_tables.h", pic_label).value(0); + QString gfx_label = parser.readCArray(projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables), pic_label).value(0); gfx_label = gfx_label.section(QRegularExpression("[\\(\\)]"), 1, 1); - QString path = parser.readCIncbin("src/data/object_events/object_event_graphics.h", gfx_label); + QString path = parser.readCIncbin(projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx), gfx_label); if (!path.isNull()) { path = fixGraphicPath(path); @@ -2535,7 +2535,7 @@ QMap> Project::readObjEventGfxInfo() { // TODO: refactor this to be more general if we end up directly parsing C // for more use cases in the future. auto cParser = fex::Parser(); - auto tokens = fex::Lexer().LexFile((root + "/src/data/object_events/object_event_graphics_info.h").toStdString()); + auto tokens = fex::Lexer().LexFile((root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info)).toStdString()); auto gfxInfoObjects = cParser.ParseTopLevelObjects(tokens); QMap> gfxInfos; for (auto it = gfxInfoObjects.begin(); it != gfxInfoObjects.end(); it++) { @@ -2575,8 +2575,8 @@ QMap> Project::readObjEventGfxInfo() { bool Project::readSpeciesIconPaths() { speciesToIconPath.clear(); - QString srcfilename = "src/pokemon_icon.c"; - QString incfilename = "src/data/graphics/pokemon.h"; + QString srcfilename = projectConfig.getFilePath(ProjectFilePath::path_pokemon_icon_table); + QString incfilename = projectConfig.getFilePath(ProjectFilePath::data_pokemon_gfx); fileWatcher.addPath(root + "/" + srcfilename); fileWatcher.addPath(root + "/" + incfilename); QMap monIconNames = parser.readNamedIndexCArray(srcfilename, "gMonIconTable"); diff --git a/src/scriptapi/apiutility.cpp b/src/scriptapi/apiutility.cpp index 8bf25a17..16ca967d 100644 --- a/src/scriptapi/apiutility.cpp +++ b/src/scriptapi/apiutility.cpp @@ -123,7 +123,7 @@ void ScriptUtility::setMainTab(int index) { if (!window || !window->ui || !window->ui->mainTabBar || index < 0 || index >= window->ui->mainTabBar->count()) return; // Can't select Wild Encounters tab if it's disabled - if (index == 4 && !projectConfig.getEncounterJsonActive()) + if (index == 4 && !userConfig.getEncounterJsonActive()) return; window->on_mainTabBar_tabBarClicked(index); } @@ -165,7 +165,7 @@ bool ScriptUtility::getSmartPathsEnabled() { } QList ScriptUtility::getCustomScripts() { - return projectConfig.getCustomScripts(); + return userConfig.getCustomScripts(); } QList ScriptUtility::getMetatileLayerOrder() { diff --git a/src/scriptapi/scripting.cpp b/src/scriptapi/scripting.cpp index 52bbe872..12b549f0 100644 --- a/src/scriptapi/scripting.cpp +++ b/src/scriptapi/scripting.cpp @@ -35,7 +35,7 @@ void Scripting::init(MainWindow *mainWindow) { Scripting::Scripting(MainWindow *mainWindow) { this->engine = new QJSEngine(mainWindow); this->engine->installExtensions(QJSEngine::ConsoleExtension); - for (QString script : projectConfig.getCustomScripts()) { + for (QString script : userConfig.getCustomScripts()) { this->filepaths.append(script); } this->loadModules(this->filepaths); @@ -46,7 +46,7 @@ void Scripting::loadModules(QStringList moduleFiles) { for (QString filepath : moduleFiles) { QJSValue module = this->engine->importModule(filepath); if (module.isError()) { - QString relativePath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath); + QString relativePath = QDir::cleanPath(userConfig.getProjectDir() + QDir::separator() + filepath); module = this->engine->importModule(relativePath); if (tryErrorJS(module)) continue; } diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index 8e4f036c..dc2c458e 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -110,7 +110,7 @@ void RegionMapEditor::applyUserShortcuts() { bool RegionMapEditor::loadRegionMapEntries() { this->region_map_entries.clear(); - QString regionMapSectionFilepath = QString("%1/src/data/region_map/region_map_sections.json").arg(this->project->root); + QString regionMapSectionFilepath = QString("%1/%2").arg(this->project->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_map_entries)); ParseUtil parser; QJsonDocument sectionsDoc; @@ -140,7 +140,7 @@ bool RegionMapEditor::loadRegionMapEntries() { } bool RegionMapEditor::saveRegionMapEntries() { - QString regionMapSectionFilepath = QString("%1/src/data/region_map/region_map_sections.json").arg(this->project->root); + QString regionMapSectionFilepath = QString("%1/%2").arg(this->project->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_map_entries)); QFile sectionsFile(regionMapSectionFilepath); if (!sectionsFile.open(QIODevice::WriteOnly)) { @@ -508,7 +508,7 @@ bool RegionMapEditor::setup() { bool RegionMapEditor::load() { // check for config json file - QString jsonConfigFilepath = this->project->root + "/src/data/region_map/porymap_config.json"; + QString jsonConfigFilepath = this->project->root + "/" + projectConfig.getFilePath(ProjectFilePath::json_region_porymap_cfg); bool badConfig = true; @@ -586,7 +586,7 @@ void RegionMapEditor::saveConfig() { mapsObject["region_maps"] = mapArray; OrderedJson newConfigJson(mapsObject); - QString filepath = QString("%1/src/data/region_map/porymap_config.json").arg(this->project->root); + QString filepath = QString("%1/%2").arg(this->project->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_porymap_cfg)); QFile file(filepath); if (!file.open(QIODevice::WriteOnly)) { logError(QString("Error: Could not open %1 for writing").arg(filepath));