armor deserialize done.

This commit is contained in:
2022-07-27 23:33:14 +02:00
parent 9926c3b617
commit 5d62062803
6 changed files with 226 additions and 96 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ defense = 400
[sets."Kamura Legacy Set".head]
name = "Kamura Legacy Head Scarf"
slots = [2]
skills."Devine Blessing" = 2
skills."Divine Blessing" = 2
skills."Resuscitate" = 1
[sets."Kamura Legacy Set".chest]
+76 -32
View File
@@ -12,13 +12,13 @@
#include "mhache_skill.h"
class MHacheSkill;
template <class P>
template <class P, class LessOperator = std::less<P>>
struct PtrLessComparator {
bool operator () (const P* a, const P* b) const
{
if (!a) return true;
if (!b) return false;
return *a < *b;
return LessOperator()(*a, *b);
}
};
@@ -43,6 +43,11 @@ public:
LEGS,
count
} Appellation;
static const constexpr std::array<std::string_view, Appellation::count> AppellationStr =
{
"head", "chest", "arms", "waist", "legs"
};
private:
friend class MHacheArmor;
@@ -57,25 +62,30 @@ public:
const MHacheArmor* _armor;
Part() = default;
Part()
: _label(Appellation::HEAD)
, _name()
, _slots({})
, _skills({})
, _armor(nullptr)
{}
public:
~Part() = default;
const std::string& name() const { return _name; }
const std::vector<unsigned char> slots() const { return _slots; }
// const std::set<Skill> skills() const { return _skills; }
const auto& skills() const { return _skills; }
Part& set_name(std::string&& name)
{
_name = std::forward<std::string>(name);
return *this;
_name = std::move(name);
return *this;
}
Part& set_slots(std::vector<unsigned char>&& slots)
{
_slots = std::forward<std::vector<unsigned char>>(slots);
_slots = std::move(slots);
return *this;
}
@@ -86,6 +96,22 @@ public:
return *this;
}
Part& detach()
{
_armor = nullptr;
return *this;
}
unsigned char has_skill(const std::string& skill_name) const
{
for (const auto skill: _skills) {
if (skill.first && skill.first->name() == skill_name)
return skill.second;
}
return 0;
}
};
private:
@@ -97,29 +123,58 @@ private:
private:
MHacheArmor() = delete;
MHacheArmor(const MHacheArmor&) = delete;
MHacheArmor(MHacheArmor&&) = delete;
MHacheArmor& operator=(const MHacheArmor&) = delete;
MHacheArmor& operator=(MHacheArmor&&) = delete;
public:
MHacheArmor(const std::string& name, unsigned char rarity, unsigned short defense, std::array<char, ResistanceElement::count> resistances)
: _name(name), _rarity(rarity), _defense(defense), _resistances(resistances), _parts({})
MHacheArmor(std::string_view name, unsigned char rarity, unsigned short defense, std::array<char, ResistanceElement::count>&& resistances)
: _name(name), _rarity(rarity), _defense(defense), _resistances(std::move(resistances)), _parts({})
{}
~MHacheArmor() = default;
MHacheArmor(const MHacheArmor&) = default;
MHacheArmor(MHacheArmor&&) = default;
~MHacheArmor() = default;
MHacheArmor& operator=(const MHacheArmor&) = default;
MHacheArmor& operator=(MHacheArmor&&) = default;
bool operator < (const MHacheArmor& armor) const { return _name < armor._name; }
bool operator == (const MHacheArmor& armor) const { return _name == armor._name; }
const std::string& name() const { return _name; }
std::vector<size_t> attached_parts() const
{
std::vector<size_t> ap;
const Part& part(Part::Appellation appellation) const { return _parts[appellation]; }
for (const auto& p: _parts)
if (p._armor)
ap.push_back(p._label);
Part& forge_part(Part::Appellation appellation)
{
_parts[appellation]._armor = this;
return _parts[appellation];
return ap;
}
const Part& operator[](size_t label) const
{
return _parts.at(label);
}
Part& operator[](size_t label)
{
Part& p = _parts.at(label);
p._label = Part::Appellation(label);
p._armor = this;
return p;
}
std::vector<size_t> search_for_skill(const std::string& skill_name) const
{
std::vector<size_t> ap;
for (const auto& p: _parts)
if (p._armor && p.has_skill(skill_name) > 0)
ap.push_back(p._label);
return ap;
}
};
@@ -132,15 +187,4 @@ struct std::hash<MHacheArmor>
}
};
/*
namespace std {
template<>
struct less<>
{
bool operator ()(const MHacheArmor::Part::Skill& a, const MHacheArmor::Part::Skill& b) const { return a < b; }
bool operator ()(const MHacheArmor::Part::Skill& a, const std::string& b) const { return a < b; }
bool operator ()(const std::string& b, const MHacheArmor::Part::Skill& a) const { return a < b; }
};
}*/
#endif
+48 -13
View File
@@ -11,7 +11,7 @@
class MHacheFactory {
private:
std::set<MHacheSkill> _skills;
std::set<MHacheSkill, MHacheSkillLessOperator> _skills;
std::set<MHacheArmor> _armors;
MHacheFactory() = default;
@@ -21,14 +21,28 @@ private:
template <typename T>
static bool deserialize_table_node(const toml::table& table, std::string_view node_name, T& node_value)
{
const auto node = table.get_as<T>(node_name);
if constexpr (std::is_integral<T>::value)
{
const auto node = table.get_as<int64_t>(node_name);
if (node) {
node_value = node->template ref<T>();
return true;
if (node) {
node_value = static_cast<T>(node->template ref<int64_t>());
return true;
}
return false;
}
else
{
const auto node = table.get_as<T>(node_name);
return false;
if (node) {
node_value = node->template ref<T>();
return true;
}
return false;
}
}
template <typename T>
@@ -41,10 +55,20 @@ private:
listof_values.reserve(array->size());
for (const auto& entry: *array) {
const auto wrap = entry.as<T>();
if constexpr (std::is_integral<T>::value)
{
const auto wrap = entry.as<int64_t>();
if (wrap)
listof_values.push_back(wrap->template ref<T>());
if (wrap)
listof_values.push_back(static_cast<T>(wrap->template ref<int64_t>()));
}
else
{
const auto wrap = entry.as<T>();
if (wrap)
listof_values.push_back(wrap->template ref<T>());
}
}
}
@@ -59,10 +83,20 @@ private:
if (array && array->size() == Length) {
for (size_t i = 0; i < Length; ++i) {
const auto wrap = array->get_as<T>(i);
if constexpr (std::is_integral<T>::value)
{
const auto wrap = array->get_as<int64_t>(i);
if (wrap)
listof_values[i] = wrap->template ref<T>();
if (wrap)
listof_values[i] = static_cast<T>(wrap->template ref<int64_t>());
}
else
{
const auto wrap = array->get_as<T>(i);
if (wrap)
listof_values[i] = wrap->template ref<T>();
}
}
}
@@ -77,7 +111,8 @@ public:
bool load_skills(const std::filesystem::path&);
bool load_armors(const std::filesystem::path&);
inline const std::set<MHacheSkill>& available_skills() const { return _skills; }
inline const auto& available_skills() const { return _skills; }
inline const auto& available_armors() const { return _armors; }
};
#endif
+8
View File
@@ -46,4 +46,12 @@ struct std::hash<MHacheSkill>
}
};
struct MHacheSkillLessOperator {
using is_transparent = void;
bool operator() (const MHacheSkill& a, const MHacheSkill& b) const { return a < b; }
bool operator() (const MHacheSkill& a, std::string_view b) const { return a.name() < b; }
bool operator() (std::string_view a, const MHacheSkill& b) const { return a < b.name(); }
};
#endif
+49 -28
View File
@@ -85,52 +85,73 @@ MHacheFactory::load_armors(const std::filesystem::path& tomlfile)
if (!deserialize_table_node(root, "sets", sets))
return false;
}
for (const auto& set_entry: sets) {
const auto p_set = set_entry.second.as_table();
if (!p_set) continue;
const auto& set = *p_set;
sets.for_each([this](const toml::key& set_name, const toml::table& set)
{
const std::string name = std::string(set_name.str());
if (name.empty()) return false;
const std::string name = std::string(set_entry.first.str());
if (name.empty()) continue;
int64_t rarity;
unsigned char rarity;
if (!deserialize_table_node(set, "rarity", rarity))
return false;
int64_t defense;
unsigned short defense;
if (!deserialize_table_node(set, "defense", defense))
return false;
std::array<int64_t, MHacheArmor::ResistanceElement::count> resistances;
std::array<char, MHacheArmor::ResistanceElement::count> resistances;
if (!deserialize_table_node(set, "resistances", resistances))
return false;
MHacheArmor armor(name, rarity, defense, resistances);
static constexpr std::array<std::string_view, MHacheArmor::Part::Appellation::count> appellations =
{
"head", "chest", "arms", "waist", "legs"
};
for (auto appellation: appellations)
// Prepare the armor
MHacheArmor armor(name, rarity, defense, std::move(resistances));
// Attach its parts
for (unsigned char label = 0; label < MHacheArmor::Part::Appellation::count; ++label)
{
toml::table part;
if (!deserialize_table_node<toml::table>(set, appellation, part))
return false;
if (!deserialize_table_node(set, MHacheArmor::Part::AppellationStr[label], part))
continue;
std::string part_name;
if (!deserialize_table_node(part, "name", part_name))
continue;
std::vector<unsigned char> part_slots;
if (!deserialize_table_node(part, "slots", part_slots))
continue;
toml::table part_skills;
if (!deserialize_table_node(part, "skills", part_skills))
continue;
part_skills.for_each([this, &armor, label](const toml::key& skill_name, toml::value<int64_t> skill_level)
{
const auto it_skill = _skills.find(skill_name.str());
if ((_skills.end() == it_skill) || 0 >= skill_level)
return false;
armor[label].add_skill(&(*it_skill), static_cast<unsigned char>(skill_level.get()));
return true;
});
if (armor[label].skills().empty())
{
armor[label].detach();
continue;
}
armor[label]
.set_name(std::move(part_name))
.set_slots(std::move(part_slots));
}
// MHacheArmor armor()
if (armor.attached_parts().size() > 0)
_armors.insert(std::move(armor));
/*
toml::table head;
deserialize_table_node(set, "head", head);
*/
}
return true;
});
return !_armors.empty();
}
+44 -22
View File
@@ -55,6 +55,7 @@ MHacheWindow::MHacheWindow(int width, int height)
MHacheFactory& mhf = MHacheFactory::singleton();
mhf.load_skills("../../skills.toml");
mhf.load_armors("../../armors.toml");
}
MHacheWindow::~MHacheWindow()
@@ -134,32 +135,53 @@ MHacheWindow::build_widgets()
//--
build_menu();
ImGuiTextFilter filter;
filter.Draw();
static std::vector<const MHacheSkill*> filtered_skills;
static ImGuiTextFilter filter;
const auto& skills = MHacheFactory::singleton().available_skills();
if (ImGui::CollapsingHeader("Skills")) {
filtered_skills.clear();
filter.Draw();
for (const auto& skill: skills) {
if (filter.PassFilter(skill.name().c_str())) {
const MHacheColor* color = skill.color();
if (!color) {
std::cerr << "Missing color for " << skill.name() << std::endl;
continue;
const auto& skills = MHacheFactory::singleton().available_skills();
for (const auto& skill: skills) {
if (filter.PassFilter(skill.name().c_str())) {
const MHacheColor* color = skill.color();
if (!color) {
std::cerr << "Missing color for " << skill.name() << std::endl;
continue;
}
const auto rgba = color->channels<float>();
ImGui::TextColored(
ImVec4(rgba[0], rgba[1], rgba[2], rgba[3]),
"%s", skill.name().c_str()
);
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(skill.description().c_str());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
filtered_skills.push_back(&skill);
}
}
}
const auto rgba = color->channels<float>();
ImGui::TextColored(
ImVec4(rgba[0], rgba[1], rgba[2], rgba[3]),
"%s", skill.name().c_str()
);
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(skill.description().c_str());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
if (ImGui::CollapsingHeader("Armors")) {
const auto& armors = MHacheFactory::singleton().available_armors();
for (const auto& armor: armors) {
for (const auto skill: filtered_skills) {
if (!armor.search_for_skill(skill->name()).empty()) {
ImGui::Text(armor.name().c_str());
break;
}
}
}
}