diff --git a/include/game/Mobs.h b/include/game/Mobs.h index f4d246c..9108ff7 100644 --- a/include/game/Mobs.h +++ b/include/game/Mobs.h @@ -4,6 +4,8 @@ #include "Types.h" #include "Team.h" +#include "misc/ObjectNotifier.h" + #include #include @@ -218,6 +220,18 @@ MobPtr createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender); std::string getMobName(MobType type); } +class MobListener { +public: + virtual void OnMobSpawn(MobPtr mob) {} + virtual void OnMobDie(MobPtr mob) {} + + virtual void OnMobDamage(MobPtr target, float damage, Tower* damager) {} + + virtual void OnMobTouchCastle(MobPtr damager, TeamCastle* enemyCastle) {} + virtual void OnMobCastleDamage(MobPtr damager, TeamCastle* enemyCastle) {} +}; + +typedef utils::ObjectNotifier MobNotifier; } // namespace game } // namespace td diff --git a/include/game/World.h b/include/game/World.h index e2e710f..b594513 100644 --- a/include/game/World.h +++ b/include/game/World.h @@ -10,8 +10,6 @@ #include "Mobs.h" #include "Team.h" -#include "misc/ObjectNotifier.h" - namespace td { namespace game { typedef std::pair ChunkCoord; @@ -127,15 +125,11 @@ public: virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {} virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {} - - virtual void OnMobDamage(MobPtr target, float damage, Tower* damager) {} - - virtual void OnMobDead(MobPtr mob) {} }; typedef utils::ObjectNotifier WorldNotifier; -class World : public WorldNotifier, public WorldListener { +class World : public WorldListener, public MobListener { protected: TowerTileColorPalette m_TowerPlacePalette; Color m_WalkablePalette; @@ -152,6 +146,9 @@ protected: TowerList m_Towers; Game* m_Game; + + WorldNotifier m_WorldNotifier; + MobNotifier m_MobNotifier; public: World(Game* game); @@ -211,6 +208,9 @@ public: const TowerList& getTowers() const { return m_Towers; }; TowerPtr getTowerById(TowerID tower); + WorldNotifier& getWorldNotifier() { return m_WorldNotifier; } + MobNotifier& getMobNotifier() { return m_MobNotifier; } + // WorldListener virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter); @@ -218,6 +218,8 @@ public: virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter); virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter); + // MobListener + virtual void OnMobDamage(MobPtr target, float damage, Tower* source); private: void moveMobs(std::uint64_t delta); diff --git a/src/game/Towers.cpp b/src/game/Towers.cpp index 0f179c5..3905c7b 100644 --- a/src/game/Towers.cpp +++ b/src/game/Towers.cpp @@ -213,7 +213,7 @@ 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->notifyListeners(&WorldListener::OnArcherTowerShot, mob, this); + world->getWorldNotifier().notifyListeners(&WorldListener::OnArcherTowerShot, mob, this); m_Timer.applyCooldown(); arrowsShot++; if (arrowsShot >= arrows) @@ -229,8 +229,8 @@ void IceTower::tick(std::uint64_t delta, World* world) { for (MobPtr mob : world->getMobList()) { if (isMobInRange(mob)) { mob->addEffect(EffectType::Slowness, 1, this); // slowness for 1s every second - if(damage > 0) - world->notifyListeners(&WorldListener::OnMobDamage, mob, damage, this); + if (damage > 0) + world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, damage, this); m_Timer.applyCooldown(); } } @@ -253,7 +253,7 @@ void PoisonTower::tick(std::uint64_t delta, World* world) { for (MobPtr mob : world->getMobList()) { if (isMobInRange(mob)) { if (getLevel().getPath() == TowerPath::Bottom) { - world->notifyListeners(&WorldListener::OnMobDamage, mob, getStats()->getDamage(), this); + world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, getStats()->getDamage(), this); } else { float durationSec; switch (getLevel().getLevel()) { diff --git a/src/game/World.cpp b/src/game/World.cpp index 3e43104..59567dc 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -13,7 +13,8 @@ namespace td { namespace game { World::World(Game* game) : m_Game(game) { - bindListener(this); + getWorldNotifier().bindListener(this); + getMobNotifier().bindListener(this); } TilePtr World::getTile(std::int32_t x, std::int32_t y) const { @@ -413,14 +414,14 @@ void World::OnArcherTowerShot(MobPtr target, ArcherTower* shooter) { bool fireArrows = shooter->getLevel().getPath() == TowerPath::Bottom; bool explosiveArrows = shooter->getLevel().getLevel() == 4 && fireArrows; - notifyListeners(&WorldListener::OnArrowShot, target, fireArrows, shooter); + getWorldNotifier().notifyListeners(&WorldListener::OnArrowShot, target, fireArrows, shooter); if (explosiveArrows) { - notifyListeners(&WorldListener::OnExplosion, utils::shape::Circle{ target->getCenterX(), target->getCenterY(), ArcherTower::ExplosionRadius }, shooter->getStats()->getDamage(), shooter); + getWorldNotifier().notifyListeners(&WorldListener::OnExplosion, utils::shape::Circle{ target->getCenterX(), target->getCenterY(), ArcherTower::ExplosionRadius }, shooter->getStats()->getDamage(), shooter); } } void World::OnArrowShot(MobPtr target, bool fireArrow, Tower* shooter) { - notifyListeners(&WorldListener::OnMobDamage, target, shooter->getStats()->getDamage(), shooter); + getMobNotifier().notifyListeners(&MobListener::OnMobDamage, target, shooter->getStats()->getDamage(), shooter); if (fireArrow) { target->addEffect(EffectType::Fire, ArcherTower::FireDurationSec, shooter); } @@ -431,7 +432,7 @@ void World::OnExplosion(utils::shape::Circle explosion, float centerDamage, Towe if (mob->isAlive() && mob->collidesWith(explosion)) { // linear distance damage reduction float explosionDamage = mob->distance(explosion) / explosion.getRadius() * centerDamage; - notifyListeners(&WorldListener::OnMobDamage, mob, explosionDamage, shooter); + getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, explosionDamage, shooter); } } } @@ -439,7 +440,7 @@ void World::OnExplosion(utils::shape::Circle explosion, float centerDamage, Towe void World::OnMobDamage(MobPtr target, float damage, Tower* source) { target->damage(damage, source); if (target->isDead()) { - notifyListeners(&WorldListener::OnMobDead, target); + getMobNotifier().notifyListeners(&MobListener::OnMobDie, target); } } diff --git a/src/game/client/WorldClient.cpp b/src/game/client/WorldClient.cpp index 58d093d..ca54f7c 100644 --- a/src/game/client/WorldClient.cpp +++ b/src/game/client/WorldClient.cpp @@ -37,14 +37,14 @@ void WorldClient::HandlePacket(const protocol::UpgradeTowerPacket* packet) { void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) { game::TowerPtr newTower = placeTowerAt(packet->getTowerID(), packet->getTowerType(), packet->getTowerX(), packet->getTowerY(), packet->getBuilder()); - notifyListeners(&WorldListener::OnTowerAdd, newTower); + getWorldNotifier().notifyListeners(&WorldListener::OnTowerAdd, newTower); } void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) { game::TowerPtr tower = removeTower(packet->getTowerID()); if (tower != nullptr) { - notifyListeners(&WorldListener::OnTowerRemove, tower); + getWorldNotifier().notifyListeners(&WorldListener::OnTowerRemove, tower); } } diff --git a/src/game/server/ServerConnexion.cpp b/src/game/server/ServerConnexion.cpp index 2b8f11a..1cca60a 100644 --- a/src/game/server/ServerConnexion.cpp +++ b/src/game/server/ServerConnexion.cpp @@ -160,7 +160,7 @@ void ServerConnexion::HandlePacket(const protocol::PlaceTowerPacket* packet) { game::TowerPtr tower = world->placeTowerAt(towerType, packet->getTowerX(), packet->getTowerY(), m_ID); - world->notifyListeners(&game::WorldListener::OnTowerAdd, tower); + world->getWorldNotifier().notifyListeners(&game::WorldListener::OnTowerAdd, tower); protocol::WorldAddTowerPacket addTowerPacket(tower->getID(), packet->getTowerX(), packet->getTowerY(), packet->getTowerType(), m_ID); m_Server->broadcastPacket(&addTowerPacket); diff --git a/src/render/WorldRenderer.cpp b/src/render/WorldRenderer.cpp index 3dbfff5..0b5aa1b 100644 --- a/src/render/WorldRenderer.cpp +++ b/src/render/WorldRenderer.cpp @@ -37,7 +37,7 @@ WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m m_Renderer->setCamMovement({}); m_TowerPlacePopup = std::make_unique(m_Client->getClient()); m_MobTooltip = std::make_unique(m_Client->getClient()); - m_Client->getWorld().bindListener(this); + m_Client->getWorld().getWorldNotifier().bindListener(this); } void WorldRenderer::updateCursorPos() {