From a241d7691b589a2d730087b5e712d05f46d532ce Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sat, 11 Dec 2021 19:51:45 +0100 Subject: [PATCH] refactor: mob die event --- include/game/Mobs.h | 12 ++++++------ include/game/World.h | 4 +++- src/game/Mobs.cpp | 10 +++++----- src/game/Towers.cpp | 4 ++-- src/game/World.cpp | 29 ++++++++++++++++------------- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/include/game/Mobs.h b/include/game/Mobs.h index 7c263d0..4edf40b 100644 --- a/include/game/Mobs.h +++ b/include/game/Mobs.h @@ -73,7 +73,7 @@ public: struct EffectDuration { EffectType type; float duration; // in seconds - const Tower* tower; // the tower that gived the effect + Tower* tower; // the tower that gived the effect }; const MobStats* getMobStats(MobType type, std::uint8_t level); @@ -129,7 +129,7 @@ public: bool isImmuneTo(TowerType type); bool isImmuneTo(EffectType type); - void addEffect(EffectType type, float durationSec, const Tower* tower); + void addEffect(EffectType type, float durationSec, Tower* tower); bool hasEffect(EffectType type); float getTileX() { return getCenterX() - static_cast(static_cast(getCenterX())); } // returns a float between 0 and 1 excluded @@ -143,7 +143,7 @@ protected: setSize(getStats()->getSize().x, getStats()->getSize().y); } private: - void updateEffects(std::uint64_t delta); + void updateEffects(std::uint64_t delta, World* world); void attackCastle(std::uint64_t delta, World* world); void move(std::uint64_t delta, World* world); void walk(std::uint64_t delta, World* world); @@ -232,10 +232,10 @@ std::string getMobName(MobType type); class MobListener { public: - virtual void OnMobSpawn(MobPtr mob) {} - virtual void OnMobDie(MobPtr mob) {} + virtual void OnMobSpawn(Mob* mob) {} + virtual void OnMobDie(Mob* mob) {} - virtual void OnMobDamage(MobPtr target, float damage, Tower* damager) {} + virtual void OnMobDamage(Mob* target, float damage, Tower* damager) {} virtual void OnMobTouchCastle(Mob* damager, TeamCastle* enemyCastle) {} virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {} diff --git a/include/game/World.h b/include/game/World.h index 8913ad6..a13afce 100644 --- a/include/game/World.h +++ b/include/game/World.h @@ -222,7 +222,9 @@ public: // MobListener - virtual void OnMobDamage(MobPtr target, float damage, Tower* source); + virtual void OnMobDamage(Mob* target, float damage, Tower* source); + + virtual void OnMobDie(Mob* mob); private: void tickMobs(std::uint64_t delta); void cleanDeadMobs(); diff --git a/src/game/Mobs.cpp b/src/game/Mobs.cpp index 60cac82..e715ce4 100644 --- a/src/game/Mobs.cpp +++ b/src/game/Mobs.cpp @@ -20,7 +20,7 @@ EffectDuration& Mob::getEffect(EffectType effectType) { return *std::find_if(m_Effects.begin(), m_Effects.end(), [&effectType](EffectDuration effect) { return effect.type == effectType;}); } -void Mob::addEffect(EffectType effectType, float durationSec, const Tower* tower) { +void Mob::addEffect(EffectType effectType, float durationSec, Tower* tower) { if (isImmuneTo(effectType)) return; if (hasEffect(effectType)) { @@ -194,12 +194,12 @@ bool Mob::isTouchingCastle(const TeamCastle& enemyCastle) const { } void Mob::tick(std::uint64_t delta, World* world) { - updateEffects(delta); + updateEffects(delta, world); move(delta, world); attackCastle(delta, world); } -void Mob::updateEffects(std::uint64_t delta) { +void Mob::updateEffects(std::uint64_t delta, World* world) { float deltaSec = (float)delta / 1000.0f; for (std::size_t i = 0; i < m_Effects.size(); i++) { EffectDuration& effect = m_Effects[i]; @@ -228,12 +228,12 @@ void Mob::updateEffects(std::uint64_t delta) { } if (hasEffect(EffectType::Fire)) { if (m_EffectFireTimer.update(delta)) { - damage(3, getEffect(EffectType::Fire).tower); + world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, this, 3.0f, getEffect(EffectType::Fire).tower); } } if (hasEffect(EffectType::Poison)) { if (m_EffectPoisonTimer.update(delta)) { - damage(1, getEffect(EffectType::Poison).tower); + world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, this, 1.0f, getEffect(EffectType::Poison).tower); } } if (hasEffect(EffectType::Heal)) { diff --git a/src/game/Towers.cpp b/src/game/Towers.cpp index 3905c7b..5dd0464 100644 --- a/src/game/Towers.cpp +++ b/src/game/Towers.cpp @@ -230,7 +230,7 @@ void IceTower::tick(std::uint64_t delta, World* world) { if (isMobInRange(mob)) { mob->addEffect(EffectType::Slowness, 1, this); // slowness for 1s every second if (damage > 0) - world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, damage, this); + world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob.get(), 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->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, getStats()->getDamage(), this); + world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob.get(), getStats()->getDamage(), this); } else { float durationSec; switch (getLevel().getLevel()) { diff --git a/src/game/World.cpp b/src/game/World.cpp index 208b1fc..4724e61 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -214,20 +214,23 @@ bool World::CanPlaceBigTower(const glm::vec2& worldPos, PlayerID playerID) const return false; } +void World::OnMobDie(Mob* mob) { + if (mob->OnDeath(this)) { // check if the mob is actually dead (slimes ...) + //reward players + Player* sender = m_Game->getPlayerById(mob->getSender()); + sender->addExp(mob->getStats()->getExpReward()); + + Player* killer = m_Game->getPlayerById(mob->getLastDamageTower()->getBuilder()); + killer->addGold(mob->getStats()->getMoneyCost()); + } +} + void World::cleanDeadMobs() { + // safely remove mobs when unused for (std::size_t i = 0; i < m_Mobs.size(); i++) { MobPtr mob = m_Mobs[i]; if (mob->isDead()) { - if (mob->OnDeath(this)) { - //reward players - Player* sender = m_Game->getPlayerById(mob->getSender()); - sender->addExp(mob->getStats()->getExpReward()); - - Player* killer = m_Game->getPlayerById(mob->getLastDamageTower()->getBuilder()); - killer->addGold(mob->getStats()->getMoneyCost()); - - m_Mobs.erase(m_Mobs.begin() + i); - } + m_Mobs.erase(m_Mobs.begin() + i); } } } @@ -266,7 +269,7 @@ void World::OnArcherTowerShot(MobPtr target, ArcherTower* shooter) { } void World::OnArrowShot(MobPtr target, bool fireArrow, Tower* shooter) { - getMobNotifier().notifyListeners(&MobListener::OnMobDamage, target, shooter->getStats()->getDamage(), shooter); + getMobNotifier().notifyListeners(&MobListener::OnMobDamage, target.get(), shooter->getStats()->getDamage(), shooter); if (fireArrow) { target->addEffect(EffectType::Fire, ArcherTower::FireDurationSec, shooter); } @@ -277,12 +280,12 @@ 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; - getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, explosionDamage, shooter); + getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob.get(), explosionDamage, shooter); } } } -void World::OnMobDamage(MobPtr target, float damage, Tower* source) { +void World::OnMobDamage(Mob* target, float damage, Tower* source) { target->damage(damage, source); if (target->isDead()) { getMobNotifier().notifyListeners(&MobListener::OnMobDie, target);