diff --git a/include/td/game/Towers.h b/include/td/game/Towers.h index af84e02..19dc243 100644 --- a/include/td/game/Towers.h +++ b/include/td/game/Towers.h @@ -1,12 +1,16 @@ #pragma once -#include #include +#include #include #include +#include +#include +#include + namespace td { namespace game { @@ -15,69 +19,66 @@ class Mob; typedef std::shared_ptr MobPtr; -enum class TowerType : std::uint8_t { - Archer = 0, - Ice, - Sorcerer, - Zeus, - Mage, - Artillery, - Quake, - Poison, - - Leach, - Turret, - Necromancer, - - TowerCount -}; - enum class TowerSize : std::uint8_t { - Little = 3, // 3x3 - Big = 5, // 5x5 + Little = 3, // 3x3 + Big = 5, // 5x5 }; enum class TowerPath : std::uint8_t { Top = 0, - Base, // Base Path + Base, // Base Path Bottom }; class TowerStats { -private: + private: float m_Rate; float m_Damage; std::uint8_t m_Range; -public: - TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage), - m_Range(range) { - } - float GetDamageRate() const { return m_Rate; } - float GetDamage() const { return m_Damage; } - std::uint8_t GetRange() const { return m_Range; } + public: + TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage), m_Range(range) {} + + float GetDamageRate() const { + return m_Rate; + } + float GetDamage() const { + return m_Damage; + } + std::uint8_t GetRange() const { + return m_Range; + } }; class TowerLevel { -private: + private: // 1, 2, 3, 4 std::uint8_t m_Level : 3; // 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path) TowerPath m_Path : 2; -public: + + public: TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {} TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {} - std::uint8_t GetLevel() const { return m_Level; } - TowerPath GetPath() const { return m_Path; } + std::uint8_t GetLevel() const { + return m_Level; + } + TowerPath GetPath() const { + return m_Path; + } - void SetLevel(std::uint8_t level) { m_Level = level; } - void SetPath(TowerPath path) { m_Path = path; } + void SetLevel(std::uint8_t level) { + m_Level = level; + } + void SetPath(TowerPath path) { + m_Path = path; + } // operator to sort maps friend bool operator<(const TowerLevel& level, const TowerLevel& other) { return level.GetLevel() + static_cast(level.GetPath()) * 4 < - other.GetLevel() + static_cast(other.GetPath()) * 4; + other.GetLevel() + static_cast(other.GetPath()) * 4; } }; @@ -85,182 +86,64 @@ const TowerStats* GetTowerStats(TowerType type, TowerLevel level); typedef std::uint16_t TowerID; -class Tower : public utils::shape::Circle { -private: +class TowerHandler; + +class Tower : public utils::shape::Circle, public sp::MessageBase { + public: TowerID m_ID; - TowerType m_Type; TowerLevel m_Level{}; PlayerID m_Builder; -protected: - // utils::CooldownTimer m_Timer; -public: - Tower(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder) : utils::shape::Circle(x + 0.5f, y + 0.5f, 0), m_ID(id), m_Type(type), m_Builder(builder) - // m_Timer(GetStats()->GetDamageRate() * 1000) - { // converting seconds to millis - SetRadius(GetStats()->GetRange()); - } + + public: + Tower() : m_ID(0), m_Level({}), m_Builder(0) {} virtual TowerType GetType() const = 0; virtual TowerSize GetSize() const = 0; virtual void Tick(std::uint64_t delta, World* world) = 0; +}; - void Upgrade(std::uint8_t level, TowerPath path) { - m_Level.SetLevel(level); - m_Level.SetPath(path); - // m_Timer.SetCooldown(GetStats()->GetDamageRate() * 1000); // converting seconds to millis - // m_Timer.Reset(); - SetRadius(GetStats()->GetRange()); +struct TowerData {}; + +template +class ConcreteTower : public sp::ConcreteMessage { + public: + using HandlerType = typename sp::ConcreteMessage::HandlerType; + + virtual TowerSize GetSize() const { + return Size; } - std::uint16_t GetID() const { return m_ID; } - const TowerLevel& GetLevel() const { return m_Level; } - const TowerStats* GetStats() const { return GetTowerStats(m_Type, m_Level); } - PlayerID GetBuilder() const { return m_Builder; } - - bool IsMobInRange(MobPtr mob); -}; - -typedef std::shared_ptr TowerPtr; - -namespace TowerFactory { - -TowerPtr CreateTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder); -std::string GetTowerName(TowerType type); - -} // namespace TowerFactory - - -class TowerInfo { -private: - std::string m_Name, m_Description; - bool m_IsBigTower; -public: - TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)), - m_Description(std::move(description)), m_IsBigTower(big) { + virtual TowerType GetType() const { + return Type; } - const std::string& GetName() const { return m_Name; } - const std::string& GetDescription() const { return m_Description; } + virtual void Tick(std::uint64_t delta, World* world) {} - bool IsBigTower() const { return m_IsBigTower; } + virtual void Dispatch(HandlerType& handler) const override { + handler.Handle(*this); + } }; -const TowerInfo& GetTowerInfo(TowerType type); +using TowerPtr = std::shared_ptr; -// ---------- Little Towers ---------- +using ArcherTower = ConcreteTower; +using ArtilleryTower = ConcreteTower; +using IceTower = ConcreteTower; +using LeachTower = ConcreteTower; +using MageTower = ConcreteTower; +using NecromancerTower = ConcreteTower; +using PoisonTower = ConcreteTower; +using QuakeTower = ConcreteTower; +using SorcererTower = ConcreteTower; +using TurretTower = ConcreteTower; +using ZeusTower = ConcreteTower; -class LittleTower : public Tower { -public: - LittleTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {} +using AllTowers = std::tuple; - virtual TowerSize GetSize() const { return TowerSize::Little; } +using TowerFactory = sp::MessageFactory; - virtual TowerType GetType() const = 0; - virtual void Tick(std::uint64_t delta, World* world) = 0; -}; +class TowerHandler : public sp::GenericHandler {}; -class ArcherTower : public LittleTower { -public: - ArcherTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - constexpr static float ExplosionRadius = 1.5f; - constexpr static float FireDurationSec = 10.0f; - - virtual TowerType GetType() const { return TowerType::Archer; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class IceTower : public LittleTower { -public: - IceTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Ice; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class MageTower : public LittleTower { -public: - MageTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Mage; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class PoisonTower : public LittleTower { -public: - PoisonTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Poison; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class QuakeTower : public LittleTower { -public: - QuakeTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Quake; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class ArtilleryTower : public LittleTower { -public: - ArtilleryTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Artillery; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class SorcererTower : public LittleTower { -public: - SorcererTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Sorcerer; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class ZeusTower : public LittleTower { -public: - ZeusTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Zeus; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -// ---------- Big Towers ---------- - -class BigTower : public Tower { -public: - BigTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {} - - virtual TowerSize GetSize() const { return TowerSize::Big; } - - virtual TowerType GetType() const = 0; - virtual void Tick(std::uint64_t delta, World* world) = 0; -}; - -class TurretTower : public BigTower { -public: - TurretTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Turret; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class NecromancerTower : public BigTower { -public: - NecromancerTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Necromancer; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -class LeachTower : public BigTower { -public: - LeachTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {} - - virtual TowerType GetType() const { return TowerType::Leach; } - virtual void Tick(std::uint64_t delta, World* world); -}; - -} // namespace game -} // namespace td +} // namespace game +} // namespace td