From 5059c1888b7a78bdbf2347baf4ec6372c1e6236f Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 17 Nov 2022 23:42:16 +0100 Subject: Implemented naive hit detection events --- battles/include/kurator/battles/Battle.h | 2 ++ battles/src/BaseBattle.cpp | 13 ++++++++++- battles/src/BaseBattle.h | 3 +++ kurator/src/Battle.cpp | 40 ++++++++++++++++++++++++++++++-- kurator/src/Battle.h | 3 +++ kurator/src/DamagePop.h | 15 ++++++++++++ 6 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 kurator/src/DamagePop.h diff --git a/battles/include/kurator/battles/Battle.h b/battles/include/kurator/battles/Battle.h index 82a5da5..1542597 100644 --- a/battles/include/kurator/battles/Battle.h +++ b/battles/include/kurator/battles/Battle.h @@ -3,6 +3,7 @@ #include #include +#include #include "Scenario.h" @@ -18,6 +19,7 @@ class Battle public: virtual ~Battle() = default; virtual entt::registry& registry() = 0; + virtual entt::dispatcher& dispatcher() = 0; virtual void update(float dt) = 0; }; diff --git a/battles/src/BaseBattle.cpp b/battles/src/BaseBattle.cpp index e7d70c2..4088936 100644 --- a/battles/src/BaseBattle.cpp +++ b/battles/src/BaseBattle.cpp @@ -1,8 +1,10 @@ #include "BaseBattle.h" #include +#include #include +#include #include #include @@ -37,6 +39,13 @@ BaseBattle::registry() } +entt::dispatcher& +BaseBattle::dispatcher() +{ + return _dispatcher; +} + + void BaseBattle::update(const float dt) { @@ -108,8 +117,10 @@ BaseBattle::turrets(const float dt) auto& target_points = _registry.get(state.target); const auto& target = _registry.get(state.target); const auto distance = transform.position - target.position; - if (def.range > distance.magnitude()) + if (def.range > distance.magnitude()) { target_points.health -= def.base_damage; + _dispatcher.trigger(Hit{def.base_damage, entity, state.target}); + } control.reload = def.rate_of_fire; } } diff --git a/battles/src/BaseBattle.h b/battles/src/BaseBattle.h index 02cc024..8240fd2 100644 --- a/battles/src/BaseBattle.h +++ b/battles/src/BaseBattle.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -20,9 +21,11 @@ class BaseBattle : public Battle public: BaseBattle(const Scenario& scenario); entt::registry& registry() override; + entt::dispatcher& dispatcher() override; void update(float dt) override; private: entt::registry _registry; + entt::dispatcher _dispatcher; RandomSpawner spawner; TeamManager manager; void pick_random_targets(); diff --git a/kurator/src/Battle.cpp b/kurator/src/Battle.cpp index f78675c..ffddc92 100644 --- a/kurator/src/Battle.cpp +++ b/kurator/src/Battle.cpp @@ -8,10 +8,12 @@ #include #include +#include #include #include #include +#include "DamagePop.h" #include "Session.h" #include "Title.h" @@ -24,6 +26,13 @@ Battle::Battle(std::shared_ptr _session) : session {std::move(_session)}, battle {battles::prepare(battles::scenarios::example())} { + battle->dispatcher().sink().connect<&Battle::receive>(*this); +} + + +Battle::~Battle() +{ + battle->dispatcher().sink().disconnect(*this); } @@ -31,6 +40,13 @@ void Battle::update(const float dt) { battle->update(dt); + auto& registry = battle->registry(); + auto pops = registry.view(); + for (auto&& [entity, pop] : pops.each()) { + pop.timer -= dt; + if (pop.timer < 0.0) + registry.destroy(entity); + } if (IsKeyPressed(KEY_SPACE)) session->set(std::make_shared(session)); } @@ -43,9 +59,9 @@ Battle::draw() const const int width = GetScreenWidth(); const int height = GetScreenHeight(); const double scale = std::min(width/10.0, height/10.0); - auto view = battle->registry().view<const universe::ShipType, const battles::Team, const battles::Transform>(); + auto& registry = battle->registry(); + auto view = registry.view<const universe::ShipType, const battles::Team, const battles::Transform>(); for (auto [entity, ship_type, team, transform] : view.each()) { - (void) entity; const auto color = team.id == 1 ? RED : GREEN; const int x = width/2 + transform.position.x*scale; const int y = height/2 + transform.position.y*scale; @@ -53,6 +69,26 @@ Battle::draw() const DrawLine(x, y, x + 6 * std::cos(transform.angle), y + 6 * std::sin(transform.angle), WHITE); DrawText(ship_type.name.c_str(), x+10, y-10, 20.0f, GRAY); } + auto pops = registry.view<DamagePop, const battles::Transform>(); + for (auto [entity, pop, transform] : pops.each()) { + const int x = width/2 + transform.position.x*scale; + const int y = height/2 + transform.position.y*scale; + const int text = MeasureText(pop.text, 10); + DrawText(pop.text, x-text/2, y-5-22*(0.4-pop.timer), 10, RED); + } +} + + +void +Battle::receive(const battles::Hit& hit) +{ + auto& registry = battle->registry(); + if (!registry.valid(hit.victim)) + return; + const auto entity = registry.create(); + const auto& transform = registry.get<battles::Transform>(hit.victim); + registry.emplace<DamagePop>(entity, 0.4, TextFormat("%.1f", hit.damage)); + registry.emplace<battles::Transform>(entity, transform.position, 0.0); } diff --git a/kurator/src/Battle.h b/kurator/src/Battle.h index 64cdb47..d59f024 100644 --- a/kurator/src/Battle.h +++ b/kurator/src/Battle.h @@ -3,6 +3,7 @@ #include <memory> #include <kurator/battles/Battle.h> +#include <kurator/battles/events.h> #include "Scene.h" #include "Session.h" @@ -16,8 +17,10 @@ class Battle : public Scene { public: explicit Battle(std::shared_ptr<Session> _session); + virtual ~Battle(); void update(float dt) override; void draw() const override; + void receive(const battles::Hit& hit); private: std::shared_ptr<Session> session; std::unique_ptr<battles::Battle> battle; diff --git a/kurator/src/DamagePop.h b/kurator/src/DamagePop.h new file mode 100644 index 0000000..dc4c19a --- /dev/null +++ b/kurator/src/DamagePop.h @@ -0,0 +1,15 @@ +#pragma once + + +namespace kurator +{ + + +struct DamagePop +{ + double timer; + const char* text; +}; + + +} // namespace kurator -- cgit v1.1