#pragma once #include "Towers.h" #include "Types.h" #include #include namespace td { namespace game { enum class EffectType : std::uint8_t { Slowness = 0, Stun, Fire, Poison, Heal, }; enum class MobType : std::uint8_t { Zombie = 0, Spider, Skeleton, Pigman, Creeper, Silverfish, Blaze, Witch, Slime, Giant }; typedef std::uint8_t PlayerID; typedef std::uint32_t MobID; typedef std::uint8_t MobLevel; typedef std::vector TowerImmunities; typedef std::vector EffectImmunities; class MobStats { private: float m_Damage; float m_Speed; std::uint16_t m_MoneyCost; std::uint16_t m_ExpCost; std::uint16_t m_MaxLife; std::uint16_t m_ExpReward; public: MobStats(float damage, float speed, std::uint16_t moneyCost, std::uint16_t expCost, std::uint16_t maxLife, std::uint16_t expReward) : m_Damage(damage), m_Speed(speed), m_MoneyCost(moneyCost), m_ExpCost(expCost), m_MaxLife(maxLife), m_ExpReward(expReward) { } float getDamage() const { return m_Damage; } float getMovementSpeed() const { return m_Speed; } std::uint16_t getMoneyCost() const { return m_MoneyCost; } std::uint16_t getExpCost() const { return m_ExpCost; } std::uint16_t getExpReward() const { return m_ExpReward; } std::uint16_t getMaxLife() const { return m_MaxLife; } }; const MobStats* getMobStats(MobType type, std::uint8_t level); const TowerImmunities& getMobTowerImmunities(MobType type, std::uint8_t level); const EffectImmunities& getMobEffectImmunities(MobType type, std::uint8_t level); class Mob { protected: float m_Health; private: MobID m_ID; PlayerID m_Sender; MobLevel m_Level; Direction m_Direction; float m_X = 0, m_Y = 0; public: Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level) { } virtual MobType getType() const = 0; virtual void tick(std::uint64_t delta) {} const TowerImmunities& getTowerImmunities() const { return getMobTowerImmunities(getType(), m_Level); } const EffectImmunities& getEffectImmunities() const { return getMobEffectImmunities(getType(), m_Level); } PlayerID getSender() const { return m_Sender; } MobLevel getLevel() const { return m_Level; } const MobStats* getStats() const { return getMobStats(getType(), m_Level); } float getHealth() const { return m_Health; } bool isAlive() const { return m_Health > 0; } void damage(float dmg) { m_Health -= dmg; } void heal(float heal) { m_Health = std::min((float)getStats()->getMaxLife(), m_Health + heal); } float getX() const { return m_X; } void setX(float x) { m_X = x; } float getY() const { return m_Y; } void setY(float y) { m_Y = y; } Direction getDirection() const { return m_Direction; } void setDirection(Direction dir) { m_Direction = dir; } protected: void initHealth() { m_Health = (float)getStats()->getMaxLife(); } }; typedef std::shared_ptr MobPtr; class Zombie : public Mob { public: Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); } virtual MobType getType() const { return MobType::Zombie; } }; class Spider : public Mob { public: Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); } virtual MobType getType() const { return MobType::Spider; } }; namespace MobFactory { MobPtr createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender); } } // namespace game } // namespace td