armor deserialize done.
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user