mr. propre
This commit is contained in:
parent
5d62062803
commit
2096e6814a
@ -2,7 +2,5 @@ cmake_minimum_required(VERSION 3.23)
|
||||
|
||||
project(MHache VERSION 0.1)
|
||||
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_subdirectory(dependencies)
|
||||
add_subdirectory(src)
|
||||
|
5
dependencies/tomlplusplus/CMakeLists.txt
vendored
5
dependencies/tomlplusplus/CMakeLists.txt
vendored
@ -3,6 +3,11 @@ add_library(
|
||||
"${tomlplusplus_SOURCE_DIR}/src/toml++/toml.cpp"
|
||||
)
|
||||
|
||||
target_compile_features(
|
||||
tomlplusplus PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
target_compile_definitions(
|
||||
tomlplusplus PUBLIC
|
||||
TOML_EXCEPTIONS=0
|
||||
|
@ -14,14 +14,32 @@ class MHacheSkill;
|
||||
|
||||
template <class P, class LessOperator = std::less<P>>
|
||||
struct PtrLessComparator {
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator () (const P* a, const P* b) const
|
||||
{
|
||||
if (!a) return true;
|
||||
if (!b) return false;
|
||||
return LessOperator()(*a, *b);
|
||||
}
|
||||
|
||||
bool operator() (std::string_view a, const P* b) const
|
||||
{
|
||||
if (!b) return false;
|
||||
return LessOperator()(a, *b);
|
||||
}
|
||||
|
||||
bool operator() (const P* a, std::string_view b) const
|
||||
{
|
||||
if (!a) return false;
|
||||
return LessOperator()(*a, b);
|
||||
}
|
||||
};
|
||||
|
||||
using MappedSkillLevels =
|
||||
std::map<const MHacheSkill*, unsigned char,
|
||||
PtrLessComparator<MHacheSkill, MHacheSkillLessOperator>>;
|
||||
|
||||
class MHacheArmor {
|
||||
public:
|
||||
typedef enum: unsigned char {
|
||||
@ -33,149 +51,99 @@ public:
|
||||
count
|
||||
} ResistanceElement;
|
||||
|
||||
using ElementalResistances = std::array<char, ResistanceElement::count>;
|
||||
|
||||
class Part {
|
||||
public:
|
||||
typedef enum : unsigned char {
|
||||
enum Label : unsigned char {
|
||||
HEAD,
|
||||
CHEST,
|
||||
ARMS,
|
||||
WAIST,
|
||||
LEGS,
|
||||
count
|
||||
} Appellation;
|
||||
|
||||
static const constexpr std::array<std::string_view, Appellation::count> AppellationStr =
|
||||
{
|
||||
"head", "chest", "arms", "waist", "legs"
|
||||
};
|
||||
|
||||
static constexpr std::array<std::string_view, Label::count> label_names =
|
||||
{ "head", "chest", "arms", "waist", "legs" };
|
||||
|
||||
private:
|
||||
friend class MHacheArmor;
|
||||
|
||||
Appellation _label;
|
||||
Label _label;
|
||||
std::string _name;
|
||||
std::vector<unsigned char> _slots;
|
||||
MappedSkillLevels _skills;
|
||||
const MHacheArmor* _armor;
|
||||
|
||||
std::string _name;
|
||||
std::vector<unsigned char> _slots;
|
||||
|
||||
std::map<const MHacheSkill*, unsigned char,
|
||||
PtrLessComparator<MHacheSkill>> _skills;
|
||||
|
||||
const MHacheArmor* _armor;
|
||||
|
||||
Part()
|
||||
: _label(Appellation::HEAD)
|
||||
, _name()
|
||||
, _slots({})
|
||||
, _skills({})
|
||||
, _armor(nullptr)
|
||||
{}
|
||||
Part();
|
||||
|
||||
public:
|
||||
~Part() = default;
|
||||
|
||||
const std::string& name() const { return _name; }
|
||||
const std::vector<unsigned char> slots() const { return _slots; }
|
||||
const auto& skills() const { return _skills; }
|
||||
Part(const Part&);
|
||||
Part(Part&&);
|
||||
|
||||
Part& set_name(std::string&& name)
|
||||
{
|
||||
_name = std::move(name);
|
||||
return *this;
|
||||
}
|
||||
Part& operator =(const Part&);
|
||||
Part& operator =(Part&&);
|
||||
|
||||
Part& set_slots(std::vector<unsigned char>&& slots)
|
||||
{
|
||||
_slots = std::move(slots);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Part& add_skill(const MHacheSkill* skill, unsigned char level)
|
||||
{
|
||||
if (skill && level > 0)
|
||||
_skills.insert_or_assign(skill, level);
|
||||
|
||||
return *this;
|
||||
}
|
||||
bool operator < (const Part& other) const;
|
||||
bool operator == (const Part& other) const;
|
||||
|
||||
Part& detach()
|
||||
{
|
||||
_armor = nullptr;
|
||||
return *this;
|
||||
}
|
||||
const std::string& name() const;
|
||||
const std::vector<unsigned char>& slots() const;
|
||||
const MappedSkillLevels& skills() const;
|
||||
ElementalResistances resistances() const;
|
||||
|
||||
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;
|
||||
}
|
||||
unsigned char has_skill(std::string_view skill_name) const;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Part& is_called(std::string_view name);
|
||||
Part& define_jewel_slots(std::vector<unsigned char>&& slots);
|
||||
Part& add_skill(const MHacheSkill* skill, unsigned char level);
|
||||
Part& detach();
|
||||
};
|
||||
|
||||
using PartList = std::array<Part, Part::Label::count>;
|
||||
using LabelList = std::vector<Part::Label>;
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
unsigned char _rarity;
|
||||
unsigned short _defense;
|
||||
std::array<char, ResistanceElement::count> _resistances;
|
||||
std::array<Part, Part::count> _parts;
|
||||
std::string _name;
|
||||
unsigned char _rarity;
|
||||
unsigned short _defense;
|
||||
ElementalResistances _resistances;
|
||||
PartList _parts;
|
||||
|
||||
private:
|
||||
MHacheArmor() = delete;
|
||||
MHacheArmor();
|
||||
|
||||
public:
|
||||
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(std::string_view name, unsigned char rarity, unsigned short defense,
|
||||
ElementalResistances&& resistances);
|
||||
|
||||
MHacheArmor(const MHacheArmor&);
|
||||
MHacheArmor(MHacheArmor&&);
|
||||
|
||||
MHacheArmor(const MHacheArmor&) = default;
|
||||
MHacheArmor(MHacheArmor&&) = default;
|
||||
~MHacheArmor() = default;
|
||||
|
||||
~MHacheArmor() = default;
|
||||
MHacheArmor& operator=(const MHacheArmor&);
|
||||
MHacheArmor& operator=(MHacheArmor&&);
|
||||
|
||||
MHacheArmor& operator=(const MHacheArmor&) = default;
|
||||
MHacheArmor& operator=(MHacheArmor&&) = default;
|
||||
bool operator < (const MHacheArmor& armor) const;
|
||||
bool operator == (const MHacheArmor& armor) const;
|
||||
|
||||
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;
|
||||
unsigned char rarity() const;
|
||||
unsigned char defense() const;
|
||||
const ElementalResistances& resistances() const;
|
||||
|
||||
const std::string& name() const { return _name; }
|
||||
|
||||
std::vector<size_t> attached_parts() const
|
||||
{
|
||||
std::vector<size_t> ap;
|
||||
LabelList attached_parts() const;
|
||||
LabelList search_for_skill(std::string_view skill_name) const;
|
||||
|
||||
for (const auto& p: _parts)
|
||||
if (p._armor)
|
||||
ap.push_back(p._label);
|
||||
const Part& operator[](size_t label) const;
|
||||
Part& operator[](size_t label);
|
||||
|
||||
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;
|
||||
}
|
||||
const Part& operator[](Part::Label label) const;
|
||||
Part& operator[](Part::Label label);
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -187,4 +155,12 @@ struct std::hash<MHacheArmor>
|
||||
}
|
||||
};
|
||||
|
||||
struct MHacheArmorLessOperator {
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator() (const MHacheArmor& a, const MHacheArmor& b) const { return a < b; }
|
||||
bool operator() (const MHacheArmor& a, std::string_view b) const { return a.name() < b; }
|
||||
bool operator() (std::string_view a, const MHacheArmor& b) const { return a < b.name(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
class MHacheFactory {
|
||||
private:
|
||||
std::set<MHacheSkill, MHacheSkillLessOperator> _skills;
|
||||
std::set<MHacheArmor> _armors;
|
||||
std::set<MHacheArmor, MHacheArmorLessOperator> _armors;
|
||||
|
||||
MHacheFactory() = default;
|
||||
|
||||
@ -113,6 +113,8 @@ public:
|
||||
|
||||
inline const auto& available_skills() const { return _skills; }
|
||||
inline const auto& available_armors() const { return _armors; }
|
||||
|
||||
void find_builds(const MappedSkillLevels& skill_names) const;
|
||||
};
|
||||
|
||||
#endif
|
@ -22,8 +22,8 @@ private:
|
||||
|
||||
public:
|
||||
inline
|
||||
MHacheSkill(const std::string& name, const std::string& description, const MHacheColor* color, const std::vector<std::string>& levels)
|
||||
: _name(name), _description(description), _color(color), _levels(levels)
|
||||
MHacheSkill(std::string_view name, std::string_view description, const MHacheColor* color, std::vector<std::string>&& levels)
|
||||
: _name(name), _description(description), _color(color), _levels(std::move(levels))
|
||||
{}
|
||||
|
||||
~MHacheSkill() = default;
|
||||
|
@ -10,6 +10,11 @@ add_executable(
|
||||
mhache_window.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(
|
||||
${PROJECT_NAME} PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
target_compile_options(
|
||||
${PROJECT_NAME} PUBLIC
|
||||
-Wall
|
||||
|
@ -1 +1,288 @@
|
||||
#include <utility>
|
||||
|
||||
#include "mhache_armor.h"
|
||||
|
||||
// -- PART --
|
||||
MHacheArmor::Part::Part()
|
||||
: _label(MHacheArmor::Part::count)
|
||||
, _name("")
|
||||
, _slots({})
|
||||
, _skills({})
|
||||
, _armor(nullptr)
|
||||
{}
|
||||
|
||||
MHacheArmor::Part::Part(const Part& other)
|
||||
: MHacheArmor::Part()
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
MHacheArmor::Part::Part(Part&& other)
|
||||
: MHacheArmor::Part()
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::Part::operator =(const Part& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
_label = other._label;
|
||||
_name = other._name;
|
||||
_slots = other._slots;
|
||||
_skills = other._skills;
|
||||
_armor = other._armor;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::Part::operator =(Part&& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
_label = std::exchange(other._label, MHacheArmor::Part::count);
|
||||
_name = std::exchange(other._name, "");
|
||||
_slots = std::exchange(other._slots, {});
|
||||
_skills = std::exchange(other._skills, {});
|
||||
_armor = std::exchange(other._armor, nullptr);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
MHacheArmor::Part::operator <(const MHacheArmor::Part& other) const
|
||||
{
|
||||
return _name < other._name;
|
||||
}
|
||||
|
||||
bool
|
||||
MHacheArmor::Part::operator ==(const MHacheArmor::Part& other) const
|
||||
{
|
||||
return _name == other._name;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
MHacheArmor::Part::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
const std::vector<unsigned char>&
|
||||
MHacheArmor::Part::slots() const
|
||||
{
|
||||
return _slots;
|
||||
}
|
||||
|
||||
const MappedSkillLevels&
|
||||
MHacheArmor::Part::skills() const
|
||||
{
|
||||
return _skills;
|
||||
}
|
||||
|
||||
MHacheArmor::ElementalResistances
|
||||
MHacheArmor::Part::resistances() const
|
||||
{
|
||||
MHacheArmor::ElementalResistances resistances;
|
||||
|
||||
if (_armor) {
|
||||
const size_t nb_parts = _armor->attached_parts().size();
|
||||
|
||||
if (nb_parts > 0) {
|
||||
resistances = _armor->resistances();
|
||||
|
||||
for (char& res: resistances)
|
||||
res /= nb_parts;
|
||||
}
|
||||
}
|
||||
|
||||
return resistances;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
MHacheArmor::Part::has_skill(std::string_view name) const
|
||||
{
|
||||
unsigned char level = 0;
|
||||
|
||||
const auto it = _skills.find(name);
|
||||
if (_skills.end() != it)
|
||||
level = it->second;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::Part::is_called(std::string_view name)
|
||||
{
|
||||
_name = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::Part::define_jewel_slots(std::vector<unsigned char>&& slots)
|
||||
{
|
||||
_slots = std::exchange(slots, {});
|
||||
return *this;
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::Part::add_skill(const MHacheSkill* skill, unsigned char level)
|
||||
{
|
||||
if (skill && level > 0 && level <= skill->levels().size())
|
||||
_skills[skill] = level;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::Part::detach()
|
||||
{
|
||||
*this = MHacheArmor::Part();
|
||||
return *this;
|
||||
}
|
||||
// -- PART --
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- ARMOR --
|
||||
MHacheArmor::MHacheArmor()
|
||||
: _name("")
|
||||
, _rarity(0)
|
||||
, _defense(0)
|
||||
, _resistances({ 0, 0, 0, 0, 0 })
|
||||
, _parts({})
|
||||
{}
|
||||
|
||||
MHacheArmor::MHacheArmor(std::string_view name, unsigned char rarity, unsigned short defense,
|
||||
ElementalResistances&& elemental_resistances)
|
||||
: _name(name)
|
||||
, _rarity(rarity)
|
||||
, _defense(defense)
|
||||
, _resistances(std::move(elemental_resistances))
|
||||
, _parts({})
|
||||
{}
|
||||
|
||||
MHacheArmor::MHacheArmor(const MHacheArmor& other)
|
||||
: MHacheArmor()
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
MHacheArmor::MHacheArmor(MHacheArmor&& other)
|
||||
: MHacheArmor()
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
MHacheArmor&
|
||||
MHacheArmor::operator =(const MHacheArmor& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
_name = other._name;
|
||||
_rarity = other._rarity;
|
||||
_defense = other._defense;
|
||||
_resistances = other._resistances;
|
||||
_parts = other._parts;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MHacheArmor&
|
||||
MHacheArmor::operator =(MHacheArmor&& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
_name = std::exchange(other._name, "");
|
||||
_rarity = std::exchange(other._rarity, 0);
|
||||
_defense = std::exchange(other._defense, 0);
|
||||
_resistances = std::exchange(other._resistances, {});
|
||||
_parts = std::exchange(other._parts, {});
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
MHacheArmor::operator <(const MHacheArmor& other) const
|
||||
{
|
||||
return _name < other._name;
|
||||
}
|
||||
|
||||
bool
|
||||
MHacheArmor::operator ==(const MHacheArmor& other) const
|
||||
{
|
||||
return _name == other._name;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
MHacheArmor::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
MHacheArmor::rarity() const
|
||||
{
|
||||
return _rarity;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
MHacheArmor::defense() const
|
||||
{
|
||||
return _defense;
|
||||
}
|
||||
|
||||
const MHacheArmor::ElementalResistances&
|
||||
MHacheArmor::resistances() const
|
||||
{
|
||||
return _resistances;
|
||||
}
|
||||
|
||||
MHacheArmor::LabelList
|
||||
MHacheArmor::attached_parts() const
|
||||
{
|
||||
LabelList labels;
|
||||
|
||||
for (const auto& p: _parts)
|
||||
if (p._armor)
|
||||
labels.push_back(p._label);
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
MHacheArmor::LabelList
|
||||
MHacheArmor::search_for_skill(std::string_view skill_name) const
|
||||
{
|
||||
LabelList labels;
|
||||
|
||||
for (const auto& p: _parts)
|
||||
if (p.has_skill(skill_name))
|
||||
labels.push_back(p._label);
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
const MHacheArmor::Part&
|
||||
MHacheArmor::operator[](size_t label) const
|
||||
{
|
||||
return _parts[label];
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::operator[](size_t label)
|
||||
{
|
||||
_parts[label]._armor = this;
|
||||
_parts[label]._label = MHacheArmor::Part::Label(label);
|
||||
return _parts[label];
|
||||
}
|
||||
|
||||
const MHacheArmor::Part&
|
||||
MHacheArmor::operator[](MHacheArmor::Part::Label label) const
|
||||
{
|
||||
return _parts[static_cast<size_t>(label)];
|
||||
}
|
||||
|
||||
MHacheArmor::Part&
|
||||
MHacheArmor::operator[](MHacheArmor::Part::Label label)
|
||||
{
|
||||
return _parts[static_cast<size_t>(label)];
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <numeric>
|
||||
|
||||
#include "mhache_factory.h"
|
||||
#include "mhache_skill.h"
|
||||
@ -40,35 +42,32 @@ MHacheFactory::load_skills(const std::filesystem::path& tomlfile)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& skill_entry: skills) {
|
||||
const auto p_skill = skill_entry.second.as_table();
|
||||
if (!p_skill) continue;
|
||||
|
||||
const auto& skill = *p_skill;
|
||||
skills.for_each([this](const toml::key& skill_name, const toml::table& skill)
|
||||
{
|
||||
const std::string name = std::string(skill_name.str());
|
||||
if (name.empty()) return false;
|
||||
|
||||
MHacheColor* color = nullptr;
|
||||
{
|
||||
std::string skill_color;
|
||||
if (!deserialize_table_node(skill, "color", skill_color))
|
||||
continue;
|
||||
return false;
|
||||
|
||||
color = MHacheColor::get_color(skill_color);
|
||||
if (!color) continue;
|
||||
}
|
||||
} if (!color) return false;
|
||||
|
||||
std::string description;
|
||||
if (!deserialize_table_node(skill, "description", description) || description.empty())
|
||||
continue;
|
||||
return false;
|
||||
|
||||
std::vector<std::string> levels;
|
||||
if (!deserialize_table_node(skill, "levels", levels) || levels.empty())
|
||||
continue;
|
||||
return false;
|
||||
|
||||
std::string name = std::string(skill_entry.first.str());
|
||||
if (name.empty()) continue;
|
||||
_skills.emplace(name, description, color, std::move(levels));
|
||||
|
||||
_skills.emplace(std::move(name), std::move(description), color, std::move(levels));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return !(_skills.empty());
|
||||
}
|
||||
@ -99,7 +98,7 @@ MHacheFactory::load_armors(const std::filesystem::path& tomlfile)
|
||||
if (!deserialize_table_node(set, "defense", defense))
|
||||
return false;
|
||||
|
||||
std::array<char, MHacheArmor::ResistanceElement::count> resistances;
|
||||
MHacheArmor::ElementalResistances resistances;
|
||||
if (!deserialize_table_node(set, "resistances", resistances))
|
||||
return false;
|
||||
|
||||
@ -107,10 +106,10 @@ MHacheFactory::load_armors(const std::filesystem::path& tomlfile)
|
||||
MHacheArmor armor(name, rarity, defense, std::move(resistances));
|
||||
|
||||
// Attach its parts
|
||||
for (unsigned char label = 0; label < MHacheArmor::Part::Appellation::count; ++label)
|
||||
for (size_t label = 0; label < MHacheArmor::Part::Label::count; ++label)
|
||||
{
|
||||
toml::table part;
|
||||
if (!deserialize_table_node(set, MHacheArmor::Part::AppellationStr[label], part))
|
||||
if (!deserialize_table_node(set, MHacheArmor::Part::label_names[label], part))
|
||||
continue;
|
||||
|
||||
std::string part_name;
|
||||
@ -125,6 +124,10 @@ MHacheFactory::load_armors(const std::filesystem::path& tomlfile)
|
||||
if (!deserialize_table_node(part, "skills", part_skills))
|
||||
continue;
|
||||
|
||||
armor[label]
|
||||
.is_called(part_name)
|
||||
.define_jewel_slots(std::move(part_slots));
|
||||
|
||||
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());
|
||||
@ -141,10 +144,6 @@ MHacheFactory::load_armors(const std::filesystem::path& tomlfile)
|
||||
armor[label].detach();
|
||||
continue;
|
||||
}
|
||||
|
||||
armor[label]
|
||||
.set_name(std::move(part_name))
|
||||
.set_slots(std::move(part_slots));
|
||||
}
|
||||
|
||||
if (armor.attached_parts().size() > 0)
|
||||
@ -155,3 +154,128 @@ MHacheFactory::load_armors(const std::filesystem::path& tomlfile)
|
||||
|
||||
return !_armors.empty();
|
||||
}
|
||||
|
||||
void
|
||||
MHacheFactory::find_builds(const MappedSkillLevels& skills_levels) const
|
||||
{
|
||||
std::array<
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>,
|
||||
MHacheArmor::Part::Label::count
|
||||
> armors_parts;
|
||||
|
||||
for (const auto& skill_level: skills_levels)
|
||||
{
|
||||
const MHacheSkill* p_skill = skill_level.first;
|
||||
if (!p_skill) continue;
|
||||
|
||||
const std::string_view skill_name = p_skill->name();
|
||||
|
||||
for (const MHacheArmor& armor: _armors) {
|
||||
const auto matching_parts = armor.search_for_skill(skill_name);
|
||||
for (const size_t idx: matching_parts)
|
||||
armors_parts[idx].insert(&armor[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
if (armors_parts.empty())
|
||||
return;
|
||||
|
||||
MappedSkillLevels build;
|
||||
std::vector<std::array<const MHacheArmor::Part*, MHacheArmor::Part::count>> results;
|
||||
std::array<const MHacheArmor::Part*, MHacheArmor::Part::count> result;
|
||||
|
||||
auto accumulate_skills = [](const MappedSkillLevels& AdditionalSkills, MappedSkillLevels& OutputSkills)
|
||||
{
|
||||
for (const auto& s: AdditionalSkills)
|
||||
OutputSkills[s.first] += s.second;
|
||||
};
|
||||
|
||||
auto is_matching_build = [](const MappedSkillLevels& Skills, const MappedSkillLevels& ExpectedSkills)
|
||||
{
|
||||
size_t cpt = 0;
|
||||
|
||||
for (const auto& s: ExpectedSkills) {
|
||||
auto it = Skills.find(s.first);
|
||||
if (Skills.end() == it) break;
|
||||
if (it->second >= s.second) ++cpt;
|
||||
}
|
||||
|
||||
return (cpt == ExpectedSkills.size());
|
||||
};
|
||||
|
||||
std::array<size_t, MHacheArmor::Part::count> parts_modulo;
|
||||
parts_modulo[MHacheArmor::Part::LEGS] = 1;
|
||||
|
||||
for (size_t i = (MHacheArmor::Part::count - 1); i-- > 0;)
|
||||
{
|
||||
parts_modulo[i] = (armors_parts[i + 1].empty() ? 1 : armors_parts[i + 1].size()) * parts_modulo[i + 1];
|
||||
}
|
||||
|
||||
/*
|
||||
const size_t modulo_legs = 1;
|
||||
const size_t modulo_waist = (armors_parts[MHacheArmor::Part::LEGS ].empty() ? 1 : armors_parts[MHacheArmor::Part::LEGS ].size()) * modulo_legs;
|
||||
const size_t modulo_arms = (armors_parts[MHacheArmor::Part::WAIST].empty() ? 1 : armors_parts[MHacheArmor::Part::WAIST].size()) * modulo_waist;
|
||||
const size_t modulo_chest = (armors_parts[MHacheArmor::Part::ARMS ].empty() ? 1 : armors_parts[MHacheArmor::Part::ARMS ].size()) * modulo_arms;
|
||||
const size_t modulo_head = (armors_parts[MHacheArmor::Part::CHEST].empty() ? 1 : armors_parts[MHacheArmor::Part::CHEST].size()) * modulo_chest;
|
||||
*/
|
||||
|
||||
const size_t combinations =
|
||||
(armors_parts[MHacheArmor::Part::HEAD ].empty() ? 1 : armors_parts[MHacheArmor::Part::HEAD ].size()) * parts_modulo[MHacheArmor::Part::HEAD];
|
||||
|
||||
std::array<
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>::iterator,
|
||||
MHacheArmor::Part::count
|
||||
> parts_iterator;
|
||||
|
||||
for (unsigned char label = 0; label < MHacheArmor::Part::count; ++label)
|
||||
parts_iterator[label] = armors_parts[label].begin();
|
||||
|
||||
/*
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>::iterator it_head = armors_parts[MHacheArmor::Part::HEAD].begin();
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>::iterator it_chest = armors_parts[MHacheArmor::Part::CHEST].begin();
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>::iterator it_arms = armors_parts[MHacheArmor::Part::ARMS].begin();
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>::iterator it_waist = armors_parts[MHacheArmor::Part::WAIST].begin();
|
||||
std::set<const MHacheArmor::Part*, PtrLessComparator<MHacheArmor::Part>>::iterator it_legs = armors_parts[MHacheArmor::Part::LEGS].begin();
|
||||
*/
|
||||
|
||||
for (size_t i = 0; i < combinations; ++i)
|
||||
{
|
||||
build = {};
|
||||
result = {};
|
||||
|
||||
for (unsigned char label = 0; label < MHacheArmor::Part::count; ++label)
|
||||
{
|
||||
if (!armors_parts[label].empty() && (0 == (i % parts_modulo[label])))
|
||||
{
|
||||
if (std::next(parts_iterator[label]) == armors_parts[label].end()) {
|
||||
parts_iterator[label] = armors_parts[label].begin();
|
||||
}
|
||||
else
|
||||
parts_iterator[label] = std::next(parts_iterator[label]);
|
||||
}
|
||||
|
||||
if (parts_iterator[label] != armors_parts[label].end()) {
|
||||
accumulate_skills((*parts_iterator[label])->skills(), build);
|
||||
result[label] = (*parts_iterator[label]);
|
||||
|
||||
if (is_matching_build(build, skills_levels)) {
|
||||
results.push_back(std::move(result));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& r: results) {
|
||||
MappedSkillLevels rlevels;
|
||||
|
||||
for (unsigned char i = 0; i < MHacheArmor::Part::count; ++i)
|
||||
{
|
||||
accumulate_skills(r[i]->skills(), rlevels);
|
||||
}
|
||||
|
||||
for (const auto& s: rlevels) {
|
||||
std::cerr << s.first->name() << " -> " << s.second << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,11 +179,18 @@ MHacheWindow::build_widgets()
|
||||
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());
|
||||
ImGui::Text("%s", armor.name().c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MappedSkillLevels seeklevels;
|
||||
for (const auto skill: filtered_skills) {
|
||||
seeklevels.insert({ skill, 1 });
|
||||
}
|
||||
|
||||
MHacheFactory::singleton().find_builds(seeklevels);
|
||||
}
|
||||
|
||||
//--
|
||||
|
Loading…
x
Reference in New Issue
Block a user