160 lines
8.4 KiB
C++
160 lines
8.4 KiB
C++
#include "billy_objects.hpp"
|
|
#include "characteristic.hpp"
|
|
#include "character_sheet.hpp"
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
constexpr std::uint32_t const_hash(const char *input) {
|
|
return *input ? static_cast<unsigned int>(*input) + 33 * const_hash(input + 1) : 5381;
|
|
}
|
|
|
|
constexpr std::uint32_t weaponsHash = const_hash("weapons");
|
|
constexpr std::uint32_t equipmentHash = const_hash("equipments");
|
|
constexpr std::uint32_t toolsHash = const_hash("tools");
|
|
|
|
namespace character {
|
|
using characteristic::Characteristic;
|
|
|
|
|
|
bool BillyObjects::insert_object(CharacterSheet &sheet, const billyEnums objType) noexcept {
|
|
if (sheet.objects.size() < 3) {
|
|
sheet.objects.emplace(objType,
|
|
std::visit(overloaded{
|
|
[](const weapons &arg) {
|
|
return std::unique_ptr<GenericObject>(
|
|
std::make_unique<Weapons>(arg)
|
|
);
|
|
},
|
|
[](const equipments &arg) {
|
|
return std::unique_ptr<GenericObject>(
|
|
std::make_unique<Equipments>(arg)
|
|
);
|
|
},
|
|
[](const tools &arg) {
|
|
return std::unique_ptr<GenericObject>(
|
|
std::make_unique<Tools>(arg)
|
|
);
|
|
},
|
|
},
|
|
objType));
|
|
const auto &object = sheet.objects[objType];
|
|
sheet.available_objects.erase(objType);
|
|
|
|
auto &local_habilete = static_cast<Characteristic &>(sheet.habilete);
|
|
auto &local_adresse = static_cast<Characteristic &>(sheet.adresse);
|
|
auto &local_endurance = static_cast<Characteristic &>(sheet.endurance);
|
|
auto &local_chance = static_cast<Characteristic &>(sheet.chance);
|
|
|
|
std::visit(overloaded{
|
|
[&](const weapons &) { ++sheet.nb_weapons; },
|
|
[&](const equipments &) { ++sheet.nb_equipments; },
|
|
[&](const tools &) { ++sheet.nb_tools; },
|
|
},
|
|
objType);
|
|
change_carac(object, sheet, local_habilete, local_adresse, local_endurance, local_chance, plus);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BillyObjects::erase_object(CharacterSheet &sheet, const billyEnums objToErase) noexcept {
|
|
if (const auto it = sheet.objects.find(objToErase); it != std::end(sheet.objects)) {
|
|
const billyObjects obj{ it->second.release() };
|
|
sheet.objects.erase(objToErase);
|
|
sheet.available_objects.insert(objToErase);
|
|
|
|
auto &local_habilete = static_cast<Characteristic &>(sheet.habilete);
|
|
auto &local_adresse = static_cast<Characteristic &>(sheet.adresse);
|
|
auto &local_endurance = static_cast<Characteristic &>(sheet.endurance);
|
|
auto &local_chance = static_cast<Characteristic &>(sheet.chance);
|
|
|
|
std::visit(overloaded{
|
|
[&](const weapons &) { --sheet.nb_weapons; },
|
|
[&](const equipments &) { --sheet.nb_equipments; },
|
|
[&](const tools &) { --sheet.nb_tools; }
|
|
},
|
|
objToErase);
|
|
change_carac(obj, sheet, local_habilete, local_adresse, local_endurance, local_chance, minus);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void BillyObjects::change_carac(const billyObjects &arg,
|
|
CharacterSheet &sheet,
|
|
Characteristic &localHabilete,
|
|
Characteristic &localAdresse,
|
|
Characteristic &localEndurance,
|
|
Characteristic &localChance,
|
|
const std::function<std::uint32_t(std::uint32_t, std::uint32_t)> &operation)
|
|
noexcept {
|
|
localHabilete.materiel = operation(localHabilete.materiel, arg->add_materiel(localHabilete.type));
|
|
localAdresse.materiel = operation(localAdresse.materiel, arg->add_materiel(localAdresse.type));
|
|
localEndurance.materiel = operation(localEndurance.materiel, arg->add_materiel(localEndurance.type));
|
|
localChance.materiel = operation(localChance.materiel, arg->add_materiel(localChance.type));
|
|
sheet.armor = operation(sheet.armor, arg->add_armor());
|
|
sheet.damage = operation(sheet.armor, arg->add_damage());
|
|
sheet.critique = operation(sheet.critique, arg->add_critique());
|
|
}
|
|
|
|
void BillyObjects::check_dagger_conditions(CharacterSheet &sheet) {
|
|
if (const auto it_dagger = sheet.get_objects().find(tools::Dagger); it_dagger != sheet.get_objects().cend()) {
|
|
const std::size_t count_weapons = std::ranges::count_if(sheet.get_objects(),
|
|
[](container::const_reference node) {
|
|
return std::get_if<weapons>(&node.first) !=
|
|
nullptr;
|
|
}
|
|
);
|
|
if (count_weapons > 1 || sheet.get_objects().contains(weapons::Bow)) {
|
|
sheet.habilete.materiel -= it_dagger->second->add_materiel(sheet.get_habilete().type);
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string_view BillyObjects::billy_object_to_string(const billyObjects &object) noexcept {
|
|
return object->to_string();
|
|
}
|
|
|
|
void BillyObjects::from_json(const json &j, container &billy) {
|
|
for (const auto &element: j) {
|
|
const std::uint32_t key = element[0].get<std::uint32_t>();
|
|
const std::uint8_t value = element[1].get<std::uint8_t>();
|
|
switch (key) {
|
|
case weaponsHash:
|
|
billy.emplace(static_cast<weapons>(value), std::make_unique<Weapons>(static_cast<weapons>(value)));
|
|
break;
|
|
case equipmentHash:
|
|
billy.emplace(static_cast<equipments>(value),
|
|
std::make_unique<Equipments>(static_cast<equipments>(value)));
|
|
break;
|
|
case toolsHash:
|
|
billy.emplace(static_cast<tools>(value), std::make_unique<Tools>(static_cast<tools>(value)));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BillyObjects::to_json(json &j, const container &billy) {
|
|
std::ranges::for_each(billy | std::views::keys,
|
|
[&j](const auto &obj) {
|
|
std::visit(overloaded{
|
|
[&j](const weapons weapon) {
|
|
j.emplace_back(std::pair{
|
|
weaponsHash, static_cast<std::uint8_t>(weapon)
|
|
});
|
|
},
|
|
[&j](const equipments equipment) {
|
|
j.emplace_back(std::pair{
|
|
equipmentHash, static_cast<std::uint8_t>(equipment)
|
|
});
|
|
},
|
|
[&j](const tools tool) {
|
|
j.emplace_back(std::pair{
|
|
toolsHash, static_cast<std::uint8_t>(tool)
|
|
});
|
|
}
|
|
},
|
|
obj);
|
|
});
|
|
}
|
|
}
|