refactor: separate mob ans world listener
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
|
|
||||||
|
#include "misc/ObjectNotifier.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -218,6 +220,18 @@ MobPtr createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
|
|||||||
std::string getMobName(MobType type);
|
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<MobListener> MobNotifier;
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
#include "Mobs.h"
|
#include "Mobs.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
|
|
||||||
#include "misc/ObjectNotifier.h"
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace game {
|
namespace game {
|
||||||
typedef std::pair<std::int16_t, std::int16_t> ChunkCoord;
|
typedef std::pair<std::int16_t, std::int16_t> ChunkCoord;
|
||||||
@@ -127,15 +125,11 @@ public:
|
|||||||
|
|
||||||
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {}
|
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {}
|
||||||
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, 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<WorldListener> WorldNotifier;
|
typedef utils::ObjectNotifier<WorldListener> WorldNotifier;
|
||||||
|
|
||||||
class World : public WorldNotifier, public WorldListener {
|
class World : public WorldListener, public MobListener {
|
||||||
protected:
|
protected:
|
||||||
TowerTileColorPalette m_TowerPlacePalette;
|
TowerTileColorPalette m_TowerPlacePalette;
|
||||||
Color m_WalkablePalette;
|
Color m_WalkablePalette;
|
||||||
@@ -152,6 +146,9 @@ protected:
|
|||||||
TowerList m_Towers;
|
TowerList m_Towers;
|
||||||
|
|
||||||
Game* m_Game;
|
Game* m_Game;
|
||||||
|
|
||||||
|
WorldNotifier m_WorldNotifier;
|
||||||
|
MobNotifier m_MobNotifier;
|
||||||
public:
|
public:
|
||||||
World(Game* game);
|
World(Game* game);
|
||||||
|
|
||||||
@@ -211,6 +208,9 @@ public:
|
|||||||
const TowerList& getTowers() const { return m_Towers; };
|
const TowerList& getTowers() const { return m_Towers; };
|
||||||
TowerPtr getTowerById(TowerID tower);
|
TowerPtr getTowerById(TowerID tower);
|
||||||
|
|
||||||
|
WorldNotifier& getWorldNotifier() { return m_WorldNotifier; }
|
||||||
|
MobNotifier& getMobNotifier() { return m_MobNotifier; }
|
||||||
|
|
||||||
// WorldListener
|
// WorldListener
|
||||||
|
|
||||||
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter);
|
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter);
|
||||||
@@ -218,6 +218,8 @@ public:
|
|||||||
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter);
|
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter);
|
||||||
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter);
|
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter);
|
||||||
|
|
||||||
|
// MobListener
|
||||||
|
|
||||||
virtual void OnMobDamage(MobPtr target, float damage, Tower* source);
|
virtual void OnMobDamage(MobPtr target, float damage, Tower* source);
|
||||||
private:
|
private:
|
||||||
void moveMobs(std::uint64_t delta);
|
void moveMobs(std::uint64_t delta);
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ void ArcherTower::tick(std::uint64_t delta, World* world) {
|
|||||||
std::uint8_t arrows = explosiveArrows ? 2 : getLevel().getLevel();
|
std::uint8_t arrows = explosiveArrows ? 2 : getLevel().getLevel();
|
||||||
for (MobPtr mob : world->getMobList()) {
|
for (MobPtr mob : world->getMobList()) {
|
||||||
if (isMobInRange(mob)) {
|
if (isMobInRange(mob)) {
|
||||||
world->notifyListeners(&WorldListener::OnArcherTowerShot, mob, this);
|
world->getWorldNotifier().notifyListeners(&WorldListener::OnArcherTowerShot, mob, this);
|
||||||
m_Timer.applyCooldown();
|
m_Timer.applyCooldown();
|
||||||
arrowsShot++;
|
arrowsShot++;
|
||||||
if (arrowsShot >= arrows)
|
if (arrowsShot >= arrows)
|
||||||
@@ -230,7 +230,7 @@ void IceTower::tick(std::uint64_t delta, World* world) {
|
|||||||
if (isMobInRange(mob)) {
|
if (isMobInRange(mob)) {
|
||||||
mob->addEffect(EffectType::Slowness, 1, this); // slowness for 1s every second
|
mob->addEffect(EffectType::Slowness, 1, this); // slowness for 1s every second
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
world->notifyListeners(&WorldListener::OnMobDamage, mob, damage, this);
|
world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, damage, this);
|
||||||
m_Timer.applyCooldown();
|
m_Timer.applyCooldown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,7 +253,7 @@ void PoisonTower::tick(std::uint64_t delta, World* world) {
|
|||||||
for (MobPtr mob : world->getMobList()) {
|
for (MobPtr mob : world->getMobList()) {
|
||||||
if (isMobInRange(mob)) {
|
if (isMobInRange(mob)) {
|
||||||
if (getLevel().getPath() == TowerPath::Bottom) {
|
if (getLevel().getPath() == TowerPath::Bottom) {
|
||||||
world->notifyListeners(&WorldListener::OnMobDamage, mob, getStats()->getDamage(), this);
|
world->getMobNotifier().notifyListeners(&MobListener::OnMobDamage, mob, getStats()->getDamage(), this);
|
||||||
} else {
|
} else {
|
||||||
float durationSec;
|
float durationSec;
|
||||||
switch (getLevel().getLevel()) {
|
switch (getLevel().getLevel()) {
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
World::World(Game* game) : m_Game(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 {
|
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 fireArrows = shooter->getLevel().getPath() == TowerPath::Bottom;
|
||||||
bool explosiveArrows = shooter->getLevel().getLevel() == 4 && fireArrows;
|
bool explosiveArrows = shooter->getLevel().getLevel() == 4 && fireArrows;
|
||||||
|
|
||||||
notifyListeners(&WorldListener::OnArrowShot, target, fireArrows, shooter);
|
getWorldNotifier().notifyListeners(&WorldListener::OnArrowShot, target, fireArrows, shooter);
|
||||||
if (explosiveArrows) {
|
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) {
|
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) {
|
if (fireArrow) {
|
||||||
target->addEffect(EffectType::Fire, ArcherTower::FireDurationSec, shooter);
|
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)) {
|
if (mob->isAlive() && mob->collidesWith(explosion)) {
|
||||||
// linear distance damage reduction
|
// linear distance damage reduction
|
||||||
float explosionDamage = mob->distance(explosion) / explosion.getRadius() * centerDamage;
|
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) {
|
void World::OnMobDamage(MobPtr target, float damage, Tower* source) {
|
||||||
target->damage(damage, source);
|
target->damage(damage, source);
|
||||||
if (target->isDead()) {
|
if (target->isDead()) {
|
||||||
notifyListeners(&WorldListener::OnMobDead, target);
|
getMobNotifier().notifyListeners(&MobListener::OnMobDie, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ void WorldClient::HandlePacket(const protocol::UpgradeTowerPacket* packet) {
|
|||||||
void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) {
|
||||||
game::TowerPtr newTower = placeTowerAt(packet->getTowerID(), packet->getTowerType(), packet->getTowerX(), packet->getTowerY(), packet->getBuilder());
|
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) {
|
void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) {
|
||||||
game::TowerPtr tower = removeTower(packet->getTowerID());
|
game::TowerPtr tower = removeTower(packet->getTowerID());
|
||||||
|
|
||||||
if (tower != nullptr) {
|
if (tower != nullptr) {
|
||||||
notifyListeners(&WorldListener::OnTowerRemove, tower);
|
getWorldNotifier().notifyListeners(&WorldListener::OnTowerRemove, tower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ void ServerConnexion::HandlePacket(const protocol::PlaceTowerPacket* packet) {
|
|||||||
|
|
||||||
game::TowerPtr tower = world->placeTowerAt(towerType, packet->getTowerX(), packet->getTowerY(), m_ID);
|
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);
|
protocol::WorldAddTowerPacket addTowerPacket(tower->getID(), packet->getTowerX(), packet->getTowerY(), packet->getTowerType(), m_ID);
|
||||||
m_Server->broadcastPacket(&addTowerPacket);
|
m_Server->broadcastPacket(&addTowerPacket);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m
|
|||||||
m_Renderer->setCamMovement({});
|
m_Renderer->setCamMovement({});
|
||||||
m_TowerPlacePopup = std::make_unique<gui::TowerPlacePopup>(m_Client->getClient());
|
m_TowerPlacePopup = std::make_unique<gui::TowerPlacePopup>(m_Client->getClient());
|
||||||
m_MobTooltip = std::make_unique<gui::MobTooltip>(m_Client->getClient());
|
m_MobTooltip = std::make_unique<gui::MobTooltip>(m_Client->getClient());
|
||||||
m_Client->getWorld().bindListener(this);
|
m_Client->getWorld().getWorldNotifier().bindListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::updateCursorPos() {
|
void WorldRenderer::updateCursorPos() {
|
||||||
|
|||||||
Reference in New Issue
Block a user