#include "billy_objects.hpp" #include "characteristic.hpp" #include "character_sheet.hpp" #include constexpr std::uint32_t const_hash(const char *input) { return *input ? static_cast(*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( std::make_unique(arg) ); }, [](const equipments &arg) { return std::unique_ptr( std::make_unique(arg) ); }, [](const tools &arg) { return std::unique_ptr( std::make_unique(arg) ); }, }, objType)); const auto &object = sheet.objects[objType]; sheet.available_objects.erase(objType); auto &local_habilete = static_cast(sheet.habilete); auto &local_adresse = static_cast(sheet.adresse); auto &local_endurance = static_cast(sheet.endurance); auto &local_chance = static_cast(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(sheet.habilete); auto &local_adresse = static_cast(sheet.adresse); auto &local_endurance = static_cast(sheet.endurance); auto &local_chance = static_cast(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 &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(&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(); const std::uint8_t value = element[1].get(); switch (key) { case weaponsHash: billy.emplace(static_cast(value), std::make_unique(static_cast(value))); break; case equipmentHash: billy.emplace(static_cast(value), std::make_unique(static_cast(value))); break; case toolsHash: billy.emplace(static_cast(value), std::make_unique(static_cast(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(weapon) }); }, [&j](const equipments equipment) { j.emplace_back(std::pair{ equipmentHash, static_cast(equipment) }); }, [&j](const tools tool) { j.emplace_back(std::pair{ toolsHash, static_cast(tool) }); } }, obj); }); } }