2018-12-21 15:25:28 +00:00
|
|
|
#include "config.h"
|
|
|
|
#include "log.h"
|
|
|
|
#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>
|
2018-12-21 15:25:28 +00: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();
|
|
|
|
this->save();
|
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);
|
2019-02-09 20:27:45 +00:00
|
|
|
in.setCodec("UTF-8");
|
2018-12-21 15:25:28 +00:00
|
|
|
QList<QString> configLines;
|
2020-05-08 17:26:23 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
this->parseConfigKeyValue(match.captured("key").toLower(), match.captured("value"));
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
2020-05-26 22:01:18 +01:00
|
|
|
this->setUnreadKeys();
|
2018-12-21 15:25:28 +00:00
|
|
|
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void KeyValueConfigBase::save() {
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2018-12-21 15:25:28 +00:00
|
|
|
} else if (key == "recent_map") {
|
2018-12-25 20:41:06 +00:00
|
|
|
this->recentMap = value;
|
2018-12-21 15:25:28 +00:00
|
|
|
} else if (key == "pretty_cursors") {
|
|
|
|
bool ok;
|
2018-12-25 20:41:06 +00:00
|
|
|
this->prettyCursors = value.toInt(&ok);
|
2018-12-21 15:25:28 +00:00
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for pretty_cursors: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} 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
|
|
|
}
|
2019-01-07 23:14:44 +00:00
|
|
|
} else if (key == "window_geometry") {
|
|
|
|
this->windowGeometry = bytesFromString(value);
|
|
|
|
} else if (key == "window_state") {
|
|
|
|
this->windowState = bytesFromString(value);
|
|
|
|
} 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") {
|
|
|
|
bool ok;
|
|
|
|
this->collisionOpacity = qMax(0, qMin(100, value.toInt(&ok)));
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for collision_opacity: '%1'. Must be an integer.").arg(value));
|
|
|
|
this->collisionOpacity = 50;
|
|
|
|
}
|
2019-02-16 20:32:19 +00:00
|
|
|
} else if (key == "metatiles_zoom") {
|
|
|
|
bool ok;
|
|
|
|
this->metatilesZoom = qMax(10, qMin(100, value.toInt(&ok)));
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for metatiles_zoom: '%1'. Must be an integer.").arg(value));
|
|
|
|
this->metatilesZoom = 30;
|
|
|
|
}
|
2019-01-09 15:35:34 +00:00
|
|
|
} else if (key == "show_player_view") {
|
|
|
|
bool ok;
|
|
|
|
this->showPlayerView = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for show_player_view: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "show_cursor_tile") {
|
|
|
|
bool ok;
|
|
|
|
this->showCursorTile = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for show_cursor_tile: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
2020-04-08 05:42:38 +01:00
|
|
|
} else if (key == "monitor_files") {
|
|
|
|
bool ok;
|
2020-04-21 03:02:14 +01:00
|
|
|
this->monitorFiles = value.toInt(&ok);
|
2020-04-08 05:42:38 +01:00
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for monitor_files: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
2019-01-15 22:06:18 +00:00
|
|
|
} else if (key == "region_map_dimensions") {
|
|
|
|
bool ok1, ok2;
|
|
|
|
QStringList dims = value.split("x");
|
|
|
|
int w = dims[0].toInt(&ok1);
|
|
|
|
int h = dims[1].toInt(&ok2);
|
|
|
|
if (!ok1 || !ok2) {
|
|
|
|
logWarn("Cannot parse region map dimensions. Using default values instead.");
|
|
|
|
this->regionMapDimensions = QSize(32, 20);
|
|
|
|
} else {
|
|
|
|
this->regionMapDimensions = QSize(w, h);
|
|
|
|
}
|
2019-08-14 23:02:00 +01:00
|
|
|
} else if (key == "theme") {
|
|
|
|
this->theme = value;
|
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);
|
|
|
|
map.insert("recent_map", this->recentMap);
|
|
|
|
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
|
|
|
|
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
|
2019-01-07 23:14:44 +00:00
|
|
|
map.insert("window_geometry", stringFromByteArray(this->windowGeometry));
|
|
|
|
map.insert("window_state", stringFromByteArray(this->windowState));
|
|
|
|
map.insert("map_splitter_state", stringFromByteArray(this->mapSplitterState));
|
|
|
|
map.insert("main_splitter_state", stringFromByteArray(this->mainSplitterState));
|
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");
|
2020-04-08 05:42:38 +01:00
|
|
|
map.insert("monitor_files", this->monitorFiles ? "1" : "0");
|
2019-01-15 22:06:18 +00:00
|
|
|
map.insert("region_map_dimensions", QString("%1x%2").arg(this->regionMapDimensions.width())
|
|
|
|
.arg(this->regionMapDimensions.height()));
|
2019-08-14 23:02:00 +01:00
|
|
|
map.insert("theme", this->theme);
|
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
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
void PorymapConfig::setRecentMap(QString map) {
|
|
|
|
this->recentMap = map;
|
|
|
|
this->save();
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2019-11-02 01:19:39 +00:00
|
|
|
void PorymapConfig::setGeometry(QByteArray windowGeometry_, QByteArray windowState_,
|
|
|
|
QByteArray mapSplitterState_, QByteArray mainSplitterState_) {
|
2019-01-07 23:14:44 +00:00
|
|
|
this->windowGeometry = windowGeometry_;
|
|
|
|
this->windowState = windowState_;
|
|
|
|
this->mapSplitterState = mapSplitterState_;
|
|
|
|
this->mainSplitterState = mainSplitterState_;
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2019-01-15 22:06:18 +00:00
|
|
|
void PorymapConfig::setRegionMapDimensions(int width, int height) {
|
2019-02-25 18:31:34 +00:00
|
|
|
this->regionMapDimensions = QSize(width, height);
|
2019-01-15 22:06:18 +00:00
|
|
|
}
|
|
|
|
|
2019-08-14 23:02:00 +01:00
|
|
|
void PorymapConfig::setTheme(QString theme) {
|
|
|
|
this->theme = theme;
|
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
QString PorymapConfig::getRecentProject() {
|
|
|
|
return this->recentProject;
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-25 20:41:06 +00:00
|
|
|
QString PorymapConfig::getRecentMap() {
|
|
|
|
return this->recentMap;
|
2018-12-21 15:25:28 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2019-01-07 23:14:44 +00:00
|
|
|
QMap<QString, QByteArray> PorymapConfig::getGeometry() {
|
|
|
|
QMap<QString, QByteArray> geometry;
|
|
|
|
|
|
|
|
geometry.insert("window_geometry", this->windowGeometry);
|
|
|
|
geometry.insert("window_state", this->windowState);
|
|
|
|
geometry.insert("map_splitter_state", this->mapSplitterState);
|
|
|
|
geometry.insert("main_splitter_state", this->mainSplitterState);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-04-08 05:42:38 +01:00
|
|
|
bool PorymapConfig::getMonitorFiles() {
|
|
|
|
return this->monitorFiles;
|
|
|
|
}
|
|
|
|
|
2019-01-15 22:06:18 +00:00
|
|
|
QSize PorymapConfig::getRegionMapDimensions() {
|
|
|
|
return this->regionMapDimensions;
|
|
|
|
}
|
|
|
|
|
2019-08-14 23:02:00 +01:00
|
|
|
QString PorymapConfig::getTheme() {
|
|
|
|
return this->theme;
|
|
|
|
}
|
|
|
|
|
2018-12-25 21:26:13 +00:00
|
|
|
const QMap<BaseGameVersion, QString> baseGameVersionMap = {
|
|
|
|
{BaseGameVersion::pokeruby, "pokeruby"},
|
2020-03-11 05:52:00 +00:00
|
|
|
{BaseGameVersion::pokefirered, "pokefirered"},
|
2018-12-25 21:26:13 +00:00
|
|
|
{BaseGameVersion::pokeemerald, "pokeemerald"},
|
|
|
|
};
|
|
|
|
|
|
|
|
const QMap<QString, BaseGameVersion> baseGameVersionReverseMap = {
|
|
|
|
{"pokeruby", BaseGameVersion::pokeruby},
|
2020-03-11 05:52:00 +00:00
|
|
|
{"pokefirered", BaseGameVersion::pokefirered},
|
2018-12-25 21:26:13 +00:00
|
|
|
{"pokeemerald", BaseGameVersion::pokeemerald},
|
|
|
|
};
|
|
|
|
|
|
|
|
ProjectConfig projectConfig;
|
|
|
|
|
|
|
|
QString ProjectConfig::getConfigFilepath() {
|
|
|
|
// porymap config file is in the same directory as porymap itself.
|
|
|
|
return QDir(this->projectDir).filePath("porymap.project.cfg");;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
|
|
|
if (key == "base_game_version") {
|
|
|
|
QString baseGameVersion = value.toLower();
|
|
|
|
if (baseGameVersionReverseMap.contains(baseGameVersion)) {
|
|
|
|
this->baseGameVersion = baseGameVersionReverseMap.value(baseGameVersion);
|
|
|
|
} else {
|
|
|
|
this->baseGameVersion = BaseGameVersion::pokeemerald;
|
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));
|
2018-12-25 21:26:13 +00:00
|
|
|
}
|
2019-07-03 21:21:48 +01:00
|
|
|
} else if (key == "use_encounter_json") {
|
|
|
|
bool ok;
|
|
|
|
this->useEncounterJson = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for use_encounter_json: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
2020-03-13 06:23:47 +00:00
|
|
|
} else if (key == "use_poryscript") {
|
2019-10-22 13:48:41 +01:00
|
|
|
bool ok;
|
|
|
|
this->usePoryScript = value.toInt(&ok);
|
2020-03-13 06:23:47 +00:00
|
|
|
if (!ok) {
|
2019-10-22 13:48:41 +01:00
|
|
|
logWarn(QString("Invalid config value for use_poryscript: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
2020-03-13 06:23:47 +00:00
|
|
|
} else if (key == "use_custom_border_size") {
|
|
|
|
bool ok;
|
|
|
|
this->useCustomBorderSize = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for use_custom_border_size: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
2020-05-22 22:51:56 +01:00
|
|
|
} else if (key == "enable_event_weather_trigger") {
|
|
|
|
bool ok;
|
|
|
|
this->enableEventWeatherTrigger = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_event_weather_trigger: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "enable_event_secret_base") {
|
|
|
|
bool ok;
|
|
|
|
this->enableEventSecretBase = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_event_secret_base: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "enable_hidden_item_quantity") {
|
|
|
|
bool ok;
|
|
|
|
this->enableHiddenItemQuantity = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_hidden_item_quantity: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "enable_hidden_item_requires_itemfinder") {
|
|
|
|
bool ok;
|
|
|
|
this->enableHiddenItemRequiresItemfinder = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_hidden_item_requires_itemfinder: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "enable_heal_location_respawn_data") {
|
|
|
|
bool ok;
|
|
|
|
this->enableHealLocationRespawnData = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_heal_location_respawn_data: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "enable_object_event_in_connection") {
|
|
|
|
bool ok;
|
|
|
|
this->enableObjectEventInConnection = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_object_event_in_connection: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
|
|
|
} else if (key == "enable_floor_number") {
|
|
|
|
bool ok;
|
|
|
|
this->enableFloorNumber = value.toInt(&ok);
|
|
|
|
if (!ok) {
|
|
|
|
logWarn(QString("Invalid config value for enable_floor_number: '%1'. Must be 0 or 1.").arg(value));
|
|
|
|
}
|
2020-05-08 17:26:23 +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);
|
|
|
|
}
|
|
|
|
}
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
if (!readKeys.contains("enable_object_event_in_connection")) this->enableObjectEventInConnection = isPokefirered;
|
|
|
|
if (!readKeys.contains("enable_floor_number")) this->enableFloorNumber = isPokefirered;
|
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-07-03 21:21:48 +01:00
|
|
|
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
|
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));
|
|
|
|
map.insert("enable_object_event_in_connection", QString::number(this->enableObjectEventInConnection));
|
|
|
|
map.insert("enable_floor_number", QString::number(this->enableFloorNumber));
|
2020-05-08 17:26:23 +01:00
|
|
|
map.insert("custom_scripts", this->customScripts.join(","));
|
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);
|
|
|
|
connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
|
|
|
|
form.addRow(&buttonBox);
|
|
|
|
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
|
|
this->baseGameVersion = static_cast<BaseGameVersion>(baseGameVersionComboBox->currentData().toInt());
|
|
|
|
}
|
|
|
|
}
|
2020-05-22 22:51:56 +01:00
|
|
|
bool isPokefirered = this->baseGameVersion == BaseGameVersion::pokefirered;
|
|
|
|
this->useCustomBorderSize = isPokefirered;
|
|
|
|
this->enableEventWeatherTrigger = !isPokefirered;
|
|
|
|
this->enableEventSecretBase = !isPokefirered;
|
|
|
|
this->enableHiddenItemQuantity = isPokefirered;
|
|
|
|
this->enableHiddenItemRequiresItemfinder = isPokefirered;
|
|
|
|
this->enableHealLocationRespawnData = isPokefirered;
|
|
|
|
this->enableObjectEventInConnection = isPokefirered;
|
|
|
|
this->enableFloorNumber = isPokefirered;
|
2019-07-03 21:21:48 +01:00
|
|
|
this->useEncounterJson = true;
|
2019-10-22 13:48:41 +01:00
|
|
|
this->usePoryScript = false;
|
2020-05-08 17:26:23 +01:00
|
|
|
this->customScripts.clear();
|
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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
void ProjectConfig::setEncounterJsonActive(bool active) {
|
|
|
|
this->useEncounterJson = active;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getEncounterJsonActive() {
|
|
|
|
return this->useEncounterJson;
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setObjectEventInConnectionEnabled(bool enable) {
|
|
|
|
this->enableObjectEventInConnection = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getObjectEventInConnectionEnabled() {
|
|
|
|
return this->enableObjectEventInConnection;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectConfig::setFloorNumberEnabled(bool enable) {
|
|
|
|
this->enableFloorNumber = enable;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectConfig::getFloorNumberEnabled() {
|
|
|
|
return this->enableFloorNumber;
|
|
|
|
}
|
|
|
|
|
2020-05-08 17:26:23 +01:00
|
|
|
void ProjectConfig::setCustomScripts(QList<QString> scripts) {
|
|
|
|
this->customScripts = scripts;
|
|
|
|
this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<QString> ProjectConfig::getCustomScripts() {
|
|
|
|
return this->customScripts;
|
|
|
|
}
|