speciesgen/include/starbound/item.h

273 lines
8.0 KiB
C++

/*
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 <https://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////////
// 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 <algorithm>
#include <cctype>
#include <filesystem>
#include <string>
#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 <class Archive>
static void load_and_construct(Archive &archive,
construct<Starbound::Item::Frames> &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 <class Archive>
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 <class Archive> 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<Starbound::Item::Rarity>(_rarity);
const auto category =
magic_enum::enum_cast<Starbound::Item::Category>(_category);
const auto tooltipKind =
magic_enum::enum_cast<Starbound::Item::TooltipKind>(_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 <class Archive>
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();
const uint16_t maxStack = m.GetMaxStack();
const std::string rarity =
static_cast<std::string>(magic_enum::enum_name(m.GetRarity()));
std::string category =
static_cast<std::string>(magic_enum::enum_name(m.GetCategory()));
const std::string description = m.GetDescription();
const std::string shortdescription = m.GetShortDescription();
const std::string tooltipKind =
static_cast<std::string>(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