2018-12-21 15:25:28 +00:00
|
|
|
#include "config.h"
|
|
|
|
#include "log.h"
|
2020-11-03 10:58:10 +00:00
|
|
|
#include "shortcut.h"
|
2022-09-11 04:30:28 +01:00
|
|
|
#include "map.h"
|
2018-12-21 15:25:28 +00:00
|
|
|
#include <QDir>
|
|
|
|
#include <QFile>
|
2018-12-25 21:26:13 +00:00
|
|
|
#include <QFormLayout>
|
|
|
|
#include <QDialog>
|
|
|
|
#include <QDialogButtonBox>
|
2018-12-21 15:25:28 +00:00
|
|
|
#include <QList>
|
2018-12-25 21:26:13 +00:00
|
|
|
#include <QComboBox>
|
|
|
|
#include <QLabel>
|
2018-12-21 15:25:28 +00:00
|
|
|
#include <QTextStream>
|
|
|
|
#include <QRegularExpression>
|
2018-12-27 01:18:33 +00:00
|
|
|
#include <QStandardPaths>
|
2020-11-01 12:35:20 +00:00
|
|
|
#include <QAction>
|
2020-11-08 13:36:02 +00:00
|
|
|
#include <QAbstractButton>
|
2018-12-21 15:25:28 +00:00
|
|
|
|
2022-09-01 17:14:47 +01:00
|
|
|
const QMap<ProjectFilePath, std::pair<QString, QString>> 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/"}},
|
2022-09-27 23:06:43 +01:00
|
|
|
{ProjectFilePath::data_tilesets_folders, { "data_tilesets_folders", "data/tilesets/"}},
|
2022-09-01 17:14:47 +01:00
|
|
|
{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"}},
|
2022-09-28 01:17:55 +01:00
|
|
|
{ProjectFilePath::tilesets_headers, { "tilesets_headers", "src/data/tilesets/headers.h"}},
|
|
|
|
{ProjectFilePath::tilesets_graphics, { "tilesets_graphics", "src/data/tilesets/graphics.h"}},
|
|
|
|
{ProjectFilePath::tilesets_metatiles, { "tilesets_metatiles", "src/data/tilesets/metatiles.h"}},
|
|
|
|
{ProjectFilePath::tilesets_headers_asm, { "tilesets_headers_asm", "data/tilesets/headers.inc"}},
|
|
|
|
{ProjectFilePath::tilesets_graphics_asm, { "tilesets_graphics_asm", "data/tilesets/graphics.inc"}},
|
|
|
|
{ProjectFilePath::tilesets_metatiles_asm, { "tilesets_metatiles_asm", "data/tilesets/metatiles.inc"}},
|
2022-09-01 17:14:47 +01:00
|
|
|
{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::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"}},
|
2022-10-24 13:03:51 +01:00
|
|
|
{ProjectFilePath::pokemon_icon_table, { "pokemon_icon_table", "src/pokemon_icon.c"}},
|
|
|
|
{ProjectFilePath::initial_facing_table, { "initial_facing_table", "src/event_object_movement.c"}},
|
2022-09-01 17:14:47 +01:00
|
|
|
};
|
|
|
|
|
2022-09-01 18:29:05 +01:00
|
|
|
ProjectFilePath reverseDefaultPaths(QString str) {
|
2022-09-01 17:14:47 +01:00
|
|
|
for (auto it = defaultPaths.constKeyValueBegin(); it != defaultPaths.constKeyValueEnd(); ++it) {
|
2022-09-01 18:03:11 +01:00
|
|
|
if ((*it).second.first == str) return (*it).first;
|
2022-09-01 17:14:47 +01:00
|
|
|
}
|
2022-09-01 18:29:05 +01:00
|
|
|
return static_cast<ProjectFilePath>(-1);
|
2022-09-01 17:14:47 +01:00
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
KeyValueConfigBase::~KeyValueConfigBase() {
|
2018-12-21 15:25:28 +00:00
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
}
|
2018-12-21 15:25:28 +00:00
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void KeyValueConfigBase::load() {
|
2020-04-07 19:44:14 +01:00
|
|
|
reset();
|
2018-12-25 21:26:13 +00:00
|
|
|
QFile file(this->getConfigFilepath());
|
2018-12-21 15:25:28 +00:00
|
|
|
if (!file.exists()) {
|
|
|
|
if (!file.open(QIODevice::WriteOnly)) {
|
2018-12-25 21:26:13 +00:00
|
|
|
logError(QString("Could not create config file '%1'").arg(this->getConfigFilepath()));
|
2018-12-21 15:25:28 +00:00
|
|
|
} else {
|
|
|
|
file.close();
|
2018-12-25 21:26:13 +00:00
|
|
|
this->onNewConfigFileCreated();
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
2018-12-25 21:26:13 +00:00
|
|
|
logError(QString("Could not open config file '%1': ").arg(this->getConfigFilepath()) + file.errorString());
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QTextStream in(&file);
|
|
|
|
QList<QString> configLines;
|
2022-11-23 03:57:26 +00:00
|
|
|
static const QRegularExpression re("^(?<key>[^=]+)=(?<value>.*)$");
|
2018-12-21 15:25:28 +00:00
|
|
|
while (!in.atEnd()) {
|
|
|
|
QString line = in.readLine().trimmed();
|
|
|
|
int commentIndex = line.indexOf("#");
|
|
|
|
if (commentIndex >= 0) {
|
|
|
|
line = line.left(commentIndex).trimmed();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.length() == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
QRegularExpressionMatch match = re.match(line);
|
|
|
|
if (!match.hasMatch()) {
|
2018-12-25 21:26:13 +00:00
|
|
|
logWarn(QString("Invalid config line in %1: '%2'").arg(this->getConfigFilepath()).arg(line));
|
2018-12-21 15:25:28 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-09-01 17:14:47 +01:00
|
|
|
this->parseConfigKeyValue(match.captured("key").trimmed().toLower(), match.captured("value").trimmed());
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
2020-05-26 22:01:18 +01:00
|
|
|
this->setUnreadKeys();
|
2022-09-26 18:31:10 +01:00
|
|
|
this->save();
|
2018-12-21 15:25:28 +00:00
|
|
|
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void KeyValueConfigBase::save() {
|
2023-08-24 02:07:13 +01:00
|
|
|
if (this->saveDisabled)
|
|
|
|
return;
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
QString text = "";
|
|
|
|
QMap<QString, QString> map = this->getKeyValueMap();
|
|
|
|
for (QMap<QString, QString>::iterator it = map.begin(); it != map.end(); it++) {
|
|
|
|
text += QString("%1=%2\n").arg(it.key()).arg(it.value());
|
|
|
|
}
|
|
|
|
|
2018-12-25 21:26:13 +00:00
|
|
|
QFile file(this->getConfigFilepath());
|
2018-12-25 20:41:06 +00:00
|
|
|
if (file.open(QIODevice::WriteOnly)) {
|
|
|
|
file.write(text.toUtf8());
|
|
|
|
file.close();
|
|
|
|
} else {
|
2018-12-25 21:26:13 +00:00
|
|
|
logError(QString("Could not open config file '%1' for writing: ").arg(this->getConfigFilepath()) + file.errorString());
|
2018-12-25 20:41:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-11 04:30:28 +01:00
|
|
|
bool KeyValueConfigBase::getConfigBool(QString key, QString value) {
|
2022-07-04 20:23:43 +01:00
|
|
|
bool ok;
|
2022-10-28 17:40:36 +01:00
|
|
|
int result = value.toInt(&ok, 0);
|
2022-09-11 04:30:28 +01:00
|
|
|
if (!ok || (result != 0 && result != 1)) {
|
2022-07-04 20:23:43 +01:00
|
|
|
logWarn(QString("Invalid config value for %1: '%2'. Must be 0 or 1.").arg(key).arg(value));
|
|
|
|
}
|
2022-09-11 04:30:28 +01:00
|
|
|
return (result != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int KeyValueConfigBase::getConfigInteger(QString key, QString value, int min, int max, int defaultValue) {
|
|
|
|
bool ok;
|
2022-10-25 22:51:32 +01:00
|
|
|
int result = value.toInt(&ok, 0);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for %1: '%2'. Must be an integer.").arg(key).arg(value));
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
return qMin(max, qMax(min, result));
|
|
|
|
}
|
|
|
|
|
2023-01-22 17:34:51 +00:00
|
|
|
uint32_t KeyValueConfigBase::getConfigUint32(QString key, QString value, uint32_t min, uint32_t max, uint32_t defaultValue) {
|
2022-10-25 22:51:32 +01:00
|
|
|
bool ok;
|
2023-01-22 17:34:51 +00:00
|
|
|
uint32_t result = value.toUInt(&ok, 0);
|
2022-09-11 04:30:28 +01:00
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for %1: '%2'. Must be an integer.").arg(key).arg(value));
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
return qMin(max, qMax(min, result));
|
2022-07-04 20:23:43 +01:00
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
// For temporarily disabling saving during frequent config changes.
|
|
|
|
void KeyValueConfigBase::setSaveDisabled(bool disabled) {
|
|
|
|
this->saveDisabled = disabled;
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
const QMap<MapSortOrder, QString> mapSortOrderMap = {
|
|
|
|
{MapSortOrder::Group, "group"},
|
|
|
|
{MapSortOrder::Layout, "layout"},
|
|
|
|
{MapSortOrder::Area, "area"},
|
|
|
|
};
|
|
|
|
|
|
|
|
const QMap<QString, MapSortOrder> mapSortOrderReverseMap = {
|
|
|
|
{"group", MapSortOrder::Group},
|
|
|
|
{"layout", MapSortOrder::Layout},
|
|
|
|
{"area", MapSortOrder::Area},
|
|
|
|
};
|
|
|
|
|
|
|
|
PorymapConfig porymapConfig;
|
|
|
|
|
2018-12-25 21:26:13 +00:00
|
|
|
QString PorymapConfig::getConfigFilepath() {
|
|
|
|
// porymap config file is in the same directory as porymap itself.
|
2018-12-27 01:18:33 +00:00
|
|
|
QString settingsPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
|
|
|
QDir dir(settingsPath);
|
|
|
|
if (!dir.exists())
|
|
|
|
dir.mkpath(settingsPath);
|
|
|
|
|
|
|
|
QString configPath = dir.absoluteFilePath("porymap.cfg");
|
|
|
|
|
|
|
|
return configPath;
|
2018-12-25 21:26:13 +00:00
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
2018-12-21 15:25:28 +00:00
|
|
|
if (key == "recent_project") {
|
2018-12-25 20:41:06 +00:00
|
|
|
this->recentProject = value;
|
2022-07-04 20:47:03 +01:00
|
|
|
} else if (key == "reopen_on_launch") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->reopenOnLaunch = getConfigBool(key, value);
|
2018-12-21 15:25:28 +00:00
|
|
|
} else if (key == "pretty_cursors") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->prettyCursors = getConfigBool(key, value);
|
2018-12-21 15:25:28 +00:00
|
|
|
} else if (key == "map_sort_order") {
|
|
|
|
QString sortOrder = value.toLower();
|
|
|
|
if (mapSortOrderReverseMap.contains(sortOrder)) {
|
2018-12-25 20:41:06 +00:00
|
|
|
this->mapSortOrder = mapSortOrderReverseMap.value(sortOrder);
|
2018-12-21 15:25:28 +00:00
|
|
|
} else {
|
2018-12-25 20:41:06 +00:00
|
|
|
this->mapSortOrder = MapSortOrder::Group;
|
2018-12-25 21:26:13 +00:00
|
|
|
logWarn(QString("Invalid config value for map_sort_order: '%1'. Must be 'group', 'area', or 'layout'.").arg(value));
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
2020-09-15 19:57:46 +01:00
|
|
|
} else if (key == "main_window_geometry") {
|
|
|
|
this->mainWindowGeometry = bytesFromString(value);
|
|
|
|
} else if (key == "main_window_state") {
|
|
|
|
this->mainWindowState = bytesFromString(value);
|
2019-01-07 23:14:44 +00:00
|
|
|
} else if (key == "map_splitter_state") {
|
|
|
|
this->mapSplitterState = bytesFromString(value);
|
|
|
|
} else if (key == "main_splitter_state") {
|
|
|
|
this->mainSplitterState = bytesFromString(value);
|
2019-01-06 18:53:31 +00:00
|
|
|
} else if (key == "collision_opacity") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->collisionOpacity = getConfigInteger(key, value, 0, 100, 50);
|
2020-09-15 19:57:46 +01:00
|
|
|
} else if (key == "tileset_editor_geometry") {
|
|
|
|
this->tilesetEditorGeometry = bytesFromString(value);
|
|
|
|
} else if (key == "tileset_editor_state") {
|
|
|
|
this->tilesetEditorState = bytesFromString(value);
|
2020-09-16 02:43:52 +01:00
|
|
|
} else if (key == "palette_editor_geometry") {
|
|
|
|
this->paletteEditorGeometry = bytesFromString(value);
|
|
|
|
} else if (key == "palette_editor_state") {
|
|
|
|
this->paletteEditorState = bytesFromString(value);
|
2020-09-16 00:03:15 +01:00
|
|
|
} else if (key == "region_map_editor_geometry") {
|
|
|
|
this->regionMapEditorGeometry = bytesFromString(value);
|
|
|
|
} else if (key == "region_map_editor_state") {
|
|
|
|
this->regionMapEditorState = bytesFromString(value);
|
2023-08-29 02:02:52 +01:00
|
|
|
} else if (key == "project_settings_editor_geometry") {
|
|
|
|
this->projectSettingsEditorGeometry = bytesFromString(value);
|
|
|
|
} else if (key == "project_settings_editor_state") {
|
|
|
|
this->projectSettingsEditorState = bytesFromString(value);
|
2019-02-16 20:32:19 +00:00
|
|
|
} else if (key == "metatiles_zoom") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->metatilesZoom = getConfigInteger(key, value, 10, 100, 30);
|
2019-01-09 15:35:34 +00:00
|
|
|
} else if (key == "show_player_view") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->showPlayerView = getConfigBool(key, value);
|
2019-01-09 15:35:34 +00:00
|
|
|
} else if (key == "show_cursor_tile") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->showCursorTile = getConfigBool(key, value);
|
2021-11-08 03:00:20 +00:00
|
|
|
} else if (key == "show_border") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->showBorder = getConfigBool(key, value);
|
2021-11-08 03:00:20 +00:00
|
|
|
} else if (key == "show_grid") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->showGrid = getConfigBool(key, value);
|
2020-04-08 05:42:38 +01:00
|
|
|
} else if (key == "monitor_files") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->monitorFiles = getConfigBool(key, value);
|
2022-11-28 19:04:47 +00:00
|
|
|
} else if (key == "tileset_checkerboard_fill") {
|
|
|
|
this->tilesetCheckerboardFill = getConfigBool(key, value);
|
2019-08-14 23:02:00 +01:00
|
|
|
} else if (key == "theme") {
|
|
|
|
this->theme = value;
|
2020-12-01 12:12:32 +00:00
|
|
|
} else if (key == "text_editor_open_directory") {
|
|
|
|
this->textEditorOpenFolder = value;
|
|
|
|
} else if (key == "text_editor_goto_line") {
|
|
|
|
this->textEditorGotoLine = value;
|
2023-02-22 16:21:30 +00:00
|
|
|
} else if (key == "palette_editor_bit_depth") {
|
|
|
|
this->paletteEditorBitDepth = getConfigInteger(key, value, 15, 24, 24);
|
|
|
|
if (this->paletteEditorBitDepth != 15 && this->paletteEditorBitDepth != 24){
|
|
|
|
this->paletteEditorBitDepth = 24;
|
|
|
|
}
|
2018-12-21 15:25:28 +00:00
|
|
|
} else {
|
2018-12-25 21:26:13 +00:00
|
|
|
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
QMap<QString, QString> PorymapConfig::getKeyValueMap() {
|
|
|
|
QMap<QString, QString> map;
|
|
|
|
map.insert("recent_project", this->recentProject);
|
2022-07-04 20:47:03 +01:00
|
|
|
map.insert("reopen_on_launch", this->reopenOnLaunch ? "1" : "0");
|
2018-12-25 20:41:06 +00:00
|
|
|
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
|
|
|
|
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
|
2020-09-15 19:57:46 +01:00
|
|
|
map.insert("main_window_geometry", stringFromByteArray(this->mainWindowGeometry));
|
|
|
|
map.insert("main_window_state", stringFromByteArray(this->mainWindowState));
|
2019-01-07 23:14:44 +00:00
|
|
|
map.insert("map_splitter_state", stringFromByteArray(this->mapSplitterState));
|
|
|
|
map.insert("main_splitter_state", stringFromByteArray(this->mainSplitterState));
|
2020-09-15 19:57:46 +01:00
|
|
|
map.insert("tileset_editor_geometry", stringFromByteArray(this->tilesetEditorGeometry));
|
|
|
|
map.insert("tileset_editor_state", stringFromByteArray(this->tilesetEditorState));
|
2020-09-16 02:43:52 +01:00
|
|
|
map.insert("palette_editor_geometry", stringFromByteArray(this->paletteEditorGeometry));
|
|
|
|
map.insert("palette_editor_state", stringFromByteArray(this->paletteEditorState));
|
2020-09-16 00:03:15 +01:00
|
|
|
map.insert("region_map_editor_geometry", stringFromByteArray(this->regionMapEditorGeometry));
|
|
|
|
map.insert("region_map_editor_state", stringFromByteArray(this->regionMapEditorState));
|
2023-08-29 02:02:52 +01:00
|
|
|
map.insert("project_settings_editor_geometry", stringFromByteArray(this->projectSettingsEditorGeometry));
|
|
|
|
map.insert("project_settings_editor_state", stringFromByteArray(this->projectSettingsEditorState));
|
2019-01-06 18:53:31 +00:00
|
|
|
map.insert("collision_opacity", QString("%1").arg(this->collisionOpacity));
|
2019-02-16 20:32:19 +00:00
|
|
|
map.insert("metatiles_zoom", QString("%1").arg(this->metatilesZoom));
|
2019-01-09 15:35:34 +00:00
|
|
|
map.insert("show_player_view", this->showPlayerView ? "1" : "0");
|
|
|
|
map.insert("show_cursor_tile", this->showCursorTile ? "1" : "0");
|
2021-11-08 03:00:20 +00:00
|
|
|
map.insert("show_border", this->showBorder ? "1" : "0");
|
|
|
|
map.insert("show_grid", this->showGrid ? "1" : "0");
|
2020-04-08 05:42:38 +01:00
|
|
|
map.insert("monitor_files", this->monitorFiles ? "1" : "0");
|
2022-11-28 19:04:47 +00:00
|
|
|
map.insert("tileset_checkerboard_fill", this->tilesetCheckerboardFill ? "1" : "0");
|
2019-08-14 23:02:00 +01:00
|
|
|
map.insert("theme", this->theme);
|
2020-12-01 12:12:32 +00:00
|
|
|
map.insert("text_editor_open_directory", this->textEditorOpenFolder);
|
|
|
|
map.insert("text_editor_goto_line", this->textEditorGotoLine);
|
2023-02-22 16:21:30 +00:00
|
|
|
map.insert("palette_editor_bit_depth", QString("%1").arg(this->paletteEditorBitDepth));
|
2022-09-01 17:14:47 +01:00
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
return map;
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 23:14:44 +00:00
|
|
|
QString PorymapConfig::stringFromByteArray(QByteArray bytearray) {
|
|
|
|
QString ret;
|
|
|
|
for (auto ch : bytearray) {
|
|
|
|
ret += QString::number(static_cast<int>(ch)) + ":";
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray PorymapConfig::bytesFromString(QString in) {
|
|
|
|
QByteArray ba;
|
|
|
|
QStringList split = in.split(":");
|
|
|
|
for (auto ch : split) {
|
|
|
|
ba.append(static_cast<char>(ch.toInt()));
|
|
|
|
}
|
|
|
|
return ba;
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void PorymapConfig::setRecentProject(QString project) {
|
|
|
|
this->recentProject = project;
|
|
|
|
this->save();
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2022-07-04 20:47:03 +01:00
|
|
|
void PorymapConfig::setReopenOnLaunch(bool enabled) {
|
|
|
|
this->reopenOnLaunch = enabled;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void PorymapConfig::setMapSortOrder(MapSortOrder order) {
|
|
|
|
this->mapSortOrder = order;
|
|
|
|
this->save();
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void PorymapConfig::setPrettyCursors(bool enabled) {
|
|
|
|
this->prettyCursors = enabled;
|
|
|
|
this->save();
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2020-04-08 05:42:38 +01:00
|
|
|
void PorymapConfig::setMonitorFiles(bool monitor) {
|
|
|
|
this->monitorFiles = monitor;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-11-28 19:04:47 +00:00
|
|
|
void PorymapConfig::setTilesetCheckerboardFill(bool checkerboard) {
|
|
|
|
this->tilesetCheckerboardFill = checkerboard;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2020-09-15 19:57:46 +01:00
|
|
|
void PorymapConfig::setMainGeometry(QByteArray mainWindowGeometry_, QByteArray mainWindowState_,
|
2019-11-02 01:19:39 +00:00
|
|
|
QByteArray mapSplitterState_, QByteArray mainSplitterState_) {
|
2020-09-15 19:57:46 +01:00
|
|
|
this->mainWindowGeometry = mainWindowGeometry_;
|
|
|
|
this->mainWindowState = mainWindowState_;
|
2019-01-07 23:14:44 +00:00
|
|
|
this->mapSplitterState = mapSplitterState_;
|
|
|
|
this->mainSplitterState = mainSplitterState_;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2020-09-15 19:57:46 +01:00
|
|
|
void PorymapConfig::setTilesetEditorGeometry(QByteArray tilesetEditorGeometry_, QByteArray tilesetEditorState_) {
|
|
|
|
this->tilesetEditorGeometry = tilesetEditorGeometry_;
|
|
|
|
this->tilesetEditorState = tilesetEditorState_;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2020-09-16 02:43:52 +01:00
|
|
|
void PorymapConfig::setPaletteEditorGeometry(QByteArray paletteEditorGeometry_, QByteArray paletteEditorState_) {
|
|
|
|
this->paletteEditorGeometry = paletteEditorGeometry_;
|
|
|
|
this->paletteEditorState = paletteEditorState_;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2020-09-16 00:03:15 +01:00
|
|
|
void PorymapConfig::setRegionMapEditorGeometry(QByteArray regionMapEditorGeometry_, QByteArray regionMapEditorState_) {
|
|
|
|
this->regionMapEditorGeometry = regionMapEditorGeometry_;
|
|
|
|
this->regionMapEditorState = regionMapEditorState_;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2023-08-29 02:02:52 +01:00
|
|
|
void PorymapConfig::setProjectSettingsEditorGeometry(QByteArray projectSettingsEditorGeometry_, QByteArray projectSettingsEditorState_) {
|
|
|
|
this->projectSettingsEditorGeometry = projectSettingsEditorGeometry_;
|
|
|
|
this->projectSettingsEditorState = projectSettingsEditorState_;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2019-01-06 18:53:31 +00:00
|
|
|
void PorymapConfig::setCollisionOpacity(int opacity) {
|
|
|
|
this->collisionOpacity = opacity;
|
|
|
|
// don't auto-save here because this can be called very frequently.
|
|
|
|
}
|
|
|
|
|
2019-02-16 20:32:19 +00:00
|
|
|
void PorymapConfig::setMetatilesZoom(int zoom) {
|
|
|
|
this->metatilesZoom = zoom;
|
|
|
|
// don't auto-save here because this can be called very frequently.
|
|
|
|
}
|
|
|
|
|
2019-01-09 15:35:34 +00:00
|
|
|
void PorymapConfig::setShowPlayerView(bool enabled) {
|
|
|
|
this->showPlayerView = enabled;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PorymapConfig::setShowCursorTile(bool enabled) {
|
|
|
|
this->showCursorTile = enabled;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2021-11-08 03:00:20 +00:00
|
|
|
void PorymapConfig::setShowBorder(bool enabled) {
|
|
|
|
this->showBorder = enabled;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PorymapConfig::setShowGrid(bool enabled) {
|
|
|
|
this->showGrid = enabled;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2019-08-14 23:02:00 +01:00
|
|
|
void PorymapConfig::setTheme(QString theme) {
|
|
|
|
this->theme = theme;
|
|
|
|
}
|
|
|
|
|
2020-12-01 12:12:32 +00:00
|
|
|
void PorymapConfig::setTextEditorOpenFolder(const QString &command) {
|
|
|
|
this->textEditorOpenFolder = command;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PorymapConfig::setTextEditorGotoLine(const QString &command) {
|
|
|
|
this->textEditorGotoLine = command;
|
2020-11-16 11:46:21 +00:00
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2023-02-22 16:21:30 +00:00
|
|
|
void PorymapConfig::setPaletteEditorBitDepth(int bitDepth) {
|
|
|
|
this->paletteEditorBitDepth = bitDepth;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
QString PorymapConfig::getRecentProject() {
|
|
|
|
return this->recentProject;
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2022-07-04 20:47:03 +01:00
|
|
|
bool PorymapConfig::getReopenOnLaunch() {
|
|
|
|
return this->reopenOnLaunch;
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
MapSortOrder PorymapConfig::getMapSortOrder() {
|
|
|
|
return this->mapSortOrder;
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
bool PorymapConfig::getPrettyCursors() {
|
|
|
|
return this->prettyCursors;
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
2018-12-25 21:26:13 +00:00
|
|
|
|
2020-09-15 19:57:46 +01:00
|
|
|
QMap<QString, QByteArray> PorymapConfig::getMainGeometry() {
|
2019-01-07 23:14:44 +00:00
|
|
|
QMap<QString, QByteArray> geometry;
|
|
|
|
|
2020-09-15 19:57:46 +01:00
|
|
|
geometry.insert("main_window_geometry", this->mainWindowGeometry);
|
|
|
|
geometry.insert("main_window_state", this->mainWindowState);
|
2019-01-07 23:14:44 +00:00
|
|
|
geometry.insert("map_splitter_state", this->mapSplitterState);
|
|
|
|
geometry.insert("main_splitter_state", this->mainSplitterState);
|
|
|
|
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
|
2020-09-15 19:57:46 +01:00
|
|
|
QMap<QString, QByteArray> PorymapConfig::getTilesetEditorGeometry() {
|
|
|
|
QMap<QString, QByteArray> geometry;
|
|
|
|
|
|
|
|
geometry.insert("tileset_editor_geometry", this->tilesetEditorGeometry);
|
|
|
|
geometry.insert("tileset_editor_state", this->tilesetEditorState);
|
|
|
|
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
|
2020-09-16 02:43:52 +01:00
|
|
|
QMap<QString, QByteArray> PorymapConfig::getPaletteEditorGeometry() {
|
|
|
|
QMap<QString, QByteArray> geometry;
|
|
|
|
|
|
|
|
geometry.insert("palette_editor_geometry", this->paletteEditorGeometry);
|
|
|
|
geometry.insert("palette_editor_state", this->paletteEditorState);
|
|
|
|
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
|
2020-09-16 00:03:15 +01:00
|
|
|
QMap<QString, QByteArray> PorymapConfig::getRegionMapEditorGeometry() {
|
|
|
|
QMap<QString, QByteArray> geometry;
|
|
|
|
|
|
|
|
geometry.insert("region_map_editor_geometry", this->regionMapEditorGeometry);
|
|
|
|
geometry.insert("region_map_editor_state", this->regionMapEditorState);
|
|
|
|
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
|
2023-08-29 02:02:52 +01:00
|
|
|
QMap<QString, QByteArray> PorymapConfig::getProjectSettingsEditorGeometry() {
|
|
|
|
QMap<QString, QByteArray> geometry;
|
|
|
|
|
|
|
|
geometry.insert("project_settings_editor_geometry", this->projectSettingsEditorGeometry);
|
|
|
|
geometry.insert("project_settings_editor_state", this->projectSettingsEditorState);
|
|
|
|
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
|
2019-01-06 18:53:31 +00:00
|
|
|
int PorymapConfig::getCollisionOpacity() {
|
|
|
|
return this->collisionOpacity;
|
|
|
|
}
|
|
|
|
|
2019-02-16 20:32:19 +00:00
|
|
|
int PorymapConfig::getMetatilesZoom() {
|
|
|
|
return this->metatilesZoom;
|
|
|
|
}
|
|
|
|
|
2019-01-09 15:35:34 +00:00
|
|
|
bool PorymapConfig::getShowPlayerView() {
|
|
|
|
return this->showPlayerView;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PorymapConfig::getShowCursorTile() {
|
|
|
|
return this->showCursorTile;
|
|
|
|
}
|
|
|
|
|
2021-11-08 03:00:20 +00:00
|
|
|
bool PorymapConfig::getShowBorder() {
|
|
|
|
return this->showBorder;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PorymapConfig::getShowGrid() {
|
|
|
|
return this->showGrid;
|
|
|
|
}
|
|
|
|
|
2020-04-08 05:42:38 +01:00
|
|
|
bool PorymapConfig::getMonitorFiles() {
|
|
|
|
return this->monitorFiles;
|
|
|
|
}
|
|
|
|
|
2022-11-28 19:04:47 +00:00
|
|
|
bool PorymapConfig::getTilesetCheckerboardFill() {
|
|
|
|
return this->tilesetCheckerboardFill;
|
|
|
|
}
|
|
|
|
|
2019-08-14 23:02:00 +01:00
|
|
|
QString PorymapConfig::getTheme() {
|
|
|
|
return this->theme;
|
|
|
|
}
|
|
|
|
|
2020-12-01 12:12:32 +00:00
|
|
|
QString PorymapConfig::getTextEditorOpenFolder() {
|
|
|
|
return this->textEditorOpenFolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString PorymapConfig::getTextEditorGotoLine() {
|
|
|
|
return this->textEditorGotoLine;
|
2020-11-16 11:46:21 +00:00
|
|
|
}
|
|
|
|
|
2023-02-22 16:21:30 +00:00
|
|
|
int PorymapConfig::getPaletteEditorBitDepth() {
|
|
|
|
return this->paletteEditorBitDepth;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
const QStringList ProjectConfig::versionStrings = {
|
2023-08-23 07:32:32 +01:00
|
|
|
"pokeruby",
|
|
|
|
"pokefirered",
|
|
|
|
"pokeemerald",
|
|
|
|
};
|
|
|
|
|
2018-12-25 21:26:13 +00:00
|
|
|
const QMap<BaseGameVersion, QString> baseGameVersionMap = {
|
2023-08-24 02:07:13 +01:00
|
|
|
{BaseGameVersion::pokeruby, ProjectConfig::versionStrings[0]},
|
|
|
|
{BaseGameVersion::pokefirered, ProjectConfig::versionStrings[1]},
|
|
|
|
{BaseGameVersion::pokeemerald, ProjectConfig::versionStrings[2]},
|
2018-12-25 21:26:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const QMap<QString, BaseGameVersion> baseGameVersionReverseMap = {
|
2023-08-24 02:07:13 +01:00
|
|
|
{ProjectConfig::versionStrings[0], BaseGameVersion::pokeruby},
|
|
|
|
{ProjectConfig::versionStrings[1], BaseGameVersion::pokefirered},
|
|
|
|
{ProjectConfig::versionStrings[2], BaseGameVersion::pokeemerald},
|
2018-12-25 21:26:13 +00:00
|
|
|
};
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
BaseGameVersion ProjectConfig::stringToBaseGameVersion(QString string, bool * ok) {
|
|
|
|
if (baseGameVersionReverseMap.contains(string)) {
|
|
|
|
if (ok) *ok = true;
|
|
|
|
return baseGameVersionReverseMap.value(string);
|
|
|
|
} else {
|
|
|
|
if (ok) *ok = false;
|
|
|
|
return BaseGameVersion::pokeemerald;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-25 21:26:13 +00:00
|
|
|
ProjectConfig projectConfig;
|
|
|
|
|
|
|
|
QString ProjectConfig::getConfigFilepath() {
|
|
|
|
// porymap config file is in the same directory as porymap itself.
|
2020-11-01 12:35:20 +00:00
|
|
|
return QDir(this->projectDir).filePath("porymap.project.cfg");
|
2018-12-25 21:26:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
|
|
|
if (key == "base_game_version") {
|
2023-08-24 02:07:13 +01:00
|
|
|
bool ok;
|
|
|
|
this->baseGameVersion = this->stringToBaseGameVersion(value.toLower(), &ok);
|
|
|
|
if (!ok)
|
2020-03-11 05:52:00 +00:00
|
|
|
logWarn(QString("Invalid config value for base_game_version: '%1'. Must be 'pokeruby', 'pokefirered' or 'pokeemerald'.").arg(value));
|
2020-03-13 06:23:47 +00:00
|
|
|
} else if (key == "use_poryscript") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->usePoryScript = getConfigBool(key, value);
|
2020-03-13 06:23:47 +00:00
|
|
|
} else if (key == "use_custom_border_size") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->useCustomBorderSize = getConfigBool(key, value);
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_event_weather_trigger") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableEventWeatherTrigger = getConfigBool(key, value);
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_event_secret_base") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableEventSecretBase = getConfigBool(key, value);
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_hidden_item_quantity") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableHiddenItemQuantity = getConfigBool(key, value);
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_hidden_item_requires_itemfinder") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableHiddenItemRequiresItemfinder = getConfigBool(key, value);
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_heal_location_respawn_data") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableHealLocationRespawnData = getConfigBool(key, value);
|
2022-10-23 22:22:19 +01:00
|
|
|
} else if (key == "enable_event_clone_object" || key == "enable_object_event_in_connection") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableEventCloneObject = getConfigBool(key, value);
|
2022-10-23 22:22:19 +01:00
|
|
|
key = "enable_event_clone_object"; // Backwards compatibiliy, replace old name above
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_floor_number") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableFloorNumber = getConfigBool(key, value);
|
2021-02-19 09:04:14 +00:00
|
|
|
} else if (key == "create_map_text_file") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->createMapTextFile = getConfigBool(key, value);
|
2020-06-25 06:32:42 +01:00
|
|
|
} else if (key == "enable_triple_layer_metatiles") {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->enableTripleLayerMetatiles = getConfigBool(key, value);
|
|
|
|
} else if (key == "new_map_metatile") {
|
2023-08-24 02:07:13 +01:00
|
|
|
this->newMapMetatileId = getConfigUint32(key, value, 0, 1023, 0);
|
2022-09-11 04:30:28 +01:00
|
|
|
} else if (key == "new_map_elevation") {
|
|
|
|
this->newMapElevation = getConfigInteger(key, value, 0, 15, 3);
|
|
|
|
} else if (key == "new_map_border_metatiles") {
|
|
|
|
this->newMapBorderMetatileIds.clear();
|
|
|
|
QList<QString> metatileIds = value.split(",");
|
2023-08-24 02:07:13 +01:00
|
|
|
for (int i = 0; i < metatileIds.size(); i++) {
|
|
|
|
// TODO: The max of 1023 here should eventually reflect Project::num_metatiles_total-1,
|
|
|
|
// but the config is parsed well before that constant is.
|
|
|
|
int metatileId = getConfigUint32(key, metatileIds.at(i), 0, 1023, 0);
|
2022-09-11 04:30:28 +01:00
|
|
|
this->newMapBorderMetatileIds.append(metatileId);
|
|
|
|
}
|
2022-10-24 00:28:55 +01:00
|
|
|
} else if (key == "default_primary_tileset") {
|
|
|
|
this->defaultPrimaryTileset = value;
|
|
|
|
} else if (key == "default_secondary_tileset") {
|
|
|
|
this->defaultSecondaryTileset = value;
|
2022-10-25 22:51:32 +01:00
|
|
|
} else if (key == "metatile_attributes_size") {
|
|
|
|
int size = getConfigInteger(key, value, 1, 4, 2);
|
|
|
|
if (size & (size - 1)) {
|
|
|
|
logWarn(QString("Invalid config value for %1: must be 1, 2, or 4").arg(key));
|
2022-10-26 05:14:55 +01:00
|
|
|
return; // Don't set a default now, it will be set later based on the base game version
|
2022-10-25 22:51:32 +01:00
|
|
|
}
|
|
|
|
this->metatileAttributesSize = size;
|
|
|
|
} else if (key == "metatile_behavior_mask") {
|
2023-01-22 17:34:51 +00:00
|
|
|
this->metatileBehaviorMask = getConfigUint32(key, value, 0, 0xFFFFFFFF, 0);
|
2022-10-25 22:51:32 +01:00
|
|
|
} else if (key == "metatile_terrain_type_mask") {
|
2023-01-22 17:34:51 +00:00
|
|
|
this->metatileTerrainTypeMask = getConfigUint32(key, value, 0, 0xFFFFFFFF, 0);
|
2022-10-25 22:51:32 +01:00
|
|
|
} else if (key == "metatile_encounter_type_mask") {
|
2023-01-22 17:34:51 +00:00
|
|
|
this->metatileEncounterTypeMask = getConfigUint32(key, value, 0, 0xFFFFFFFF, 0);
|
2022-10-25 22:51:32 +01:00
|
|
|
} else if (key == "metatile_layer_type_mask") {
|
2023-01-22 17:34:51 +00:00
|
|
|
this->metatileLayerTypeMask = getConfigUint32(key, value, 0, 0xFFFFFFFF, 0);
|
2022-10-26 08:56:46 +01:00
|
|
|
} else if (key == "enable_map_allow_flags") {
|
|
|
|
this->enableMapAllowFlags = getConfigBool(key, value);
|
2022-09-01 05:57:31 +01:00
|
|
|
#ifdef CONFIG_BACKWARDS_COMPATABILITY
|
|
|
|
} else if (key == "recent_map") {
|
|
|
|
userConfig.setRecentMap(value);
|
|
|
|
} else if (key == "use_encounter_json") {
|
2022-09-25 16:02:24 +01:00
|
|
|
userConfig.useEncounterJson = getConfigBool(key, value);
|
2020-05-08 17:26:23 +01:00
|
|
|
} else if (key == "custom_scripts") {
|
2022-09-01 05:57:31 +01:00
|
|
|
userConfig.customScripts.clear();
|
2020-05-08 17:26:23 +01:00
|
|
|
QList<QString> paths = value.split(",");
|
|
|
|
paths.removeDuplicates();
|
|
|
|
for (QString script : paths) {
|
|
|
|
if (!script.isEmpty()) {
|
2022-09-01 05:57:31 +01:00
|
|
|
userConfig.customScripts.append(script);
|
2020-05-08 17:26:23 +01:00
|
|
|
}
|
|
|
|
}
|
2022-09-01 05:57:31 +01:00
|
|
|
#endif
|
2022-09-01 17:14:47 +01:00
|
|
|
} else if (key.startsWith("path/")) {
|
|
|
|
auto k = reverseDefaultPaths(key.mid(5));
|
2022-09-01 18:29:05 +01:00
|
|
|
if (k != static_cast<ProjectFilePath>(-1)) {
|
2022-09-25 16:02:24 +01:00
|
|
|
this->setFilePath(k, value);
|
2022-09-01 17:14:47 +01:00
|
|
|
} else {
|
|
|
|
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
|
|
|
}
|
2022-09-06 02:51:31 +01:00
|
|
|
} else if (key == "prefabs_filepath") {
|
|
|
|
this->prefabFilepath = value;
|
2022-09-24 21:28:31 +01:00
|
|
|
} else if (key == "prefabs_import_prompted") {
|
2022-09-24 21:47:21 +01:00
|
|
|
this->prefabImportPrompted = getConfigBool(key, value);
|
2022-10-08 07:18:47 +01:00
|
|
|
} else if (key == "tilesets_have_callback") {
|
|
|
|
this->tilesetsHaveCallback = getConfigBool(key, value);
|
|
|
|
} else if (key == "tilesets_have_is_compressed") {
|
|
|
|
this->tilesetsHaveIsCompressed = getConfigBool(key, value);
|
2018-12-25 21:26:13 +00:00
|
|
|
} else {
|
|
|
|
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
|
|
|
}
|
2020-05-26 22:01:18 +01:00
|
|
|
readKeys.append(key);
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
// Restore config to version-specific defaults
|
|
|
|
void::ProjectConfig::reset(BaseGameVersion baseGameVersion) {
|
|
|
|
this->reset();
|
2023-08-29 02:02:52 +01:00
|
|
|
this->baseGameVersion = baseGameVersion;
|
2023-08-24 02:07:13 +01:00
|
|
|
this->setUnreadKeys();
|
|
|
|
}
|
|
|
|
|
2020-05-26 22:01:18 +01:00
|
|
|
void ProjectConfig::setUnreadKeys() {
|
|
|
|
// Set game-version specific defaults for any config field that wasn't read
|
|
|
|
bool isPokefirered = this->baseGameVersion == BaseGameVersion::pokefirered;
|
|
|
|
if (!readKeys.contains("use_custom_border_size")) this->useCustomBorderSize = isPokefirered;
|
|
|
|
if (!readKeys.contains("enable_event_weather_trigger")) this->enableEventWeatherTrigger = !isPokefirered;
|
|
|
|
if (!readKeys.contains("enable_event_secret_base")) this->enableEventSecretBase = !isPokefirered;
|
|
|
|
if (!readKeys.contains("enable_hidden_item_quantity")) this->enableHiddenItemQuantity = isPokefirered;
|
|
|
|
if (!readKeys.contains("enable_hidden_item_requires_itemfinder")) this->enableHiddenItemRequiresItemfinder = isPokefirered;
|
|
|
|
if (!readKeys.contains("enable_heal_location_respawn_data")) this->enableHealLocationRespawnData = isPokefirered;
|
2022-02-06 02:31:54 +00:00
|
|
|
if (!readKeys.contains("enable_event_clone_object")) this->enableEventCloneObject = isPokefirered;
|
2020-05-26 22:01:18 +01:00
|
|
|
if (!readKeys.contains("enable_floor_number")) this->enableFloorNumber = isPokefirered;
|
2021-02-19 09:04:14 +00:00
|
|
|
if (!readKeys.contains("create_map_text_file")) this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald);
|
2022-09-11 04:30:28 +01:00
|
|
|
if (!readKeys.contains("new_map_border_metatiles")) this->newMapBorderMetatileIds = isPokefirered ? DEFAULT_BORDER_FRLG : DEFAULT_BORDER_RSE;
|
2022-10-24 00:28:55 +01:00
|
|
|
if (!readKeys.contains("default_secondary_tileset")) this->defaultSecondaryTileset = isPokefirered ? "gTileset_PalletTown" : "gTileset_Petalburg";
|
2022-10-26 05:14:55 +01:00
|
|
|
if (!readKeys.contains("metatile_attributes_size")) this->metatileAttributesSize = Metatile::getDefaultAttributesSize(this->baseGameVersion);
|
2022-10-26 09:13:53 +01:00
|
|
|
if (!readKeys.contains("metatile_behavior_mask")) this->metatileBehaviorMask = Metatile::getBehaviorMask(this->baseGameVersion);
|
|
|
|
if (!readKeys.contains("metatile_terrain_type_mask")) this->metatileTerrainTypeMask = Metatile::getTerrainTypeMask(this->baseGameVersion);
|
|
|
|
if (!readKeys.contains("metatile_encounter_type_mask")) this->metatileEncounterTypeMask = Metatile::getEncounterTypeMask(this->baseGameVersion);
|
2023-08-23 07:32:32 +01:00
|
|
|
if (!readKeys.contains("metatile_layer_type_mask")) this->metatileLayerTypeMask = Metatile::getLayerTypeMask(this->baseGameVersion);
|
2022-10-26 08:56:46 +01:00
|
|
|
if (!readKeys.contains("enable_map_allow_flags")) this->enableMapAllowFlags = (this->baseGameVersion != BaseGameVersion::pokeruby);
|
2018-12-25 21:26:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QString, QString> ProjectConfig::getKeyValueMap() {
|
|
|
|
QMap<QString, QString> map;
|
|
|
|
map.insert("base_game_version", baseGameVersionMap.value(this->baseGameVersion));
|
2019-10-22 13:48:41 +01:00
|
|
|
map.insert("use_poryscript", QString::number(this->usePoryScript));
|
2020-03-13 06:23:47 +00:00
|
|
|
map.insert("use_custom_border_size", QString::number(this->useCustomBorderSize));
|
2020-05-22 22:51:56 +01:00
|
|
|
map.insert("enable_event_weather_trigger", QString::number(this->enableEventWeatherTrigger));
|
|
|
|
map.insert("enable_event_secret_base", QString::number(this->enableEventSecretBase));
|
|
|
|
map.insert("enable_hidden_item_quantity", QString::number(this->enableHiddenItemQuantity));
|
|
|
|
map.insert("enable_hidden_item_requires_itemfinder", QString::number(this->enableHiddenItemRequiresItemfinder));
|
|
|
|
map.insert("enable_heal_location_respawn_data", QString::number(this->enableHealLocationRespawnData));
|
2022-02-06 02:31:54 +00:00
|
|
|
map.insert("enable_event_clone_object", QString::number(this->enableEventCloneObject));
|
2020-05-22 22:51:56 +01:00
|
|
|
map.insert("enable_floor_number", QString::number(this->enableFloorNumber));
|
2021-02-19 09:04:14 +00:00
|
|
|
map.insert("create_map_text_file", QString::number(this->createMapTextFile));
|
2020-06-25 06:32:42 +01:00
|
|
|
map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles));
|
2023-08-24 02:07:13 +01:00
|
|
|
map.insert("new_map_metatile", Metatile::getMetatileIdString(this->newMapMetatileId));
|
2022-09-11 04:30:28 +01:00
|
|
|
map.insert("new_map_elevation", QString::number(this->newMapElevation));
|
2023-08-23 07:32:32 +01:00
|
|
|
map.insert("new_map_border_metatiles", this->getNewMapBorderMetatileIdsString());
|
2022-10-24 00:28:55 +01:00
|
|
|
map.insert("default_primary_tileset", this->defaultPrimaryTileset);
|
|
|
|
map.insert("default_secondary_tileset", this->defaultSecondaryTileset);
|
2022-09-06 02:51:31 +01:00
|
|
|
map.insert("prefabs_filepath", this->prefabFilepath);
|
2022-09-24 21:28:31 +01:00
|
|
|
map.insert("prefabs_import_prompted", QString::number(this->prefabImportPrompted));
|
2022-09-01 17:14:47 +01:00
|
|
|
for (auto it = this->filePaths.constKeyValueBegin(); it != this->filePaths.constKeyValueEnd(); ++it) {
|
2022-09-01 18:03:11 +01:00
|
|
|
map.insert("path/"+defaultPaths[(*it).first].first, (*it).second);
|
2022-09-01 17:14:47 +01:00
|
|
|
}
|
2022-10-08 07:18:47 +01:00
|
|
|
map.insert("tilesets_have_callback", QString::number(this->tilesetsHaveCallback));
|
|
|
|
map.insert("tilesets_have_is_compressed", QString::number(this->tilesetsHaveIsCompressed));
|
2022-10-25 22:51:32 +01:00
|
|
|
map.insert("metatile_attributes_size", QString::number(this->metatileAttributesSize));
|
2023-08-24 02:07:13 +01:00
|
|
|
map.insert("metatile_behavior_mask", "0x" + QString::number(this->metatileBehaviorMask, 16).toUpper());
|
|
|
|
map.insert("metatile_terrain_type_mask", "0x" + QString::number(this->metatileTerrainTypeMask, 16).toUpper());
|
|
|
|
map.insert("metatile_encounter_type_mask", "0x" + QString::number(this->metatileEncounterTypeMask, 16).toUpper());
|
|
|
|
map.insert("metatile_layer_type_mask", "0x" + QString::number(this->metatileLayerTypeMask, 16).toUpper());
|
2022-10-26 08:56:46 +01:00
|
|
|
map.insert("enable_map_allow_flags", QString::number(this->enableMapAllowFlags));
|
2018-12-25 21:26:13 +00:00
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::onNewConfigFileCreated() {
|
|
|
|
QString dirName = QDir(this->projectDir).dirName().toLower();
|
|
|
|
if (baseGameVersionReverseMap.contains(dirName)) {
|
|
|
|
this->baseGameVersion = baseGameVersionReverseMap.value(dirName);
|
|
|
|
logInfo(QString("Auto-detected base_game_version as '%1'").arg(dirName));
|
|
|
|
} else {
|
|
|
|
QDialog dialog(nullptr, Qt::WindowTitleHint);
|
|
|
|
dialog.setWindowTitle("Project Configuration");
|
|
|
|
dialog.setWindowModality(Qt::NonModal);
|
|
|
|
|
|
|
|
QFormLayout form(&dialog);
|
|
|
|
|
|
|
|
QComboBox *baseGameVersionComboBox = new QComboBox();
|
|
|
|
baseGameVersionComboBox->addItem("pokeruby", BaseGameVersion::pokeruby);
|
2020-03-11 05:52:00 +00:00
|
|
|
baseGameVersionComboBox->addItem("pokefirered", BaseGameVersion::pokefirered);
|
2018-12-25 21:26:13 +00:00
|
|
|
baseGameVersionComboBox->addItem("pokeemerald", BaseGameVersion::pokeemerald);
|
|
|
|
form.addRow(new QLabel("Game Version"), baseGameVersionComboBox);
|
|
|
|
|
|
|
|
QDialogButtonBox buttonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog);
|
2021-02-18 13:43:52 +00:00
|
|
|
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
2018-12-25 21:26:13 +00:00
|
|
|
form.addRow(&buttonBox);
|
|
|
|
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
|
|
this->baseGameVersion = static_cast<BaseGameVersion>(baseGameVersionComboBox->currentData().toInt());
|
|
|
|
}
|
|
|
|
}
|
2022-10-24 00:28:55 +01:00
|
|
|
this->setUnreadKeys(); // Initialize version-specific options
|
2018-12-25 21:26:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setProjectDir(QString projectDir) {
|
|
|
|
this->projectDir = projectDir;
|
|
|
|
}
|
|
|
|
|
2020-05-08 17:26:23 +01:00
|
|
|
QString ProjectConfig::getProjectDir() {
|
|
|
|
return this->projectDir;
|
|
|
|
}
|
|
|
|
|
2022-09-01 17:14:47 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-25 21:26:13 +00:00
|
|
|
void ProjectConfig::setBaseGameVersion(BaseGameVersion baseGameVersion) {
|
|
|
|
this->baseGameVersion = baseGameVersion;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
BaseGameVersion ProjectConfig::getBaseGameVersion() {
|
|
|
|
return this->baseGameVersion;
|
|
|
|
}
|
2019-07-03 21:21:48 +01:00
|
|
|
|
2021-12-15 04:50:56 +00:00
|
|
|
QString ProjectConfig::getBaseGameVersionString() {
|
|
|
|
return baseGameVersionMap.value(this->baseGameVersion);
|
|
|
|
}
|
|
|
|
|
2019-10-22 13:48:41 +01:00
|
|
|
void ProjectConfig::setUsePoryScript(bool usePoryScript) {
|
|
|
|
this->usePoryScript = usePoryScript;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getUsePoryScript() {
|
|
|
|
return this->usePoryScript;
|
|
|
|
}
|
2020-03-13 06:23:47 +00:00
|
|
|
|
|
|
|
void ProjectConfig::setUseCustomBorderSize(bool enable) {
|
|
|
|
this->useCustomBorderSize = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getUseCustomBorderSize() {
|
|
|
|
return this->useCustomBorderSize;
|
|
|
|
}
|
2020-05-08 17:26:23 +01:00
|
|
|
|
2020-05-22 22:51:56 +01:00
|
|
|
void ProjectConfig::setEventWeatherTriggerEnabled(bool enable) {
|
|
|
|
this->enableEventWeatherTrigger = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getEventWeatherTriggerEnabled() {
|
|
|
|
return this->enableEventWeatherTrigger;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setEventSecretBaseEnabled(bool enable) {
|
|
|
|
this->enableEventSecretBase = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getEventSecretBaseEnabled() {
|
|
|
|
return this->enableEventSecretBase;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setHiddenItemQuantityEnabled(bool enable) {
|
|
|
|
this->enableHiddenItemQuantity = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getHiddenItemQuantityEnabled() {
|
|
|
|
return this->enableHiddenItemQuantity;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setHiddenItemRequiresItemfinderEnabled(bool enable) {
|
|
|
|
this->enableHiddenItemRequiresItemfinder = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getHiddenItemRequiresItemfinderEnabled() {
|
|
|
|
return this->enableHiddenItemRequiresItemfinder;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setHealLocationRespawnDataEnabled(bool enable) {
|
|
|
|
this->enableHealLocationRespawnData = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getHealLocationRespawnDataEnabled() {
|
|
|
|
return this->enableHealLocationRespawnData;
|
|
|
|
}
|
|
|
|
|
2022-02-06 02:31:54 +00:00
|
|
|
void ProjectConfig::setEventCloneObjectEnabled(bool enable) {
|
|
|
|
this->enableEventCloneObject = enable;
|
2020-05-22 22:51:56 +01:00
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-02-06 02:31:54 +00:00
|
|
|
bool ProjectConfig::getEventCloneObjectEnabled() {
|
|
|
|
return this->enableEventCloneObject;
|
2020-05-22 22:51:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setFloorNumberEnabled(bool enable) {
|
|
|
|
this->enableFloorNumber = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getFloorNumberEnabled() {
|
|
|
|
return this->enableFloorNumber;
|
|
|
|
}
|
|
|
|
|
2021-02-19 09:04:14 +00:00
|
|
|
void ProjectConfig::setCreateMapTextFileEnabled(bool enable) {
|
|
|
|
this->createMapTextFile = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getCreateMapTextFileEnabled() {
|
|
|
|
return this->createMapTextFile;
|
|
|
|
}
|
|
|
|
|
2020-06-25 06:32:42 +01:00
|
|
|
void ProjectConfig::setTripleLayerMetatilesEnabled(bool enable) {
|
|
|
|
this->enableTripleLayerMetatiles = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getTripleLayerMetatilesEnabled() {
|
|
|
|
return this->enableTripleLayerMetatiles;
|
|
|
|
}
|
|
|
|
|
2022-10-04 02:28:16 +01:00
|
|
|
int ProjectConfig::getNumLayersInMetatile() {
|
|
|
|
return this->enableTripleLayerMetatiles ? 3 : 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ProjectConfig::getNumTilesInMetatile() {
|
|
|
|
return this->enableTripleLayerMetatiles ? 12 : 8;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
void ProjectConfig::setNewMapMetatileId(uint16_t metatileId) {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->newMapMetatileId = metatileId;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
uint16_t ProjectConfig::getNewMapMetatileId() {
|
2022-09-11 04:30:28 +01:00
|
|
|
return this->newMapMetatileId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setNewMapElevation(int elevation) {
|
|
|
|
this->newMapElevation = elevation;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
int ProjectConfig::getNewMapElevation() {
|
|
|
|
return this->newMapElevation;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
void ProjectConfig::setNewMapBorderMetatileIds(QList<uint16_t> metatileIds) {
|
2022-09-11 04:30:28 +01:00
|
|
|
this->newMapBorderMetatileIds = metatileIds;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
QList<uint16_t> ProjectConfig::getNewMapBorderMetatileIds() {
|
2022-09-11 04:30:28 +01:00
|
|
|
return this->newMapBorderMetatileIds;
|
|
|
|
}
|
|
|
|
|
2023-08-23 07:32:32 +01:00
|
|
|
QString ProjectConfig::getNewMapBorderMetatileIdsString() {
|
|
|
|
QStringList metatiles;
|
|
|
|
for (auto metatileId : this->newMapBorderMetatileIds){
|
2023-08-24 02:07:13 +01:00
|
|
|
metatiles << Metatile::getMetatileIdString(metatileId);
|
2023-08-23 07:32:32 +01:00
|
|
|
}
|
|
|
|
return metatiles.join(",");
|
|
|
|
}
|
|
|
|
|
2022-10-24 00:28:55 +01:00
|
|
|
QString ProjectConfig::getDefaultPrimaryTileset() {
|
|
|
|
return this->defaultPrimaryTileset;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ProjectConfig::getDefaultSecondaryTileset() {
|
|
|
|
return this->defaultSecondaryTileset;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
void ProjectConfig::setDefaultPrimaryTileset(QString tilesetName) {
|
|
|
|
this->defaultPrimaryTileset = tilesetName;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setDefaultSecondaryTileset(QString tilesetName) {
|
|
|
|
this->defaultSecondaryTileset = tilesetName;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-09-06 02:51:31 +01:00
|
|
|
void ProjectConfig::setPrefabFilepath(QString filepath) {
|
|
|
|
this->prefabFilepath = filepath;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-09-24 21:28:31 +01:00
|
|
|
QString ProjectConfig::getPrefabFilepath(bool setIfEmpty) {
|
|
|
|
if (setIfEmpty && this->prefabFilepath.isEmpty()) {
|
2022-09-11 16:19:13 +01:00
|
|
|
this->setPrefabFilepath("prefabs.json");
|
2022-09-10 14:54:16 +01:00
|
|
|
}
|
2022-09-06 02:51:31 +01:00
|
|
|
return this->prefabFilepath;
|
|
|
|
}
|
|
|
|
|
2022-09-24 21:28:31 +01:00
|
|
|
void ProjectConfig::setPrefabImportPrompted(bool prompted) {
|
|
|
|
this->prefabImportPrompted = prompted;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getPrefabImportPrompted() {
|
|
|
|
return this->prefabImportPrompted;
|
|
|
|
}
|
|
|
|
|
2022-10-08 07:18:47 +01:00
|
|
|
void ProjectConfig::setTilesetsHaveCallback(bool has) {
|
|
|
|
this->tilesetsHaveCallback = has;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getTilesetsHaveCallback() {
|
|
|
|
return this->tilesetsHaveCallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setTilesetsHaveIsCompressed(bool has) {
|
|
|
|
this->tilesetsHaveIsCompressed = has;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getTilesetsHaveIsCompressed() {
|
|
|
|
return this->tilesetsHaveIsCompressed;
|
|
|
|
}
|
|
|
|
|
2022-10-25 22:51:32 +01:00
|
|
|
int ProjectConfig::getMetatileAttributesSize() {
|
|
|
|
return this->metatileAttributesSize;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
void ProjectConfig::setMetatileAttributesSize(int size) {
|
|
|
|
this->metatileAttributesSize = size;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-10-25 22:51:32 +01:00
|
|
|
uint32_t ProjectConfig::getMetatileBehaviorMask() {
|
|
|
|
return this->metatileBehaviorMask;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ProjectConfig::getMetatileTerrainTypeMask() {
|
|
|
|
return this->metatileTerrainTypeMask;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ProjectConfig::getMetatileEncounterTypeMask() {
|
|
|
|
return this->metatileEncounterTypeMask;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ProjectConfig::getMetatileLayerTypeMask() {
|
|
|
|
return this->metatileLayerTypeMask;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
void ProjectConfig::setMetatileBehaviorMask(uint32_t mask) {
|
|
|
|
this->metatileBehaviorMask = mask;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setMetatileTerrainTypeMask(uint32_t mask) {
|
|
|
|
this->metatileTerrainTypeMask = mask;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setMetatileEncounterTypeMask(uint32_t mask) {
|
|
|
|
this->metatileEncounterTypeMask = mask;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setMetatileLayerTypeMask(uint32_t mask) {
|
|
|
|
this->metatileLayerTypeMask = mask;
|
|
|
|
this->save();
|
2023-08-23 07:32:32 +01:00
|
|
|
}
|
|
|
|
|
2022-10-26 08:56:46 +01:00
|
|
|
bool ProjectConfig::getMapAllowFlagsEnabled() {
|
|
|
|
return this->enableMapAllowFlags;
|
|
|
|
}
|
|
|
|
|
2023-08-24 02:07:13 +01:00
|
|
|
void ProjectConfig::setMapAllowFlagsEnabled(bool enabled) {
|
|
|
|
this->enableMapAllowFlags = enabled;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-09-25 16:02:24 +01:00
|
|
|
|
2022-09-01 05:57:31 +01:00
|
|
|
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") {
|
2022-09-25 16:02:24 +01:00
|
|
|
this->useEncounterJson = getConfigBool(key, value);
|
2022-09-01 05:57:31 +01:00
|
|
|
} else if (key == "custom_scripts") {
|
|
|
|
this->customScripts.clear();
|
|
|
|
QList<QString> 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<QString, QString> UserConfig::getKeyValueMap() {
|
|
|
|
QMap<QString, QString> 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<QString> scripts) {
|
2020-05-08 17:26:23 +01:00
|
|
|
this->customScripts = scripts;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
2022-09-01 05:57:31 +01:00
|
|
|
QList<QString> UserConfig::getCustomScripts() {
|
2020-05-08 17:26:23 +01:00
|
|
|
return this->customScripts;
|
|
|
|
}
|
2020-11-01 12:35:20 +00:00
|
|
|
|
|
|
|
ShortcutsConfig shortcutsConfig;
|
|
|
|
|
|
|
|
QString ShortcutsConfig::getConfigFilepath() {
|
|
|
|
QString settingsPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
|
|
|
QDir dir(settingsPath);
|
|
|
|
if (!dir.exists())
|
|
|
|
dir.mkpath(settingsPath);
|
|
|
|
|
|
|
|
QString configPath = dir.absoluteFilePath("porymap.shortcuts.cfg");
|
|
|
|
|
|
|
|
return configPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShortcutsConfig::parseConfigKeyValue(QString key, QString value) {
|
2020-11-03 10:58:10 +00:00
|
|
|
QStringList keySequences = value.split(' ');
|
|
|
|
for (auto keySequence : keySequences)
|
2020-11-08 13:36:02 +00:00
|
|
|
user_shortcuts.insert(key, keySequence);
|
2020-11-01 12:35:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QString, QString> ShortcutsConfig::getKeyValueMap() {
|
|
|
|
QMap<QString, QString> map;
|
2020-11-08 13:36:02 +00:00
|
|
|
for (auto cfg_key : user_shortcuts.uniqueKeys()) {
|
|
|
|
auto keySequences = user_shortcuts.values(cfg_key);
|
2020-11-13 04:48:03 +00:00
|
|
|
QStringList keySequenceStrings;
|
2020-11-03 10:58:10 +00:00
|
|
|
for (auto keySequence : keySequences)
|
2020-11-13 04:48:03 +00:00
|
|
|
keySequenceStrings.append(keySequence.toString());
|
|
|
|
map.insert(cfg_key, keySequenceStrings.join(' '));
|
2020-11-01 12:35:20 +00:00
|
|
|
}
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
void ShortcutsConfig::setDefaultShortcuts(const QObjectList &objects) {
|
|
|
|
storeShortcutsFromList(StoreType::Default, objects);
|
2020-11-05 11:32:31 +00:00
|
|
|
save();
|
|
|
|
}
|
2020-11-03 10:58:10 +00:00
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
QList<QKeySequence> ShortcutsConfig::defaultShortcuts(const QObject *object) const {
|
|
|
|
return default_shortcuts.values(cfgKey(object));
|
2020-11-03 10:58:10 +00:00
|
|
|
}
|
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
void ShortcutsConfig::setUserShortcuts(const QObjectList &objects) {
|
|
|
|
storeShortcutsFromList(StoreType::User, objects);
|
2020-11-05 11:32:31 +00:00
|
|
|
save();
|
|
|
|
}
|
2020-11-03 10:58:10 +00:00
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
void ShortcutsConfig::setUserShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences) {
|
|
|
|
for (auto *object : objects_keySequences.uniqueKeys())
|
2020-11-13 04:48:03 +00:00
|
|
|
if (!object->objectName().isEmpty() && !object->objectName().startsWith("_q_"))
|
|
|
|
storeShortcuts(StoreType::User, cfgKey(object), objects_keySequences.values(object));
|
2020-11-05 11:32:31 +00:00
|
|
|
save();
|
|
|
|
}
|
2020-11-03 10:58:10 +00:00
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
QList<QKeySequence> ShortcutsConfig::userShortcuts(const QObject *object) const {
|
|
|
|
return user_shortcuts.values(cfgKey(object));
|
2020-11-05 11:32:31 +00:00
|
|
|
}
|
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
void ShortcutsConfig::storeShortcutsFromList(StoreType storeType, const QObjectList &objects) {
|
|
|
|
for (const auto *object : objects)
|
2020-11-13 04:48:03 +00:00
|
|
|
if (!object->objectName().isEmpty() && !object->objectName().startsWith("_q_"))
|
2020-11-08 13:36:02 +00:00
|
|
|
storeShortcuts(storeType, cfgKey(object), currentShortcuts(object));
|
2020-11-05 11:32:31 +00:00
|
|
|
}
|
|
|
|
|
2020-11-08 13:36:02 +00:00
|
|
|
void ShortcutsConfig::storeShortcuts(
|
2020-11-05 11:32:31 +00:00
|
|
|
StoreType storeType,
|
|
|
|
const QString &cfgKey,
|
|
|
|
const QList<QKeySequence> &keySequences)
|
|
|
|
{
|
2020-11-08 13:36:02 +00:00
|
|
|
bool storeUser = (storeType == User) || !user_shortcuts.contains(cfgKey);
|
2020-11-05 11:32:31 +00:00
|
|
|
|
|
|
|
if (storeType == Default)
|
2020-11-08 13:36:02 +00:00
|
|
|
default_shortcuts.remove(cfgKey);
|
2020-11-05 11:32:31 +00:00
|
|
|
if (storeUser)
|
2020-11-08 13:36:02 +00:00
|
|
|
user_shortcuts.remove(cfgKey);
|
2020-11-05 11:32:31 +00:00
|
|
|
|
|
|
|
if (keySequences.isEmpty()) {
|
|
|
|
if (storeType == Default)
|
2020-11-08 13:36:02 +00:00
|
|
|
default_shortcuts.insert(cfgKey, QKeySequence());
|
2020-11-05 11:32:31 +00:00
|
|
|
if (storeUser)
|
2020-11-08 13:36:02 +00:00
|
|
|
user_shortcuts.insert(cfgKey, QKeySequence());
|
2020-11-05 11:32:31 +00:00
|
|
|
} else {
|
|
|
|
for (auto keySequence : keySequences) {
|
|
|
|
if (storeType == Default)
|
2020-11-08 13:36:02 +00:00
|
|
|
default_shortcuts.insert(cfgKey, keySequence);
|
2020-11-05 11:32:31 +00:00
|
|
|
if (storeUser)
|
2020-11-08 13:36:02 +00:00
|
|
|
user_shortcuts.insert(cfgKey, keySequence);
|
2020-11-05 11:32:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Creates a config key from the object's name prepended with the parent
|
|
|
|
* window's object name, and converts camelCase to snake_case. */
|
2020-11-08 13:36:02 +00:00
|
|
|
QString ShortcutsConfig::cfgKey(const QObject *object) const {
|
2020-11-05 11:32:31 +00:00
|
|
|
auto cfg_key = QString();
|
|
|
|
auto *parentWidget = static_cast<QWidget *>(object->parent());
|
|
|
|
if (parentWidget)
|
|
|
|
cfg_key = parentWidget->window()->objectName() + '_';
|
|
|
|
cfg_key += object->objectName();
|
|
|
|
|
2022-11-23 03:57:26 +00:00
|
|
|
static const QRegularExpression re("[A-Z]");
|
2020-11-08 13:36:02 +00:00
|
|
|
int i = cfg_key.indexOf(re, 1);
|
2020-11-01 12:35:20 +00:00
|
|
|
while (i != -1) {
|
2020-11-08 13:36:02 +00:00
|
|
|
if (cfg_key.at(i - 1) != '_')
|
2020-11-03 10:58:10 +00:00
|
|
|
cfg_key.insert(i++, '_');
|
|
|
|
i = cfg_key.indexOf(re, i + 1);
|
2020-11-01 12:35:20 +00:00
|
|
|
}
|
2020-11-03 10:58:10 +00:00
|
|
|
return cfg_key.toLower();
|
2020-11-01 12:35:20 +00:00
|
|
|
}
|
2020-11-08 13:36:02 +00:00
|
|
|
|
|
|
|
QList<QKeySequence> ShortcutsConfig::currentShortcuts(const QObject *object) const {
|
|
|
|
if (object->inherits("QAction")) {
|
|
|
|
const auto *action = qobject_cast<const QAction *>(object);
|
|
|
|
return action->shortcuts();
|
|
|
|
} else if (object->inherits("Shortcut")) {
|
|
|
|
const auto *shortcut = qobject_cast<const Shortcut *>(object);
|
|
|
|
return shortcut->keys();
|
|
|
|
} else if (object->inherits("QShortcut")) {
|
|
|
|
const auto *qshortcut = qobject_cast<const QShortcut *>(object);
|
|
|
|
return { qshortcut->key() };
|
|
|
|
} else if (object->property("shortcut").isValid()) {
|
|
|
|
return { object->property("shortcut").value<QKeySequence>() };
|
|
|
|
} else {
|
|
|
|
return { };
|
|
|
|
}
|
|
|
|
}
|