// // Created by postaron on 23/02/24. // #include "billy_objects.hpp" #include #include "characteristic/characteristic.hpp" #include "character_sheet.hpp" std::uint32_t constexpr 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; void BillyObjects::push_object(const billyObject &object, CharacterSheet &sheet) noexcept { if (sheet.objects.size() < 3) { sheet.objects.emplace_back(object); 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 &arg) { ++sheet.nb_weapons; change_carac_weapon(arg, sheet, local_habilete, local_adresse, local_endurance, plus); }, [&](const equipments &arg) { ++sheet.nb_equipments; change_carac_equipment(arg, sheet, local_habilete, local_adresse, local_endurance, local_chance, plus, minus); }, [&](const tools &arg) { ++sheet.nb_tools; change_carac_tools(arg, sheet, local_habilete, local_adresse, local_endurance, local_chance, plus); }, }, object); } } void BillyObjects::pop_object(CharacterSheet &sheet) noexcept { if (!sheet.objects.empty()) { const billyObject obj = sheet.objects.back(); sheet.objects.pop_back(); 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 &arg) { --sheet.nb_weapons; change_carac_weapon(arg, sheet, local_habilete, local_adresse, local_endurance, minus); }, [&](const equipments &arg) { --sheet.nb_equipments; change_carac_equipment(arg, sheet, local_habilete, local_adresse, local_endurance, local_chance, minus, plus); }, [&](const tools &arg) { --sheet.nb_tools; change_carac_tools(arg, sheet, local_habilete, local_adresse, local_endurance, local_chance, minus); } }, obj); } } void BillyObjects::change_carac_tools(const tools &arg, CharacterSheet &sheet, Characteristic &localHabilete, Characteristic &localAdresse, Characteristic &localEndurance, Characteristic &localChance, const std::function &operation) noexcept { switch (arg) { case tools::Fourche: localHabilete.materiel = operation(localHabilete.materiel, 1); localEndurance.materiel = operation(localEndurance.materiel, 3); break; case tools::Dagger: break; case tools::RockClimbingKit: localAdresse.materiel = operation(localAdresse.materiel, 1); break; case tools::SackOfGrain: localEndurance.materiel = operation(localEndurance.materiel, 2); localChance.materiel = operation(localChance.materiel, 2); break; } } void BillyObjects::change_carac_equipment(const equipments &arg, CharacterSheet &sheet, Characteristic &localHabilete, Characteristic &localAdresse, Characteristic &localEndurance, Characteristic &localChance, const std::function &primary, const std::function &complement) noexcept { switch (arg) { case equipments::Chainmail: localHabilete.materiel = complement(localHabilete.materiel, 1); localAdresse.materiel = complement(localAdresse.materiel, 1); localEndurance.materiel = primary(localEndurance.materiel, 1); sheet.armor = primary(sheet.armor, 2); break; case equipments::CookingPot: localEndurance.materiel = primary(localEndurance.materiel, 2); sheet.armor = primary(sheet.armor, 1); break; case equipments::PamphletTourist: localChance.materiel = primary(localChance.materiel, 4); break; case equipments::MedicKit: localChance.materiel = primary(localChance.materiel, 1); break; } } void BillyObjects::change_carac_weapon(const weapons &arg, CharacterSheet &sheet, Characteristic &localHabilete, Characteristic &localAdresse, Characteristic &localEndurance, const std::function &operation) noexcept { switch (arg) { case weapons::Sword: localHabilete.materiel = operation(localHabilete.materiel, 4); break; case weapons::Lance: localHabilete.materiel = operation(localHabilete.materiel, 3); localAdresse.materiel = operation(localAdresse.materiel, 1); break; case weapons::Morgenstern: localHabilete.materiel = operation(localHabilete.materiel, 1); localEndurance.materiel = operation(localEndurance.materiel, 1); sheet.damage = operation(sheet.damage, 1); break; case weapons::Bow: localHabilete.materiel = operation(localHabilete.materiel, 3); localAdresse.materiel = operation(localAdresse.materiel, 1); break; } } std::string_view BillyObjects::billy_object_to_string(const billyObject &object) noexcept { return std::visit(overloaded{ [](const weapons &arg) { switch (arg) { case weapons::Sword: return sword; case weapons::Lance: return lance; case weapons::Morgenstern: return morgenstern; case weapons::Bow: return bow; } }, [](const equipments &arg) { switch (arg) { case equipments::Chainmail: return chainmail; case equipments::CookingPot: return cooking_pot; case equipments::MedicKit: return medic_kit; case equipments::PamphletTourist: return pamphlet_tourist; } }, [](const tools &arg) { switch (arg) { case tools::Fourche: return fourche; case tools::Dagger: return dagger; case tools::RockClimbingKit: return rock_climbing_kit; case tools::SackOfGrain: return sack_of_grain; } } }, object); } void BillyObjects::from_json(const json &j, BillyObjects::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.push_back(static_cast(value)); break; case equipmentHash: billy.push_back(static_cast(value)); break; case toolsHash: billy.push_back(static_cast(value)); break; } } } void BillyObjects::to_json(json &j, const BillyObjects::container &billy) { for (const auto &object: billy) { 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) }); } }, object); } } }