diff options
Diffstat (limited to 'source/game/StarItemDescriptor.cpp')
-rw-r--r-- | source/game/StarItemDescriptor.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/source/game/StarItemDescriptor.cpp b/source/game/StarItemDescriptor.cpp new file mode 100644 index 0000000..4621de5 --- /dev/null +++ b/source/game/StarItemDescriptor.cpp @@ -0,0 +1,160 @@ +#include "StarItemDescriptor.hpp" +#include "StarItem.hpp" +#include "StarRoot.hpp" +#include "StarVersioningDatabase.hpp" + +namespace Star { + +ItemDescriptor::ItemDescriptor() : m_count(0), m_parameters(JsonObject()) {} + +ItemDescriptor::ItemDescriptor(String name, uint64_t count, Json parameters) + : m_name(move(name)), m_count(count), m_parameters(move(parameters)) { + if (m_parameters.isNull()) + m_parameters = JsonObject(); + if (!m_parameters.isType(Json::Type::Object)) + throw StarException("Item parameters not map in ItemDescriptor constructor"); +} + +ItemDescriptor::ItemDescriptor(Json const& spec) { + if (spec.type() == Json::Type::Array) { + m_name = spec.getString(0); + m_count = spec.getInt(1, 1); + m_parameters = spec.getObject(2, {}); + } else if (spec.type() == Json::Type::Object) { + if (spec.contains("name")) + m_name = spec.getString("name"); + else if (spec.contains("item")) + m_name = spec.getString("item"); + else + throw StarException("Item name missing."); + m_count = spec.getInt("count", 1); + m_parameters = spec.getObject("parameters", spec.getObject("data", JsonObject{})); + } else if (spec.type() == Json::Type::String) { + m_name = spec.toString(); + m_count = 1; + m_parameters = JsonObject(); + } else if (spec.isNull()) { + m_parameters = JsonObject(); + m_count = 0; + } else { + throw ItemException("ItemDescriptor spec variant not list, map, string, or null"); + } +} + +ItemDescriptor ItemDescriptor::loadStore(Json const& spec) { + auto versioningDatabase = Root::singleton().versioningDatabase(); + return ItemDescriptor{versioningDatabase->loadVersionedJson(VersionedJson::fromJson(spec), "Item")}; +} + +String const& ItemDescriptor::name() const { + return m_name; +} + +uint64_t ItemDescriptor::count() const { + return m_count; +} + +Json const& ItemDescriptor::parameters() const { + return m_parameters; +} + +ItemDescriptor ItemDescriptor::singular() const { + return ItemDescriptor(name(), 1, parameters(), m_parametersHash); +} + +ItemDescriptor ItemDescriptor::withCount(uint64_t count) const { + return ItemDescriptor(name(), count, parameters(), m_parametersHash); +} + +ItemDescriptor ItemDescriptor::multiply(uint64_t count) const { + return ItemDescriptor(name(), this->count() * count, parameters(), m_parametersHash); +} + +ItemDescriptor ItemDescriptor::applyParameters(JsonObject const& parameters) const { + return ItemDescriptor(name(), this->count(), this->parameters().setAll(parameters)); +} + +bool ItemDescriptor::isNull() const { + return m_name.empty(); +} + +ItemDescriptor::operator bool() const { + return !isNull(); +} + +bool ItemDescriptor::isEmpty() const { + return m_name.empty() || m_count == 0; +} + +bool ItemDescriptor::operator==(ItemDescriptor const& rhs) const { + return std::tie(m_name, m_count, m_parameters) == std::tie(rhs.m_name, rhs.m_count, rhs.m_parameters); +} + +bool ItemDescriptor::operator!=(ItemDescriptor const& rhs) const { + return std::tie(m_name, m_count, m_parameters) != std::tie(rhs.m_name, rhs.m_count, rhs.m_parameters); +} + +bool ItemDescriptor::matches(ItemDescriptor const& other, bool exactMatch) const { + return other.name() == m_name && (!exactMatch || other.parameters() == m_parameters); +} + +bool ItemDescriptor::matches(ItemConstPtr const& other, bool exactMatch) const { + return other->name() == m_name && (!exactMatch || other->parameters() == m_parameters); +} + +Json ItemDescriptor::diskStore() const { + auto versioningDatabase = Root::singleton().versioningDatabase(); + auto res = JsonObject{ + {"name", m_name}, {"count", m_count}, {"parameters", m_parameters}, + }; + + return versioningDatabase->makeCurrentVersionedJson("Item", res).toJson(); +} + +Json ItemDescriptor::toJson() const { + if (isNull()) { + return Json(); + } else { + return JsonObject{ + {"name", m_name}, {"count", m_count}, {"parameters", m_parameters}, + }; + } +} + +ItemDescriptor::ItemDescriptor(String name, uint64_t count, Json parameters, Maybe<size_t> parametersHash) + : m_name(move(name)), m_count(count), m_parameters(move(parameters)), m_parametersHash(parametersHash) {} + +size_t ItemDescriptor::parametersHash() const { + if (!m_parametersHash) + m_parametersHash = hash<Json>()(m_parameters); + return *m_parametersHash; +} + +DataStream& operator>>(DataStream& ds, ItemDescriptor& itemDescriptor) { + ds.read(itemDescriptor.m_name); + ds.readVlqU(itemDescriptor.m_count); + ds.read(itemDescriptor.m_parameters); + + itemDescriptor.m_parametersHash.reset(); + + return ds; +} + +DataStream& operator<<(DataStream& ds, ItemDescriptor const& itemDescriptor) { + ds.write(itemDescriptor.m_name); + ds.writeVlqU(itemDescriptor.m_count); + ds.write(itemDescriptor.m_parameters); + + return ds; +} + +std::ostream& operator<<(std::ostream& os, ItemDescriptor const& descriptor) { + format(os, "[%s, %s, %s]", descriptor.m_name, descriptor.m_count, descriptor.m_parameters); + return os; +} + +size_t hash<ItemDescriptor>::operator()(ItemDescriptor const& v) const { + return hashOf(v.m_name, v.m_count, v.m_parametersHash); +} + +} |