#pragma once #include #include "misc/Time.h" namespace td { namespace game { enum class TowerType : std::uint8_t{ Archer = 0, Ice, Sorcerer, Zeus, Mage, Artillery, Quake, Poison, Leach, Turret, Necromancer }; enum class TowerSize : bool{ Little = 0, // 3x3 Big, // 5x5 }; enum class TowerPath : std::uint8_t{ Top = 1, // 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 : 1; public: TowerLevel(): m_Level(1), m_Path(TowerPath::Top){} 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() * (std::uint8_t)level.getPath() < other.getLevel() * (std::uint8_t)other.getPath(); } }; const TowerStats* getTowerStats(TowerType type, TowerLevel level); class Tower{ private: std::uint16_t m_X, m_Y; TowerLevel m_Level{}; protected: utils::Timer m_Timer; public: // converting seconds to millis Tower(std::uint16_t x, std::uint16_t y): m_X(x), m_Y(y), m_Timer(getStats()->getDamageRate() * 1000){} virtual TowerType getType() const = 0; virtual TowerSize getSize() const = 0; virtual void tick(std::uint64_t delta) = 0; void upgrade(std::uint8_t level, TowerPath path){ m_Level.setLevel(level); m_Level.setPath(path); } std::uint16_t getX() const{ return m_X; } std::uint16_t getY() const{ return m_Y; } const TowerLevel& getLevel() const{ return m_Level; } const TowerStats* getStats() const{ return getTowerStats(getType(), m_Level); } }; // ---------- Little Towers ---------- class LittleTower : public Tower{ public: LittleTower(std::uint16_t x, std::uint16_t y): Tower(x, y){} virtual TowerSize getSize() const{ return TowerSize::Little; } virtual TowerType getType() const = 0; virtual void tick(std::uint64_t delta) = 0; }; class ArcherTower : public LittleTower{ public: ArcherTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Archer; } virtual void tick(std::uint64_t delta); }; class IceTower : public LittleTower{ public: IceTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Ice; } virtual void tick(std::uint64_t delta); }; class MageTower : public LittleTower{ public: MageTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Mage; } virtual void tick(std::uint64_t delta); }; class PoisonTower : public LittleTower{ public: PoisonTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Poison; } virtual void tick(std::uint64_t delta); }; class QuakeTower : public LittleTower{ public: QuakeTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Quake; } virtual void tick(std::uint64_t delta); }; class ArtilleryTower : public LittleTower{ public: ArtilleryTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Artillery; } virtual void tick(std::uint64_t delta); }; class SorcererTower : public LittleTower{ public: SorcererTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Sorcerer; } virtual void tick(std::uint64_t delta); }; class ZeusTower : public LittleTower{ public: ZeusTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){} virtual TowerType getType() const{ return TowerType::Zeus; } virtual void tick(std::uint64_t delta); }; // ---------- Big Towers ---------- class BigTower : public Tower{ public: BigTower(std::uint16_t x, std::uint16_t y): Tower(x, y){} virtual TowerSize getSize() const{ return TowerSize::Big; } virtual TowerType getType() const = 0; virtual void tick(std::uint64_t delta) = 0; }; class TurretTower : public BigTower{ public: TurretTower(std::uint16_t x, std::uint16_t y): BigTower(x, y){} virtual TowerType getType() const{ return TowerType::Turret; } virtual void tick(std::uint64_t delta); }; class NecromancerTower : public BigTower{ public: NecromancerTower(std::uint16_t x, std::uint16_t y): BigTower(x, y){} virtual TowerType getType() const{ return TowerType::Necromancer; } virtual void tick(std::uint64_t delta); }; class LeachTower : public BigTower{ public: LeachTower(std::uint16_t x, std::uint16_t y): BigTower(x, y){} virtual TowerType getType() const{ return TowerType::Leach; } virtual void tick(std::uint64_t delta); }; } // namespace game } // namespace td