#pragma once #include #include #include #include #include #include #include namespace td { namespace game { class World; class Mob; typedef std::shared_ptr MobPtr; enum class TowerSize : std::uint8_t { Little = 3, // 3x3 Big = 5, // 5x5 }; enum class TowerPath : std::uint8_t { Top = 0, Base, // Base Path Bottom }; class TowerStats { 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; } }; class TowerLevel { 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: 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; } 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; } }; using TowerID = std::uint16_t; class TowerHandler; class Tower : public utils::shape::Circle, public sp::MessageBase { public: TowerID m_ID; TowerLevel m_Level{}; PlayerID m_Builder; 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; }; struct TowerData {}; template class ConcreteTower : public sp::ConcreteMessage { public: using HandlerType = typename sp::ConcreteMessage::HandlerType; virtual TowerSize GetSize() const override { return Size; } virtual TowerType GetType() const override { return Type; } virtual void Tick(std::uint64_t delta, World* world) override {} virtual void Dispatch(HandlerType& handler) const override { handler.Handle(*this); } }; using TowerPtr = std::shared_ptr; 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; using AllTowers = std::tuple; using TowerFactory = sp::MessageFactory; class TowerHandler : public sp::GenericHandler {}; } // namespace game } // namespace td