refactor towers
This commit is contained in:
@@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <td/misc/Shapes.h>
|
#include <td/misc/Shapes.h>
|
||||||
|
|
||||||
#include <td/Types.h>
|
#include <td/Types.h>
|
||||||
|
|
||||||
|
#include <sp/common/GenericHandler.h>
|
||||||
|
#include <sp/protocol/ConcreteMessage.h>
|
||||||
|
#include <sp/protocol/MessageFactory.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
@@ -15,69 +19,66 @@ class Mob;
|
|||||||
|
|
||||||
typedef std::shared_ptr<Mob> MobPtr;
|
typedef std::shared_ptr<Mob> 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 {
|
enum class TowerSize : std::uint8_t {
|
||||||
Little = 3, // 3x3
|
Little = 3, // 3x3
|
||||||
Big = 5, // 5x5
|
Big = 5, // 5x5
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TowerPath : std::uint8_t {
|
enum class TowerPath : std::uint8_t {
|
||||||
Top = 0,
|
Top = 0,
|
||||||
Base, // Base Path
|
Base, // Base Path
|
||||||
Bottom
|
Bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
class TowerStats {
|
class TowerStats {
|
||||||
private:
|
private:
|
||||||
float m_Rate;
|
float m_Rate;
|
||||||
float m_Damage;
|
float m_Damage;
|
||||||
std::uint8_t m_Range;
|
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; }
|
public:
|
||||||
float GetDamage() const { return m_Damage; }
|
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage), m_Range(range) {}
|
||||||
std::uint8_t GetRange() const { return m_Range; }
|
|
||||||
|
float GetDamageRate() const {
|
||||||
|
return m_Rate;
|
||||||
|
}
|
||||||
|
float GetDamage() const {
|
||||||
|
return m_Damage;
|
||||||
|
}
|
||||||
|
std::uint8_t GetRange() const {
|
||||||
|
return m_Range;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TowerLevel {
|
class TowerLevel {
|
||||||
private:
|
private:
|
||||||
// 1, 2, 3, 4
|
// 1, 2, 3, 4
|
||||||
std::uint8_t m_Level : 3;
|
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)
|
// 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path)
|
||||||
TowerPath m_Path : 2;
|
TowerPath m_Path : 2;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {}
|
TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {}
|
||||||
TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {}
|
TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {}
|
||||||
|
|
||||||
std::uint8_t GetLevel() const { return m_Level; }
|
std::uint8_t GetLevel() const {
|
||||||
TowerPath GetPath() const { return m_Path; }
|
return m_Level;
|
||||||
|
}
|
||||||
|
TowerPath GetPath() const {
|
||||||
|
return m_Path;
|
||||||
|
}
|
||||||
|
|
||||||
void SetLevel(std::uint8_t level) { m_Level = level; }
|
void SetLevel(std::uint8_t level) {
|
||||||
void SetPath(TowerPath path) { m_Path = path; }
|
m_Level = level;
|
||||||
|
}
|
||||||
|
void SetPath(TowerPath path) {
|
||||||
|
m_Path = path;
|
||||||
|
}
|
||||||
|
|
||||||
// operator to sort maps
|
// operator to sort maps
|
||||||
friend bool operator<(const TowerLevel& level, const TowerLevel& other) {
|
friend bool operator<(const TowerLevel& level, const TowerLevel& other) {
|
||||||
return level.GetLevel() + static_cast<std::uint8_t>(level.GetPath()) * 4 <
|
return level.GetLevel() + static_cast<std::uint8_t>(level.GetPath()) * 4 <
|
||||||
other.GetLevel() + static_cast<std::uint8_t>(other.GetPath()) * 4;
|
other.GetLevel() + static_cast<std::uint8_t>(other.GetPath()) * 4;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,182 +86,64 @@ const TowerStats* GetTowerStats(TowerType type, TowerLevel level);
|
|||||||
|
|
||||||
typedef std::uint16_t TowerID;
|
typedef std::uint16_t TowerID;
|
||||||
|
|
||||||
class Tower : public utils::shape::Circle {
|
class TowerHandler;
|
||||||
private:
|
|
||||||
|
class Tower : public utils::shape::Circle, public sp::MessageBase<TowerType, TowerHandler> {
|
||||||
|
public:
|
||||||
TowerID m_ID;
|
TowerID m_ID;
|
||||||
TowerType m_Type;
|
|
||||||
TowerLevel m_Level{};
|
TowerLevel m_Level{};
|
||||||
PlayerID m_Builder;
|
PlayerID m_Builder;
|
||||||
protected:
|
|
||||||
// utils::CooldownTimer m_Timer;
|
public:
|
||||||
public:
|
Tower() : m_ID(0), m_Level({}), m_Builder(0) {}
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual TowerType GetType() const = 0;
|
virtual TowerType GetType() const = 0;
|
||||||
virtual TowerSize GetSize() const = 0;
|
virtual TowerSize GetSize() const = 0;
|
||||||
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
void Upgrade(std::uint8_t level, TowerPath path) {
|
struct TowerData {};
|
||||||
m_Level.SetLevel(level);
|
|
||||||
m_Level.SetPath(path);
|
template <TowerType Type, TowerSize Size>
|
||||||
// m_Timer.SetCooldown(GetStats()->GetDamageRate() * 1000); // converting seconds to millis
|
class ConcreteTower : public sp::ConcreteMessage<TowerData, Tower, Type, false> {
|
||||||
// m_Timer.Reset();
|
public:
|
||||||
SetRadius(GetStats()->GetRange());
|
using HandlerType = typename sp::ConcreteMessage<TowerData, Tower, Type, false>::HandlerType;
|
||||||
|
|
||||||
|
virtual TowerSize GetSize() const {
|
||||||
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t GetID() const { return m_ID; }
|
virtual TowerType GetType() const {
|
||||||
const TowerLevel& GetLevel() const { return m_Level; }
|
return Type;
|
||||||
const TowerStats* GetStats() const { return GetTowerStats(m_Type, m_Level); }
|
|
||||||
PlayerID GetBuilder() const { return m_Builder; }
|
|
||||||
|
|
||||||
bool IsMobInRange(MobPtr mob);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Tower> 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) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& GetName() const { return m_Name; }
|
virtual void Tick(std::uint64_t delta, World* world) {}
|
||||||
const std::string& GetDescription() const { return m_Description; }
|
|
||||||
|
|
||||||
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<Tower>;
|
||||||
|
|
||||||
// ---------- Little Towers ----------
|
using ArcherTower = ConcreteTower<TowerType::Archer, TowerSize::Little>;
|
||||||
|
using ArtilleryTower = ConcreteTower<TowerType::Artillery, TowerSize::Little>;
|
||||||
|
using IceTower = ConcreteTower<TowerType::Ice, TowerSize::Little>;
|
||||||
|
using LeachTower = ConcreteTower<TowerType::Leach, TowerSize::Big>;
|
||||||
|
using MageTower = ConcreteTower<TowerType::Mage, TowerSize::Little>;
|
||||||
|
using NecromancerTower = ConcreteTower<TowerType::Necromancer, TowerSize::Big>;
|
||||||
|
using PoisonTower = ConcreteTower<TowerType::Poison, TowerSize::Little>;
|
||||||
|
using QuakeTower = ConcreteTower<TowerType::Quake, TowerSize::Little>;
|
||||||
|
using SorcererTower = ConcreteTower<TowerType::Sorcerer, TowerSize::Little>;
|
||||||
|
using TurretTower = ConcreteTower<TowerType::Turret, TowerSize::Big>;
|
||||||
|
using ZeusTower = ConcreteTower<TowerType::Zeus, TowerSize::Little>;
|
||||||
|
|
||||||
class LittleTower : public Tower {
|
using AllTowers = std::tuple<ArcherTower, ArtilleryTower, IceTower, LeachTower, MageTower, NecromancerTower, PoisonTower, QuakeTower,
|
||||||
public:
|
SorcererTower, TurretTower, ZeusTower>;
|
||||||
LittleTower(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::Little; }
|
using TowerFactory = sp::MessageFactory<Tower, AllTowers>;
|
||||||
|
|
||||||
virtual TowerType GetType() const = 0;
|
class TowerHandler : public sp::GenericHandler<AllTowers> {};
|
||||||
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ArcherTower : public LittleTower {
|
} // namespace game
|
||||||
public:
|
} // namespace td
|
||||||
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
|
|
||||||
|
|||||||
Reference in New Issue
Block a user