BillySheet/src/billy_objects.cpp

158 lines
8.1 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() < max_obj) {
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;
}
bool BillyObjects::is_full(const CharacterSheet &sheet) noexcept {
return sheet.get_objects().size() >= max_obj;
}
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()) {
if (sheet.get_nb_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);
});
}
}