render entities
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
#include <td/Types.h>
|
||||
#include <td/game/Team.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
@@ -42,8 +42,7 @@ typedef std::uint8_t MobLevel;
|
||||
typedef std::vector<TowerType> TowerImmunities;
|
||||
typedef std::vector<EffectType> EffectImmunities;
|
||||
|
||||
class MobStats {
|
||||
private:
|
||||
struct MobStats {
|
||||
float m_Damage;
|
||||
float m_Speed;
|
||||
Vec2f m_Size;
|
||||
@@ -51,27 +50,12 @@ private:
|
||||
std::uint16_t m_ExpCost;
|
||||
std::uint16_t m_MaxLife;
|
||||
std::uint16_t m_ExpReward;
|
||||
public:
|
||||
MobStats(float damage, float speed, Vec2f size, std::uint16_t moneyCost,
|
||||
std::uint16_t expCost, std::uint16_t expReward,
|
||||
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
|
||||
m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
|
||||
m_MaxLife(maxLife), m_ExpReward(expReward) {
|
||||
}
|
||||
|
||||
float GetDamage() const { return m_Damage; }
|
||||
float GetMovementSpeed() const { return m_Speed; }
|
||||
const Vec2f& GetSize() const { return m_Size; }
|
||||
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; }
|
||||
};
|
||||
|
||||
struct EffectDuration {
|
||||
EffectType type;
|
||||
float duration; // in seconds
|
||||
Tower* tower; // the tower that gived the effect
|
||||
float duration; // in seconds
|
||||
Tower* tower; // the tower that gived the effect
|
||||
};
|
||||
|
||||
const MobStats* GetMobStats(MobType type, std::uint8_t level);
|
||||
@@ -79,15 +63,16 @@ const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level);
|
||||
const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level);
|
||||
|
||||
class Mob : public utils::shape::Rectangle {
|
||||
protected:
|
||||
protected:
|
||||
float m_Health;
|
||||
private:
|
||||
|
||||
private:
|
||||
MobID m_ID;
|
||||
PlayerID m_Sender;
|
||||
MobLevel m_Level;
|
||||
Direction m_Direction;
|
||||
std::vector<EffectDuration> m_Effects;
|
||||
const Tower* m_LastDamage; // the last tower that damaged the mob
|
||||
const Tower* m_LastDamage; // the last tower that damaged the mob
|
||||
float m_HitCooldown;
|
||||
|
||||
// utils::Timer m_EffectFireTimer;
|
||||
@@ -97,30 +82,55 @@ private:
|
||||
TeamCastle* m_CastleTarget;
|
||||
// utils::CooldownTimer m_AttackTimer;
|
||||
|
||||
public:
|
||||
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
|
||||
m_HitCooldown(0), m_CastleTarget(nullptr) {
|
||||
public:
|
||||
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level), m_HitCooldown(0), m_CastleTarget(nullptr) {}
|
||||
|
||||
}
|
||||
virtual ~Mob() {}
|
||||
|
||||
virtual MobType GetType() const = 0;
|
||||
|
||||
virtual void Tick(std::uint64_t delta, World* world);
|
||||
virtual void Tick(std::uint64_t delta, World* world) {}
|
||||
|
||||
virtual bool OnDeath(World* world) { return true; }
|
||||
virtual bool OnDeath(World* world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MobID GetMobID() const { return m_ID; }
|
||||
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); }
|
||||
void SetHealth(float newHealth) { m_Health = newHealth; }
|
||||
float GetHealth() const { return m_Health; }
|
||||
bool IsDead() const { return m_Health <= 0; }
|
||||
bool IsAlive() const { return m_Health > 0; }
|
||||
const Tower* GetLastDamageTower() { return m_LastDamage; }
|
||||
bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; }
|
||||
MobID GetMobID() const {
|
||||
return m_ID;
|
||||
}
|
||||
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);
|
||||
}
|
||||
void SetHealth(float newHealth) {
|
||||
m_Health = newHealth;
|
||||
}
|
||||
float GetHealth() const {
|
||||
return m_Health;
|
||||
}
|
||||
bool IsDead() const {
|
||||
return m_Health <= 0;
|
||||
}
|
||||
bool IsAlive() const {
|
||||
return m_Health > 0;
|
||||
}
|
||||
const Tower* GetLastDamageTower() {
|
||||
return m_LastDamage;
|
||||
}
|
||||
bool HasReachedEnemyCastle() {
|
||||
return m_CastleTarget != nullptr;
|
||||
}
|
||||
|
||||
void Damage(float dmg, const Tower* damager) {
|
||||
m_Health = std::max(0.0f, m_Health - dmg);
|
||||
@@ -129,10 +139,12 @@ public:
|
||||
}
|
||||
|
||||
void Heal(float heal) {
|
||||
m_Health = std::min(static_cast<float>(GetStats()->GetMaxLife()), m_Health + heal);
|
||||
m_Health = std::min(static_cast<float>(GetStats()->m_MaxLife), m_Health + heal);
|
||||
}
|
||||
|
||||
void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle
|
||||
void SetMobReachedCastle(TeamCastle* castle) {
|
||||
m_CastleTarget = castle;
|
||||
} // used when mob is in front of the castle
|
||||
|
||||
bool IsImmuneTo(TowerType type);
|
||||
|
||||
@@ -140,19 +152,34 @@ public:
|
||||
void AddEffect(EffectType type, float durationSec, Tower* tower);
|
||||
bool HasEffect(EffectType type);
|
||||
|
||||
bool HasTakenDamage() { return m_HitCooldown > 0; }
|
||||
|
||||
float GetTileX() { return GetCenterX() - static_cast<float>(static_cast<std::int32_t>(GetCenterX())); } // returns a float between 0 and 1 excluded
|
||||
float GetTileY() { return GetCenterY() - static_cast<float>(static_cast<std::int32_t>(GetCenterY())); } // returns a float between 0 and 1 excluded
|
||||
|
||||
Direction GetDirection() const { return m_Direction; }
|
||||
void SetDirection(Direction dir) { m_Direction = dir; }
|
||||
protected:
|
||||
void InitMob() {
|
||||
m_Health = static_cast<float>(GetStats()->GetMaxLife());
|
||||
SetSize(GetStats()->GetSize().x, GetStats()->GetSize().y);
|
||||
bool HasTakenDamage() {
|
||||
return m_HitCooldown > 0;
|
||||
}
|
||||
private:
|
||||
|
||||
// returns a float between 0 and 1 excluded
|
||||
float GetTileX() {
|
||||
return GetCenterX() - static_cast<float>(static_cast<std::int32_t>(GetCenterX()));
|
||||
}
|
||||
|
||||
// returns a float between 0 and 1 excluded
|
||||
float GetTileY() {
|
||||
return GetCenterY() - static_cast<float>(static_cast<std::int32_t>(GetCenterY()));
|
||||
}
|
||||
|
||||
Direction GetDirection() const {
|
||||
return m_Direction;
|
||||
}
|
||||
void SetDirection(Direction dir) {
|
||||
m_Direction = dir;
|
||||
}
|
||||
|
||||
protected:
|
||||
void InitMob() {
|
||||
m_Health = static_cast<float>(GetStats()->m_MaxLife);
|
||||
SetSize(GetStats()->m_Size.x, GetStats()->m_Size.y);
|
||||
}
|
||||
|
||||
private:
|
||||
void UpdateEffects(std::uint64_t delta, World* world);
|
||||
void AttackCastle(std::uint64_t delta, World* world);
|
||||
void Move(std::uint64_t delta, World* world);
|
||||
@@ -165,85 +192,42 @@ private:
|
||||
|
||||
typedef std::shared_ptr<Mob> MobPtr;
|
||||
|
||||
class Zombie : public Mob {
|
||||
public:
|
||||
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
template <MobType MT>
|
||||
class ConcreteMob : public Mob {
|
||||
public:
|
||||
ConcreteMob(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) {
|
||||
InitMob();
|
||||
}
|
||||
|
||||
virtual MobType GetType() const { return MobType::Zombie; }
|
||||
virtual ~ConcreteMob() {}
|
||||
|
||||
virtual void Tick(std::uint64_t delta, World* world) {}
|
||||
|
||||
virtual constexpr MobType GetType() const {
|
||||
return MT;
|
||||
}
|
||||
};
|
||||
|
||||
class Spider : public Mob {
|
||||
public:
|
||||
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Spider; }
|
||||
};
|
||||
|
||||
class Skeleton : public Mob {
|
||||
public:
|
||||
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Skeleton; }
|
||||
};
|
||||
|
||||
class PigMan : public Mob {
|
||||
public:
|
||||
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Pigman; }
|
||||
};
|
||||
|
||||
class Creeper : public Mob {
|
||||
public:
|
||||
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Creeper; }
|
||||
};
|
||||
|
||||
class Silverfish : public Mob {
|
||||
public:
|
||||
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Silverfish; }
|
||||
};
|
||||
|
||||
class Blaze : public Mob {
|
||||
public:
|
||||
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Blaze; }
|
||||
};
|
||||
|
||||
class Witch : public Mob {
|
||||
public:
|
||||
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Witch; }
|
||||
};
|
||||
|
||||
class Slime : public Mob {
|
||||
public:
|
||||
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Slime; }
|
||||
};
|
||||
|
||||
class Giant : public Mob {
|
||||
public:
|
||||
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||
|
||||
virtual MobType GetType() const { return MobType::Giant; }
|
||||
};
|
||||
using Zombie = ConcreteMob<MobType::Zombie>;
|
||||
using Spider = ConcreteMob<MobType::Spider>;
|
||||
using Skeleton = ConcreteMob<MobType::Skeleton>;
|
||||
using PigMan = ConcreteMob<MobType::Pigman>;
|
||||
using Creeper = ConcreteMob<MobType::Creeper>;
|
||||
using Silverfish = ConcreteMob<MobType::Silverfish>;
|
||||
using Blaze = ConcreteMob<MobType::Blaze>;
|
||||
using Witch = ConcreteMob<MobType::Witch>;
|
||||
using Slime = ConcreteMob<MobType::Slime>;
|
||||
using Giant = ConcreteMob<MobType::Giant>;
|
||||
|
||||
namespace MobFactory {
|
||||
|
||||
MobPtr CreateMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
|
||||
std::string GetMobName(MobType type);
|
||||
|
||||
}
|
||||
} // namespace MobFactory
|
||||
|
||||
class MobListener {
|
||||
public:
|
||||
public:
|
||||
virtual void OnMobSpawn(Mob* mob) {}
|
||||
virtual void OnMobDie(Mob* mob) {}
|
||||
|
||||
@@ -255,6 +239,5 @@ public:
|
||||
|
||||
// typedef utils::ObjectNotifier<MobListener> MobNotifier;
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
|
||||
Reference in New Issue
Block a user