/* speciesgen Copyright (C) 2022-2023 prisixia This file is part of speciesgen. speciesgen is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. speciesgen is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with speciesgen. If not, see . */ ///////////////////////////////////////////////////////////////////////////// // Name: item.cpp // Purpose: Implementation of Item and related // Author: prisixia // Created: 2022-10-02 // Copyright: (C) 2022-2023 prisixia // Licence: GNU General Public License version 3 ///////////////////////////////////////////////////////////////////////////// #ifndef SPECIESGEN_STARBOUND_ITEM_H #define SPECIESGEN_STARBOUND_ITEM_H #include #include #include #include #include "cereal/types/string.hpp" #include "magic_enum.hpp" namespace Starbound::Item { enum class Rarity { Common = 0, Uncommon = 1, Rare = 2, Legendary = 3, Essential = 4 }; enum class Category { Headwear = 0, Chestwear = 1, Legwear = 2 }; enum class TooltipKind { Armor = 0 }; class Frames { public: Frames() = default; Frames(std::filesystem::path); Frames(std::filesystem::path, std::filesystem::path, std::filesystem::path); [[nodiscard]] std::filesystem::path GetBody() const; [[nodiscard]] std::filesystem::path GetBackSleeve() const; [[nodiscard]] std::filesystem::path GetFrontSleeve() const; void SetBody(const std::filesystem::path &); void SetBackSleeve(const std::filesystem::path &); void SetFrontSleeve(const std::filesystem::path &); private: std::filesystem::path m_body; std::filesystem::path m_backSleeve; std::filesystem::path m_frontSleeve; }; class Item { public: Item() = default; Item(std::string, const Rarity); Item(std::string, std::filesystem::path, const Category, std::string, std::string, Frames, Frames); [[nodiscard]] std::string GetItemName() const; [[nodiscard]] uint32_t GetPrice() const; [[nodiscard]] std::filesystem::path GetInventoryIcon() const; [[nodiscard]] uint16_t GetMaxStack() const; [[nodiscard]] Rarity GetRarity() const; [[nodiscard]] Category GetCategory() const; [[nodiscard]] std::string GetDescription() const; [[nodiscard]] std::string GetShortDescription() const; [[nodiscard]] TooltipKind GetTooltipKind() const; [[nodiscard]] Frames GetMaleFrames() const; [[nodiscard]] Frames GetFemaleFrames() const; void SetItemName(const std::string &); void SetPrice(const uint32_t); void SetInventoryIcon(const std::filesystem::path &); void SetMaxStack(const uint16_t); void SetRarity(const Rarity); void SetCategory(const Category); void SetDescription(const std::string &); void SetShortDescription(const std::string &); void SetTooltipKind(const TooltipKind); void SetMaleFrames(const Frames &); void SetFemaleFrames(const Frames &); private: std::string m_itemName; uint32_t m_price; std::filesystem::path m_inventoryIcon; uint16_t m_maxStack; Rarity m_rarity; Category m_category; std::string m_description; std::string m_shortDescription; TooltipKind m_tooltipKind; Frames m_maleFrames; Frames m_femaleFrames; }; } // namespace Starbound::Item //---------------------------------------------------------------------- // Serialisation //---------------------------------------------------------------------- namespace cereal { template static void load_and_construct(Archive &archive, construct &construct) { std::filesystem::path body; std::filesystem::path backSleeve; std::filesystem::path frontSleeve; archive(CEREAL_NVP(body), CEREAL_NVP(backSleeve), CEREAL_NVP(frontSleeve)); construct(body, backSleeve, frontSleeve); } template void Save(Archive &archive, Starbound::Item::Frames const &m) { const std::string body = m.GetBody().string(); const std::string backSleeve = m.GetBackSleeve().string(); const std::string frontSleeve = m.GetFrontSleeve().string(); archive(CEREAL_NVP(body), CEREAL_NVP(backSleeve), CEREAL_NVP(frontSleeve)); } template void Load(Archive &archive, Starbound::Item::Item &m) { std::string itemName; uint32_t price; std::string inventoryIcon; uint16_t maxStack; std::string _rarity; std::string _category; std::string description; std::string shortdescription; std::string _tooltipKind; Starbound::Item::Frames maleFrames; Starbound::Item::Frames femaleFrames; archive(CEREAL_NVP(itemName), CEREAL_NVP(price), CEREAL_NVP(inventoryIcon), CEREAL_NVP(maxStack), CEREAL_NVP_("rarity", _rarity), CEREAL_NVP_("category", _category), CEREAL_NVP(description), CEREAL_NVP(shortdescription), CEREAL_NVP_("tooltipKind", _tooltipKind), CEREAL_NVP(maleFrames), CEREAL_NVP(femaleFrames)); const auto rarity = magic_enum::enum_cast(_rarity); const auto category = magic_enum::enum_cast(_category); const auto tooltipKind = magic_enum::enum_cast(_tooltipKind); m.SetItemName(itemName); m.SetPrice(price); m.SetInventoryIcon(inventoryIcon); m.SetMaxStack(maxStack); if (rarity.has_value()) { m.SetRarity(rarity.value()); } if (category.has_value()) { m.SetCategory(category.value()); } m.SetDescription(description); m.SetShortDescription(shortdescription); if (tooltipKind.has_value()) { m.SetTooltipKind(tooltipKind.value()); } m.SetMaleFrames(maleFrames); m.SetFemaleFrames(femaleFrames); } template void Save(Archive &archive, Starbound::Item::Item const &m) { const std::string itemName = m.GetItemName(); const uint32_t price = m.GetPrice(); const std::string inventoryIcon = m.GetInventoryIcon().string(); const uint16_t maxStack = m.GetMaxStack(); const std::string rarity = static_cast(magic_enum::enum_name(m.GetRarity())); std::string category = static_cast(magic_enum::enum_name(m.GetCategory())); const std::string description = m.GetDescription(); const std::string shortdescription = m.GetShortDescription(); const std::string tooltipKind = static_cast(magic_enum::enum_name(m.GetTooltipKind())); const Starbound::Item::Frames maleFrames = m.GetMaleFrames(); const Starbound::Item::Frames femaleFrames = m.GetFemaleFrames(); category[0] = tolower(category[0]); archive(CEREAL_NVP(itemName), CEREAL_NVP(price), CEREAL_NVP(inventoryIcon), CEREAL_NVP(maxStack), CEREAL_NVP(rarity), CEREAL_NVP(category), CEREAL_NVP(description), CEREAL_NVP(shortdescription), CEREAL_NVP(tooltipKind)); if (maleFrames.GetBackSleeve().empty() && maleFrames.GetFrontSleeve().empty() && femaleFrames.GetBackSleeve().empty() && femaleFrames.GetFrontSleeve().empty()) { archive(CEREAL_NVP_("maleFrames", maleFrames.GetBody()), CEREAL_NVP_("femaleFrames", femaleFrames.GetBody())); } else { archive(CEREAL_NVP(maleFrames), CEREAL_NVP(femaleFrames)); } /* * At the moment, cereal doesn't really support optional values * for deserialisation, meaning that we have to serialise all fields * even if they're eventually unneeded. */ /* archive(CEREAL_NVP(itemName), CEREAL_NVP(rarity), CEREAL_NVP(maleFrames), CEREAL_NVP(femaleFrames)); if (price > 0) { archive(CEREAL_NVP(price)); } if (!inventoryIcon.empty()) { archive(CEREAL_NVP(inventoryIcon)); } if (maxStack > 1) { archive(CEREAL_NVP(maxStack)); } if (!category.empty()) { category[0] = tolower(category[0]); archive(CEREAL_NVP(category)); } if (!description.empty()) { archive(CEREAL_NVP(description)); } if (!shortdescription.empty()) { archive(CEREAL_NVP(shortdescription)); } if (!tooltipKind.empty()) { archive(CEREAL_NVP(tooltipKind)); } */ } } // namespace cereal #endif // SPECIESGEN_STARBOUND_ITEM_H