diff --git a/include/lib/orderedjson.h b/include/lib/orderedjson.h index cb5139d3..ddd64d56 100644 --- a/include/lib/orderedjson.h +++ b/include/lib/orderedjson.h @@ -183,6 +183,12 @@ public: // Return a reference to obj[key] if this is an object, Json() otherwise. const Json & operator[](const QString &key) const; + // Equivalent to string_value(), int_value(), and bool_value(), + // but will attempt to convert the internal value if it's of a different type. + QString toString() const; + int toInt() const; + bool toBool() const; + // Serialize. void dump(QString &out, int *) const; QString dump(int *indent = nullptr) const { @@ -251,8 +257,11 @@ protected: virtual void dump(QString &out, int *indent) const = 0; virtual double number_value() const; virtual int int_value() const; + virtual int toInt() const; virtual bool bool_value() const; + virtual bool toBool() const; virtual const QString &string_value() const; + virtual QString toString() const; virtual const Json::array &array_items() const; virtual const Json &operator[](int i) const; virtual const Json::object &object_items() const; diff --git a/src/core/regionmap.cpp b/src/core/regionmap.cpp index a16d3b54..53450be9 100644 --- a/src/core/regionmap.cpp +++ b/src/core/regionmap.cpp @@ -27,7 +27,7 @@ RegionMap::RegionMap(Project *project) : bool RegionMap::loadMapData(poryjson::Json data) { poryjson::Json::object mapObject = data.object_items(); - this->alias = mapObject["alias"].string_value(); + this->alias = mapObject["alias"].toString(); poryjson::Json tilemapJson = mapObject["tilemap"]; poryjson::Json layoutJson = mapObject["layout"]; @@ -63,19 +63,19 @@ bool RegionMap::loadTilemap(poryjson::Json tilemapJson) { poryjson::Json::object tilemapObject = tilemapJson.object_items(); - this->tilemap_width = tilemapObject["width"].int_value(); - this->tilemap_height = tilemapObject["height"].int_value(); + this->tilemap_width = tilemapObject["width"].toInt(); + this->tilemap_height = tilemapObject["height"].toInt(); - QString tilemapFormat = tilemapObject["format"].string_value(); + QString tilemapFormat = tilemapObject["format"].toString(); QMap formatsMap = { {"plain", TilemapFormat::Plain}, {"4bpp", TilemapFormat::BPP_4}, {"8bpp", TilemapFormat::BPP_8} }; this->tilemap_format = formatsMap[tilemapFormat]; - this->tileset_path = tilemapObject["tileset_path"].string_value(); - this->tilemap_path = tilemapObject["tilemap_path"].string_value(); + this->tileset_path = tilemapObject["tileset_path"].toString(); + this->tilemap_path = tilemapObject["tilemap_path"].toString(); if (tilemapObject.contains("palette")) { - this->palette_path = tilemapObject["palette"].string_value(); + this->palette_path = tilemapObject["palette"].toString(); } QImage tilesetFile(fullPath(this->tileset_path)); @@ -118,16 +118,16 @@ bool RegionMap::loadLayout(poryjson::Json layoutJson) { poryjson::Json::object layoutObject = layoutJson.object_items(); - QString layoutFormat = layoutObject["format"].string_value(); + QString layoutFormat = layoutObject["format"].toString(); QMap layoutFormatMap = { {"binary", LayoutFormat::Binary}, {"C array", LayoutFormat::CArray} }; this->layout_format = layoutFormatMap[layoutFormat]; - this->layout_path = layoutObject["path"].string_value(); - this->layout_width = layoutObject["width"].int_value(); - this->layout_height = layoutObject["height"].int_value(); + this->layout_path = layoutObject["path"].toString(); + this->layout_width = layoutObject["width"].toInt(); + this->layout_height = layoutObject["height"].toInt(); - this->offset_left = layoutObject["offset_left"].int_value(); - this->offset_top = layoutObject["offset_top"].int_value(); + this->offset_left = layoutObject["offset_left"].toInt(); + this->offset_top = layoutObject["offset_top"].toInt(); bool errored = false; diff --git a/src/lib/orderedjson.cpp b/src/lib/orderedjson.cpp index 4d3a460c..1743946f 100644 --- a/src/lib/orderedjson.cpp +++ b/src/lib/orderedjson.cpp @@ -162,6 +162,8 @@ protected: class JsonDouble final : public Value { double number_value() const override { return m_value; } int int_value() const override { return static_cast(m_value); } + QString toString() const override { return QString::number(m_value); } + bool toBool() const override { return m_value != 0; } bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } bool less(const JsonValue * other) const override { return m_value < other->number_value(); } public: @@ -171,6 +173,8 @@ public: class JsonInt final : public Value { double number_value() const override { return m_value; } int int_value() const override { return m_value; } + QString toString() const override { return QString::number(m_value); } + bool toBool() const override { return m_value != 0; } bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } bool less(const JsonValue * other) const override { return m_value < other->number_value(); } public: @@ -179,12 +183,20 @@ public: class JsonBoolean final : public Value { bool bool_value() const override { return m_value; } + QString toString() const override { return m_value ? "true" : "false"; } + int toInt() const override { return m_value ? 1 : 0; } public: explicit JsonBoolean(bool value) : Value(value) {} }; class JsonString final : public Value { const QString &string_value() const override { return m_value; } + int toInt() const override { + if (QString::compare(m_value, "true", Qt::CaseInsensitive) == 0) return 1; + if (QString::compare(m_value, "false", Qt::CaseInsensitive) == 0) return 0; + return m_value.toInt(nullptr, 0); + } + bool toBool() const override { return toInt() != 0; } public: explicit JsonString(const QString &value) : Value(value) {} explicit JsonString(QString &&value) : Value(std::move(value)) {} @@ -244,8 +256,8 @@ Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {} Json::Json(double value) : m_ptr(make_shared(value)) {} Json::Json(int value) : m_ptr(make_shared(value)) {} Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {} -Json::Json(const QString &value) : m_ptr(make_shared(value)) {} -Json::Json(QString &&value) : m_ptr(make_shared(std::move(value))) {} +Json::Json(const QString &value) : m_ptr(make_shared(value)) {} +Json::Json(QString &&value) : m_ptr(make_shared(std::move(value))) {} Json::Json(const char * value) : m_ptr(make_shared(value)) {} Json::Json(const Json::array &values) : m_ptr(make_shared(values)) {} Json::Json(Json::array &&values) : m_ptr(make_shared(std::move(values))) {} @@ -256,24 +268,30 @@ Json::Json(Json::object &&values) : m_ptr(make_shared(std::move * Accessors */ -Json::Type Json::type() const { return m_ptr->type(); } -double Json::number_value() const { return m_ptr->number_value(); } -int Json::int_value() const { return m_ptr->int_value(); } -bool Json::bool_value() const { return m_ptr->bool_value(); } -const QString & Json::string_value() const { return m_ptr->string_value(); } -const QVector & Json::array_items() const { return m_ptr->array_items(); } -const Json::object & Json::object_items() const { return m_ptr->object_items(); } -const Json & Json::operator[] (int i) const { return (*m_ptr)[i]; } -const Json & Json::operator[] (const QString &key) const { return (*m_ptr)[key]; } +Json::Type Json::type() const { return m_ptr->type(); } +double Json::number_value() const { return m_ptr->number_value(); } +int Json::int_value() const { return m_ptr->int_value(); } +int Json::toInt() const { return m_ptr->toInt(); } +bool Json::bool_value() const { return m_ptr->bool_value(); } +bool Json::toBool() const { return m_ptr->toBool(); } +const QString & Json::string_value() const { return m_ptr->string_value(); } +QString Json::toString() const { return m_ptr->toString(); } +const QVector & Json::array_items() const { return m_ptr->array_items(); } +const Json::object & Json::object_items() const { return m_ptr->object_items(); } +const Json & Json::operator[] (int i) const { return (*m_ptr)[i]; } +const Json & Json::operator[] (const QString &key) const { return (*m_ptr)[key]; } -double JsonValue::number_value() const { return 0; } -int JsonValue::int_value() const { return 0; } -bool JsonValue::bool_value() const { return false; } -const QString & JsonValue::string_value() const { return statics().empty_string; } -const QVector & JsonValue::array_items() const { return statics().empty_vector; } -const Json::object & JsonValue::object_items() const { return statics().empty_map; } -const Json & JsonValue::operator[] (int) const { return static_null(); } -const Json & JsonValue::operator[] (const QString &) const { return static_null(); } +double JsonValue::number_value() const { return 0; } +int JsonValue::int_value() const { return 0; } +int JsonValue::toInt() const { return int_value(); } +bool JsonValue::bool_value() const { return false; } +bool JsonValue::toBool() const { return bool_value(); } +const QString & JsonValue::string_value() const { return statics().empty_string; } +QString JsonValue::toString() const { return string_value(); } +const QVector & JsonValue::array_items() const { return statics().empty_vector; } +const Json::object & JsonValue::object_items() const { return statics().empty_map; } +const Json & JsonValue::operator[] (int) const { return static_null(); } +const Json & JsonValue::operator[] (const QString &) const { return static_null(); } const Json & JsonObject::operator[] (const QString &key) const { static auto iter = m_value.find(key); diff --git a/src/project.cpp b/src/project.cpp index b564b34b..0f52456d 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1792,7 +1792,7 @@ bool Project::readWildMonData() { // We're only interested in wild encounter data that's associated with maps ("for_maps" == true). // Any other wild encounter data (e.g. for Battle Pike / Battle Pyramid) will be ignored. // We'll record any data that's not for maps in extraEncounterGroups to be outputted when we save. - if (!mainArrayObject["for_maps"].bool_value()) { + if (!mainArrayObject["for_maps"].toBool()) { this->extraEncounterGroups.push_back(mainArrayObject); continue; } else { @@ -1802,7 +1802,7 @@ bool Project::readWildMonData() { } // If multiple "for_maps" data sets are found they will be collapsed into a single set. - QString label = mainArrayObject.take("label").string_value(); + QString label = mainArrayObject.take("label").toString(); if (this->wildMonTableName.isEmpty()) { this->wildMonTableName = label; } else { @@ -1820,11 +1820,11 @@ bool Project::readWildMonData() { OrderedJson::object fieldObject = fieldJson.object_items(); EncounterField encounterField; - encounterField.name = fieldObject.take("type").string_value(); + encounterField.name = fieldObject.take("type").toString(); OrderedJson::array encounterRatesArray = fieldObject.take("encounter_rates").array_items(); for (const auto &val : encounterRatesArray) { - encounterField.encounterRates.append(val.int_value()); + encounterField.encounterRates.append(val.toInt()); } // Each element of the "groups" array is an object with the group name as the key (e.g. "old_rod") @@ -1833,7 +1833,7 @@ bool Project::readWildMonData() { for (auto groupPair : groups) { const QString groupName = groupPair.first; for (auto slotNum : groupPair.second.array_items()) { - encounterField.groups[groupName].append(slotNum.int_value()); + encounterField.groups[groupName].append(slotNum.toInt()); } } encounterField.customData = fieldObject; @@ -1865,7 +1865,7 @@ bool Project::readWildMonData() { monInfo.active = true; // Read encounter rate - monInfo.encounterRate = encounterFieldObj.take("encounter_rate").int_value(); + monInfo.encounterRate = encounterFieldObj.take("encounter_rate").toInt(); encounterRateFrequencyMaps[field][monInfo.encounterRate]++; // Read wild pokémon list @@ -1874,9 +1874,9 @@ bool Project::readWildMonData() { OrderedJson::object monObj = monJson.object_items(); WildPokemon newMon; - newMon.minLevel = monObj.take("min_level").int_value(); - newMon.maxLevel = monObj.take("max_level").int_value(); - newMon.species = monObj.take("species").string_value(); + newMon.minLevel = monObj.take("min_level").toInt(); + newMon.maxLevel = monObj.take("max_level").toInt(); + newMon.species = monObj.take("species").toString(); newMon.customData = monObj; monInfo.wildPokemon.append(newMon); } @@ -1888,8 +1888,8 @@ bool Project::readWildMonData() { } header.wildMons[field] = monInfo; } - const QString mapConstant = encounterObj.take("map").string_value(); - const QString baseLabel = encounterObj.take("base_label").string_value(); + const QString mapConstant = encounterObj.take("map").toString(); + const QString baseLabel = encounterObj.take("base_label").toString(); header.customData = encounterObj; this->wildMonData[mapConstant].insert({baseLabel, header}); this->encounterGroupLabels.append(baseLabel); diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index 0331c1dd..46b5de0f 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -184,7 +184,7 @@ bool RegionMapEditor::buildConfigDialog() { for (auto o : mapsObject["region_maps"].array_items()) { poryjson::Json::object object = o.object_items(); QListWidgetItem *newItem = new QListWidgetItem; - newItem->setText(object["alias"].string_value()); + newItem->setText(object["alias"].toString()); QString objectString; int i = 0; o.dump(objectString, &i); @@ -245,7 +245,7 @@ bool RegionMapEditor::buildConfigDialog() { resultJson.dump(resultStr, &tab); QListWidgetItem *newItem = new QListWidgetItem; - newItem->setText(resultObj["alias"].string_value()); + newItem->setText(resultObj["alias"].toString()); newItem->setData(Qt::UserRole, resultStr); regionMapList->addItem(newItem); updateJsonFromList(); @@ -398,7 +398,7 @@ bool RegionMapEditor::setup() { // load the region maps into this->region_maps poryjson::Json::object regionMapObjectCopy = this->rmConfigJson.object_items(); for (auto o : regionMapObjectCopy["region_maps"].array_items()) { - QString alias = o.object_items().at("alias").string_value(); + QString alias = o.object_items().at("alias").toString(); RegionMap *newMap = new RegionMap(this->project); newMap->setEntries(&this->region_map_entries); diff --git a/src/ui/regionmappropertiesdialog.cpp b/src/ui/regionmappropertiesdialog.cpp index 10ce3c4a..77afd7c1 100644 --- a/src/ui/regionmappropertiesdialog.cpp +++ b/src/ui/regionmappropertiesdialog.cpp @@ -44,30 +44,30 @@ void RegionMapPropertiesDialog::setProperties(poryjson::Json json) { poryjson::Json::object object = json.object_items(); // Region Map Properties - ui->config_alias->setText(object["alias"].string_value()); + ui->config_alias->setText(object["alias"].toString()); // Tilemap properties poryjson::Json::object tilemap = object["tilemap"].object_items(); - ui->config_tilemapFormat->setCurrentText(tilemap["format"].string_value()); - ui->config_tilemapWidth->setValue(tilemap["width"].int_value()); - ui->config_tilemapHeight->setValue(tilemap["height"].int_value()); + ui->config_tilemapFormat->setCurrentText(tilemap["format"].toString()); + ui->config_tilemapWidth->setValue(tilemap["width"].toInt()); + ui->config_tilemapHeight->setValue(tilemap["height"].toInt()); - ui->config_tilemapImagePath->setText(tilemap["tileset_path"].string_value()); - ui->config_tilemapBinPath->setText(tilemap["tilemap_path"].string_value()); + ui->config_tilemapImagePath->setText(tilemap["tileset_path"].toString()); + ui->config_tilemapBinPath->setText(tilemap["tilemap_path"].toString()); if (tilemap.contains("palette")) - ui->config_tilemapPalettePath->setText(tilemap["palette"].string_value()); + ui->config_tilemapPalettePath->setText(tilemap["palette"].toString()); // Layout props if (object["layout"].is_null()) { ui->group_layout->setChecked(false); } else { poryjson::Json::object layout = object["layout"].object_items(); - ui->config_layoutFormat->setCurrentText(layout["format"].string_value()); - ui->config_layoutPath->setText(layout["path"].string_value()); - ui->config_layoutWidth->setValue(layout["width"].int_value()); - ui->config_layoutHeight->setValue(layout["height"].int_value()); - ui->config_leftOffs->setValue(layout["offset_left"].int_value()); - ui->config_topOffs->setValue(layout["offset_top"].int_value()); + ui->config_layoutFormat->setCurrentText(layout["format"].toString()); + ui->config_layoutPath->setText(layout["path"].toString()); + ui->config_layoutWidth->setValue(layout["width"].toInt()); + ui->config_layoutHeight->setValue(layout["height"].toInt()); + ui->config_leftOffs->setValue(layout["offset_left"].toInt()); + ui->config_topOffs->setValue(layout["offset_top"].toInt()); } }