From 1843fc6f4d10f58b745c16c63bb48dbd1dc1f660 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Tue, 30 Nov 2021 18:01:48 +0100 Subject: [PATCH] feat: add archer tower aoe --- include/game/World.h | 24 +++++++++++++++++++++--- src/game/Towers.cpp | 4 ++-- src/game/World.cpp | 25 ++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/include/game/World.h b/include/game/World.h index 3be569d..d3f4fa7 100644 --- a/include/game/World.h +++ b/include/game/World.h @@ -114,7 +114,19 @@ typedef std::array SpawnColorPalette; typedef std::vector TowerList; -class World { +class WorldListener { +public: + WorldListener(){} + + virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter){} + + virtual void OnArrowShot(MobPtr target, Tower* shooter){} + virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter){} + + virtual void OnMobDamage(MobPtr target, float damage){} +}; + +class World : public WorldListener{ protected: TowerTileColorPalette m_TowerPlacePalette; Color m_WalkablePalette; @@ -189,8 +201,14 @@ public: const TowerList& getTowers() const { return m_Towers; }; TowerPtr getTowerById(TowerID tower); - // Archer Tower - virtual void OnArrowShot(MobPtr target, Tower* shooter); + // WorldListener + + virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter){} + + virtual void OnArrowShot(MobPtr target, Tower* shooter){} + virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter){} + + virtual void OnMobDamage(MobPtr target, float damage, Tower* source){} private: void moveMobs(std::uint64_t delta); void moveMob(MobPtr mob, std::uint64_t delta); diff --git a/src/game/Towers.cpp b/src/game/Towers.cpp index a200a88..2fc6d5a 100644 --- a/src/game/Towers.cpp +++ b/src/game/Towers.cpp @@ -213,11 +213,11 @@ void ArcherTower::tick(std::uint64_t delta, World* world) { std::uint8_t arrows = explosiveArrows ? 2 : getLevel().getLevel(); for (MobPtr mob : world->getMobList()) { if (isMobInRange(mob)) { - world->OnArrowShot(mob, this); + world->OnArcherTowerShot(mob, this); + m_Timer.applyCooldown(); arrowsShot++; if (arrowsShot >= arrows) break; - m_Timer.applyCooldown(); } } } diff --git a/src/game/World.cpp b/src/game/World.cpp index d67c628..f517a0c 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -398,15 +398,34 @@ TowerPtr World::getTowerById(TowerID towerID) { return *it; } -void World::OnArrowShot(MobPtr target, Tower* shooter) { +void World::OnArcherTowerShot(MobPtr target, ArcherTower* shooter) { bool explosiveArrows = shooter->getLevel().getPath() == TowerPath::Bottom; if (explosiveArrows) { - // aoe damage + OnArrowShot(target, shooter); + OnExplosion({ target->getCenterX(), target->getCenterY(), 1.0f }, 10.0f, shooter); } else { - target->damage(shooter->getStats()->getDamage(), shooter); + OnArrowShot(target, shooter); } } +void World::OnArrowShot(MobPtr target, Tower* shooter) { + OnMobDamage(target, shooter->getStats()->getDamage(), shooter); +} + +void World::OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) { + for (MobPtr mob : m_Mobs) { + if (mob->collidesWith(explosion)) { + // linear distance damage reduction + float explosionDamage = mob->distance(explosion) / explosion.getRadius() * centerDamage; + OnMobDamage(mob, explosionDamage, shooter); + } + } +} + +void World::OnMobDamage(MobPtr target, float damage, Tower* source){ + target->damage(damage, source); +} + Team& World::getRedTeam() { return m_Game->getRedTeam(); }