diff --git a/assets/bosses.json b/assets/bosses.json index e714b3e..cf1e708 100644 --- a/assets/bosses.json +++ b/assets/bosses.json @@ -3,7 +3,7 @@ "components": [ {"_type": "BossFight", "background": "boss_fight_background", - "stage": "none", + "stage": false, "weapon_sound": "Sword_Hit_2" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, @@ -16,7 +16,7 @@ "components": [ {"_type": "BossFight", "background": "devils_fingers_background", - "stage": "none", + "stage": false, "weapon_sound": "Sword_Hit_2" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, diff --git a/boss_fight_ui.cpp b/boss_fight_ui.cpp index d6cd0ae..e92bcc8 100644 --- a/boss_fight_ui.cpp +++ b/boss_fight_ui.cpp @@ -50,14 +50,14 @@ namespace gui { void BossFightUI::configure_background() { auto& boss = $world->get($boss_id); - $boss_has_stage = boss.stage != "none"; $boss_background = textures::get(boss.background); $boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); $status.world().set_the({$status.$parser}); - if($boss_has_stage) { - $boss_stage = textures::get(boss.stage); + if(boss.stage) { + $boss_has_stage = true; + $boss_stage = textures::get(*boss.stage); $boss_stage.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); } } diff --git a/components.hpp b/components.hpp index 8ca708d..8353c39 100644 --- a/components.hpp +++ b/components.hpp @@ -1,5 +1,4 @@ #pragma once -#include "components.hpp" #include "config.hpp" #include "constants.hpp" #include "dinkyecs.hpp" @@ -7,15 +6,10 @@ #include #include #include -#include -#include +#include #include "easings.hpp" +#include "json_mods.hpp" -#define ENROLL_COMPONENT(COMPONENT, ...) \ - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \ - template <> struct NameOf { \ - static constexpr const char *name = #COMPONENT; \ - }; namespace components { using namespace nlohmann; @@ -69,7 +63,7 @@ namespace components { struct BossFight { std::string background; - std::string stage; + std::optional stage; std::string weapon_sound; }; @@ -126,8 +120,16 @@ namespace components { void step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out); }; + struct Player { + DinkyECS::Entity entity; + }; + template struct NameOf; + using ReflFuncSignature = std::function; + + using ComponentMap = std::unordered_map; + ENROLL_COMPONENT(Tile, display, foreground, background); ENROLL_COMPONENT(BossFight, background, stage, weapon_sound); ENROLL_COMPONENT(Sprite, name, width, height, scale); @@ -144,12 +146,6 @@ namespace components { speed, easing, ease_rate, stationary); ENROLL_COMPONENT(Sound, attack, death); - using ReflFuncSignature = std::function; - using ComponentMap = std::unordered_map; - struct Player { - DinkyECS::Entity entity; - }; - template COMPONENT convert(nlohmann::json &data) { COMPONENT result; from_json(data, result); diff --git a/json_mods.hpp b/json_mods.hpp new file mode 100644 index 0000000..85481af --- /dev/null +++ b/json_mods.hpp @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include + +#define ENROLL_COMPONENT(COMPONENT, ...) \ + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \ + template <> struct NameOf { \ + static constexpr const char *name = #COMPONENT; \ + }; + +// partial specialization (full specialization works too) +namespace nlohmann { + template + struct adl_serializer> { + static void to_json(json& j, const std::optional& opt) { + if (opt == std::nullopt) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, std::optional& opt) { + if (j.is_null() || j == false) { + opt = std::nullopt; + } else { + opt = std::make_optional(j.template get()); + // same as above, but with adl_serializer::from_json + } + } + }; +}