Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2e42c33a0 | |||
| 8bddbce07a | |||
| add62fb24a | |||
| 68b389f938 | |||
| f3adb639c3 | |||
| 88a9020da7 | |||
| 0a814233a4 | |||
| b4836847f5 | |||
| f941862637 | |||
| 36f37b6548 | |||
| 1dde1dbf1e | |||
| f5012f770c | |||
| e7b9a57723 | |||
| 02b4aa3c91 | |||
| f184982bc1 | |||
| 1cdc738839 | |||
| 368bc450ce | |||
| 148b5f397a | |||
| f62322752d | |||
| fb9e125f16 | |||
| b70e8f7790 | |||
| 39bdd0a11e | |||
| c95c8b7fde | |||
| e984ed9085 | |||
| 92035d7b9e | |||
| 48841fa4e9 | |||
| 83ab8c70f0 | |||
| ccdcdac7c6 | |||
| a2b5424888 | |||
| a4fb56b549 | |||
| 22e62df04d | |||
| faf544f997 | |||
| b72f4a7673 | |||
| 19c03010cb | |||
| 41f8c152eb | |||
| 051c9d8744 | |||
| 193e4db651 | |||
| cb5f5a4cf8 | |||
| bc7e5914ce | |||
| 0365902971 | |||
| f2fcc348d7 | |||
| 95c92ec6c9 | |||
| 721f15b601 | |||
| 3970103b01 | |||
| 4e866c1032 | |||
| ca268781fd | |||
| a2d8984199 | |||
| e7f9ca2b6c | |||
| deb0075aac | |||
| 28b8659e16 | |||
| 0b9fc0520e | |||
| c54017c7be | |||
| bbfe341d23 | |||
| 14efe2cc39 | |||
| fcda12e321 | |||
| 1200a6e087 | |||
| 512fb23d0e | |||
| 5a547b6514 | |||
| ed45995645 | |||
| 0b6d826eba | |||
| 6d0c6be166 | |||
| 222b79b40a | |||
| 8f95b1a750 | |||
| 7d30017742 | |||
| 386ea5b6ad | |||
| 8949c37891 | |||
| 019174128c | |||
| 4e8b095e31 | |||
| 0e0368cada | |||
|
|
6e0923ac75 | ||
|
|
bba9ef8219 |
148
include/Defines.h
Normal file
148
include/Defines.h
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
static constexpr float PI = 3.141592653f;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Vec2 {
|
||||||
|
union {
|
||||||
|
T x;
|
||||||
|
T r;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
T y;
|
||||||
|
T g;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Vec2(T X = 0, T Y = 0) : x(X), y(Y) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool operator==(const Vec2<T>& vec2, const Vec2<T>& other) {
|
||||||
|
return vec2.x == other.x && vec2.y == other.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Vec3 {
|
||||||
|
union {
|
||||||
|
T x;
|
||||||
|
T r;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
T y;
|
||||||
|
T g;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
T z;
|
||||||
|
T b;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Vec3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool operator==(const Vec3<T>& vec3, const Vec3<T>& other) {
|
||||||
|
return vec3.x == other.x && vec3.y == other.y && vec3.z == other.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Vec4 {
|
||||||
|
union {
|
||||||
|
T x;
|
||||||
|
T r;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
T y;
|
||||||
|
T g;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
T z;
|
||||||
|
T b;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
T w;
|
||||||
|
T a;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Vec4(Vec3<T> vec, T W = 1) : x(vec.x), y(vec.y), z(vec.z), w(W) {}
|
||||||
|
constexpr Vec4(T X = 0, T Y = 0, T Z = 0, T W = 0) : x(X), y(Y), z(Z), w(W) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool operator==(const Vec4<T>& vec4, const Vec4<T>& other) {
|
||||||
|
return vec4.x == other.x && vec4.y == other.y && vec4.z == other.z && vec4.w = other.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Vec2i = Vec2<int>;
|
||||||
|
using Vec2u = Vec2<unsigned int>;
|
||||||
|
using Vec2f = Vec2<float>;
|
||||||
|
using Vec2d = Vec2<double>;
|
||||||
|
|
||||||
|
using Vec3i = Vec3<int>;
|
||||||
|
using Vec3u = Vec3<unsigned int>;
|
||||||
|
using Vec3f = Vec3<float>;
|
||||||
|
using Vec3d = Vec3<double>;
|
||||||
|
|
||||||
|
using Vec4i = Vec4<int>;
|
||||||
|
using Vec4u = Vec4<unsigned int>;
|
||||||
|
using Vec4f = Vec4<float>;
|
||||||
|
using Vec4d = Vec4<double>;
|
||||||
|
|
||||||
|
using Color = Vec3<unsigned char>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Mat4 {
|
||||||
|
static const std::size_t MATRIX_SIZE = 4;
|
||||||
|
|
||||||
|
T x0, x1, x2, x3;
|
||||||
|
T y0, y1, y2, y3;
|
||||||
|
T z0, z1, z2, z3;
|
||||||
|
T w0, w1, w2, w3;
|
||||||
|
|
||||||
|
T operator[] (std::size_t offset) const {
|
||||||
|
return reinterpret_cast<const T*>(this)[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[] (std::size_t offset) {
|
||||||
|
return reinterpret_cast<T*>(this)[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
T* data() {
|
||||||
|
return reinterpret_cast<T*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* data() const{
|
||||||
|
return reinterpret_cast<const T*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
T at(std::size_t row, std::size_t column) const {
|
||||||
|
return operator[](row * MATRIX_SIZE + column);
|
||||||
|
}
|
||||||
|
|
||||||
|
T& at(std::size_t row, std::size_t column) {
|
||||||
|
return operator[](row * MATRIX_SIZE + column);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Mat4<float> Mat4f;
|
||||||
|
typedef Mat4<int> Mat4i;
|
||||||
|
typedef Mat4<double> Mat4d;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
|
||||||
|
return mat.x0 == other.x0 && mat.y0 == other.y0 && mat.z0 == other.z0 && mat.w0 == other.w0 &&
|
||||||
|
mat.x1 == other.x1 && mat.y1 == other.y1 && mat.z1 == other.z1 && mat.w1 == other.w1 &&
|
||||||
|
mat.x2 == other.x2 && mat.y2 == other.y2 && mat.z2 == other.z2 && mat.w2 == other.w2 &&
|
||||||
|
mat.x3 == other.x3 && mat.y3 == other.y3 && mat.z3 == other.z3 && mat.w3 == other.w3;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
@@ -8,62 +8,66 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
enum class GameState : std::uint8_t {
|
enum class GameState : std::uint8_t {
|
||||||
Lobby,
|
Lobby,
|
||||||
Game,
|
Game,
|
||||||
EndGame,
|
EndGame,
|
||||||
Disconnected,
|
Disconnected,
|
||||||
Closed
|
Closed
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::uint8_t, Player> PlayerList;
|
typedef std::map<std::uint8_t, Player> PlayerList;
|
||||||
|
|
||||||
class GameListener {
|
class GameListener {
|
||||||
public:
|
public:
|
||||||
virtual void OnPlayerJoin(PlayerID player) {}
|
virtual void OnPlayerJoin(PlayerID player) {}
|
||||||
virtual void OnPlayerLeave(PlayerID player) {}
|
virtual void OnPlayerLeave(PlayerID player) {}
|
||||||
|
|
||||||
virtual void OnGameStateUpdate(GameState newState) {}
|
virtual void OnGameStateUpdate(GameState newState) {}
|
||||||
virtual void OnGameBegin() {}
|
virtual void OnGameBegin() {}
|
||||||
virtual void OnGameEnd() {}
|
virtual void OnGameEnd() {}
|
||||||
virtual void OnGameClose() {}
|
virtual void OnGameClose() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef utils::ObjectNotifier<GameListener> GameNotifier;
|
typedef utils::ObjectNotifier<GameListener> GameNotifier;
|
||||||
|
|
||||||
class Game : public GameNotifier {
|
class Game : public GameNotifier {
|
||||||
protected:
|
protected:
|
||||||
World* m_World;
|
World* m_World;
|
||||||
TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
|
TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
|
||||||
GameState m_GameState = GameState::Lobby;
|
GameState m_GameState = GameState::Lobby;
|
||||||
PlayerList m_Players;
|
PlayerList m_Players;
|
||||||
|
|
||||||
|
std::uint64_t m_GameStartTime = 0;
|
||||||
public:
|
public:
|
||||||
Game(World* world);
|
Game(World* world);
|
||||||
virtual ~Game();
|
virtual ~Game();
|
||||||
|
|
||||||
virtual void Tick(std::uint64_t delta);
|
virtual void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
Team& GetRedTeam() { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
|
Team& GetRedTeam() { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
|
||||||
const Team& GetRedTeam() const { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
|
const Team& GetRedTeam() const { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
|
||||||
|
|
||||||
Team& GetBlueTeam() { return m_Teams[static_cast<std::uint8_t>(TeamColor::Blue)]; }
|
Team& GetBlueTeam() { return m_Teams[static_cast<std::uint8_t>(TeamColor::Blue)]; }
|
||||||
const Team& GetBlueTeam() const { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
|
const Team& GetBlueTeam() const { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
|
||||||
|
|
||||||
Team& GetTeam(TeamColor team) { return m_Teams[static_cast<std::uint8_t>(team)]; }
|
Team& GetTeam(TeamColor team) { return m_Teams[static_cast<std::uint8_t>(team)]; }
|
||||||
const Team& GetTeam(TeamColor team) const { return m_Teams[static_cast<std::uint8_t>(team)]; }
|
const Team& GetTeam(TeamColor team) const { return m_Teams[static_cast<std::uint8_t>(team)]; }
|
||||||
|
|
||||||
GameState GetGameState() const { return m_GameState; }
|
GameState GetGameState() const { return m_GameState; }
|
||||||
void SetGameState(GameState gameState) { m_GameState = gameState; };
|
void SetGameState(GameState gameState) { m_GameState = gameState; };
|
||||||
|
|
||||||
const World* GetWorld() const { return m_World; }
|
const World* GetWorld() const { return m_World; }
|
||||||
World* GetWorld() { return m_World; }
|
World* GetWorld() { return m_World; }
|
||||||
|
|
||||||
const PlayerList& GetPlayers() const { return m_Players; }
|
const PlayerList& GetPlayers() const { return m_Players; }
|
||||||
PlayerList& GetPlayers() { return m_Players; }
|
PlayerList& GetPlayers() { return m_Players; }
|
||||||
|
|
||||||
const Player* GetPlayerById(PlayerID id) const;
|
const Player* GetPlayerById(PlayerID id) const;
|
||||||
Player* GetPlayerById(PlayerID id);
|
Player* GetPlayerById(PlayerID id);
|
||||||
|
|
||||||
const TeamList& GetTeams() const { return m_Teams; }
|
const TeamList& GetTeams() const { return m_Teams; }
|
||||||
|
|
||||||
|
std::uint64_t GetGameStartTime() const { return m_GameStartTime; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,26 +10,26 @@ namespace protocol {
|
|||||||
|
|
||||||
class Connexion : public protocol::PacketHandler {
|
class Connexion : public protocol::PacketHandler {
|
||||||
protected:
|
protected:
|
||||||
protocol::PacketDispatcher m_Dispatcher;
|
protocol::PacketDispatcher m_Dispatcher;
|
||||||
private:
|
private:
|
||||||
network::TCPSocket m_Socket;
|
network::TCPSocket m_Socket;
|
||||||
public:
|
public:
|
||||||
Connexion();
|
Connexion();
|
||||||
Connexion(Connexion&& move);
|
Connexion(Connexion&& move);
|
||||||
Connexion(protocol::PacketDispatcher* dispatcher);
|
Connexion(protocol::PacketDispatcher* dispatcher);
|
||||||
Connexion(protocol::PacketDispatcher* dispatcher, network::TCPSocket& socket);
|
Connexion(protocol::PacketDispatcher* dispatcher, network::TCPSocket& socket);
|
||||||
virtual ~Connexion();
|
virtual ~Connexion();
|
||||||
|
|
||||||
virtual bool UpdateSocket();
|
virtual bool UpdateSocket();
|
||||||
void CloseConnection();
|
void CloseConnection();
|
||||||
|
|
||||||
bool Connect(const std::string& address, std::uint16_t port);
|
bool Connect(const std::string& address, std::uint16_t port);
|
||||||
|
|
||||||
network::Socket::Status GetSocketStatus() const { return m_Socket.GetStatus(); }
|
network::Socket::Status GetSocketStatus() const { return m_Socket.GetStatus(); }
|
||||||
|
|
||||||
void SendPacket(const protocol::Packet* packet);
|
void SendPacket(const protocol::Packet* packet);
|
||||||
|
|
||||||
REMOVE_COPY(Connexion);
|
REMOVE_COPY(Connexion);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Defines.h"
|
||||||
#include "Towers.h"
|
#include "Towers.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
@@ -9,34 +10,32 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
struct WalkableTile;
|
struct WalkableTile;
|
||||||
|
|
||||||
enum class EffectType : std::uint8_t {
|
enum class EffectType : std::uint8_t {
|
||||||
Slowness = 0,
|
Slowness = 0,
|
||||||
Stun,
|
Stun,
|
||||||
Fire,
|
Fire,
|
||||||
Poison,
|
Poison,
|
||||||
Heal,
|
Heal,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MobType : std::uint8_t {
|
enum class MobType : std::uint8_t {
|
||||||
Zombie = 0,
|
Zombie = 0,
|
||||||
Spider,
|
Spider,
|
||||||
Skeleton,
|
Skeleton,
|
||||||
Pigman,
|
Pigman,
|
||||||
Creeper,
|
Creeper,
|
||||||
Silverfish,
|
Silverfish,
|
||||||
Blaze,
|
Blaze,
|
||||||
Witch,
|
Witch,
|
||||||
Slime,
|
Slime,
|
||||||
Giant,
|
Giant,
|
||||||
|
|
||||||
MOB_COUNT
|
MOB_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::uint32_t MobID;
|
typedef std::uint32_t MobID;
|
||||||
@@ -46,34 +45,34 @@ typedef std::vector<EffectType> EffectImmunities;
|
|||||||
|
|
||||||
class MobStats {
|
class MobStats {
|
||||||
private:
|
private:
|
||||||
float m_Damage;
|
float m_Damage;
|
||||||
float m_Speed;
|
float m_Speed;
|
||||||
glm::vec2 m_Size;
|
Vec2f m_Size;
|
||||||
std::uint16_t m_MoneyCost;
|
std::uint16_t m_MoneyCost;
|
||||||
std::uint16_t m_ExpCost;
|
std::uint16_t m_ExpCost;
|
||||||
std::uint16_t m_MaxLife;
|
std::uint16_t m_MaxLife;
|
||||||
std::uint16_t m_ExpReward;
|
std::uint16_t m_ExpReward;
|
||||||
public:
|
public:
|
||||||
MobStats(float damage, float speed, glm::vec2 size, std::uint16_t moneyCost,
|
MobStats(float damage, float speed, Vec2f size, std::uint16_t moneyCost,
|
||||||
std::uint16_t expCost, std::uint16_t expReward,
|
std::uint16_t expCost, std::uint16_t expReward,
|
||||||
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
|
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
|
||||||
m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
|
m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
|
||||||
m_MaxLife(maxLife), m_ExpReward(expReward) {
|
m_MaxLife(maxLife), m_ExpReward(expReward) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetDamage() const { return m_Damage; }
|
float GetDamage() const { return m_Damage; }
|
||||||
float GetMovementSpeed() const { return m_Speed; }
|
float GetMovementSpeed() const { return m_Speed; }
|
||||||
const glm::vec2& GetSize() const { return m_Size; }
|
const Vec2f& GetSize() const { return m_Size; }
|
||||||
std::uint16_t GetMoneyCost() const { return m_MoneyCost; }
|
std::uint16_t GetMoneyCost() const { return m_MoneyCost; }
|
||||||
std::uint16_t GetExpCost() const { return m_ExpCost; }
|
std::uint16_t GetExpCost() const { return m_ExpCost; }
|
||||||
std::uint16_t GetExpReward() const { return m_ExpReward; }
|
std::uint16_t GetExpReward() const { return m_ExpReward; }
|
||||||
std::uint16_t GetMaxLife() const { return m_MaxLife; }
|
std::uint16_t GetMaxLife() const { return m_MaxLife; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EffectDuration {
|
struct EffectDuration {
|
||||||
EffectType type;
|
EffectType type;
|
||||||
float duration; // in seconds
|
float duration; // in seconds
|
||||||
Tower* tower; // the tower that gived the effect
|
Tower* tower; // the tower that gived the effect
|
||||||
};
|
};
|
||||||
|
|
||||||
const MobStats* GetMobStats(MobType type, std::uint8_t level);
|
const MobStats* GetMobStats(MobType type, std::uint8_t level);
|
||||||
@@ -82,149 +81,160 @@ const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level)
|
|||||||
|
|
||||||
class Mob : public utils::shape::Rectangle {
|
class Mob : public utils::shape::Rectangle {
|
||||||
protected:
|
protected:
|
||||||
float m_Health;
|
float m_Health;
|
||||||
private:
|
private:
|
||||||
MobID m_ID;
|
MobID m_ID;
|
||||||
PlayerID m_Sender;
|
PlayerID m_Sender;
|
||||||
MobLevel m_Level;
|
MobLevel m_Level;
|
||||||
Direction m_Direction;
|
Direction m_Direction;
|
||||||
std::vector<EffectDuration> m_Effects;
|
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;
|
utils::Timer m_EffectFireTimer;
|
||||||
utils::Timer m_EffectPoisonTimer;
|
utils::Timer m_EffectPoisonTimer;
|
||||||
utils::Timer m_EffectHealTimer;
|
utils::Timer m_EffectHealTimer;
|
||||||
|
|
||||||
TeamCastle* m_CastleTarget;
|
TeamCastle* m_CastleTarget;
|
||||||
utils::CooldownTimer m_AttackTimer;
|
utils::CooldownTimer m_AttackTimer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
|
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
|
||||||
m_EffectFireTimer(1000), m_EffectPoisonTimer(1000),
|
m_HitCooldown(0), m_EffectFireTimer(1000), m_EffectPoisonTimer(1000),
|
||||||
m_EffectHealTimer(1000), m_CastleTarget(nullptr), m_AttackTimer(1000) {
|
m_EffectHealTimer(1000), m_CastleTarget(nullptr), m_AttackTimer(1000) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MobType GetType() const = 0;
|
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; }
|
MobID GetMobID() const { return m_ID; }
|
||||||
const TowerImmunities& GetTowerImmunities() const { return GetMobTowerImmunities(GetType(), m_Level); }
|
const TowerImmunities& GetTowerImmunities() const { return GetMobTowerImmunities(GetType(), m_Level); }
|
||||||
const EffectImmunities& GetEffectImmunities() const { return GetMobEffectImmunities(GetType(), m_Level); }
|
const EffectImmunities& GetEffectImmunities() const { return GetMobEffectImmunities(GetType(), m_Level); }
|
||||||
PlayerID GetSender() const { return m_Sender; }
|
PlayerID GetSender() const { return m_Sender; }
|
||||||
MobLevel GetLevel() const { return m_Level; }
|
MobLevel GetLevel() const { return m_Level; }
|
||||||
const MobStats* GetStats() const { return GetMobStats(GetType(), m_Level); }
|
const MobStats* GetStats() const { return GetMobStats(GetType(), m_Level); }
|
||||||
void SetHealth(float newHealth) { m_Health = newHealth; }
|
void SetHealth(float newHealth) { m_Health = newHealth; }
|
||||||
float GetHealth() const { return m_Health; }
|
float GetHealth() const { return m_Health; }
|
||||||
bool IsDead() const { return m_Health <= 0; }
|
bool IsDead() const { return m_Health <= 0; }
|
||||||
bool IsAlive() const { return m_Health > 0; }
|
bool IsAlive() const { return m_Health > 0; }
|
||||||
const Tower* GetLastDamageTower() { return m_LastDamage; }
|
const Tower* GetLastDamageTower() { return m_LastDamage; }
|
||||||
bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; }
|
bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; }
|
||||||
|
|
||||||
void Damage(float dmg, const Tower* damager) { m_Health = std::max(0.0f, m_Health - dmg); m_LastDamage = damager; }
|
void Damage(float dmg, const Tower* damager) {
|
||||||
void Heal(float heal) { m_Health = std::min(static_cast<float>(GetStats()->GetMaxLife()), m_Health + heal); }
|
m_Health = std::max(0.0f, m_Health - dmg);
|
||||||
void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle
|
m_LastDamage = damager;
|
||||||
|
m_HitCooldown = 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsImmuneTo(TowerType type);
|
void Heal(float heal) {
|
||||||
|
m_Health = std::min(static_cast<float>(GetStats()->GetMaxLife()), m_Health + heal);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsImmuneTo(EffectType type);
|
void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle
|
||||||
void AddEffect(EffectType type, float durationSec, Tower* tower);
|
|
||||||
bool HasEffect(EffectType type);
|
|
||||||
|
|
||||||
float GetTileX() { return GetCenterX() - static_cast<float>(static_cast<std::int32_t>(GetCenterX())); } // returns a float between 0 and 1 excluded
|
bool IsImmuneTo(TowerType type);
|
||||||
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; }
|
bool IsImmuneTo(EffectType type);
|
||||||
void SetDirection(Direction dir) { m_Direction = dir; }
|
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:
|
protected:
|
||||||
void InitMob() {
|
void InitMob() {
|
||||||
m_Health = static_cast<float>(GetStats()->GetMaxLife());
|
m_Health = static_cast<float>(GetStats()->GetMaxLife());
|
||||||
SetSize(GetStats()->GetSize().x, GetStats()->GetSize().y);
|
SetSize(GetStats()->GetSize().x, GetStats()->GetSize().y);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void UpdateEffects(std::uint64_t delta, World* world);
|
void UpdateEffects(std::uint64_t delta, World* world);
|
||||||
void AttackCastle(std::uint64_t delta, World* world);
|
void AttackCastle(std::uint64_t delta, World* world);
|
||||||
void Move(std::uint64_t delta, World* world);
|
void Move(std::uint64_t delta, World* world);
|
||||||
void Walk(std::uint64_t delta, World* world);
|
void Walk(std::uint64_t delta, World* world);
|
||||||
void MoveBack(const TeamCastle& castle, World* world);
|
void MoveBack(const TeamCastle& castle, World* world);
|
||||||
void ChangeDirection(const WalkableTile& tile, World* world);
|
void ChangeDirection(const WalkableTile& tile, World* world);
|
||||||
bool IsTouchingCastle(const TeamCastle& castle) const;
|
bool IsTouchingCastle(const TeamCastle& castle) const;
|
||||||
EffectDuration& GetEffect(EffectType type);
|
EffectDuration& GetEffect(EffectType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Mob> MobPtr;
|
typedef std::shared_ptr<Mob> MobPtr;
|
||||||
|
|
||||||
class Zombie : public Mob {
|
class Zombie : public Mob {
|
||||||
public:
|
public:
|
||||||
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Zombie; }
|
virtual MobType GetType() const { return MobType::Zombie; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Spider : public Mob {
|
class Spider : public Mob {
|
||||||
public:
|
public:
|
||||||
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Spider; }
|
virtual MobType GetType() const { return MobType::Spider; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Skeleton : public Mob {
|
class Skeleton : public Mob {
|
||||||
public:
|
public:
|
||||||
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Skeleton; }
|
virtual MobType GetType() const { return MobType::Skeleton; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PigMan : public Mob {
|
class PigMan : public Mob {
|
||||||
public:
|
public:
|
||||||
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Pigman; }
|
virtual MobType GetType() const { return MobType::Pigman; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Creeper : public Mob {
|
class Creeper : public Mob {
|
||||||
public:
|
public:
|
||||||
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Creeper; }
|
virtual MobType GetType() const { return MobType::Creeper; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Silverfish : public Mob {
|
class Silverfish : public Mob {
|
||||||
public:
|
public:
|
||||||
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Silverfish; }
|
virtual MobType GetType() const { return MobType::Silverfish; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Blaze : public Mob {
|
class Blaze : public Mob {
|
||||||
public:
|
public:
|
||||||
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Blaze; }
|
virtual MobType GetType() const { return MobType::Blaze; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Witch : public Mob {
|
class Witch : public Mob {
|
||||||
public:
|
public:
|
||||||
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Witch; }
|
virtual MobType GetType() const { return MobType::Witch; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Slime : public Mob {
|
class Slime : public Mob {
|
||||||
public:
|
public:
|
||||||
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Slime; }
|
virtual MobType GetType() const { return MobType::Slime; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Giant : public Mob {
|
class Giant : public Mob {
|
||||||
public:
|
public:
|
||||||
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
virtual MobType GetType() const { return MobType::Giant; }
|
virtual MobType GetType() const { return MobType::Giant; }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MobFactory {
|
namespace MobFactory {
|
||||||
@@ -236,13 +246,13 @@ std::string GetMobName(MobType type);
|
|||||||
|
|
||||||
class MobListener {
|
class MobListener {
|
||||||
public:
|
public:
|
||||||
virtual void OnMobSpawn(Mob* mob) {}
|
virtual void OnMobSpawn(Mob* mob) {}
|
||||||
virtual void OnMobDie(Mob* mob) {}
|
virtual void OnMobDie(Mob* mob) {}
|
||||||
|
|
||||||
virtual void OnMobDamage(Mob* target, float damage, Tower* damager) {}
|
virtual void OnMobDamage(Mob* target, float damage, Tower* damager) {}
|
||||||
|
|
||||||
virtual void OnMobTouchCastle(Mob* damager, TeamCastle* enemyCastle) {}
|
virtual void OnMobTouchCastle(Mob* damager, TeamCastle* enemyCastle) {}
|
||||||
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {}
|
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef utils::ObjectNotifier<MobListener> MobNotifier;
|
typedef utils::ObjectNotifier<MobListener> MobNotifier;
|
||||||
|
|||||||
@@ -10,41 +10,41 @@ namespace game {
|
|||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
private:
|
private:
|
||||||
TeamColor m_TeamColor;
|
TeamColor m_TeamColor;
|
||||||
PlayerUpgrades m_Upgrades;
|
PlayerUpgrades m_Upgrades;
|
||||||
|
|
||||||
std::uint32_t m_Gold;
|
std::uint32_t m_Gold;
|
||||||
std::uint32_t m_Exp;
|
std::uint32_t m_Exp;
|
||||||
std::string m_Name;
|
std::string m_Name;
|
||||||
PlayerID m_ID;
|
PlayerID m_ID;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Player(std::uint8_t id = 0) : m_TeamColor(TeamColor::None), m_Gold(0), m_Exp(0), m_ID(id) {}
|
Player(std::uint8_t id = 0) : m_TeamColor(TeamColor::None), m_Gold(0), m_Exp(0), m_ID(id) {}
|
||||||
|
|
||||||
const std::string& GetName() const { return m_Name; }
|
const std::string& GetName() const { return m_Name; }
|
||||||
void SetName(const std::string& name) { m_Name = name; }
|
void SetName(const std::string& name) { m_Name = name; }
|
||||||
|
|
||||||
TeamColor GetTeamColor() const { return m_TeamColor; }
|
TeamColor GetTeamColor() const { return m_TeamColor; }
|
||||||
void SetTeamColor(TeamColor teamColor) { m_TeamColor = teamColor; }
|
void SetTeamColor(TeamColor teamColor) { m_TeamColor = teamColor; }
|
||||||
|
|
||||||
std::uint32_t GetGold() const { return m_Gold; }
|
std::uint32_t GetGold() const { return m_Gold; }
|
||||||
void SetGold(std::uint32_t gold) { m_Gold = gold; }
|
void SetGold(std::uint32_t gold) { m_Gold = gold; }
|
||||||
void AddGold(std::uint32_t gold) { m_Gold += gold; }
|
void AddGold(std::uint32_t gold) { m_Gold += gold; }
|
||||||
void RemoveGold(std::uint32_t gold) { m_Gold -= gold; }
|
void RemoveGold(std::uint32_t gold) { m_Gold -= gold; }
|
||||||
|
|
||||||
std::uint32_t GetExp() const { return m_Exp; }
|
std::uint32_t GetExp() const { return m_Exp; }
|
||||||
void SetExp(std::uint32_t exp) { m_Exp = exp; }
|
void SetExp(std::uint32_t exp) { m_Exp = exp; }
|
||||||
void AddExp(std::uint32_t exp) { m_Exp += exp; }
|
void AddExp(std::uint32_t exp) { m_Exp += exp; }
|
||||||
void RemoveExp(std::uint32_t exp) { m_Exp -= exp; }
|
void RemoveExp(std::uint32_t exp) { m_Exp -= exp; }
|
||||||
|
|
||||||
const PlayerUpgrades& getUpgrades() const { return m_Upgrades; }
|
const PlayerUpgrades& getUpgrades() const { return m_Upgrades; }
|
||||||
PlayerUpgrades& getUpgrades() { return m_Upgrades; }
|
PlayerUpgrades& getUpgrades() { return m_Upgrades; }
|
||||||
|
|
||||||
bool HasEnoughGold(std::uint32_t gold) const { return m_Gold >= gold; }
|
bool HasEnoughGold(std::uint32_t gold) const { return m_Gold >= gold; }
|
||||||
bool HasEnoughExp(std::uint32_t exp) const { return m_Exp >= exp; }
|
bool HasEnoughExp(std::uint32_t exp) const { return m_Exp >= exp; }
|
||||||
|
|
||||||
PlayerID GetID() const { return m_ID; }
|
PlayerID GetID() const { return m_ID; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -7,27 +7,27 @@ namespace game {
|
|||||||
|
|
||||||
class PlayerUpgrades {
|
class PlayerUpgrades {
|
||||||
private:
|
private:
|
||||||
std::uint8_t m_ClickerLevel;
|
std::uint8_t m_ClickerLevel;
|
||||||
std::uint8_t m_GoldPerSecond;
|
std::uint8_t m_GoldPerSecond;
|
||||||
std::array<std::uint8_t, static_cast<std::size_t>(MobType::MOB_COUNT)> m_MobsUpgradeLevel;
|
std::array<std::uint8_t, static_cast<std::size_t>(MobType::MOB_COUNT)> m_MobsUpgradeLevel;
|
||||||
public:
|
public:
|
||||||
static const int MAX_MOB_LEVEL = 5;
|
static const int MAX_MOB_LEVEL = 5;
|
||||||
static const int MAX_CLICKER_LEVEL = 3;
|
static const int MAX_CLICKER_LEVEL = 3;
|
||||||
|
|
||||||
PlayerUpgrades() : m_ClickerLevel(1), m_GoldPerSecond(5) {}
|
PlayerUpgrades() : m_ClickerLevel(1), m_GoldPerSecond(5) {}
|
||||||
|
|
||||||
std::uint8_t GetClickerLevel() const { return m_ClickerLevel; }
|
std::uint8_t GetClickerLevel() const { return m_ClickerLevel; }
|
||||||
std::uint8_t GetMobUpgradeLevel(MobType mob) const { return m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob)); }
|
std::uint8_t GetMobUpgradeLevel(MobType mob) const { return m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob)); }
|
||||||
std::uint8_t GetGoldPerSecond() const { return m_GoldPerSecond; }
|
std::uint8_t GetGoldPerSecond() const { return m_GoldPerSecond; }
|
||||||
|
|
||||||
|
|
||||||
void UpgradeMob(MobType mob) {
|
void UpgradeMob(MobType mob) {
|
||||||
std::uint8_t& mobLevel = m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob));
|
std::uint8_t& mobLevel = m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob));
|
||||||
mobLevel = std::min(mobLevel + 1, MAX_MOB_LEVEL);
|
mobLevel = std::min(mobLevel + 1, MAX_MOB_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpgradeClicker() { m_ClickerLevel = std::min(m_ClickerLevel + 1, MAX_CLICKER_LEVEL); }
|
void UpgradeClicker() { m_ClickerLevel = std::min(m_ClickerLevel + 1, MAX_CLICKER_LEVEL); }
|
||||||
void SetGoldPerSecond(std::uint8_t goldPerSecond) { m_GoldPerSecond = goldPerSecond; }
|
void SetGoldPerSecond(std::uint8_t goldPerSecond) { m_GoldPerSecond = goldPerSecond; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -14,76 +14,76 @@ namespace game {
|
|||||||
class Player;
|
class Player;
|
||||||
|
|
||||||
enum class TeamColor : std::int8_t {
|
enum class TeamColor : std::int8_t {
|
||||||
None = -1,
|
None = -1,
|
||||||
Red,
|
Red,
|
||||||
Blue
|
Blue
|
||||||
};
|
};
|
||||||
|
|
||||||
class Spawn : public utils::shape::Rectangle {
|
class Spawn : public utils::shape::Rectangle {
|
||||||
private:
|
private:
|
||||||
Direction m_Direction;
|
Direction m_Direction;
|
||||||
public:
|
public:
|
||||||
Spawn() {
|
Spawn() {
|
||||||
SetWidth(5);
|
SetWidth(5);
|
||||||
SetHeight(5);
|
SetHeight(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction GetDirection() const { return m_Direction; }
|
Direction GetDirection() const { return m_Direction; }
|
||||||
|
|
||||||
void SetDirection(Direction direction) { m_Direction = direction; }
|
void SetDirection(Direction direction) { m_Direction = direction; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Team;
|
class Team;
|
||||||
|
|
||||||
class TeamCastle : public utils::shape::Rectangle {
|
class TeamCastle : public utils::shape::Rectangle {
|
||||||
private:
|
private:
|
||||||
const Team* m_Team;
|
const Team* m_Team;
|
||||||
float m_Life;
|
float m_Life;
|
||||||
public:
|
public:
|
||||||
static constexpr int CastleMaxLife = 1000;
|
static constexpr int CastleMaxLife = 1000;
|
||||||
|
|
||||||
TeamCastle(const Team* team) : m_Team(team), m_Life(CastleMaxLife) {
|
TeamCastle(const Team* team) : m_Team(team), m_Life(CastleMaxLife) {
|
||||||
SetWidth(5);
|
SetWidth(5);
|
||||||
SetHeight(5);
|
SetHeight(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TeamCastle() : TeamCastle(nullptr) {}
|
TeamCastle() : TeamCastle(nullptr) {}
|
||||||
|
|
||||||
float GetLife() const { return m_Life; }
|
float GetLife() const { return m_Life; }
|
||||||
|
|
||||||
const Team* GetTeam() const { return m_Team; }
|
const Team* GetTeam() const { return m_Team; }
|
||||||
void SetTeam(const Team* team) { m_Team = team; }
|
void SetTeam(const Team* team) { m_Team = team; }
|
||||||
|
|
||||||
void SetLife(float life) { m_Life = life; }
|
void SetLife(float life) { m_Life = life; }
|
||||||
void Damage(float damage) { m_Life = std::max(0.0f, m_Life - damage); }
|
void Damage(float damage) { m_Life = std::max(0.0f, m_Life - damage); }
|
||||||
|
|
||||||
void SetShape(utils::shape::Rectangle rect) {
|
void SetShape(utils::shape::Rectangle rect) {
|
||||||
SetCenter(rect.GetCenter());
|
SetCenter(rect.GetCenter());
|
||||||
SetSize(rect.GetSize());
|
SetSize(rect.GetSize());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Team {
|
class Team {
|
||||||
private:
|
private:
|
||||||
std::vector<Player*> m_Players;
|
std::vector<Player*> m_Players;
|
||||||
TeamColor m_Color;
|
TeamColor m_Color;
|
||||||
Spawn m_Spawn;
|
Spawn m_Spawn;
|
||||||
TeamCastle m_TeamCastle;
|
TeamCastle m_TeamCastle;
|
||||||
public:
|
public:
|
||||||
Team(TeamColor color);
|
Team(TeamColor color);
|
||||||
|
|
||||||
void AddPlayer(Player* newPlayer);
|
void AddPlayer(Player* newPlayer);
|
||||||
void RemovePlayer(const Player* player);
|
void RemovePlayer(const Player* player);
|
||||||
|
|
||||||
TeamColor GetColor() const;
|
TeamColor GetColor() const;
|
||||||
|
|
||||||
const Spawn& GetSpawn() const { return m_Spawn; }
|
const Spawn& GetSpawn() const { return m_Spawn; }
|
||||||
Spawn& GetSpawn() { return m_Spawn; }
|
Spawn& GetSpawn() { return m_Spawn; }
|
||||||
|
|
||||||
const TeamCastle& GetCastle() const { return m_TeamCastle; }
|
const TeamCastle& GetCastle() const { return m_TeamCastle; }
|
||||||
TeamCastle& GetCastle() { return m_TeamCastle; }
|
TeamCastle& GetCastle() { return m_TeamCastle; }
|
||||||
|
|
||||||
std::uint8_t GetPlayerCount() const;
|
std::uint8_t GetPlayerCount() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::array<Team, 2> TeamList;
|
typedef std::array<Team, 2> TeamList;
|
||||||
|
|||||||
@@ -17,69 +17,69 @@ class Mob;
|
|||||||
typedef std::shared_ptr<Mob> MobPtr;
|
typedef std::shared_ptr<Mob> MobPtr;
|
||||||
|
|
||||||
enum class TowerType : std::uint8_t {
|
enum class TowerType : std::uint8_t {
|
||||||
Archer = 0,
|
Archer = 0,
|
||||||
Ice,
|
Ice,
|
||||||
Sorcerer,
|
Sorcerer,
|
||||||
Zeus,
|
Zeus,
|
||||||
Mage,
|
Mage,
|
||||||
Artillery,
|
Artillery,
|
||||||
Quake,
|
Quake,
|
||||||
Poison,
|
Poison,
|
||||||
|
|
||||||
Leach,
|
Leach,
|
||||||
Turret,
|
Turret,
|
||||||
Necromancer,
|
Necromancer,
|
||||||
|
|
||||||
TowerCount
|
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:
|
public:
|
||||||
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage),
|
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage),
|
||||||
m_Range(range) {
|
m_Range(range) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetDamageRate() const { return m_Rate; }
|
float GetDamageRate() const { return m_Rate; }
|
||||||
float GetDamage() const { return m_Damage; }
|
float GetDamage() const { return m_Damage; }
|
||||||
std::uint8_t GetRange() const { return m_Range; }
|
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 { return m_Level; }
|
||||||
TowerPath GetPath() const { return m_Path; }
|
TowerPath GetPath() const { return m_Path; }
|
||||||
|
|
||||||
void SetLevel(std::uint8_t level) { m_Level = level; }
|
void SetLevel(std::uint8_t level) { m_Level = level; }
|
||||||
void SetPath(TowerPath path) { m_Path = path; }
|
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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const TowerStats* GetTowerStats(TowerType type, TowerLevel level);
|
const TowerStats* GetTowerStats(TowerType type, TowerLevel level);
|
||||||
@@ -88,36 +88,36 @@ typedef std::uint16_t TowerID;
|
|||||||
|
|
||||||
class Tower : public utils::shape::Circle {
|
class Tower : public utils::shape::Circle {
|
||||||
private:
|
private:
|
||||||
TowerID m_ID;
|
TowerID m_ID;
|
||||||
TowerType m_Type;
|
TowerType m_Type;
|
||||||
TowerLevel m_Level{};
|
TowerLevel m_Level{};
|
||||||
PlayerID m_Builder;
|
PlayerID m_Builder;
|
||||||
protected:
|
protected:
|
||||||
utils::CooldownTimer m_Timer;
|
utils::CooldownTimer m_Timer;
|
||||||
public:
|
public:
|
||||||
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),
|
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
|
m_Timer(GetStats()->GetDamageRate() * 1000) { // converting seconds to millis
|
||||||
SetRadius(GetStats()->GetRange());
|
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) {
|
void Upgrade(std::uint8_t level, TowerPath path) {
|
||||||
m_Level.SetLevel(level);
|
m_Level.SetLevel(level);
|
||||||
m_Level.SetPath(path);
|
m_Level.SetPath(path);
|
||||||
m_Timer.SetCooldown(GetStats()->GetDamageRate() * 1000); // converting seconds to millis
|
m_Timer.SetCooldown(GetStats()->GetDamageRate() * 1000); // converting seconds to millis
|
||||||
m_Timer.Reset();
|
m_Timer.Reset();
|
||||||
SetRadius(GetStats()->GetRange());
|
SetRadius(GetStats()->GetRange());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t GetID() const { return m_ID; }
|
std::uint16_t GetID() const { return m_ID; }
|
||||||
const TowerLevel& GetLevel() const { return m_Level; }
|
const TowerLevel& GetLevel() const { return m_Level; }
|
||||||
const TowerStats* GetStats() const { return GetTowerStats(m_Type, m_Level); }
|
const TowerStats* GetStats() const { return GetTowerStats(m_Type, m_Level); }
|
||||||
PlayerID GetBuilder() const { return m_Builder; }
|
PlayerID GetBuilder() const { return m_Builder; }
|
||||||
|
|
||||||
bool IsMobInRange(MobPtr mob);
|
bool IsMobInRange(MobPtr mob);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Tower> TowerPtr;
|
typedef std::shared_ptr<Tower> TowerPtr;
|
||||||
@@ -132,16 +132,17 @@ std::string GetTowerName(TowerType type);
|
|||||||
|
|
||||||
class TowerInfo {
|
class TowerInfo {
|
||||||
private:
|
private:
|
||||||
std::string m_Name, m_Description;
|
std::string m_Name, m_Description;
|
||||||
bool m_IsBigTower;
|
bool m_IsBigTower;
|
||||||
public:
|
public:
|
||||||
TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)),
|
TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)),
|
||||||
m_Description(std::move(description)), m_IsBigTower(big) {}
|
m_Description(std::move(description)), m_IsBigTower(big) {
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& GetName() const { return m_Name; }
|
const std::string& GetName() const { return m_Name; }
|
||||||
const std::string& GetDescription() const { return m_Description; }
|
const std::string& GetDescription() const { return m_Description; }
|
||||||
|
|
||||||
bool IsBigTower() const { return m_IsBigTower; }
|
bool IsBigTower() const { return m_IsBigTower; }
|
||||||
};
|
};
|
||||||
|
|
||||||
const TowerInfo& GetTowerInfo(TowerType type);
|
const TowerInfo& GetTowerInfo(TowerType type);
|
||||||
@@ -150,115 +151,115 @@ const TowerInfo& GetTowerInfo(TowerType type);
|
|||||||
|
|
||||||
class LittleTower : public Tower {
|
class LittleTower : public Tower {
|
||||||
public:
|
public:
|
||||||
LittleTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
|
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; }
|
virtual TowerSize GetSize() const { return TowerSize::Little; }
|
||||||
|
|
||||||
virtual TowerType GetType() const = 0;
|
virtual TowerType GetType() const = 0;
|
||||||
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArcherTower : public LittleTower {
|
class ArcherTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
ArcherTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 ExplosionRadius = 1.5f;
|
||||||
constexpr static float FireDurationSec = 10.0f;
|
constexpr static float FireDurationSec = 10.0f;
|
||||||
|
|
||||||
virtual TowerType GetType() const { return TowerType::Archer; }
|
virtual TowerType GetType() const { return TowerType::Archer; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IceTower : public LittleTower {
|
class IceTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
IceTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Ice; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MageTower : public LittleTower {
|
class MageTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
MageTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Mage; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PoisonTower : public LittleTower {
|
class PoisonTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
PoisonTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Poison; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class QuakeTower : public LittleTower {
|
class QuakeTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
QuakeTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Quake; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArtilleryTower : public LittleTower {
|
class ArtilleryTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
ArtilleryTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Artillery; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SorcererTower : public LittleTower {
|
class SorcererTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
SorcererTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Sorcerer; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ZeusTower : public LittleTower {
|
class ZeusTower : public LittleTower {
|
||||||
public:
|
public:
|
||||||
ZeusTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Zeus; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------- Big Towers ----------
|
// ---------- Big Towers ----------
|
||||||
|
|
||||||
class BigTower : public Tower {
|
class BigTower : public Tower {
|
||||||
public:
|
public:
|
||||||
BigTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
|
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 TowerSize GetSize() const { return TowerSize::Big; }
|
||||||
|
|
||||||
virtual TowerType GetType() const = 0;
|
virtual TowerType GetType() const = 0;
|
||||||
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TurretTower : public BigTower {
|
class TurretTower : public BigTower {
|
||||||
public:
|
public:
|
||||||
TurretTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Turret; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NecromancerTower : public BigTower {
|
class NecromancerTower : public BigTower {
|
||||||
public:
|
public:
|
||||||
NecromancerTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Necromancer; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
class LeachTower : public BigTower {
|
class LeachTower : public BigTower {
|
||||||
public:
|
public:
|
||||||
LeachTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
|
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 TowerType GetType() const { return TowerType::Leach; }
|
||||||
virtual void Tick(std::uint64_t delta, World* world);
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
enum class Direction : std::uint8_t {
|
enum class Direction : std::uint8_t {
|
||||||
PositiveX = 1 << 0,
|
PositiveX = 1 << 0,
|
||||||
NegativeX = 1 << 1,
|
NegativeX = 1 << 1,
|
||||||
PositiveY = 1 << 2,
|
PositiveY = 1 << 2,
|
||||||
NegativeY = 1 << 3,
|
NegativeY = 1 << 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::uint8_t PlayerID;
|
typedef std::uint8_t PlayerID;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "Mobs.h"
|
#include "Mobs.h"
|
||||||
@@ -14,11 +13,11 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
struct ChunkCoord {
|
struct ChunkCoord {
|
||||||
std::int16_t x, y;
|
std::int16_t x, y;
|
||||||
|
|
||||||
friend bool operator==(const td::game::ChunkCoord& first, const td::game::ChunkCoord& other) {
|
friend bool operator==(const td::game::ChunkCoord& first, const td::game::ChunkCoord& other) {
|
||||||
return first.x == other.x && first.y == other.y;
|
return first.x == other.x && first.y == other.y;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -29,9 +28,9 @@ struct ChunkCoord {
|
|||||||
namespace std {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
struct hash<td::game::ChunkCoord> {
|
struct hash<td::game::ChunkCoord> {
|
||||||
std::size_t operator()(const td::game::ChunkCoord& key) const noexcept{
|
std::size_t operator()(const td::game::ChunkCoord& key) const noexcept {
|
||||||
return std::hash<std::int16_t>()(key.x << 16 | key.y);
|
return std::hash<std::int16_t>()(key.x << 16 | key.y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,19 +47,15 @@ namespace game {
|
|||||||
class Game;
|
class Game;
|
||||||
|
|
||||||
enum class TileType : std::uint8_t {
|
enum class TileType : std::uint8_t {
|
||||||
None = 0,
|
None = 0,
|
||||||
Tower,
|
Tower,
|
||||||
Walk,
|
Walk,
|
||||||
Decoration,
|
Decoration,
|
||||||
/*Heal,
|
/*Heal,
|
||||||
Lava,
|
Lava,
|
||||||
Bedrock,
|
Bedrock,
|
||||||
Freeze,
|
Freeze,
|
||||||
Ice,*/
|
Ice,*/
|
||||||
};
|
|
||||||
|
|
||||||
struct Color {
|
|
||||||
std::uint8_t r, g, b;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr Color BLACK{ 0, 0, 0 };
|
static constexpr Color BLACK{ 0, 0, 0 };
|
||||||
@@ -71,26 +66,26 @@ static constexpr Color GREEN{ 0, 255, 0 };
|
|||||||
static constexpr Color BLUE{ 0, 0, 255 };
|
static constexpr Color BLUE{ 0, 0, 255 };
|
||||||
|
|
||||||
struct Tile {
|
struct Tile {
|
||||||
virtual TileType GetType() const = 0;
|
virtual TileType GetType() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TowerTile : Tile {
|
struct TowerTile : Tile {
|
||||||
std::uint8_t color_palette_ref;
|
std::uint8_t color_palette_ref;
|
||||||
TeamColor team_owner;
|
TeamColor team_owner;
|
||||||
|
|
||||||
virtual TileType GetType() const { return TileType::Tower; }
|
virtual TileType GetType() const { return TileType::Tower; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WalkableTile : Tile {
|
struct WalkableTile : Tile {
|
||||||
Direction direction;
|
Direction direction;
|
||||||
|
|
||||||
virtual TileType GetType() const { return TileType::Walk; }
|
virtual TileType GetType() const { return TileType::Walk; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DecorationTile : Tile {
|
struct DecorationTile : Tile {
|
||||||
std::uint16_t color_palette_ref;
|
std::uint16_t color_palette_ref;
|
||||||
|
|
||||||
virtual TileType GetType() const { return TileType::Decoration; }
|
virtual TileType GetType() const { return TileType::Decoration; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Tile> TilePtr;
|
typedef std::shared_ptr<Tile> TilePtr;
|
||||||
@@ -102,19 +97,19 @@ typedef std::uint32_t TileIndex;
|
|||||||
|
|
||||||
//32 x 32 area
|
//32 x 32 area
|
||||||
struct Chunk {
|
struct Chunk {
|
||||||
enum { ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
|
enum { ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
|
||||||
typedef std::array<std::uint16_t, ChunkSize> ChunkData;
|
typedef std::array<std::uint16_t, ChunkSize> ChunkData;
|
||||||
|
|
||||||
// stores index of tile palette
|
// stores index of tile palette
|
||||||
ChunkData tiles{ 0 };
|
ChunkData tiles{ 0 };
|
||||||
ChunkPalette palette;
|
ChunkPalette palette;
|
||||||
|
|
||||||
TileIndex GetTileIndex(std::uint16_t tileNumber) const {
|
TileIndex GetTileIndex(std::uint16_t tileNumber) const {
|
||||||
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
|
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
|
||||||
if (chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
|
if (chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
|
||||||
return 0;
|
return 0;
|
||||||
return palette.at(chunkPaletteIndex);
|
return palette.at(chunkPaletteIndex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||||
@@ -131,119 +126,119 @@ typedef std::vector<TowerPtr> TowerList;
|
|||||||
|
|
||||||
class WorldListener {
|
class WorldListener {
|
||||||
public:
|
public:
|
||||||
WorldListener() {}
|
WorldListener() {}
|
||||||
|
|
||||||
virtual void OnTowerAdd(TowerPtr tower) {}
|
virtual void OnTowerAdd(TowerPtr tower) {}
|
||||||
virtual void OnTowerRemove(TowerPtr tower) {}
|
virtual void OnTowerRemove(TowerPtr tower) {}
|
||||||
|
|
||||||
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) {}
|
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) {}
|
||||||
|
|
||||||
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {}
|
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {}
|
||||||
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {}
|
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef utils::ObjectNotifier<WorldListener> WorldNotifier;
|
typedef utils::ObjectNotifier<WorldListener> WorldNotifier;
|
||||||
|
|
||||||
class World : public WorldListener, public MobListener {
|
class World : public WorldListener, public MobListener {
|
||||||
protected:
|
protected:
|
||||||
TowerTileColorPalette m_TowerPlacePalette;
|
TowerTileColorPalette m_TowerPlacePalette;
|
||||||
Color m_WalkablePalette;
|
Color m_WalkablePalette;
|
||||||
std::vector<Color> m_DecorationPalette;
|
std::vector<Color> m_DecorationPalette;
|
||||||
Color m_Background;
|
Color m_Background;
|
||||||
|
|
||||||
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
|
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
|
||||||
|
|
||||||
SpawnColorPalette m_SpawnColorPalette;
|
SpawnColorPalette m_SpawnColorPalette;
|
||||||
|
|
||||||
TilePalette m_TilePalette;
|
TilePalette m_TilePalette;
|
||||||
|
|
||||||
MobList m_Mobs;
|
MobList m_Mobs;
|
||||||
|
|
||||||
TowerList m_Towers;
|
TowerList m_Towers;
|
||||||
|
|
||||||
Game* m_Game;
|
Game* m_Game;
|
||||||
|
|
||||||
WorldNotifier m_WorldNotifier;
|
WorldNotifier m_WorldNotifier;
|
||||||
MobNotifier m_MobNotifier;
|
MobNotifier m_MobNotifier;
|
||||||
public:
|
public:
|
||||||
World(Game* game);
|
World(Game* game);
|
||||||
|
|
||||||
bool LoadMap(const protocol::WorldBeginDataPacket* worldHeader);
|
bool LoadMap(const protocol::WorldBeginDataPacket* worldHeader);
|
||||||
bool LoadMap(const protocol::WorldDataPacket* worldData);
|
bool LoadMap(const protocol::WorldDataPacket* worldData);
|
||||||
|
|
||||||
bool LoadMapFromFile(const std::string& fileName);
|
bool LoadMapFromFile(const std::string& fileName);
|
||||||
bool SaveMap(const std::string& fileName) const;
|
bool SaveMap(const std::string& fileName) const;
|
||||||
|
|
||||||
void Tick(std::uint64_t delta);
|
void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
void SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
void SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
||||||
|
|
||||||
TowerPtr PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
|
TowerPtr PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
|
||||||
TowerPtr RemoveTower(TowerID id);
|
TowerPtr RemoveTower(TowerID id);
|
||||||
|
|
||||||
TilePtr GetTile(std::int32_t x, std::int32_t y) const;
|
TilePtr GetTile(std::int32_t x, std::int32_t y) const;
|
||||||
|
|
||||||
const TowerTileColorPalette& GetTowerTileColorPalette() const { return m_TowerPlacePalette; }
|
const TowerTileColorPalette& GetTowerTileColorPalette() const { return m_TowerPlacePalette; }
|
||||||
const Color& GetWalkableTileColor() const { return m_WalkablePalette; }
|
const Color& GetWalkableTileColor() const { return m_WalkablePalette; }
|
||||||
const std::vector<Color>& GetDecorationPalette() const { return m_DecorationPalette; }
|
const std::vector<Color>& GetDecorationPalette() const { return m_DecorationPalette; }
|
||||||
const Color& GetBackgroundColor() const { return m_Background; }
|
const Color& GetBackgroundColor() const { return m_Background; }
|
||||||
|
|
||||||
const TilePalette& GetTilePalette() const { return m_TilePalette; }
|
const TilePalette& GetTilePalette() const { return m_TilePalette; }
|
||||||
|
|
||||||
TilePtr GetTilePtr(TileIndex index) const {
|
TilePtr GetTilePtr(TileIndex index) const {
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return m_TilePalette.at(index - 1);
|
return m_TilePalette.at(index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID player) const;
|
bool CanPlaceLittleTower(const Vec2f& worldPos, PlayerID player) const;
|
||||||
bool CanPlaceBigTower(const glm::vec2& worldPos, PlayerID player) const;
|
bool CanPlaceBigTower(const Vec2f& worldPos, PlayerID player) const;
|
||||||
|
|
||||||
TowerPtr GetTower(const glm::vec2& position) const; // returns null if no tower is here
|
TowerPtr GetTower(const Vec2f& position) const; // returns null if no tower is here
|
||||||
|
|
||||||
const std::unordered_map<ChunkCoord, ChunkPtr>& GetChunks() const { return m_Chunks; }
|
const std::unordered_map<ChunkCoord, ChunkPtr>& GetChunks() const { return m_Chunks; }
|
||||||
|
|
||||||
const Color& GetSpawnColor(TeamColor color) const { return m_SpawnColorPalette[static_cast<std::size_t>(color)]; }
|
const Color& GetSpawnColor(TeamColor color) const { return m_SpawnColorPalette[static_cast<std::size_t>(color)]; }
|
||||||
const SpawnColorPalette& GetSpawnColors() const { return m_SpawnColorPalette; }
|
const SpawnColorPalette& GetSpawnColors() const { return m_SpawnColorPalette; }
|
||||||
|
|
||||||
const MobList& GetMobList() const { return m_Mobs; }
|
const MobList& GetMobList() const { return m_Mobs; }
|
||||||
MobList& GetMobList() { return m_Mobs; }
|
MobList& GetMobList() { return m_Mobs; }
|
||||||
|
|
||||||
const Color* GetTileColor(TilePtr tile) const;
|
const Color* GetTileColor(TilePtr tile) const;
|
||||||
|
|
||||||
Team& GetRedTeam();
|
Team& GetRedTeam();
|
||||||
const Team& GetRedTeam() const;
|
const Team& GetRedTeam() const;
|
||||||
|
|
||||||
Team& GetBlueTeam();
|
Team& GetBlueTeam();
|
||||||
const Team& GetBlueTeam() const;
|
const Team& GetBlueTeam() const;
|
||||||
|
|
||||||
Team& GetTeam(TeamColor team);
|
Team& GetTeam(TeamColor team);
|
||||||
const Team& GetTeam(TeamColor team) const;
|
const Team& GetTeam(TeamColor team) const;
|
||||||
|
|
||||||
const TeamList& GetTeams() const;
|
const TeamList& GetTeams() const;
|
||||||
|
|
||||||
const TowerList& GetTowers() const { return m_Towers; }
|
const TowerList& GetTowers() const { return m_Towers; }
|
||||||
TowerPtr GetTowerById(TowerID tower);
|
TowerPtr GetTowerById(TowerID tower);
|
||||||
|
|
||||||
const Player* GetPlayerById(PlayerID id) const;
|
const Player* GetPlayerById(PlayerID id) const;
|
||||||
|
|
||||||
WorldNotifier& GetWorldNotifier() { return m_WorldNotifier; }
|
WorldNotifier& GetWorldNotifier() { return m_WorldNotifier; }
|
||||||
MobNotifier& GetMobNotifier() { return m_MobNotifier; }
|
MobNotifier& GetMobNotifier() { return m_MobNotifier; }
|
||||||
|
|
||||||
// WorldListener
|
// WorldListener
|
||||||
|
|
||||||
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) override;
|
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) override;
|
||||||
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) override;
|
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) override;
|
||||||
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) override;
|
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) override;
|
||||||
|
|
||||||
// MobListener
|
// MobListener
|
||||||
|
|
||||||
virtual void OnMobDamage(Mob* target, float damage, Tower* source) override;
|
virtual void OnMobDamage(Mob* target, float damage, Tower* source) override;
|
||||||
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) override;
|
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void TickMobs(std::uint64_t delta);
|
void TickMobs(std::uint64_t delta);
|
||||||
void CleanDeadMobs();
|
void CleanDeadMobs();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "game/Player.h"
|
#include "game/Player.h"
|
||||||
|
|
||||||
#include "protocol/Protocol.h"
|
#include "protocol/Protocol.h"
|
||||||
|
#include "protocol/packets/SendMobsPacket.h"
|
||||||
|
|
||||||
#include "render/Renderer.h"
|
#include "render/Renderer.h"
|
||||||
|
|
||||||
@@ -17,38 +18,38 @@ namespace client {
|
|||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
private:
|
private:
|
||||||
render::Renderer* m_Renderer;
|
render::Renderer* m_Renderer;
|
||||||
ClientConnexion m_Connexion;
|
ClientConnexion m_Connexion;
|
||||||
std::unique_ptr<ClientGame> m_Game;
|
std::unique_ptr<ClientGame> m_Game;
|
||||||
bool m_Connected;
|
bool m_Connected;
|
||||||
public:
|
public:
|
||||||
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(std::make_unique<ClientGame>(this)), m_Connected(false) {}
|
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(std::make_unique<ClientGame>(this)), m_Connected(false) {}
|
||||||
|
|
||||||
const ClientGame& GetGame() const { return *m_Game; }
|
const ClientGame& GetGame() const { return *m_Game; }
|
||||||
const ClientConnexion& GetConnexion() const { return m_Connexion; }
|
const ClientConnexion& GetConnexion() const { return m_Connexion; }
|
||||||
render::Renderer* GetRenderer() const { return m_Renderer; }
|
render::Renderer* GetRenderer() const { return m_Renderer; }
|
||||||
|
|
||||||
ClientGame& GetGame() { return *m_Game; }
|
ClientGame& GetGame() { return *m_Game; }
|
||||||
ClientConnexion& GetConnexion() { return m_Connexion; }
|
ClientConnexion& GetConnexion() { return m_Connexion; }
|
||||||
|
|
||||||
const game::Player* GetPlayer() { return m_Game->GetPlayer(); }
|
const game::Player* GetPlayer() { return m_Game->GetPlayer(); }
|
||||||
|
|
||||||
void Tick(std::uint64_t delta);
|
void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
bool Connect(const network::IPAddresses& addresses, std::uint16_t port);
|
bool Connect(const network::IPAddresses& addresses, std::uint16_t port);
|
||||||
void CloseConnection();
|
void CloseConnection();
|
||||||
|
|
||||||
bool IsConnected() const { return m_Connexion.GetSocketStatus() == network::Socket::Connected; }
|
bool IsConnected() const { return m_Connexion.GetSocketStatus() == network::Socket::Connected; }
|
||||||
|
|
||||||
void SelectTeam(game::TeamColor team);
|
void SelectTeam(game::TeamColor team);
|
||||||
void SendMobs(const std::vector<protocol::MobSend>& mobSends);
|
void SendMobs(const std::vector<protocol::MobSend>& mobSends);
|
||||||
void PlaceTower(game::TowerType type, const glm::vec2& position);
|
void PlaceTower(game::TowerType type, const Vec2f& position);
|
||||||
void UpgradeTower(game::TowerID tower, game::TowerLevel level);
|
void UpgradeTower(game::TowerID tower, game::TowerLevel level);
|
||||||
void RemoveTower(game::TowerID tower);
|
void RemoveTower(game::TowerID tower);
|
||||||
private:
|
private:
|
||||||
void Reset();
|
void Reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -9,28 +9,30 @@ namespace client {
|
|||||||
|
|
||||||
class ClientConnexion : public protocol::Connexion {
|
class ClientConnexion : public protocol::Connexion {
|
||||||
private:
|
private:
|
||||||
std::uint8_t m_ConnectionID;
|
std::uint8_t m_ConnectionID;
|
||||||
std::string m_DisconnectReason;
|
std::string m_DisconnectReason;
|
||||||
float m_ServerTPS;
|
float m_ServerTPS;
|
||||||
int m_Ping = 0;
|
float m_ServerMSPT;
|
||||||
|
int m_Ping = 0;
|
||||||
public:
|
public:
|
||||||
ClientConnexion();
|
ClientConnexion();
|
||||||
|
|
||||||
virtual bool UpdateSocket();
|
virtual bool UpdateSocket();
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
|
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::ServerTpsPacket* packet) override;
|
virtual void HandlePacket(const protocol::ServerTpsPacket* packet) override;
|
||||||
|
|
||||||
const std::string& GetDisconnectReason() const { return m_DisconnectReason; }
|
const std::string& GetDisconnectReason() const { return m_DisconnectReason; }
|
||||||
float GetServerTPS() const { return m_ServerTPS; }
|
float GetServerTPS() const { return m_ServerTPS; }
|
||||||
int GetServerPing() const { return m_Ping; }
|
float GetServerMSPT() const { return m_ServerMSPT; }
|
||||||
|
int GetServerPing() const { return m_Ping; }
|
||||||
|
|
||||||
REMOVE_COPY(ClientConnexion);
|
REMOVE_COPY(ClientConnexion);
|
||||||
private:
|
private:
|
||||||
void RegisterHandlers();
|
void RegisterHandlers();
|
||||||
void Login();
|
void Login();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -16,40 +16,40 @@ class Client;
|
|||||||
|
|
||||||
class ClientGame : public protocol::PacketHandler, public game::Game {
|
class ClientGame : public protocol::PacketHandler, public game::Game {
|
||||||
private:
|
private:
|
||||||
Client* m_Client;
|
Client* m_Client;
|
||||||
std::uint8_t m_ConnexionID;
|
std::uint8_t m_ConnexionID;
|
||||||
std::uint32_t m_LobbyTime = 0;
|
std::uint64_t m_LobbyStartTime = 0;
|
||||||
game::Player* m_Player = nullptr;
|
game::Player* m_Player = nullptr;
|
||||||
render::Renderer* m_Renderer;
|
render::Renderer* m_Renderer;
|
||||||
client::WorldClient m_WorldClient;
|
client::WorldClient m_WorldClient;
|
||||||
render::WorldRenderer m_WorldRenderer;
|
render::WorldRenderer m_WorldRenderer;
|
||||||
public:
|
public:
|
||||||
ClientGame(Client* client);
|
ClientGame(Client* client);
|
||||||
virtual ~ClientGame();
|
virtual ~ClientGame();
|
||||||
|
|
||||||
virtual void Tick(std::uint64_t delta);
|
virtual void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
void RenderWorld();
|
void RenderWorld();
|
||||||
|
|
||||||
std::uint32_t GetLobbyTime() const { return m_LobbyTime; }
|
std::uint64_t GetLobbyStartTime() const { return m_LobbyStartTime; }
|
||||||
const game::Player* GetPlayer() const { return m_Player; }
|
const game::Player* GetPlayer() const { return m_Player; }
|
||||||
const WorldClient& GetWorld() const { return m_WorldClient; }
|
const WorldClient& GetWorld() const { return m_WorldClient; }
|
||||||
Client* GetClient() const { return m_Client; }
|
Client* GetClient() const { return m_Client; }
|
||||||
|
|
||||||
render::Renderer* GetRenderer() const { return m_Renderer; }
|
render::Renderer* GetRenderer() const { return m_Renderer; }
|
||||||
WorldClient& GetWorldClient() { return m_WorldClient; }
|
WorldClient& GetWorldClient() { return m_WorldClient; }
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet) override;
|
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
|
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
|
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdatePlayerTeamPacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdatePlayerTeamPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdateLobbyTimePacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdateLobbyTimePacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdateMoneyPacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdateMoneyPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdateExpPacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdateExpPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,18 +10,18 @@ class ClientGame;
|
|||||||
|
|
||||||
class WorldClient : public game::World, public protocol::PacketHandler {
|
class WorldClient : public game::World, public protocol::PacketHandler {
|
||||||
private:
|
private:
|
||||||
ClientGame* m_Game;
|
ClientGame* m_Game;
|
||||||
public:
|
public:
|
||||||
WorldClient(ClientGame* game);
|
WorldClient(ClientGame* game);
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::WorldBeginDataPacket* packet) override;
|
virtual void HandlePacket(const protocol::WorldBeginDataPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
|
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet) override;
|
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdateMobStatesPacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdateMobStatesPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpdateCastleLifePacket* packet) override;
|
virtual void HandlePacket(const protocol::UpdateCastleLifePacket* packet) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,23 +11,23 @@ class Server;
|
|||||||
|
|
||||||
class Lobby {
|
class Lobby {
|
||||||
private:
|
private:
|
||||||
Server* m_Server;
|
Server* m_Server;
|
||||||
bool m_GameStarted = false;
|
bool m_GameStarted = false;
|
||||||
std::uint64_t m_StartTimerTime = 0;
|
std::uint64_t m_StartTime = 0;
|
||||||
std::vector<std::uint8_t> m_Players;
|
std::vector<std::uint8_t> m_Players;
|
||||||
utils::AutoTimer m_Timer;
|
utils::AutoTimer m_Timer;
|
||||||
public:
|
public:
|
||||||
Lobby(Server* server);
|
Lobby(Server* server);
|
||||||
|
|
||||||
void OnPlayerJoin(std::uint8_t playerID);
|
void OnPlayerJoin(std::uint8_t playerID);
|
||||||
void OnPlayerLeave(std::uint8_t playerID);
|
void OnPlayerLeave(std::uint8_t playerID);
|
||||||
|
|
||||||
void SendTimeRemaining();
|
void SendTimeRemaining();
|
||||||
|
|
||||||
void Tick();
|
void Tick();
|
||||||
|
|
||||||
//static constexpr int LobbyWaitingTime = 2 * 60 * 1000; // in millis
|
//static constexpr int LobbyWaitingTime = 2 * 60 * 1000; // in millis
|
||||||
static constexpr int LobbyWaitingTime = 5 * 1000; // in millis
|
static constexpr int LobbyWaitingTime = 5 * 1000; // in millis
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
@@ -21,80 +21,84 @@ typedef std::map<std::uint8_t, ServerConnexion> ConnexionMap;
|
|||||||
|
|
||||||
class TickCounter {
|
class TickCounter {
|
||||||
private:
|
private:
|
||||||
float m_TPS;
|
float m_TPS;
|
||||||
std::uint64_t m_LastTPSTime;
|
float m_MSPT;
|
||||||
std::uint8_t m_TickCount;
|
std::uint64_t m_LastTPSTime;
|
||||||
|
std::uint8_t m_TickCount;
|
||||||
public:
|
public:
|
||||||
TickCounter() {}
|
TickCounter() {}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
m_TPS = SERVER_TPS;
|
m_TPS = SERVER_TPS;
|
||||||
m_LastTPSTime = utils::GetTime();
|
m_LastTPSTime = utils::GetTime();
|
||||||
m_TickCount = 0;
|
m_TickCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Update() { // return true when tps is updated
|
bool Update() { // return true when tps is updated
|
||||||
m_TickCount++;
|
m_TickCount++;
|
||||||
if (m_TickCount >= SERVER_TPS) {
|
if (m_TickCount >= SERVER_TPS) {
|
||||||
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::GetTime() - m_LastTPSTime;
|
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::GetTime() - m_LastTPSTime;
|
||||||
m_TPS = static_cast<float>(SERVER_TPS) / static_cast<float>(timeElapsedSinceLast20Ticks / 1000.0f);
|
m_TPS = static_cast<float>(SERVER_TPS) / static_cast<float>(timeElapsedSinceLast20Ticks / 1000.0f);
|
||||||
m_TickCount = 0;
|
m_TickCount = 0;
|
||||||
m_LastTPSTime = td::utils::GetTime();
|
m_LastTPSTime = td::utils::GetTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetTPS() const { return m_TPS; }
|
float GetTPS() const { return m_TPS; }
|
||||||
|
float GetMSPT() const { return m_MSPT; }
|
||||||
|
|
||||||
|
void SetMSPT(float mspt) { m_MSPT = mspt; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
private:
|
private:
|
||||||
network::TCPListener m_Listener;
|
network::TCPListener m_Listener;
|
||||||
ConnexionMap m_Connections;
|
ConnexionMap m_Connections;
|
||||||
ServerGame m_Game{ this };
|
ServerGame m_Game{ this };
|
||||||
Lobby m_Lobby{ this };
|
Lobby m_Lobby{ this };
|
||||||
TickCounter m_TickCounter;
|
TickCounter m_TickCounter;
|
||||||
|
|
||||||
std::thread m_Thread;
|
std::thread m_Thread;
|
||||||
bool m_ServerRunning;
|
bool m_ServerRunning;
|
||||||
public:
|
public:
|
||||||
Server(const std::string& worldFilePath);
|
Server(const std::string& worldFilePath);
|
||||||
virtual ~Server();
|
virtual ~Server();
|
||||||
|
|
||||||
bool Start(std::uint16_t port);
|
bool Start(std::uint16_t port);
|
||||||
void Stop(); // force the server to stop
|
void Stop(); // force the server to stop
|
||||||
void Close(); // at the end of a game
|
void Close(); // at the end of a game
|
||||||
|
|
||||||
void RemoveConnexion(std::uint8_t connexionID);
|
void RemoveConnexion(std::uint8_t connexionID);
|
||||||
|
|
||||||
void BroadcastPacket(const protocol::Packet* packet);
|
void BroadcastPacket(const protocol::Packet* packet);
|
||||||
|
|
||||||
float GetTPS() const { return m_TickCounter.GetTPS(); }
|
float GetTPS() const { return m_TickCounter.GetTPS(); }
|
||||||
|
|
||||||
bool IsRunning() { return m_ServerRunning; }
|
bool IsRunning() { return m_ServerRunning; }
|
||||||
|
|
||||||
const ServerGame& GetGame() const { return m_Game; }
|
const ServerGame& GetGame() const { return m_Game; }
|
||||||
ServerGame& GetGame() { return m_Game; }
|
ServerGame& GetGame() { return m_Game; }
|
||||||
|
|
||||||
const Lobby& GetLobby() const { return m_Lobby; }
|
const Lobby& GetLobby() const { return m_Lobby; }
|
||||||
const ConnexionMap& GetConnexions() const { return m_Connections; }
|
const ConnexionMap& GetConnexions() const { return m_Connections; }
|
||||||
ConnexionMap& GetConnexions() { return m_Connections; }
|
ConnexionMap& GetConnexions() { return m_Connections; }
|
||||||
|
|
||||||
const game::PlayerList& GetPlayers() const { return m_Game.GetPlayers(); }
|
const game::PlayerList& GetPlayers() const { return m_Game.GetPlayers(); }
|
||||||
game::PlayerList& GetPlayers() { return m_Game.GetPlayers(); }
|
game::PlayerList& GetPlayers() { return m_Game.GetPlayers(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Accept();
|
void Accept();
|
||||||
void UpdateSockets();
|
void UpdateSockets();
|
||||||
|
|
||||||
void Clean();
|
void Clean();
|
||||||
void StartThread();
|
void StartThread();
|
||||||
void StopThread();
|
void StopThread();
|
||||||
void Tick(std::uint64_t delta);
|
void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
void OnPlayerJoin(std::uint8_t id);
|
void OnPlayerJoin(std::uint8_t id);
|
||||||
void OnPlayerLeave(std::uint8_t id);
|
void OnPlayerLeave(std::uint8_t id);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
@@ -11,49 +11,48 @@ namespace server {
|
|||||||
|
|
||||||
class Server;
|
class Server;
|
||||||
|
|
||||||
struct KeepAlive
|
struct KeepAlive {
|
||||||
{
|
std::uint64_t keepAliveID = 0;
|
||||||
std::uint64_t keepAliveID = 0;
|
std::uint64_t sendTime;
|
||||||
std::uint64_t sendTime;
|
bool recievedResponse = false;
|
||||||
bool recievedResponse = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ServerConnexion : public protocol::Connexion {
|
class ServerConnexion : public protocol::Connexion {
|
||||||
private:
|
private:
|
||||||
Server* m_Server = nullptr;
|
Server* m_Server = nullptr;
|
||||||
std::uint8_t m_ID;
|
std::uint8_t m_ID;
|
||||||
KeepAlive m_KeepAlive;
|
KeepAlive m_KeepAlive;
|
||||||
game::Player* m_Player;
|
game::Player* m_Player;
|
||||||
public:
|
public:
|
||||||
ServerConnexion();
|
ServerConnexion();
|
||||||
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
|
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
|
||||||
ServerConnexion(ServerConnexion&& move);
|
ServerConnexion(ServerConnexion&& move);
|
||||||
virtual ~ServerConnexion();
|
virtual ~ServerConnexion();
|
||||||
|
|
||||||
void SetServer(Server* server);
|
void SetServer(Server* server);
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet) override;
|
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
|
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::SelectTeamPacket* packet) override;
|
virtual void HandlePacket(const protocol::SelectTeamPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet) override;
|
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::SendMobsPacket* packet) override;
|
virtual void HandlePacket(const protocol::SendMobsPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
||||||
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
||||||
|
|
||||||
std::uint8_t GetID() const { return m_ID; }
|
std::uint8_t GetID() const { return m_ID; }
|
||||||
const game::Player* GetPlayer() const { return m_Player; }
|
const game::Player* GetPlayer() const { return m_Player; }
|
||||||
game::Player* GetPlayer() { return m_Player; }
|
game::Player* GetPlayer() { return m_Player; }
|
||||||
|
|
||||||
virtual bool UpdateSocket();
|
virtual bool UpdateSocket();
|
||||||
|
|
||||||
REMOVE_COPY(ServerConnexion);
|
REMOVE_COPY(ServerConnexion);
|
||||||
private:
|
private:
|
||||||
void RegisterHandlers();
|
void RegisterHandlers();
|
||||||
void CheckKeepAlive();
|
void CheckKeepAlive();
|
||||||
void SendKeepAlive();
|
void SendKeepAlive();
|
||||||
void InitConnection();
|
void InitConnection();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
@@ -11,32 +11,32 @@ class Server;
|
|||||||
|
|
||||||
class ServerGame : public game::Game, public game::GameListener {
|
class ServerGame : public game::Game, public game::GameListener {
|
||||||
private:
|
private:
|
||||||
Server* m_Server;
|
Server* m_Server;
|
||||||
ServerWorld m_ServerWorld;
|
ServerWorld m_ServerWorld;
|
||||||
utils::AutoTimer m_GoldMineTimer;
|
utils::AutoTimer m_GoldMineTimer;
|
||||||
utils::AutoTimer m_MobStatesTimer;
|
utils::AutoTimer m_MobStatesTimer;
|
||||||
utils::CooldownTimer m_EndGameCooldown;
|
utils::CooldownTimer m_EndGameCooldown;
|
||||||
public:
|
public:
|
||||||
ServerGame(Server* server);
|
ServerGame(Server* server);
|
||||||
~ServerGame() {}
|
~ServerGame() {}
|
||||||
|
|
||||||
ServerWorld* GetServerWorld() { return &m_ServerWorld; }
|
ServerWorld* GetServerWorld() { return &m_ServerWorld; }
|
||||||
|
|
||||||
virtual void Tick(std::uint64_t delta);
|
virtual void Tick(std::uint64_t delta);
|
||||||
void StartGame();
|
void StartGame();
|
||||||
|
|
||||||
// GameListener
|
// GameListener
|
||||||
|
|
||||||
virtual void OnGameStateUpdate(game::GameState newState) override;
|
virtual void OnGameStateUpdate(game::GameState newState) override;
|
||||||
virtual void OnGameBegin() override;
|
virtual void OnGameBegin() override;
|
||||||
virtual void OnGameEnd() override;
|
virtual void OnGameEnd() override;
|
||||||
virtual void OnGameClose() override;
|
virtual void OnGameClose() override;
|
||||||
private:
|
private:
|
||||||
void BalanceTeams();
|
void BalanceTeams();
|
||||||
void InitPlayerStats();
|
void InitPlayerStats();
|
||||||
void UpdateMobStates();
|
void UpdateMobStates();
|
||||||
void UpdateGoldMines();
|
void UpdateGoldMines();
|
||||||
void UpdatePlayerStats();
|
void UpdatePlayerStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -10,19 +10,19 @@ class ServerGame;
|
|||||||
|
|
||||||
class ServerWorld : public game::World {
|
class ServerWorld : public game::World {
|
||||||
private:
|
private:
|
||||||
game::MobID m_CurrentMobID;
|
game::MobID m_CurrentMobID;
|
||||||
game::TowerID m_CurrentTowerID;
|
game::TowerID m_CurrentTowerID;
|
||||||
Server* m_Server;
|
Server* m_Server;
|
||||||
public:
|
public:
|
||||||
static constexpr float MobSpawnBorder = 0.01f;
|
static constexpr float MobSpawnBorder = 0.01f;
|
||||||
|
|
||||||
ServerWorld(Server* server, ServerGame* game);
|
ServerWorld(Server* server, ServerGame* game);
|
||||||
|
|
||||||
void SpawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count);
|
void SpawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count);
|
||||||
game::TowerPtr PlaceTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder);
|
game::TowerPtr PlaceTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder);
|
||||||
|
|
||||||
virtual void OnMobDie(game::Mob* mob) override;
|
virtual void OnMobDie(game::Mob* mob) override;
|
||||||
virtual void OnMobCastleDamage(game::Mob* damager, game::TeamCastle* enemyCastle, float damage) override;
|
virtual void OnMobCastleDamage(game::Mob* damager, game::TeamCastle* enemyCastle, float damage) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,166 +10,166 @@ namespace td {
|
|||||||
|
|
||||||
class DataBuffer {
|
class DataBuffer {
|
||||||
private:
|
private:
|
||||||
typedef std::vector<std::uint8_t> Data;
|
typedef std::vector<std::uint8_t> Data;
|
||||||
Data m_Buffer;
|
Data m_Buffer;
|
||||||
std::size_t m_ReadOffset;
|
std::size_t m_ReadOffset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Data::iterator iterator;
|
typedef Data::iterator iterator;
|
||||||
typedef Data::const_iterator const_iterator;
|
typedef Data::const_iterator const_iterator;
|
||||||
typedef Data::reference reference;
|
typedef Data::reference reference;
|
||||||
typedef Data::const_reference const_reference;
|
typedef Data::const_reference const_reference;
|
||||||
|
|
||||||
DataBuffer();
|
DataBuffer();
|
||||||
DataBuffer(const DataBuffer& other);
|
DataBuffer(const DataBuffer& other);
|
||||||
DataBuffer(const DataBuffer& other, Data::difference_type offset);
|
DataBuffer(const DataBuffer& other, Data::difference_type offset);
|
||||||
DataBuffer(DataBuffer&& other);
|
DataBuffer(DataBuffer&& other);
|
||||||
DataBuffer(const std::string& str);
|
DataBuffer(const std::string& str);
|
||||||
|
|
||||||
DataBuffer& operator=(const DataBuffer& other);
|
DataBuffer& operator=(const DataBuffer& other);
|
||||||
DataBuffer& operator=(DataBuffer&& other);
|
DataBuffer& operator=(DataBuffer&& other);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Append(T data) {
|
void Append(T data) {
|
||||||
std::size_t size = sizeof(data);
|
std::size_t size = sizeof(data);
|
||||||
std::size_t end_pos = m_Buffer.size();
|
std::size_t end_pos = m_Buffer.size();
|
||||||
m_Buffer.resize(m_Buffer.size() + size);
|
m_Buffer.resize(m_Buffer.size() + size);
|
||||||
memcpy(&m_Buffer[end_pos], &data, size);
|
memcpy(&m_Buffer[end_pos], &data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DataBuffer& operator<<(T data) {
|
DataBuffer& operator<<(T data) {
|
||||||
// Switch to big endian
|
// Switch to big endian
|
||||||
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
||||||
Append(data);
|
Append(data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer& operator<<(std::string str) {
|
DataBuffer& operator<<(std::string str) {
|
||||||
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
|
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer& operator<<(DataBuffer& data) {
|
DataBuffer& operator<<(DataBuffer& data) {
|
||||||
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer& operator<<(const DataBuffer& data) {
|
DataBuffer& operator<<(const DataBuffer& data) {
|
||||||
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DataBuffer& operator>>(T& data) {
|
DataBuffer& operator>>(T& data) {
|
||||||
assert(m_ReadOffset + sizeof(T) <= GetSize());
|
assert(m_ReadOffset + sizeof(T) <= GetSize());
|
||||||
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
|
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
|
||||||
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
||||||
m_ReadOffset += sizeof(T);
|
m_ReadOffset += sizeof(T);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer& operator>>(DataBuffer& data) {
|
DataBuffer& operator>>(DataBuffer& data) {
|
||||||
data.Resize(GetSize() - m_ReadOffset);
|
data.Resize(GetSize() - m_ReadOffset);
|
||||||
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
|
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
|
||||||
m_ReadOffset = m_Buffer.size();
|
m_ReadOffset = m_Buffer.size();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer& operator>>(std::string& str) {
|
DataBuffer& operator>>(std::string& str) {
|
||||||
std::size_t stringSize = strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
|
std::size_t stringSize = strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
|
||||||
str.resize(stringSize);
|
str.resize(stringSize);
|
||||||
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset),
|
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset),
|
||||||
m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset + stringSize), str.begin());
|
m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset + stringSize), str.begin());
|
||||||
m_ReadOffset += stringSize;
|
m_ReadOffset += stringSize;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteSome(const char* buffer, std::size_t amount) {
|
void WriteSome(const char* buffer, std::size_t amount) {
|
||||||
std::size_t end_pos = m_Buffer.size();
|
std::size_t end_pos = m_Buffer.size();
|
||||||
m_Buffer.resize(m_Buffer.size() + amount);
|
m_Buffer.resize(m_Buffer.size() + amount);
|
||||||
memcpy(m_Buffer.data() + end_pos, buffer, amount);
|
memcpy(m_Buffer.data() + end_pos, buffer, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
|
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
|
||||||
std::size_t end_pos = m_Buffer.size();
|
std::size_t end_pos = m_Buffer.size();
|
||||||
m_Buffer.resize(m_Buffer.size() + amount);
|
m_Buffer.resize(m_Buffer.size() + amount);
|
||||||
memcpy(m_Buffer.data() + end_pos, buffer, amount);
|
memcpy(m_Buffer.data() + end_pos, buffer, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadSome(char* buffer, std::size_t amount) {
|
void ReadSome(char* buffer, std::size_t amount) {
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
|
||||||
m_ReadOffset += amount;
|
m_ReadOffset += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
|
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
|
||||||
m_ReadOffset += amount;
|
m_ReadOffset += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadSome(DataBuffer& buffer, std::size_t amount) {
|
void ReadSome(DataBuffer& buffer, std::size_t amount) {
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
buffer.Resize(amount);
|
buffer.Resize(amount);
|
||||||
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
|
||||||
m_ReadOffset += amount;
|
m_ReadOffset += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadSome(std::string& buffer, std::size_t amount) {
|
void ReadSome(std::string& buffer, std::size_t amount) {
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
buffer.resize(amount);
|
buffer.resize(amount);
|
||||||
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
|
||||||
m_ReadOffset += amount;
|
m_ReadOffset += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resize(std::size_t size) {
|
void Resize(std::size_t size) {
|
||||||
m_Buffer.resize(size);
|
m_Buffer.resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reserve(std::size_t amount) {
|
void Reserve(std::size_t amount) {
|
||||||
m_Buffer.reserve(amount);
|
m_Buffer.reserve(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase(iterator it) {
|
void erase(iterator it) {
|
||||||
m_Buffer.erase(it);
|
m_Buffer.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
m_Buffer.clear();
|
m_Buffer.clear();
|
||||||
m_ReadOffset = 0;
|
m_ReadOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFinished() const {
|
bool IsFinished() const {
|
||||||
return m_ReadOffset >= m_Buffer.size();
|
return m_ReadOffset >= m_Buffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t* data() {
|
std::uint8_t* data() {
|
||||||
return m_Buffer.data();
|
return m_Buffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::uint8_t* data() const {
|
const std::uint8_t* data() const {
|
||||||
return m_Buffer.data();
|
return m_Buffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t GetReadOffset() const { return m_ReadOffset; }
|
std::size_t GetReadOffset() const { return m_ReadOffset; }
|
||||||
void SetReadOffset(std::size_t pos);
|
void SetReadOffset(std::size_t pos);
|
||||||
|
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
std::size_t GetSize() const;
|
std::size_t GetSize() const;
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
std::size_t GetRemaining() const;
|
std::size_t GetRemaining() const;
|
||||||
|
|
||||||
iterator begin();
|
iterator begin();
|
||||||
iterator end();
|
iterator end();
|
||||||
const_iterator begin() const;
|
const_iterator begin() const;
|
||||||
const_iterator end() const;
|
const_iterator end() const;
|
||||||
|
|
||||||
reference operator[](Data::size_type i) { return m_Buffer[i]; }
|
reference operator[](Data::size_type i) { return m_Buffer[i]; }
|
||||||
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
|
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
|
||||||
|
|
||||||
bool ReadFile(const std::string& fileName);
|
bool ReadFile(const std::string& fileName);
|
||||||
bool WriteFile(const std::string& fileName);
|
bool WriteFile(const std::string& fileName);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
|
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
|
||||||
|
|||||||
@@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
std::string format(const std::string& format, Args... args){
|
std::string format(const std::string& format, Args... args) {
|
||||||
int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
|
int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
|
||||||
if (size <= 0){
|
if (size <= 0) {
|
||||||
throw std::runtime_error("Error during formatting.");
|
throw std::runtime_error("Error during formatting.");
|
||||||
}
|
}
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
std::unique_ptr<char[]> buf(new char[size]);
|
||||||
snprintf(buf.get(), size, format.c_str(), args...);
|
snprintf(buf.get(), static_cast<std::size_t>(size), format.c_str(), args...);
|
||||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
177
include/misc/Maths.h
Normal file
177
include/misc/Maths.h
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Defines.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// Operators //
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec2<T> operator+(const Vec2<T>& vect, const Vec2<T>& other) {
|
||||||
|
return {vect.x + other.x, vect.y + other.y};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec2<T> operator- (const Vec2<T>& vect) {
|
||||||
|
return { -vect.x, -vect.y };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec2<T> operator- (const Vec2<T>& vect, const Vec2<T>& other) {
|
||||||
|
return vect + (-other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec3<T> operator- (const Vec3<T>& vect) {
|
||||||
|
return { -vect.x, -vect.y, -vect.z };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec3<T> operator+ (const Vec3<T>& vect, const Vec3<T>& other) {
|
||||||
|
return { vect.x + other.x, vect.y + other.y, vect.z + other.y };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec3<T> operator- (const Vec3<T>& vect, const Vec3<T>& other) {
|
||||||
|
return vect + (-other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec4<T> operator- (const Vec4<T>& vect) {
|
||||||
|
return { -vect.x, -vect.y, -vect.z, -vect.w };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec4<T> operator+ (const Vec4<T>& vect, const Vec4<T>& other) {
|
||||||
|
return { vect.x + other.x, vect.y + other.y, vect.z + other.y, vect.w + other.w };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec4<T> operator- (const Vec4<T>& vect, const Vec4<T>& other) {
|
||||||
|
return vect + (-other);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// Vectors //
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace maths {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Length(const Vec3<T>& vect) {
|
||||||
|
return std::sqrt(vect.x * vect.x + vect.y * vect.y + vect.z * vect.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec3<T> Normalize(const Vec3<T>& vect) {
|
||||||
|
T length = Length(vect);
|
||||||
|
|
||||||
|
return { vect.x / length, vect.y / length, vect.z / length };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec4<T> Normalize(const Vec4<T>& vect) {
|
||||||
|
T length = std::sqrt(vect.x * vect.x + vect.y * vect.y + vect.z * vect.z + vect.w * vect.w);
|
||||||
|
|
||||||
|
return { vect.x / length, vect.y / length, vect.z / length, vect.w / length };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Dot(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||||
|
return vect.x * other.x + vect.y * other.y + vect.z * other.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec3<T> Cross(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||||
|
return {
|
||||||
|
vect.y * other.z - vect.z * other.y,
|
||||||
|
vect.z * other.x - vect.x * other.z,
|
||||||
|
vect.x * other.y - vect.y * other.x,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Dot(const Vec4<T>& vect, const Vec4<T>& other) {
|
||||||
|
return vect.x * other.x + vect.y * other.y + vect.z * other.z + vect.w * other.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Distance(const Vec3<T>& vect, const Vec3<T>& other) {
|
||||||
|
return Length(vect - other);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// Matricies //
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vec4<T> Dot(const Mat4<T>& mat, const Vec4<T>& vect) {
|
||||||
|
return {
|
||||||
|
mat.x0 * vect.x + mat.x1 * vect.y + mat.x2 * vect.z + mat.x3 * vect.w,
|
||||||
|
mat.y0 * vect.x + mat.y1 * vect.y + mat.y2 * vect.z + mat.y3 * vect.w,
|
||||||
|
mat.z0 * vect.x + mat.z1 * vect.y + mat.z2 * vect.z + mat.z3 * vect.w,
|
||||||
|
mat.w0 * vect.x + mat.w1 * vect.y + mat.w2 * vect.z + mat.w3 * vect.w
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Mat4<T> Dot(const Mat4<T>& mat, const Mat4<T>& other) {
|
||||||
|
Mat4<T> result {};
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < Mat4<T>::MATRIX_SIZE; i++) {
|
||||||
|
for (std::size_t j = 0; j < Mat4<T>::MATRIX_SIZE; j++) {
|
||||||
|
for (std::size_t k = 0; k < Mat4<T>::MATRIX_SIZE; k++) {
|
||||||
|
result.at(i, j) += mat.at(i, k) * other.at(k, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Mat4<T> Identity() {
|
||||||
|
Mat4<T> result{};
|
||||||
|
|
||||||
|
result.x0 = static_cast<T>(1);
|
||||||
|
result.y1 = static_cast<T>(1);
|
||||||
|
result.z2 = static_cast<T>(1);
|
||||||
|
result.w3 = static_cast<T>(1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Mat4<T> Transpose(const Mat4<T>& mat) {
|
||||||
|
Mat4<T> result;
|
||||||
|
|
||||||
|
result.x1 = mat.y0;
|
||||||
|
result.x2 = mat.z0;
|
||||||
|
result.x3 = mat.w0;
|
||||||
|
result.y0 = mat.x1;
|
||||||
|
result.y2 = mat.z1;
|
||||||
|
result.y3 = mat.w1;
|
||||||
|
result.z0 = mat.x2;
|
||||||
|
result.z1 = mat.y2;
|
||||||
|
result.z3 = mat.w2;
|
||||||
|
result.w0 = mat.x3;
|
||||||
|
result.w1 = mat.y3;
|
||||||
|
result.w2 = mat.z3;
|
||||||
|
result.x0 = mat.x0;
|
||||||
|
result.y1 = mat.y1;
|
||||||
|
result.z2 = mat.z2;
|
||||||
|
result.w3 = mat.w3;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat4f Perspective(float fovY, float aspectRatio, float zNear, float zFar);
|
||||||
|
Mat4f Look(const Vec3f& eye, const Vec3f& center, const Vec3f& up);
|
||||||
|
|
||||||
|
Mat4f Inverse(const Mat4f& mat);
|
||||||
|
|
||||||
|
} // namespace maths
|
||||||
|
} // namespace td
|
||||||
@@ -10,26 +10,26 @@ namespace utils {
|
|||||||
template <typename Listener>
|
template <typename Listener>
|
||||||
class ObjectNotifier {
|
class ObjectNotifier {
|
||||||
protected:
|
protected:
|
||||||
std::vector<Listener*> m_Listeners;
|
std::vector<Listener*> m_Listeners;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void BindListener(Listener* listener) {
|
void BindListener(Listener* listener) {
|
||||||
m_Listeners.push_back(listener);
|
m_Listeners.push_back(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnbindListener(Listener* listener) {
|
void UnbindListener(Listener* listener) {
|
||||||
auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);
|
auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);
|
||||||
|
|
||||||
if (iter == m_Listeners.end()) return;
|
if (iter == m_Listeners.end()) return;
|
||||||
|
|
||||||
m_Listeners.erase(iter);
|
m_Listeners.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func, typename... Args>
|
template <typename Func, typename... Args>
|
||||||
void NotifyListeners(Func function, Args... args) {
|
void NotifyListeners(Func function, Args... args) {
|
||||||
for (Listener* listener : m_Listeners)
|
for (Listener* listener : m_Listeners)
|
||||||
std::bind(function, listener, args...)();
|
std::bind(function, listener, args...)();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|||||||
@@ -4,49 +4,49 @@ namespace td {
|
|||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
enum class Os {
|
enum class Os {
|
||||||
Windows = 0,
|
Windows = 0,
|
||||||
Linux,
|
Linux,
|
||||||
Android,
|
Android,
|
||||||
Unknown,
|
Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Architecture {
|
enum class Architecture {
|
||||||
x86_64 = 0,
|
x86_64 = 0,
|
||||||
x86,
|
x86,
|
||||||
Arm64,
|
Arm64,
|
||||||
Armhf,
|
Armhf,
|
||||||
Unknown,
|
Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Os GetSystemOs() {
|
inline Os GetSystemOs() {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
return Os::Windows;
|
return Os::Windows;
|
||||||
#elif defined(__ANDROID__)
|
#elif defined(__ANDROID__)
|
||||||
return Os::Android;
|
return Os::Android;
|
||||||
#elif defined(__unix__)
|
#elif defined(__unix__)
|
||||||
return Os::Linux;
|
return Os::Linux;
|
||||||
#else
|
#else
|
||||||
#pragma message ("Target OS unknown or unsupported !")
|
#pragma message ("Target OS unknown or unsupported !")
|
||||||
return Os::Unknown;
|
return Os::Unknown;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Architecture GetSystemArchitecture() {
|
inline Architecture GetSystemArchitecture() {
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
return Architecture::x86_64;
|
return Architecture::x86_64;
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
return Architecture::x86;
|
return Architecture::x86;
|
||||||
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
|
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
|
||||||
return Architecture::x86_64;
|
return Architecture::x86_64;
|
||||||
#elif defined(_M_IX86) || defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
|
#elif defined(_M_IX86) || defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
|
||||||
return Architecture::x86;
|
return Architecture::x86;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
return Architecture::Arm64;
|
return Architecture::Arm64;
|
||||||
#elif defined(__arm__) || defined(_M_ARM)
|
#elif defined(__arm__) || defined(_M_ARM)
|
||||||
return Architecture::Armhf;
|
return Architecture::Armhf;
|
||||||
#else
|
#else
|
||||||
#pragma message ("Target CPU architecture unknown or unsupported !")
|
#pragma message ("Target CPU architecture unknown or unsupported !")
|
||||||
return Architecture::Unknown;
|
return Architecture::Unknown;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ namespace utils {
|
|||||||
|
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
NumberType GetRandomInt(NumberType min, NumberType max) {
|
NumberType GetRandomInt(NumberType min, NumberType max) {
|
||||||
std::random_device randomDevice;
|
std::random_device randomDevice;
|
||||||
std::mt19937 generator(randomDevice());
|
std::mt19937 generator(randomDevice());
|
||||||
std::uniform_int_distribution<NumberType> distrib(min, max);
|
std::uniform_int_distribution<NumberType> distrib(min, max);
|
||||||
return distrib(generator);
|
return distrib(generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
NumberType GetRandomReal(NumberType min, NumberType max) {
|
NumberType GetRandomReal(NumberType min, NumberType max) {
|
||||||
std::random_device randomDevice;
|
std::random_device randomDevice;
|
||||||
std::mt19937 generator(randomDevice());
|
std::mt19937 generator(randomDevice());
|
||||||
std::uniform_real_distribution<NumberType> distrib(min, max);
|
std::uniform_real_distribution<NumberType> distrib(min, max);
|
||||||
return distrib(generator);
|
return distrib(generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|||||||
@@ -8,87 +8,87 @@ namespace shape {
|
|||||||
|
|
||||||
class Point {
|
class Point {
|
||||||
private:
|
private:
|
||||||
float m_X, m_Y;
|
float m_X, m_Y;
|
||||||
public:
|
public:
|
||||||
Point() : m_X(0), m_Y(0) {}
|
Point() : m_X(0), m_Y(0) {}
|
||||||
Point(float x, float y) : m_X(x), m_Y(y) {}
|
Point(float x, float y) : m_X(x), m_Y(y) {}
|
||||||
|
|
||||||
float GetX() const { return m_X; }
|
float GetX() const { return m_X; }
|
||||||
float GetY() const { return m_Y; }
|
float GetY() const { return m_Y; }
|
||||||
|
|
||||||
void SetX(float x) { m_X = x; }
|
void SetX(float x) { m_X = x; }
|
||||||
void SetY(float y) { m_Y = y; }
|
void SetY(float y) { m_Y = y; }
|
||||||
|
|
||||||
float Distance(const Point& point) const;
|
float Distance(const Point& point) const;
|
||||||
float DistanceSquared(const Point& point) const;
|
float DistanceSquared(const Point& point) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Circle;
|
class Circle;
|
||||||
|
|
||||||
class Rectangle {
|
class Rectangle {
|
||||||
private:
|
private:
|
||||||
Point m_Center;
|
Point m_Center;
|
||||||
float m_Width, m_Height;
|
float m_Width, m_Height;
|
||||||
public:
|
public:
|
||||||
Rectangle() {}
|
Rectangle() {}
|
||||||
|
|
||||||
const Point& GetCenter() const { return m_Center; }
|
const Point& GetCenter() const { return m_Center; }
|
||||||
float GetCenterX() const { return m_Center.GetX(); }
|
float GetCenterX() const { return m_Center.GetX(); }
|
||||||
float GetCenterY() const { return m_Center.GetY(); }
|
float GetCenterY() const { return m_Center.GetY(); }
|
||||||
|
|
||||||
float GetWidth() const { return m_Width; }
|
float GetWidth() const { return m_Width; }
|
||||||
float GetHeight() const { return m_Height; }
|
float GetHeight() const { return m_Height; }
|
||||||
|
|
||||||
Point GetTopLeft() const { return { m_Center.GetX() - (m_Width / 2.0f), m_Center.GetY() - (m_Height / 2.0f) }; }
|
Point GetTopLeft() const { return { m_Center.GetX() - (m_Width / 2.0f), m_Center.GetY() - (m_Height / 2.0f) }; }
|
||||||
Point GetBottomRight() const { return { m_Center.GetX() + (m_Width / 2.0f), m_Center.GetY() + (m_Height / 2.0f) }; }
|
Point GetBottomRight() const { return { m_Center.GetX() + (m_Width / 2.0f), m_Center.GetY() + (m_Height / 2.0f) }; }
|
||||||
|
|
||||||
void SetCenter(const Point& center) { m_Center = center; }
|
void SetCenter(const Point& center) { m_Center = center; }
|
||||||
void SetCenterX(float x) { m_Center.SetX(x); }
|
void SetCenterX(float x) { m_Center.SetX(x); }
|
||||||
void SetCenterY(float y) { m_Center.SetY(y); }
|
void SetCenterY(float y) { m_Center.SetY(y); }
|
||||||
|
|
||||||
void SetSize(float width, float height) { SetWidth(width); SetHeight(height); }
|
void SetSize(float width, float height) { SetWidth(width); SetHeight(height); }
|
||||||
void SetSize(Point size) { SetSize(size.GetX(), size.GetY()); }
|
void SetSize(Point size) { SetSize(size.GetX(), size.GetY()); }
|
||||||
Point GetSize() { return { m_Width, m_Height }; }
|
Point GetSize() { return { m_Width, m_Height }; }
|
||||||
|
|
||||||
void SetWidth(float width) { m_Width = width; }
|
void SetWidth(float width) { m_Width = width; }
|
||||||
void SetHeight(float height) { m_Height = height; }
|
void SetHeight(float height) { m_Height = height; }
|
||||||
|
|
||||||
bool CollidesWith(const Point& point) const;
|
bool CollidesWith(const Point& point) const;
|
||||||
bool CollidesWith(const Rectangle& rect) const;
|
bool CollidesWith(const Rectangle& rect) const;
|
||||||
bool CollidesWith(const Circle& circle) const;
|
bool CollidesWith(const Circle& circle) const;
|
||||||
|
|
||||||
// distance from the closest side of the rectangle
|
// distance from the closest side of the rectangle
|
||||||
float Distance(const Circle& circle) const;
|
float Distance(const Circle& circle) const;
|
||||||
float DistanceSquared(const Circle& circle) const;
|
float DistanceSquared(const Circle& circle) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Circle {
|
class Circle {
|
||||||
private:
|
private:
|
||||||
Point m_Center;
|
Point m_Center;
|
||||||
float m_Radius;
|
float m_Radius;
|
||||||
public:
|
public:
|
||||||
Circle(float x, float y, float radius) : m_Center(x, y), m_Radius(radius) {}
|
Circle(float x, float y, float radius) : m_Center(x, y), m_Radius(radius) {}
|
||||||
Circle() : m_Radius(0) {}
|
Circle() : m_Radius(0) {}
|
||||||
|
|
||||||
const Point& GetCenter() const { return m_Center; }
|
const Point& GetCenter() const { return m_Center; }
|
||||||
float GetCenterX() const { return m_Center.GetX(); }
|
float GetCenterX() const { return m_Center.GetX(); }
|
||||||
float GetCenterY() const { return m_Center.GetY(); }
|
float GetCenterY() const { return m_Center.GetY(); }
|
||||||
|
|
||||||
float GetRadius() const { return m_Radius; }
|
float GetRadius() const { return m_Radius; }
|
||||||
|
|
||||||
void SetCenter(const Point& center) { m_Center = center; }
|
void SetCenter(const Point& center) { m_Center = center; }
|
||||||
void SetCenterX(float x) { m_Center.SetX(x); }
|
void SetCenterX(float x) { m_Center.SetX(x); }
|
||||||
void SetCenterY(float y) { m_Center.SetY(y); }
|
void SetCenterY(float y) { m_Center.SetY(y); }
|
||||||
|
|
||||||
void SetRadius(float radius) { m_Radius = radius; }
|
void SetRadius(float radius) { m_Radius = radius; }
|
||||||
|
|
||||||
bool CollidesWith(const Point& point) const;
|
bool CollidesWith(const Point& point) const;
|
||||||
bool CollidesWith(const Rectangle& rect) const;
|
bool CollidesWith(const Rectangle& rect) const;
|
||||||
bool CollidesWith(const Circle& circle) const;
|
bool CollidesWith(const Circle& circle) const;
|
||||||
|
|
||||||
// distance from the closest side of the rectangle
|
// distance from the closest side of the rectangle
|
||||||
float Distance(const Rectangle& rect) const;
|
float Distance(const Rectangle& rect) const;
|
||||||
float DistanceSquared(const Rectangle& rect) const;
|
float DistanceSquared(const Rectangle& rect) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shape
|
} // namespace shape
|
||||||
|
|||||||
@@ -14,62 +14,62 @@ typedef std::function<void()> TimerExecFunction;
|
|||||||
// utililty class to call function at regular period of time
|
// utililty class to call function at regular period of time
|
||||||
class AutoTimer {
|
class AutoTimer {
|
||||||
private:
|
private:
|
||||||
std::uint64_t m_Interval;
|
std::uint64_t m_Interval;
|
||||||
TimerExecFunction m_Function;
|
TimerExecFunction m_Function;
|
||||||
|
|
||||||
std::uint64_t m_LastTime = GetTime();
|
std::uint64_t m_LastTime = GetTime();
|
||||||
std::uint64_t m_InternalTime = 0;
|
std::uint64_t m_InternalTime = 0;
|
||||||
public:
|
public:
|
||||||
AutoTimer() : m_Interval(0), m_Function(nullptr) {}
|
AutoTimer() : m_Interval(0), m_Function(nullptr) {}
|
||||||
AutoTimer(std::uint64_t interval) : m_Interval(interval), m_Function(nullptr) {}
|
AutoTimer(std::uint64_t interval) : m_Interval(interval), m_Function(nullptr) {}
|
||||||
AutoTimer(std::uint64_t interval, TimerExecFunction callback) : m_Interval(interval), m_Function(callback) {}
|
AutoTimer(std::uint64_t interval, TimerExecFunction callback) : m_Interval(interval), m_Function(callback) {}
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
void Update(std::uint64_t delta);
|
void Update(std::uint64_t delta);
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void SetInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
|
void SetInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
|
||||||
std::uint64_t GetInterval() const { return m_Interval; }
|
std::uint64_t GetInterval() const { return m_Interval; }
|
||||||
|
|
||||||
void SetCallbackFunction(TimerExecFunction newCallback) { m_Function = newCallback; }
|
void SetCallbackFunction(TimerExecFunction newCallback) { m_Function = newCallback; }
|
||||||
TimerExecFunction GetCallbackFunction() const { return m_Function; }
|
TimerExecFunction GetCallbackFunction() const { return m_Function; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// utililty class to call function at regular period of time
|
// utililty class to call function at regular period of time
|
||||||
class Timer {
|
class Timer {
|
||||||
private:
|
private:
|
||||||
std::uint64_t m_Interval; // in millis
|
std::uint64_t m_Interval; // in millis
|
||||||
std::uint64_t m_InternalTime = 0;
|
std::uint64_t m_InternalTime = 0;
|
||||||
public:
|
public:
|
||||||
Timer() : m_Interval(0) {}
|
Timer() : m_Interval(0) {}
|
||||||
Timer(std::uint64_t interval) : m_Interval(interval) {}
|
Timer(std::uint64_t interval) : m_Interval(interval) {}
|
||||||
|
|
||||||
bool Update(std::uint64_t delta);
|
bool Update(std::uint64_t delta);
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void SetInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
|
void SetInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
|
||||||
std::uint64_t GetInterval() const { return m_Interval; }
|
std::uint64_t GetInterval() const { return m_Interval; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// utililty class to call function at regular period of time with a cooldown (used for towers and mobs )
|
// utililty class to call function at regular period of time with a cooldown (used for towers and mobs )
|
||||||
class CooldownTimer {
|
class CooldownTimer {
|
||||||
private:
|
private:
|
||||||
std::uint64_t m_Cooldown; // in millis
|
std::uint64_t m_Cooldown; // in millis
|
||||||
std::uint64_t m_CooldownTime;
|
std::uint64_t m_CooldownTime;
|
||||||
public:
|
public:
|
||||||
CooldownTimer() : m_Cooldown(0), m_CooldownTime(0) {}
|
CooldownTimer() : m_Cooldown(0), m_CooldownTime(0) {}
|
||||||
CooldownTimer(std::uint64_t cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
|
CooldownTimer(std::uint64_t cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
|
||||||
|
|
||||||
bool Update(std::uint64_t delta);
|
bool Update(std::uint64_t delta);
|
||||||
|
|
||||||
void ApplyCooldown();
|
void ApplyCooldown();
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void SetCooldown(std::uint64_t newCooldown) { m_CooldownTime = newCooldown; }
|
void SetCooldown(std::uint64_t newCooldown) { m_CooldownTime = newCooldown; }
|
||||||
std::uint64_t GetCooldown() const { return m_CooldownTime; }
|
std::uint64_t GetCooldown() const { return m_CooldownTime; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|||||||
@@ -11,38 +11,38 @@ namespace network {
|
|||||||
/* IPv4 address */
|
/* IPv4 address */
|
||||||
class IPAddress {
|
class IPAddress {
|
||||||
private:
|
private:
|
||||||
std::uint32_t m_Address;
|
std::uint32_t m_Address;
|
||||||
bool m_Valid;
|
bool m_Valid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Create an invalid address */
|
/* Create an invalid address */
|
||||||
IPAddress() noexcept;
|
IPAddress() noexcept;
|
||||||
|
|
||||||
/* Initialize by string IP */
|
/* Initialize by string IP */
|
||||||
IPAddress(const std::string& str);
|
IPAddress(const std::string& str);
|
||||||
|
|
||||||
/* Initialize by string IP */
|
/* Initialize by string IP */
|
||||||
IPAddress(const std::wstring& str);
|
IPAddress(const std::wstring& str);
|
||||||
|
|
||||||
/* Initialize by octets */
|
/* Initialize by octets */
|
||||||
IPAddress(std::uint8_t octet1, std::uint8_t octet2, std::uint8_t octet3, std::uint8_t octet4) noexcept;
|
IPAddress(std::uint8_t octet1, std::uint8_t octet2, std::uint8_t octet3, std::uint8_t octet4) noexcept;
|
||||||
|
|
||||||
/* Get the specific octet. 1-4 */
|
/* Get the specific octet. 1-4 */
|
||||||
std::uint8_t GetOctet(std::uint8_t num) const;
|
std::uint8_t GetOctet(std::uint8_t num) const;
|
||||||
|
|
||||||
/* Set the specific octet. 1-4 */
|
/* Set the specific octet. 1-4 */
|
||||||
void SetOctet(std::uint8_t num, std::uint8_t value);
|
void SetOctet(std::uint8_t num, std::uint8_t value);
|
||||||
|
|
||||||
/* Make sure the IP is valid. It will be invalid if the host wasn't found. */
|
/* Make sure the IP is valid. It will be invalid if the host wasn't found. */
|
||||||
bool IsValid() const noexcept { return m_Valid; }
|
bool IsValid() const noexcept { return m_Valid; }
|
||||||
|
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
|
||||||
static IPAddress LocalAddress();
|
static IPAddress LocalAddress();
|
||||||
|
|
||||||
bool operator==(const IPAddress& right);
|
bool operator==(const IPAddress& right);
|
||||||
bool operator!=(const IPAddress& right);
|
bool operator!=(const IPAddress& right);
|
||||||
bool operator==(bool b);
|
bool operator==(bool b);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<IPAddress> IPAddresses;
|
typedef std::vector<IPAddress> IPAddresses;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace network {
|
|||||||
|
|
||||||
class Dns {
|
class Dns {
|
||||||
public:
|
public:
|
||||||
static IPAddresses Resolve(const std::string& host);
|
static IPAddresses Resolve(const std::string& host);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // ns network
|
} // ns network
|
||||||
|
|||||||
@@ -40,45 +40,45 @@ typedef int SocketHandle;
|
|||||||
|
|
||||||
class Socket {
|
class Socket {
|
||||||
public:
|
public:
|
||||||
enum Status { Connected, Disconnected, Error };
|
enum Status { Connected, Disconnected, Error };
|
||||||
enum Type { TCP, UDP };
|
enum Type { TCP, UDP };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_Blocking;
|
bool m_Blocking;
|
||||||
Type m_Type;
|
Type m_Type;
|
||||||
Status m_Status;
|
Status m_Status;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SocketHandle m_Handle;
|
SocketHandle m_Handle;
|
||||||
|
|
||||||
Socket(Type type);
|
Socket(Type type);
|
||||||
void SetStatus(Status status);
|
void SetStatus(Status status);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Socket();
|
virtual ~Socket();
|
||||||
|
|
||||||
Socket(Socket&& rhs) = default;
|
Socket(Socket&& rhs) = default;
|
||||||
Socket& operator=(Socket&& rhs) = default;
|
Socket& operator=(Socket&& rhs) = default;
|
||||||
|
|
||||||
bool SetBlocking(bool block);
|
bool SetBlocking(bool block);
|
||||||
bool IsBlocking() const noexcept;
|
bool IsBlocking() const noexcept;
|
||||||
|
|
||||||
Type GetType() const noexcept;
|
Type GetType() const noexcept;
|
||||||
Status GetStatus() const noexcept;
|
Status GetStatus() const noexcept;
|
||||||
SocketHandle GetHandle() const noexcept;
|
SocketHandle GetHandle() const noexcept;
|
||||||
|
|
||||||
bool Connect(const std::string& ip, std::uint16_t port);
|
bool Connect(const std::string& ip, std::uint16_t port);
|
||||||
virtual bool Connect(const IPAddress& address, std::uint16_t port) = 0;
|
virtual bool Connect(const IPAddress& address, std::uint16_t port) = 0;
|
||||||
|
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
|
|
||||||
std::size_t Send(const std::string& data);
|
std::size_t Send(const std::string& data);
|
||||||
std::size_t Send(DataBuffer& buffer);
|
std::size_t Send(DataBuffer& buffer);
|
||||||
|
|
||||||
virtual std::size_t Send(const uint8_t* data, std::size_t size) = 0;
|
virtual std::size_t Send(const uint8_t* data, std::size_t size) = 0;
|
||||||
virtual DataBuffer Receive(std::size_t amount) = 0;
|
virtual DataBuffer Receive(std::size_t amount) = 0;
|
||||||
|
|
||||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount) = 0;
|
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Socket> SocketPtr;
|
typedef std::shared_ptr<Socket> SocketPtr;
|
||||||
|
|||||||
@@ -5,30 +5,30 @@ namespace td {
|
|||||||
namespace network {
|
namespace network {
|
||||||
|
|
||||||
class TCPListener {
|
class TCPListener {
|
||||||
int m_Handle;
|
int m_Handle;
|
||||||
std::uint16_t m_Port;
|
std::uint16_t m_Port;
|
||||||
int m_MaxConnections;
|
int m_MaxConnections;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TCPListener();
|
TCPListener();
|
||||||
~TCPListener();
|
~TCPListener();
|
||||||
|
|
||||||
bool Listen(std::uint16_t port, int maxConnections);
|
bool Listen(std::uint16_t port, int maxConnections);
|
||||||
bool Accept(TCPSocket& newSocket);
|
bool Accept(TCPSocket& newSocket);
|
||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
bool Close();
|
bool Close();
|
||||||
bool SetBlocking(bool blocking);
|
bool SetBlocking(bool blocking);
|
||||||
|
|
||||||
std::uint16_t GetListeningPort() const {
|
std::uint16_t GetListeningPort() const {
|
||||||
return m_Port;
|
return m_Port;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetMaximumConnections() const {
|
int GetMaximumConnections() const {
|
||||||
return m_MaxConnections;
|
return m_MaxConnections;
|
||||||
}
|
}
|
||||||
|
|
||||||
REMOVE_COPY(TCPListener);
|
REMOVE_COPY(TCPListener);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace network
|
} // namespace network
|
||||||
|
|||||||
@@ -13,22 +13,22 @@ class TCPListener;
|
|||||||
|
|
||||||
class TCPSocket : public Socket {
|
class TCPSocket : public Socket {
|
||||||
private:
|
private:
|
||||||
IPAddress m_RemoteIP;
|
IPAddress m_RemoteIP;
|
||||||
uint16_t m_Port;
|
uint16_t m_Port;
|
||||||
sockaddr m_RemoteAddr;
|
sockaddr m_RemoteAddr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TCPSocket();
|
TCPSocket();
|
||||||
TCPSocket(TCPSocket&& other);
|
TCPSocket(TCPSocket&& other);
|
||||||
|
|
||||||
virtual bool Connect(const IPAddress& address, std::uint16_t port);
|
virtual bool Connect(const IPAddress& address, std::uint16_t port);
|
||||||
virtual std::size_t Send(const std::uint8_t* data, std::size_t size);
|
virtual std::size_t Send(const std::uint8_t* data, std::size_t size);
|
||||||
virtual DataBuffer Receive(std::size_t amount);
|
virtual DataBuffer Receive(std::size_t amount);
|
||||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
|
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
|
||||||
|
|
||||||
REMOVE_COPY(TCPSocket);
|
REMOVE_COPY(TCPSocket);
|
||||||
|
|
||||||
friend class TCPListener;
|
friend class TCPListener;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SendPacket(const DataBuffer& data, network::TCPSocket& socket);
|
void SendPacket(const DataBuffer& data, network::TCPSocket& socket);
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ namespace network {
|
|||||||
|
|
||||||
class UDPSocket : public Socket {
|
class UDPSocket : public Socket {
|
||||||
private:
|
private:
|
||||||
IPAddress m_RemoteIP;
|
IPAddress m_RemoteIP;
|
||||||
uint16_t m_Port;
|
uint16_t m_Port;
|
||||||
sockaddr_in m_RemoteAddr;
|
sockaddr_in m_RemoteAddr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UDPSocket();
|
UDPSocket();
|
||||||
|
|
||||||
bool Connect(const IPAddress& address, std::uint16_t port);
|
bool Connect(const IPAddress& address, std::uint16_t port);
|
||||||
std::size_t Send(const std::uint8_t* data, std::size_t size);
|
std::size_t Send(const std::uint8_t* data, std::size_t size);
|
||||||
|
|
||||||
virtual DataBuffer Receive(std::size_t amount);
|
virtual DataBuffer Receive(std::size_t amount);
|
||||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
|
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // ns network
|
} // ns network
|
||||||
|
|||||||
@@ -12,21 +12,21 @@ class PacketHandler;
|
|||||||
|
|
||||||
class PacketDispatcher {
|
class PacketDispatcher {
|
||||||
private:
|
private:
|
||||||
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
|
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PacketDispatcher() = default;
|
PacketDispatcher() = default;
|
||||||
|
|
||||||
PacketDispatcher(const PacketDispatcher& rhs) = delete;
|
PacketDispatcher(const PacketDispatcher& rhs) = delete;
|
||||||
PacketDispatcher& operator=(const PacketDispatcher& rhs) = delete;
|
PacketDispatcher& operator=(const PacketDispatcher& rhs) = delete;
|
||||||
PacketDispatcher(PacketDispatcher&& rhs) = delete;
|
PacketDispatcher(PacketDispatcher&& rhs) = delete;
|
||||||
PacketDispatcher& operator=(PacketDispatcher&& rhs) = delete;
|
PacketDispatcher& operator=(PacketDispatcher&& rhs) = delete;
|
||||||
|
|
||||||
void Dispatch(const PacketPtr& packet);
|
void Dispatch(const PacketPtr& packet);
|
||||||
|
|
||||||
void RegisterHandler(PacketType type, PacketHandler* handler);
|
void RegisterHandler(PacketType type, PacketHandler* handler);
|
||||||
void UnregisterHandler(PacketType type, PacketHandler* handler);
|
void UnregisterHandler(PacketType type, PacketHandler* handler);
|
||||||
void UnregisterHandler(PacketHandler* handler);
|
void UnregisterHandler(PacketHandler* handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "protocol/Protocol.h"
|
#include "protocol/Protocol.h"
|
||||||
|
#include "protocol/PacketsForward.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
@@ -9,39 +10,39 @@ class PacketDispatcher;
|
|||||||
|
|
||||||
class PacketHandler {
|
class PacketHandler {
|
||||||
private:
|
private:
|
||||||
PacketDispatcher* m_Dispatcher;
|
PacketDispatcher* m_Dispatcher;
|
||||||
public:
|
public:
|
||||||
PacketHandler(PacketDispatcher* dispatcher) : m_Dispatcher(dispatcher) {}
|
PacketHandler(PacketDispatcher* dispatcher) : m_Dispatcher(dispatcher) {}
|
||||||
virtual ~PacketHandler() {}
|
virtual ~PacketHandler() {}
|
||||||
|
|
||||||
PacketDispatcher* GetDispatcher() { return m_Dispatcher; }
|
PacketDispatcher* GetDispatcher() { return m_Dispatcher; }
|
||||||
|
|
||||||
virtual void HandlePacket(const ConnexionInfoPacket* packet) {}
|
virtual void HandlePacket(const ConnexionInfoPacket* packet) {}
|
||||||
virtual void HandlePacket(const DisconnectPacket* packet) {}
|
virtual void HandlePacket(const DisconnectPacket* packet) {}
|
||||||
virtual void HandlePacket(const KeepAlivePacket* packet) {}
|
virtual void HandlePacket(const KeepAlivePacket* packet) {}
|
||||||
virtual void HandlePacket(const PlaceTowerPacket* packet) {}
|
virtual void HandlePacket(const PlaceTowerPacket* packet) {}
|
||||||
virtual void HandlePacket(const PlayerBuyItemPacket* packet) {}
|
virtual void HandlePacket(const PlayerBuyItemPacket* packet) {}
|
||||||
virtual void HandlePacket(const PlayerBuyMobUpgradePacket* packet) {}
|
virtual void HandlePacket(const PlayerBuyMobUpgradePacket* packet) {}
|
||||||
virtual void HandlePacket(const PlayerJoinPacket* packet) {}
|
virtual void HandlePacket(const PlayerJoinPacket* packet) {}
|
||||||
virtual void HandlePacket(const PlayerLeavePacket* packet) {}
|
virtual void HandlePacket(const PlayerLeavePacket* packet) {}
|
||||||
virtual void HandlePacket(const PlayerListPacket* packet) {}
|
virtual void HandlePacket(const PlayerListPacket* packet) {}
|
||||||
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
|
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
|
||||||
virtual void HandlePacket(const RemoveTowerPacket* packet) {}
|
virtual void HandlePacket(const RemoveTowerPacket* packet) {}
|
||||||
virtual void HandlePacket(const SelectTeamPacket* packet) {}
|
virtual void HandlePacket(const SelectTeamPacket* packet) {}
|
||||||
virtual void HandlePacket(const SendMobsPacket* packet) {}
|
virtual void HandlePacket(const SendMobsPacket* packet) {}
|
||||||
virtual void HandlePacket(const ServerTpsPacket* packet) {}
|
virtual void HandlePacket(const ServerTpsPacket* packet) {}
|
||||||
virtual void HandlePacket(const SpawnMobPacket* packet) {}
|
virtual void HandlePacket(const SpawnMobPacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdateCastleLifePacket* packet) {}
|
virtual void HandlePacket(const UpdateCastleLifePacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdateExpPacket* packet) {}
|
virtual void HandlePacket(const UpdateExpPacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdateGameStatePacket* packet) {}
|
virtual void HandlePacket(const UpdateGameStatePacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdateLobbyTimePacket* packet) {}
|
virtual void HandlePacket(const UpdateLobbyTimePacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdateMobStatesPacket* packet) {}
|
virtual void HandlePacket(const UpdateMobStatesPacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdateMoneyPacket* packet) {}
|
virtual void HandlePacket(const UpdateMoneyPacket* packet) {}
|
||||||
virtual void HandlePacket(const UpdatePlayerTeamPacket* packet) {}
|
virtual void HandlePacket(const UpdatePlayerTeamPacket* packet) {}
|
||||||
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
|
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
|
||||||
virtual void HandlePacket(const WorldAddTowerPacket* packet) {}
|
virtual void HandlePacket(const WorldAddTowerPacket* packet) {}
|
||||||
virtual void HandlePacket(const WorldBeginDataPacket* packet) {}
|
virtual void HandlePacket(const WorldBeginDataPacket* packet) {}
|
||||||
virtual void HandlePacket(const WorldDataPacket* packet) {}
|
virtual void HandlePacket(const WorldDataPacket* packet) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
|
|||||||
27
include/protocol/Packets.h
Normal file
27
include/protocol/Packets.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "packets/ConnectionInfoPacket.h"
|
||||||
|
#include "packets/DisconnectPacket.h"
|
||||||
|
#include "packets/KeepAlivePacket.h"
|
||||||
|
#include "packets/PlaceTowerPacket.h"
|
||||||
|
#include "packets/PlayerBuyItemPacket.h"
|
||||||
|
#include "packets/PlayerBuyMobUpgradePacket.h"
|
||||||
|
#include "packets/PlayerJoinPacket.h"
|
||||||
|
#include "packets/PlayerLeavePacket.h"
|
||||||
|
#include "packets/PlayerListPacket.h"
|
||||||
|
#include "packets/PlayerLoginPacket.h"
|
||||||
|
#include "packets/RemoveTowerPacket.h"
|
||||||
|
#include "packets/SelectTeamPacket.h"
|
||||||
|
#include "packets/SendMobsPacket.h"
|
||||||
|
#include "packets/ServerTpsPacket.h"
|
||||||
|
#include "packets/SpawnMobPacket.h"
|
||||||
|
#include "packets/UpdateCastleLifePacket.h"
|
||||||
|
#include "packets/UpdateExpPacket.h"
|
||||||
|
#include "packets/UpdateGameStatePacket.h"
|
||||||
|
#include "packets/UpdateLobbyTimePacket.h"
|
||||||
|
#include "packets/UpdateMobStatesPacket.h"
|
||||||
|
#include "packets/UpdateMoneyPacket.h"
|
||||||
|
#include "packets/UpdatePlayerTeamPacket.h"
|
||||||
|
#include "packets/UpgradeTowerPacket.h"
|
||||||
|
#include "packets/WorldAddTowerPacket.h"
|
||||||
|
#include "packets/WorldAddTowerPacket.h"
|
||||||
|
#include "packets/WorldBeginDataPacket.h"
|
||||||
|
#include "packets/WorldDataPacket.h"
|
||||||
34
include/protocol/PacketsForward.h
Normal file
34
include/protocol/PacketsForward.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PlayerLoginPacket;
|
||||||
|
class WorldBeginDataPacket;
|
||||||
|
class WorldDataPacket;
|
||||||
|
class KeepAlivePacket;
|
||||||
|
class UpdateExpPacket;
|
||||||
|
class UpdateMoneyPacket;
|
||||||
|
class UpdateLobbyTimePacket;
|
||||||
|
class UpdateGameStatePacket;
|
||||||
|
class PlayerListPacket;
|
||||||
|
class PlayerJoinPacket;
|
||||||
|
class PlayerLeavePacket;
|
||||||
|
class ConnexionInfoPacket;
|
||||||
|
class SelectTeamPacket;
|
||||||
|
class UpdatePlayerTeamPacket;
|
||||||
|
class DisconnectPacket;
|
||||||
|
class ServerTpsPacket;
|
||||||
|
class SpawnMobPacket;
|
||||||
|
class PlaceTowerPacket;
|
||||||
|
class WorldAddTowerPacket;
|
||||||
|
class RemoveTowerPacket;
|
||||||
|
class SendMobsPacket;
|
||||||
|
class UpgradeTowerPacket;
|
||||||
|
class UpdateCastleLifePacket;
|
||||||
|
class UpdateMobStatesPacket;
|
||||||
|
class PlayerBuyItemPacket;
|
||||||
|
class PlayerBuyMobUpgradePacket;
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "misc/DataBuffer.h"
|
#include "misc/DataBuffer.h"
|
||||||
#include "game/World.h"
|
|
||||||
#include "game/BaseGame.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -12,622 +10,81 @@ namespace protocol {
|
|||||||
class PacketHandler;
|
class PacketHandler;
|
||||||
|
|
||||||
enum class PacketType : std::uint8_t {
|
enum class PacketType : std::uint8_t {
|
||||||
// client --> server
|
// client --> server
|
||||||
PlayerLogin = 0,
|
PlayerLogin = 0,
|
||||||
SelectTeam,
|
SelectTeam,
|
||||||
SpawnMob,
|
SpawnMob,
|
||||||
SendMobs,
|
SendMobs,
|
||||||
PlaceTower,
|
PlaceTower,
|
||||||
|
|
||||||
// client <-- server
|
// client <-- server
|
||||||
PlayerJoin,
|
PlayerJoin,
|
||||||
PlayerLeave,
|
PlayerLeave,
|
||||||
WorldBeginData,
|
WorldBeginData,
|
||||||
WorldData,
|
WorldData,
|
||||||
UpdateMoney,
|
UpdateMoney,
|
||||||
UpdateEXP,
|
UpdateEXP,
|
||||||
UpdateLobbyTime,
|
UpdateLobbyTime,
|
||||||
UpdateGameState,
|
UpdateGameState,
|
||||||
PlayerList,
|
PlayerList,
|
||||||
ConnectionInfo,
|
ConnectionInfo,
|
||||||
UpdatePlayerTeam,
|
UpdatePlayerTeam,
|
||||||
ServerTps,
|
ServerTps,
|
||||||
WorldAddTower,
|
WorldAddTower,
|
||||||
UpdateMobStates,
|
UpdateMobStates,
|
||||||
UpdateCastleLife,
|
UpdateCastleLife,
|
||||||
|
|
||||||
// client <--> server
|
// client <--> server
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
Disconnect,
|
Disconnect,
|
||||||
UpgradeTower,
|
UpgradeTower,
|
||||||
RemoveTower,
|
RemoveTower,
|
||||||
PlayerBuyItem,
|
PlayerBuyItem,
|
||||||
PlayerBuyMobUpgrade,
|
PlayerBuyMobUpgrade,
|
||||||
|
|
||||||
PACKET_COUNT
|
PACKET_COUNT
|
||||||
};
|
|
||||||
|
|
||||||
struct WorldHeader {
|
|
||||||
game::TowerTileColorPalette m_TowerPlacePalette;
|
|
||||||
game::Color m_WalkablePalette;
|
|
||||||
std::vector<game::Color> m_DecorationPalette;
|
|
||||||
game::Color m_Background;
|
|
||||||
|
|
||||||
game::SpawnColorPalette m_SpawnColorPalette;
|
|
||||||
|
|
||||||
game::TilePalette m_TilePalette;
|
|
||||||
|
|
||||||
game::Spawn m_RedSpawn, m_BlueSpawn;
|
|
||||||
game::TeamCastle m_RedCastle, m_BlueCastle;
|
|
||||||
|
|
||||||
const game::World* m_World;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WorldData {
|
|
||||||
std::unordered_map<game::ChunkCoord, game::ChunkPtr> m_Chunks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Packet {
|
class Packet {
|
||||||
public:
|
public:
|
||||||
Packet() {}
|
Packet() {}
|
||||||
virtual ~Packet() {}
|
virtual ~Packet() {}
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const = 0;
|
virtual DataBuffer Serialize(bool packetID = true) const = 0;
|
||||||
virtual void Deserialize(DataBuffer& data) = 0;
|
virtual void Deserialize(DataBuffer& data) = 0;
|
||||||
virtual void Dispatch(PacketHandler* handler) const = 0;
|
virtual void Dispatch(PacketHandler* handler) const = 0;
|
||||||
|
|
||||||
void WritePacketID(DataBuffer& data, bool packetID) const;
|
virtual void WritePacketID(DataBuffer& data, bool packetID) const;
|
||||||
|
|
||||||
virtual PacketType GetType() const = 0;
|
virtual PacketType GetType() const = 0;
|
||||||
std::uint8_t GetID() const { return static_cast<std::uint8_t>(GetType()); }
|
std::uint8_t GetID() const { return static_cast<std::uint8_t>(GetType()); }
|
||||||
|
|
||||||
|
virtual bool IsTimed() const { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class DelayedPacket : public Packet {
|
||||||
|
protected:
|
||||||
|
std::uint64_t m_PacketTime = 69;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DelayedPacket() {}
|
||||||
|
virtual ~DelayedPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const = 0;
|
||||||
|
virtual void Deserialize(DataBuffer& data) = 0;
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const = 0;
|
||||||
|
|
||||||
|
virtual void WritePacketID(DataBuffer& data, bool packetID) const override;
|
||||||
|
|
||||||
|
virtual PacketType GetType() const = 0;
|
||||||
|
|
||||||
|
virtual bool IsTimed() const override { return true; }
|
||||||
|
|
||||||
|
void SetPacketTime(std::uint64_t packetTime) { m_PacketTime = packetTime; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<Packet> PacketPtr;
|
typedef std::unique_ptr<Packet> PacketPtr;
|
||||||
|
typedef std::unique_ptr<DelayedPacket> DelayedPacketPtr;
|
||||||
class KeepAlivePacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint64_t m_AliveID;
|
|
||||||
public:
|
|
||||||
KeepAlivePacket() {}
|
|
||||||
KeepAlivePacket(std::uint64_t aliveID) : m_AliveID(aliveID) {}
|
|
||||||
virtual ~KeepAlivePacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::uint64_t GetAliveID() const { return m_AliveID; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::KeepAlive; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlayerLoginPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::string m_PlayerName;
|
|
||||||
public:
|
|
||||||
PlayerLoginPacket() {}
|
|
||||||
PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {}
|
|
||||||
virtual ~PlayerLoginPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlayerLogin; }
|
|
||||||
|
|
||||||
const std::string& GetPlayerName() const { return m_PlayerName; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class WorldBeginDataPacket : public Packet {
|
|
||||||
private:
|
|
||||||
WorldHeader m_Header;
|
|
||||||
public:
|
|
||||||
WorldBeginDataPacket() {}
|
|
||||||
WorldBeginDataPacket(const game::World* world) {
|
|
||||||
m_Header.m_World = world;
|
|
||||||
}
|
|
||||||
virtual ~WorldBeginDataPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::WorldBeginData; }
|
|
||||||
|
|
||||||
const game::TowerTileColorPalette& GetTowerTilePalette() const { return m_Header.m_TowerPlacePalette; }
|
|
||||||
const game::Color& GetWalkableTileColor() const { return m_Header.m_WalkablePalette; }
|
|
||||||
const std::vector<game::Color>& GetDecorationPalette() const { return m_Header.m_DecorationPalette; }
|
|
||||||
const game::Color& GetBackgroundColor() const { return m_Header.m_Background; }
|
|
||||||
|
|
||||||
const game::Spawn& GetRedSpawn() const { return m_Header.m_RedSpawn; }
|
|
||||||
const game::Spawn& GetBlueSpawn() const { return m_Header.m_BlueSpawn; }
|
|
||||||
|
|
||||||
const game::SpawnColorPalette& GetSpawnPalette() const { return m_Header.m_SpawnColorPalette; }
|
|
||||||
|
|
||||||
const game::TeamCastle& GetRedCastle() const { return m_Header.m_RedCastle; }
|
|
||||||
const game::TeamCastle& GetBlueCastle() const { return m_Header.m_BlueCastle; }
|
|
||||||
|
|
||||||
const game::TilePalette GetTilePalette() const { return m_Header.m_TilePalette; }
|
|
||||||
|
|
||||||
void setWorldHeader(const WorldHeader& header) { m_Header = header; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class WorldDataPacket : public Packet {
|
|
||||||
private:
|
|
||||||
WorldData m_WorldData;
|
|
||||||
|
|
||||||
const game::World* m_World;
|
|
||||||
public:
|
|
||||||
WorldDataPacket() {}
|
|
||||||
WorldDataPacket(const game::World* world) : m_World(world) {}
|
|
||||||
virtual ~WorldDataPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::WorldData; }
|
|
||||||
|
|
||||||
const std::unordered_map<game::ChunkCoord, game::ChunkPtr>& GetChunks() const { return m_WorldData.m_Chunks; }
|
|
||||||
|
|
||||||
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
|
|
||||||
void SetWorldData(const WorldData& worldData) { m_WorldData = worldData; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateMoneyPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint32_t m_NewAmount;
|
|
||||||
public:
|
|
||||||
UpdateMoneyPacket() {}
|
|
||||||
UpdateMoneyPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
|
|
||||||
virtual ~UpdateMoneyPacket() {}
|
|
||||||
|
|
||||||
std::uint32_t GetGold() const { return m_NewAmount; }
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdateMoney; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateExpPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint32_t m_NewAmount;
|
|
||||||
public:
|
|
||||||
UpdateExpPacket() {}
|
|
||||||
UpdateExpPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
|
|
||||||
virtual ~UpdateExpPacket() {}
|
|
||||||
|
|
||||||
std::uint32_t GetExp() const { return m_NewAmount; }
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdateEXP; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateLobbyTimePacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint32_t m_RemainingTime;
|
|
||||||
public:
|
|
||||||
UpdateLobbyTimePacket() {}
|
|
||||||
UpdateLobbyTimePacket(std::uint32_t remainingTime) : m_RemainingTime(remainingTime) {}
|
|
||||||
virtual ~UpdateLobbyTimePacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::uint32_t GetRemainingTime() const { return m_RemainingTime; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdateLobbyTime; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateGameStatePacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::GameState m_GameState;
|
|
||||||
public:
|
|
||||||
UpdateGameStatePacket() {}
|
|
||||||
UpdateGameStatePacket(game::GameState gameState) : m_GameState(gameState) {}
|
|
||||||
virtual ~UpdateGameStatePacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::GameState GetGameState() const { return m_GameState; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdateGameState; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PlayerInfo {
|
|
||||||
std::string name;
|
|
||||||
game::TeamColor team;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlayerListPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::map<std::uint8_t, PlayerInfo> m_Players;
|
|
||||||
public:
|
|
||||||
PlayerListPacket() {}
|
|
||||||
PlayerListPacket(std::map<std::uint8_t, PlayerInfo> players) : m_Players(players) {}
|
|
||||||
virtual ~PlayerListPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
const std::map<std::uint8_t, PlayerInfo>& GetPlayers() const { return m_Players; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlayerList; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlayerJoinPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint8_t m_PlayerID;
|
|
||||||
std::string m_PlayerName;
|
|
||||||
public:
|
|
||||||
PlayerJoinPacket() {}
|
|
||||||
PlayerJoinPacket(std::uint8_t playerID, const std::string& playerName) : m_PlayerID(playerID), m_PlayerName(playerName) {}
|
|
||||||
virtual ~PlayerJoinPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::uint8_t GetPlayerID() const { return m_PlayerID; }
|
|
||||||
const std::string& GetPlayerName() const { return m_PlayerName; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlayerJoin; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlayerLeavePacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint8_t m_PlayerID;
|
|
||||||
public:
|
|
||||||
PlayerLeavePacket() {}
|
|
||||||
PlayerLeavePacket(std::uint8_t playerID) : m_PlayerID(playerID) {}
|
|
||||||
virtual ~PlayerLeavePacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::uint8_t GetPlayerID() const { return m_PlayerID; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlayerLeave; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConnexionInfoPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint8_t m_ConnectionID;
|
|
||||||
public:
|
|
||||||
ConnexionInfoPacket() {}
|
|
||||||
ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {}
|
|
||||||
virtual ~ConnexionInfoPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::uint8_t GetConnectionID() const { return m_ConnectionID; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::ConnectionInfo; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class SelectTeamPacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::TeamColor m_SelectedTeam;
|
|
||||||
public:
|
|
||||||
SelectTeamPacket() {}
|
|
||||||
SelectTeamPacket(game::TeamColor selectedTeam) : m_SelectedTeam(selectedTeam) {}
|
|
||||||
virtual ~SelectTeamPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::SelectTeam; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdatePlayerTeamPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint8_t m_PlayerID;
|
|
||||||
game::TeamColor m_SelectedTeam;
|
|
||||||
public:
|
|
||||||
UpdatePlayerTeamPacket() {}
|
|
||||||
UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam) : m_PlayerID(playerID), m_SelectedTeam(selectedTeam) {}
|
|
||||||
virtual ~UpdatePlayerTeamPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
|
|
||||||
std::uint8_t GetPlayerID() const { return m_PlayerID; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdatePlayerTeam; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class DisconnectPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::string m_Reason; // only when sent from server
|
|
||||||
public:
|
|
||||||
DisconnectPacket() {}
|
|
||||||
DisconnectPacket(std::string reason) : m_Reason(reason) {}
|
|
||||||
virtual ~DisconnectPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
const std::string& GetReason() const { return m_Reason; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::Disconnect; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class ServerTpsPacket : public Packet {
|
|
||||||
private:
|
|
||||||
float m_TPS;
|
|
||||||
std::uint64_t m_PacketSendTime; // used to calculate ping
|
|
||||||
public:
|
|
||||||
ServerTpsPacket() {}
|
|
||||||
ServerTpsPacket(float tps, std::uint64_t sendTime) : m_TPS(tps), m_PacketSendTime(sendTime) {}
|
|
||||||
virtual ~ServerTpsPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
float GetTPS() const { return m_TPS; }
|
|
||||||
std::uint64_t GetPacketSendTime() const { return m_PacketSendTime; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::ServerTps; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MobSend { // represents a mob send
|
|
||||||
game::MobType mobType : 4;
|
|
||||||
game::MobLevel mobLevel : 4;
|
|
||||||
std::uint8_t mobCount; // the max is 12
|
|
||||||
};
|
|
||||||
|
|
||||||
class SendMobsPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::vector<MobSend> m_MobSends;
|
|
||||||
public:
|
|
||||||
SendMobsPacket() {}
|
|
||||||
SendMobsPacket(const std::vector<MobSend>& mobSends) : m_MobSends(mobSends) {}
|
|
||||||
virtual ~SendMobsPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
const std::vector<MobSend>& GetMobSends() const { return m_MobSends; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::SendMobs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class SpawnMobPacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::MobID m_MobID;
|
|
||||||
game::MobType m_MobType;
|
|
||||||
game::MobLevel m_MobLevel;
|
|
||||||
game::Direction m_MobDirection;
|
|
||||||
game::PlayerID m_Sender;
|
|
||||||
float m_MobX, m_MobY;
|
|
||||||
public:
|
|
||||||
SpawnMobPacket() {}
|
|
||||||
SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender,
|
|
||||||
float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level),
|
|
||||||
m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y) {}
|
|
||||||
virtual ~SpawnMobPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::MobID GetMobID() const { return m_MobID; }
|
|
||||||
game::MobType GetMobType() const { return m_MobType; }
|
|
||||||
game::MobLevel GetMobLevel() const { return m_MobLevel; }
|
|
||||||
game::Direction GetMobDirection() const { return m_MobDirection; }
|
|
||||||
game::PlayerID GetSender() const { return m_Sender; }
|
|
||||||
float GetMobX() const { return m_MobX; }
|
|
||||||
float GetMobY() const { return m_MobY; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::SpawnMob; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlaceTowerPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::int32_t m_TowerX, m_TowerY;
|
|
||||||
game::TowerType m_TowerType;
|
|
||||||
public:
|
|
||||||
PlaceTowerPacket() {}
|
|
||||||
PlaceTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type) :
|
|
||||||
m_TowerX(x), m_TowerY(y), m_TowerType(type) {}
|
|
||||||
virtual ~PlaceTowerPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::int32_t GetTowerX() const { return m_TowerX; }
|
|
||||||
std::int32_t GetTowerY() const { return m_TowerY; }
|
|
||||||
game::TowerType GetTowerType() const { return m_TowerType; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlaceTower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class WorldAddTowerPacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::TowerID m_TowerID;
|
|
||||||
std::int32_t m_TowerX, m_TowerY;
|
|
||||||
game::TowerType m_TowerType;
|
|
||||||
game::PlayerID m_Builder;
|
|
||||||
public:
|
|
||||||
WorldAddTowerPacket() {}
|
|
||||||
WorldAddTowerPacket(game::TowerID id, std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) :
|
|
||||||
m_TowerID(id), m_TowerX(x), m_TowerY(y), m_TowerType(type), m_Builder(player) {}
|
|
||||||
virtual ~WorldAddTowerPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::TowerID GetTowerID() const { return m_TowerID; }
|
|
||||||
std::int32_t GetTowerX() const { return m_TowerX; }
|
|
||||||
std::int32_t GetTowerY() const { return m_TowerY; }
|
|
||||||
game::TowerType GetTowerType() const { return m_TowerType; }
|
|
||||||
game::PlayerID GetBuilder() const { return m_Builder; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::WorldAddTower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class RemoveTowerPacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::TowerID m_TowerID;
|
|
||||||
public:
|
|
||||||
RemoveTowerPacket() {}
|
|
||||||
RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
|
|
||||||
virtual ~RemoveTowerPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::TowerID GetTowerID() const { return m_TowerID; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::RemoveTower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpgradeTowerPacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::TowerID m_TowerID;
|
|
||||||
game::TowerLevel m_TowerLevel;
|
|
||||||
public:
|
|
||||||
UpgradeTowerPacket() {}
|
|
||||||
UpgradeTowerPacket(game::TowerID tower, game::TowerLevel level) : m_TowerID(tower), m_TowerLevel(level) {}
|
|
||||||
virtual ~UpgradeTowerPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::TowerID GetTowerID() const { return m_TowerID; }
|
|
||||||
game::TowerLevel GetTowerLevel() const { return m_TowerLevel; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpgradeTower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class MobState {
|
|
||||||
using Point = utils::shape::Point;
|
|
||||||
private:
|
|
||||||
game::MobID m_MobID;
|
|
||||||
Point m_MobPosition;
|
|
||||||
float m_MobLife;
|
|
||||||
game::Direction m_MobDirection;
|
|
||||||
public:
|
|
||||||
MobState() {}
|
|
||||||
MobState(game::MobID id, const Point& position, float life, game::Direction direction) :
|
|
||||||
m_MobID(id), m_MobPosition(position), m_MobLife(life), m_MobDirection(direction) {}
|
|
||||||
|
|
||||||
game::MobID GetMobId() const { return m_MobID; }
|
|
||||||
Point GetMobPosition() const { return m_MobPosition; }
|
|
||||||
float GetMobLife() const { return m_MobLife; }
|
|
||||||
game::Direction GetMobDirection() const { return m_MobDirection; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateMobStatesPacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::vector<MobState> m_MobStates;
|
|
||||||
public:
|
|
||||||
UpdateMobStatesPacket() {}
|
|
||||||
virtual ~UpdateMobStatesPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
void addMobState(MobState mobState) { m_MobStates.push_back(mobState); }
|
|
||||||
|
|
||||||
const std::vector<MobState>& GetMobStates() const { return m_MobStates; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdateMobStates; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateCastleLifePacket : public Packet {
|
|
||||||
private:
|
|
||||||
std::uint16_t m_CastleLife;
|
|
||||||
game::TeamColor m_Team;
|
|
||||||
public:
|
|
||||||
UpdateCastleLifePacket() {}
|
|
||||||
UpdateCastleLifePacket(std::uint16_t life, game::TeamColor team) : m_CastleLife(life), m_Team(team) {}
|
|
||||||
virtual ~UpdateCastleLifePacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
std::uint16_t GetCastleLife() const { return m_CastleLife; }
|
|
||||||
game::TeamColor GetTeamColor() const { return m_Team; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::UpdateCastleLife; }
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ItemType : std::uint8_t {
|
|
||||||
// Upgrades
|
|
||||||
ClickerUpgrade,
|
|
||||||
GoldPerSecUpgrade,
|
|
||||||
|
|
||||||
// Items
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Packet used by the client to buy items or upgrades
|
|
||||||
Packet used by the server to confirm transaction */
|
|
||||||
class PlayerBuyItemPacket : public Packet {
|
|
||||||
private:
|
|
||||||
ItemType m_ItemType;
|
|
||||||
std::uint8_t m_Count;
|
|
||||||
public:
|
|
||||||
PlayerBuyItemPacket() {}
|
|
||||||
PlayerBuyItemPacket(ItemType itemType, std::uint8_t count) : m_ItemType(itemType), m_Count(count) {}
|
|
||||||
virtual ~PlayerBuyItemPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
ItemType GetItemType() const { return m_ItemType; }
|
|
||||||
std::uint8_t GetCount() const { return m_Count; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlayerBuyItem; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Packet used by the client to buy mob upgrades
|
|
||||||
Packet used by the server to confirm transaction */
|
|
||||||
class PlayerBuyMobUpgradePacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::MobType m_MobType;
|
|
||||||
std::uint8_t m_MobLevel;
|
|
||||||
public:
|
|
||||||
PlayerBuyMobUpgradePacket() {}
|
|
||||||
PlayerBuyMobUpgradePacket(game::MobType mobType, std::uint8_t level) : m_MobType(mobType), m_MobLevel(level) {}
|
|
||||||
virtual ~PlayerBuyMobUpgradePacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
|
||||||
virtual void Deserialize(DataBuffer& data);
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const;
|
|
||||||
|
|
||||||
game::MobType GetMobType() const { return m_MobType; }
|
|
||||||
std::uint8_t GetLevel() const { return m_MobLevel; }
|
|
||||||
|
|
||||||
virtual PacketType GetType() const { return PacketType::PlayerBuyMobUpgrade; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
} // namespace td
|
} // namespace td
|
||||||
26
include/protocol/packets/ConnectionInfoPacket.h
Normal file
26
include/protocol/packets/ConnectionInfoPacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class ConnexionInfoPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint8_t m_ConnectionID;
|
||||||
|
public:
|
||||||
|
ConnexionInfoPacket() {}
|
||||||
|
ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {}
|
||||||
|
virtual ~ConnexionInfoPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::uint8_t GetConnectionID() const { return m_ConnectionID; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::ConnectionInfo; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/DisconnectPacket.h
Normal file
26
include/protocol/packets/DisconnectPacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class DisconnectPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::string m_Reason; // only when sent from server
|
||||||
|
public:
|
||||||
|
DisconnectPacket() {}
|
||||||
|
DisconnectPacket(std::string reason) : m_Reason(reason) {}
|
||||||
|
virtual ~DisconnectPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
const std::string& GetReason() const { return m_Reason; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::Disconnect; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/KeepAlivePacket.h
Normal file
26
include/protocol/packets/KeepAlivePacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class KeepAlivePacket : public Packet{
|
||||||
|
private:
|
||||||
|
std::uint64_t m_AliveID;
|
||||||
|
public:
|
||||||
|
KeepAlivePacket() {}
|
||||||
|
KeepAlivePacket(std::uint64_t aliveID) : m_AliveID(aliveID) {}
|
||||||
|
virtual ~KeepAlivePacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::uint64_t GetAliveID() const { return m_AliveID; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::KeepAlive; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
32
include/protocol/packets/PlaceTowerPacket.h
Normal file
32
include/protocol/packets/PlaceTowerPacket.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PlaceTowerPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::int32_t m_TowerX, m_TowerY;
|
||||||
|
game::TowerType m_TowerType;
|
||||||
|
public:
|
||||||
|
PlaceTowerPacket() {}
|
||||||
|
PlaceTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type) :
|
||||||
|
m_TowerX(x), m_TowerY(y), m_TowerType(type) {
|
||||||
|
}
|
||||||
|
virtual ~PlaceTowerPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::int32_t GetTowerX() const { return m_TowerX; }
|
||||||
|
std::int32_t GetTowerY() const { return m_TowerY; }
|
||||||
|
game::TowerType GetTowerType() const { return m_TowerType; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlaceTower; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
38
include/protocol/packets/PlayerBuyItemPacket.h
Normal file
38
include/protocol/packets/PlayerBuyItemPacket.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
enum class ItemType : std::uint8_t {
|
||||||
|
// Upgrades
|
||||||
|
ClickerUpgrade,
|
||||||
|
GoldPerSecUpgrade,
|
||||||
|
|
||||||
|
// Items
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Packet used by the client to buy items or upgrades
|
||||||
|
Packet used by the server to confirm transaction */
|
||||||
|
class PlayerBuyItemPacket : public Packet {
|
||||||
|
private:
|
||||||
|
ItemType m_ItemType;
|
||||||
|
std::uint8_t m_Count;
|
||||||
|
public:
|
||||||
|
PlayerBuyItemPacket() {}
|
||||||
|
PlayerBuyItemPacket(ItemType itemType, std::uint8_t count) : m_ItemType(itemType), m_Count(count) {}
|
||||||
|
virtual ~PlayerBuyItemPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
ItemType GetItemType() const { return m_ItemType; }
|
||||||
|
std::uint8_t GetCount() const { return m_Count; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlayerBuyItem; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
31
include/protocol/packets/PlayerBuyMobUpgradePacket.h
Normal file
31
include/protocol/packets/PlayerBuyMobUpgradePacket.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
/** Packet used by the client to buy mob upgrades
|
||||||
|
Packet used by the server to confirm transaction */
|
||||||
|
class PlayerBuyMobUpgradePacket : public Packet {
|
||||||
|
private:
|
||||||
|
game::MobType m_MobType;
|
||||||
|
std::uint8_t m_MobLevel;
|
||||||
|
public:
|
||||||
|
PlayerBuyMobUpgradePacket() {}
|
||||||
|
PlayerBuyMobUpgradePacket(game::MobType mobType, std::uint8_t level) : m_MobType(mobType), m_MobLevel(level) {}
|
||||||
|
virtual ~PlayerBuyMobUpgradePacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::MobType GetMobType() const { return m_MobType; }
|
||||||
|
std::uint8_t GetLevel() const { return m_MobLevel; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlayerBuyMobUpgrade; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
28
include/protocol/packets/PlayerJoinPacket.h
Normal file
28
include/protocol/packets/PlayerJoinPacket.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PlayerJoinPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint8_t m_PlayerID;
|
||||||
|
std::string m_PlayerName;
|
||||||
|
public:
|
||||||
|
PlayerJoinPacket() {}
|
||||||
|
PlayerJoinPacket(std::uint8_t playerID, const std::string& playerName) : m_PlayerID(playerID), m_PlayerName(playerName) {}
|
||||||
|
virtual ~PlayerJoinPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::uint8_t GetPlayerID() const { return m_PlayerID; }
|
||||||
|
const std::string& GetPlayerName() const { return m_PlayerName; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlayerJoin; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/PlayerLeavePacket.h
Normal file
26
include/protocol/packets/PlayerLeavePacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PlayerLeavePacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint8_t m_PlayerID;
|
||||||
|
public:
|
||||||
|
PlayerLeavePacket() {}
|
||||||
|
PlayerLeavePacket(std::uint8_t playerID) : m_PlayerID(playerID) {}
|
||||||
|
virtual ~PlayerLeavePacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::uint8_t GetPlayerID() const { return m_PlayerID; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlayerLeave; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
32
include/protocol/packets/PlayerListPacket.h
Normal file
32
include/protocol/packets/PlayerListPacket.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
struct PlayerInfo {
|
||||||
|
std::string name;
|
||||||
|
game::TeamColor team;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlayerListPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::map<std::uint8_t, PlayerInfo> m_Players;
|
||||||
|
public:
|
||||||
|
PlayerListPacket() {}
|
||||||
|
PlayerListPacket(std::map<std::uint8_t, PlayerInfo> players) : m_Players(players) {}
|
||||||
|
virtual ~PlayerListPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
const std::map<std::uint8_t, PlayerInfo>& GetPlayers() const { return m_Players; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlayerList; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/PlayerLoginPacket.h
Normal file
26
include/protocol/packets/PlayerLoginPacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PlayerLoginPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::string m_PlayerName;
|
||||||
|
public:
|
||||||
|
PlayerLoginPacket() {}
|
||||||
|
PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {}
|
||||||
|
virtual ~PlayerLoginPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::PlayerLogin; }
|
||||||
|
|
||||||
|
const std::string& GetPlayerName() const { return m_PlayerName; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
27
include/protocol/packets/RemoveTowerPacket.h
Normal file
27
include/protocol/packets/RemoveTowerPacket.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class RemoveTowerPacket : public DelayedPacket {
|
||||||
|
private:
|
||||||
|
game::TowerID m_TowerID;
|
||||||
|
public:
|
||||||
|
RemoveTowerPacket() {}
|
||||||
|
RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
|
||||||
|
virtual ~RemoveTowerPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::TowerID GetTowerID() const { return m_TowerID; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::RemoveTower; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
27
include/protocol/packets/SelectTeamPacket.h
Normal file
27
include/protocol/packets/SelectTeamPacket.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class SelectTeamPacket : public Packet {
|
||||||
|
private:
|
||||||
|
game::TeamColor m_SelectedTeam;
|
||||||
|
public:
|
||||||
|
SelectTeamPacket() {}
|
||||||
|
SelectTeamPacket(game::TeamColor selectedTeam) : m_SelectedTeam(selectedTeam) {}
|
||||||
|
virtual ~SelectTeamPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::SelectTeam; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
33
include/protocol/packets/SendMobsPacket.h
Normal file
33
include/protocol/packets/SendMobsPacket.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
struct MobSend { // represents a mob send
|
||||||
|
game::MobType mobType : 4;
|
||||||
|
game::MobLevel mobLevel : 4;
|
||||||
|
std::uint8_t mobCount; // the max is 12
|
||||||
|
};
|
||||||
|
|
||||||
|
class SendMobsPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::vector<MobSend> m_MobSends;
|
||||||
|
public:
|
||||||
|
SendMobsPacket() {}
|
||||||
|
SendMobsPacket(const std::vector<MobSend>& mobSends) : m_MobSends(mobSends) {}
|
||||||
|
virtual ~SendMobsPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
const std::vector<MobSend>& GetMobSends() const { return m_MobSends; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::SendMobs; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
30
include/protocol/packets/ServerTpsPacket.h
Normal file
30
include/protocol/packets/ServerTpsPacket.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class ServerTpsPacket : public Packet {
|
||||||
|
private:
|
||||||
|
float m_TPS;
|
||||||
|
float m_MSPT;
|
||||||
|
std::uint64_t m_PacketSendTime; // used to calculate ping
|
||||||
|
public:
|
||||||
|
ServerTpsPacket() {}
|
||||||
|
ServerTpsPacket(float tps, float mspt, std::uint64_t sendTime) : m_TPS(tps), m_MSPT(mspt), m_PacketSendTime(sendTime) {}
|
||||||
|
virtual ~ServerTpsPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
float GetTPS() const { return m_TPS; }
|
||||||
|
float GetMSPT() const { return m_MSPT; }
|
||||||
|
std::uint64_t GetPacketSendTime() const { return m_PacketSendTime; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::ServerTps; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
41
include/protocol/packets/SpawnMobPacket.h
Normal file
41
include/protocol/packets/SpawnMobPacket.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class SpawnMobPacket : public Packet {
|
||||||
|
private:
|
||||||
|
game::MobID m_MobID;
|
||||||
|
game::MobType m_MobType;
|
||||||
|
game::MobLevel m_MobLevel;
|
||||||
|
game::Direction m_MobDirection;
|
||||||
|
game::PlayerID m_Sender;
|
||||||
|
float m_MobX, m_MobY;
|
||||||
|
public:
|
||||||
|
SpawnMobPacket() {}
|
||||||
|
SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender,
|
||||||
|
float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level),
|
||||||
|
m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y) {
|
||||||
|
}
|
||||||
|
virtual ~SpawnMobPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::MobID GetMobID() const { return m_MobID; }
|
||||||
|
game::MobType GetMobType() const { return m_MobType; }
|
||||||
|
game::MobLevel GetMobLevel() const { return m_MobLevel; }
|
||||||
|
game::Direction GetMobDirection() const { return m_MobDirection; }
|
||||||
|
game::PlayerID GetSender() const { return m_Sender; }
|
||||||
|
float GetMobX() const { return m_MobX; }
|
||||||
|
float GetMobY() const { return m_MobY; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::SpawnMob; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
29
include/protocol/packets/UpdateCastleLifePacket.h
Normal file
29
include/protocol/packets/UpdateCastleLifePacket.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpdateCastleLifePacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint16_t m_CastleLife;
|
||||||
|
game::TeamColor m_Team;
|
||||||
|
public:
|
||||||
|
UpdateCastleLifePacket() {}
|
||||||
|
UpdateCastleLifePacket(std::uint16_t life, game::TeamColor team) : m_CastleLife(life), m_Team(team) {}
|
||||||
|
virtual ~UpdateCastleLifePacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::uint16_t GetCastleLife() const { return m_CastleLife; }
|
||||||
|
game::TeamColor GetTeamColor() const { return m_Team; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdateCastleLife; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/UpdateExpPacket.h
Normal file
26
include/protocol/packets/UpdateExpPacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpdateExpPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint32_t m_NewAmount;
|
||||||
|
public:
|
||||||
|
UpdateExpPacket() {}
|
||||||
|
UpdateExpPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
|
||||||
|
virtual ~UpdateExpPacket() {}
|
||||||
|
|
||||||
|
std::uint32_t GetExp() const { return m_NewAmount; }
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdateEXP; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
27
include/protocol/packets/UpdateGameStatePacket.h
Normal file
27
include/protocol/packets/UpdateGameStatePacket.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpdateGameStatePacket : public Packet {
|
||||||
|
private:
|
||||||
|
game::GameState m_GameState;
|
||||||
|
public:
|
||||||
|
UpdateGameStatePacket() {}
|
||||||
|
UpdateGameStatePacket(game::GameState gameState) : m_GameState(gameState) {}
|
||||||
|
virtual ~UpdateGameStatePacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::GameState GetGameState() const { return m_GameState; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdateGameState; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/UpdateLobbyTimePacket.h
Normal file
26
include/protocol/packets/UpdateLobbyTimePacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpdateLobbyTimePacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint64_t m_StartTime; // unix millis
|
||||||
|
public:
|
||||||
|
UpdateLobbyTimePacket() {}
|
||||||
|
UpdateLobbyTimePacket(std::uint64_t startTime) : m_StartTime(startTime) {}
|
||||||
|
virtual ~UpdateLobbyTimePacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
std::uint64_t GetStartTime() const { return m_StartTime; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdateLobbyTime; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
47
include/protocol/packets/UpdateMobStatesPacket.h
Normal file
47
include/protocol/packets/UpdateMobStatesPacket.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class MobState {
|
||||||
|
using Point = utils::shape::Point;
|
||||||
|
private:
|
||||||
|
game::MobID m_MobID;
|
||||||
|
Point m_MobPosition;
|
||||||
|
float m_MobLife;
|
||||||
|
game::Direction m_MobDirection;
|
||||||
|
public:
|
||||||
|
MobState() {}
|
||||||
|
MobState(game::MobID id, const Point& position, float life, game::Direction direction) :
|
||||||
|
m_MobID(id), m_MobPosition(position), m_MobLife(life), m_MobDirection(direction) {
|
||||||
|
}
|
||||||
|
|
||||||
|
game::MobID GetMobId() const { return m_MobID; }
|
||||||
|
Point GetMobPosition() const { return m_MobPosition; }
|
||||||
|
float GetMobLife() const { return m_MobLife; }
|
||||||
|
game::Direction GetMobDirection() const { return m_MobDirection; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class UpdateMobStatesPacket : public DelayedPacket {
|
||||||
|
private:
|
||||||
|
std::vector<MobState> m_MobStates;
|
||||||
|
public:
|
||||||
|
UpdateMobStatesPacket() {}
|
||||||
|
virtual ~UpdateMobStatesPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
void addMobState(MobState mobState) { m_MobStates.push_back(mobState); }
|
||||||
|
|
||||||
|
const std::vector<MobState>& GetMobStates() const { return m_MobStates; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdateMobStates; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
26
include/protocol/packets/UpdateMoneyPacket.h
Normal file
26
include/protocol/packets/UpdateMoneyPacket.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpdateMoneyPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint32_t m_NewAmount;
|
||||||
|
public:
|
||||||
|
UpdateMoneyPacket() {}
|
||||||
|
UpdateMoneyPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
|
||||||
|
virtual ~UpdateMoneyPacket() {}
|
||||||
|
|
||||||
|
std::uint32_t GetGold() const { return m_NewAmount; }
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdateMoney; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
29
include/protocol/packets/UpdatePlayerTeamPacket.h
Normal file
29
include/protocol/packets/UpdatePlayerTeamPacket.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpdatePlayerTeamPacket : public Packet {
|
||||||
|
private:
|
||||||
|
std::uint8_t m_PlayerID;
|
||||||
|
game::TeamColor m_SelectedTeam;
|
||||||
|
public:
|
||||||
|
UpdatePlayerTeamPacket() {}
|
||||||
|
UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam) : m_PlayerID(playerID), m_SelectedTeam(selectedTeam) {}
|
||||||
|
virtual ~UpdatePlayerTeamPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; }
|
||||||
|
std::uint8_t GetPlayerID() const { return m_PlayerID; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpdatePlayerTeam; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
29
include/protocol/packets/UpgradeTowerPacket.h
Normal file
29
include/protocol/packets/UpgradeTowerPacket.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class UpgradeTowerPacket : public DelayedPacket {
|
||||||
|
private:
|
||||||
|
game::TowerID m_TowerID;
|
||||||
|
game::TowerLevel m_TowerLevel;
|
||||||
|
public:
|
||||||
|
UpgradeTowerPacket() {}
|
||||||
|
UpgradeTowerPacket(game::TowerID tower, game::TowerLevel level) : m_TowerID(tower), m_TowerLevel(level) {}
|
||||||
|
virtual ~UpgradeTowerPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::TowerID GetTowerID() const { return m_TowerID; }
|
||||||
|
game::TowerLevel GetTowerLevel() const { return m_TowerLevel; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::UpgradeTower; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
36
include/protocol/packets/WorldAddTowerPacket.h
Normal file
36
include/protocol/packets/WorldAddTowerPacket.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class WorldAddTowerPacket : public DelayedPacket {
|
||||||
|
private:
|
||||||
|
game::TowerID m_TowerID;
|
||||||
|
std::int32_t m_TowerX, m_TowerY;
|
||||||
|
game::TowerType m_TowerType;
|
||||||
|
game::PlayerID m_Builder;
|
||||||
|
public:
|
||||||
|
WorldAddTowerPacket() {}
|
||||||
|
WorldAddTowerPacket(game::TowerID id, std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) :
|
||||||
|
m_TowerID(id), m_TowerX(x), m_TowerY(y), m_TowerType(type), m_Builder(player) {
|
||||||
|
}
|
||||||
|
virtual ~WorldAddTowerPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
game::TowerID GetTowerID() const { return m_TowerID; }
|
||||||
|
std::int32_t GetTowerX() const { return m_TowerX; }
|
||||||
|
std::int32_t GetTowerY() const { return m_TowerY; }
|
||||||
|
game::TowerType GetTowerType() const { return m_TowerType; }
|
||||||
|
game::PlayerID GetBuilder() const { return m_Builder; }
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::WorldAddTower; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
60
include/protocol/packets/WorldBeginDataPacket.h
Normal file
60
include/protocol/packets/WorldBeginDataPacket.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
struct WorldHeader {
|
||||||
|
game::TowerTileColorPalette m_TowerPlacePalette;
|
||||||
|
Color m_WalkablePalette;
|
||||||
|
std::vector<Color> m_DecorationPalette;
|
||||||
|
Color m_Background;
|
||||||
|
|
||||||
|
game::SpawnColorPalette m_SpawnColorPalette;
|
||||||
|
|
||||||
|
game::TilePalette m_TilePalette;
|
||||||
|
|
||||||
|
game::Spawn m_RedSpawn, m_BlueSpawn;
|
||||||
|
game::TeamCastle m_RedCastle, m_BlueCastle;
|
||||||
|
|
||||||
|
const game::World* m_World;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorldBeginDataPacket : public Packet {
|
||||||
|
private:
|
||||||
|
WorldHeader m_Header;
|
||||||
|
public:
|
||||||
|
WorldBeginDataPacket() {}
|
||||||
|
WorldBeginDataPacket(const game::World* world) {
|
||||||
|
m_Header.m_World = world;
|
||||||
|
}
|
||||||
|
virtual ~WorldBeginDataPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::WorldBeginData; }
|
||||||
|
|
||||||
|
const game::TowerTileColorPalette& GetTowerTilePalette() const { return m_Header.m_TowerPlacePalette; }
|
||||||
|
const Color& GetWalkableTileColor() const { return m_Header.m_WalkablePalette; }
|
||||||
|
const std::vector<Color>& GetDecorationPalette() const { return m_Header.m_DecorationPalette; }
|
||||||
|
const Color& GetBackgroundColor() const { return m_Header.m_Background; }
|
||||||
|
|
||||||
|
const game::Spawn& GetRedSpawn() const { return m_Header.m_RedSpawn; }
|
||||||
|
const game::Spawn& GetBlueSpawn() const { return m_Header.m_BlueSpawn; }
|
||||||
|
|
||||||
|
const game::SpawnColorPalette& GetSpawnPalette() const { return m_Header.m_SpawnColorPalette; }
|
||||||
|
|
||||||
|
const game::TeamCastle& GetRedCastle() const { return m_Header.m_RedCastle; }
|
||||||
|
const game::TeamCastle& GetBlueCastle() const { return m_Header.m_BlueCastle; }
|
||||||
|
|
||||||
|
const game::TilePalette GetTilePalette() const { return m_Header.m_TilePalette; }
|
||||||
|
|
||||||
|
void setWorldHeader(const WorldHeader& header) { m_Header = header; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
36
include/protocol/packets/WorldDataPacket.h
Normal file
36
include/protocol/packets/WorldDataPacket.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "protocol/Protocol.h"
|
||||||
|
#include "game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
struct WorldData {
|
||||||
|
std::unordered_map<game::ChunkCoord, game::ChunkPtr> m_Chunks;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorldDataPacket : public Packet {
|
||||||
|
private:
|
||||||
|
WorldData m_WorldData;
|
||||||
|
|
||||||
|
const game::World* m_World;
|
||||||
|
public:
|
||||||
|
WorldDataPacket() {}
|
||||||
|
WorldDataPacket(const game::World* world) : m_World(world) {}
|
||||||
|
virtual ~WorldDataPacket() {}
|
||||||
|
|
||||||
|
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||||
|
virtual void Deserialize(DataBuffer& data);
|
||||||
|
virtual void Dispatch(PacketHandler* handler) const;
|
||||||
|
|
||||||
|
virtual PacketType GetType() const { return PacketType::WorldData; }
|
||||||
|
|
||||||
|
const std::unordered_map<game::ChunkCoord, game::ChunkPtr>& GetChunks() const { return m_WorldData.m_Chunks; }
|
||||||
|
|
||||||
|
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
|
||||||
|
void SetWorldData(const WorldData& worldData) { m_WorldData = worldData; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
@@ -13,17 +13,17 @@
|
|||||||
#if defined(__has_include)
|
#if defined(__has_include)
|
||||||
|
|
||||||
#if __has_include(<GL/glew.h>)
|
#if __has_include(<GL/glew.h>)
|
||||||
#define TD_IMPL_OPENGL_LOADER_GLEW
|
#define TD_IMPL_OPENGL_LOADER_GLEW
|
||||||
#elif __has_include(<glad/glad.h>)
|
#elif __has_include(<glad/glad.h>)
|
||||||
#define TD_IMPL_OPENGL_LOADER_GLAD
|
#define TD_IMPL_OPENGL_LOADER_GLAD
|
||||||
#elif __has_include(<GL/gl3w.h>)
|
#elif __has_include(<GL/gl3w.h>)
|
||||||
#define TD_IMPL_OPENGL_LOADER_GL3W
|
#define TD_IMPL_OPENGL_LOADER_GL3W
|
||||||
#elif __has_include(<glbinding/glbinding.h>)
|
#elif __has_include(<glbinding/glbinding.h>)
|
||||||
#define TD_IMPL_OPENGL_LOADER_GLBINDING3
|
#define TD_IMPL_OPENGL_LOADER_GLBINDING3
|
||||||
#elif __has_include(<glbinding/Binding.h>)
|
#elif __has_include(<glbinding/Binding.h>)
|
||||||
#define TD_IMPL_OPENGL_LOADER_GLBINDING2
|
#define TD_IMPL_OPENGL_LOADER_GLBINDING2
|
||||||
#else
|
#else
|
||||||
#error "Cannot detect OpenGL loader!"
|
#error "Cannot detect OpenGL loader!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include "Defines.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "loader/GLLoader.h"
|
#include "loader/GLLoader.h"
|
||||||
#include "render/shaders/WorldShader.h"
|
#include "render/shaders/WorldShader.h"
|
||||||
@@ -9,47 +9,62 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
|
struct Camera {
|
||||||
|
Mat4f viewMatrix;
|
||||||
|
Mat4f projectionMatrix;
|
||||||
|
Mat4f InvViewMatrix;
|
||||||
|
Mat4f InvProjectionMatrix;
|
||||||
|
|
||||||
|
float CamDistance = 25.0f;
|
||||||
|
Vec3f CamPos {0, CamDistance, 0};
|
||||||
|
Vec2f CamLook {};
|
||||||
|
|
||||||
|
float m_Yaw = -PI / 2.0f;
|
||||||
|
float m_Pitch = -PI / 2.0f + 0.0000001f;
|
||||||
|
};
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
static constexpr float m_AnimationSpeed = 2.0f;
|
static constexpr float m_AnimationSpeed = 2.0f;
|
||||||
|
static constexpr float m_MouseSensitivity = 200.0f;
|
||||||
|
|
||||||
struct Model {
|
struct Model {
|
||||||
GL::VertexArray* vao;
|
GL::VertexArray* vao;
|
||||||
glm::vec2 positon;
|
Vec3f positon;
|
||||||
};
|
Vec3f color = { 1, 1, 1 };
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<shader::WorldShader> m_WorldShader;
|
std::unique_ptr<shader::WorldShader> m_WorldShader;
|
||||||
std::unique_ptr<shader::EntityShader> m_EntityShader;
|
std::unique_ptr<shader::EntityShader> m_EntityShader;
|
||||||
|
|
||||||
glm::vec3 m_BackgroundColor;
|
Vec2i m_WindowSize;
|
||||||
|
|
||||||
bool m_IsometricView = true;
|
Vec3f m_BackgroundColor;
|
||||||
float m_IsometricShade = m_IsometricView;
|
|
||||||
glm::vec2 m_CamPos{};
|
Camera m_Camera {};
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
void Prepare();
|
void Prepare();
|
||||||
void Resize(const int width, const int height);
|
void Resize(const int width, const int height);
|
||||||
|
|
||||||
void RenderVAO(const GL::VertexArray& vao);
|
void RenderVAO(const GL::VertexArray& vao);
|
||||||
void RenderModel(const Model& model);
|
void RenderModel(const Model& model);
|
||||||
|
|
||||||
void SetZoom(float zoom);
|
void AddZoom(float zoom);
|
||||||
void SetCamMovement(const glm::vec2& mov);
|
void SetCamAngularMovement(const Vec2f& mov);
|
||||||
void SetCamPos(const glm::vec2& newPos);
|
void SetCamMovement(const Vec2f& lastCursorPos, const Vec2f& currentCursorPos);
|
||||||
void SetIsometricView(bool isometric); // false = 2D true = Isometric
|
void SetCamLook(const Vec2f& worldPos);
|
||||||
|
|
||||||
void SetBackgroundColor(const glm::vec3& color) { m_BackgroundColor = color; }
|
void SetBackgroundColor(const Vec3f& color) { m_BackgroundColor = color; }
|
||||||
|
|
||||||
glm::vec2 GetCursorWorldPos(const glm::vec2& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight);
|
Vec2f GetCursorWorldPos(const Vec2f& cursorPos, float windowWidth, float windowHeight);
|
||||||
private:
|
private:
|
||||||
void UpdateIsometricView();
|
void InitShaders();
|
||||||
void UpdateIsometricFade();
|
void SetCamPos(const Vec3f& newPos);
|
||||||
void InitShaders();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -11,27 +11,27 @@ namespace render {
|
|||||||
|
|
||||||
class VertexCache {
|
class VertexCache {
|
||||||
|
|
||||||
typedef std::vector<float> Vector;
|
typedef std::vector<float> Vector;
|
||||||
|
|
||||||
struct DataIndex {
|
struct DataIndex {
|
||||||
Vector position;
|
Vector position;
|
||||||
Vector color;
|
Vector color;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t m_VertexCount;
|
std::size_t m_VertexCount;
|
||||||
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
|
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
|
||||||
std::unique_ptr<GL::VertexArray> m_VertexArray;
|
std::unique_ptr<GL::VertexArray> m_VertexArray;
|
||||||
public:
|
public:
|
||||||
VertexCache() : m_VertexCount(0) {}
|
VertexCache() : m_VertexCount(0) {}
|
||||||
|
|
||||||
void AddData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
|
void AddData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
|
||||||
void RemoveData(std::uint64_t index);
|
void RemoveData(std::uint64_t index);
|
||||||
void Clear();
|
void Clear();
|
||||||
void UpdateVertexArray();
|
void UpdateVertexArray();
|
||||||
|
|
||||||
const GL::VertexArray& GetVertexArray() const { return *m_VertexArray; }
|
const GL::VertexArray& GetVertexArray() const { return *m_VertexArray; }
|
||||||
bool IsEmpty() const { return m_VertexArray == nullptr; }
|
bool IsEmpty() const { return m_VertexArray == nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -6,13 +6,10 @@
|
|||||||
#include "render/VertexCache.h"
|
#include "render/VertexCache.h"
|
||||||
|
|
||||||
#include "render/gui/TowerPlacePopup.h"
|
#include "render/gui/TowerPlacePopup.h"
|
||||||
|
#include "render/gui/TowerUpgradePopup.h"
|
||||||
#include "render/gui/MobTooltip.h"
|
#include "render/gui/MobTooltip.h"
|
||||||
#include "render/gui/CastleTooltip.h"
|
#include "render/gui/CastleTooltip.h"
|
||||||
|
|
||||||
#include "render/gui/imgui/imgui.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@@ -21,66 +18,63 @@ class ClientGame;
|
|||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
class WorldRenderer : public game::WorldListener {
|
class WorldRenderer : public game::WorldListener {
|
||||||
private:
|
private:
|
||||||
client::ClientGame* m_Client;
|
client::ClientGame* m_Client;
|
||||||
Renderer* m_Renderer;
|
Renderer* m_Renderer;
|
||||||
game::World* m_World;
|
game::World* m_World;
|
||||||
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
|
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
|
||||||
glm::vec2 m_CamPos;
|
Vec2f m_CamPos;
|
||||||
glm::vec2 m_CursorPos;
|
Vec2f m_CursorPos;
|
||||||
glm::vec2 m_HoldCursorPos;
|
Vec2f m_HoldCursorPos;
|
||||||
glm::vec2 m_LastClicked;
|
Vec2f m_LastClicked;
|
||||||
float m_Zoom;
|
float m_Zoom;
|
||||||
float m_CamSensibility = 1;
|
float m_CamSensibility = 1;
|
||||||
bool m_PopupOpened = false;
|
bool m_PopupOpened = false;
|
||||||
VertexCache m_TowersCache;
|
VertexCache m_TowersCache;
|
||||||
|
|
||||||
std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
|
std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
|
||||||
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
|
std::unique_ptr<gui::TowerUpgradePopup> m_TowerUpgradePopup;
|
||||||
std::unique_ptr<gui::CastleTooltip> m_CastleTooltip;
|
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
|
||||||
|
std::unique_ptr<gui::CastleTooltip> m_CastleTooltip;
|
||||||
public:
|
public:
|
||||||
WorldRenderer(game::World* world, client::ClientGame* client);
|
WorldRenderer(game::World* world, client::ClientGame* client);
|
||||||
~WorldRenderer();
|
~WorldRenderer();
|
||||||
|
|
||||||
void LoadModels();
|
void LoadModels();
|
||||||
|
|
||||||
static ImVec4 GetImGuiTeamColor(game::TeamColor color);
|
void Update();
|
||||||
|
void Render();
|
||||||
|
|
||||||
void Update();
|
void SetCamPos(float camX, float camY);
|
||||||
void Render();
|
|
||||||
|
|
||||||
void SetCamPos(float camX, float camY);
|
void MoveCam(float relativeX, float relativeY);
|
||||||
|
void ChangeZoom(float zoom);
|
||||||
|
|
||||||
void MoveCam(float relativeX, float relativeY, float aspectRatio);
|
// WorldListener
|
||||||
void ChangeZoom(float zoom);
|
|
||||||
|
|
||||||
// WorldListener
|
virtual void OnTowerAdd(game::TowerPtr tower);
|
||||||
|
virtual void OnTowerRemove(game::TowerPtr tower);
|
||||||
virtual void OnTowerAdd(game::TowerPtr tower);
|
|
||||||
virtual void OnTowerRemove(game::TowerPtr tower);
|
|
||||||
private:
|
private:
|
||||||
void Click();
|
void Click();
|
||||||
void RenderWorld() const;
|
void RenderWorld() const;
|
||||||
void RenderTowers() const;
|
void RenderTowers() const;
|
||||||
void RenderMobs() const;
|
void RenderMobs() const;
|
||||||
void RenderTileSelect() const;
|
void RenderTileSelect() const;
|
||||||
void RenderPopups();
|
void RenderPopups();
|
||||||
void RenderTowerUpgradePopup();
|
void RenderMobTooltip() const;
|
||||||
void RenderMobTooltip() const;
|
void RenderCastleTooltip() const;
|
||||||
void RenderCastleTooltip() const;
|
void DetectClick();
|
||||||
void DetectClick();
|
void DetectMobHovering() const;
|
||||||
void DetectMobHovering() const;
|
void DetectCastleHovering() const;
|
||||||
void DetectCastleHovering() const;
|
void RenderTooltips() const;
|
||||||
void RenderTooltips() const;
|
void RemoveTower();
|
||||||
void RemoveTower();
|
Vec2f GetCursorWorldPos() const;
|
||||||
glm::vec2 GetCursorWorldPos() const;
|
Vec2f GetClickWorldPos() const;
|
||||||
glm::vec2 GetClickWorldPos() const;
|
|
||||||
|
|
||||||
void UpdateCursorPos();
|
void UpdateCursorPos();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ namespace gui {
|
|||||||
|
|
||||||
class CastleTooltip : public GuiWidget {
|
class CastleTooltip : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
const game::TeamCastle* m_Castle;
|
const game::TeamCastle* m_Castle;
|
||||||
public:
|
public:
|
||||||
CastleTooltip(client::Client* client);
|
CastleTooltip(client::Client* client);
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
|
|
||||||
void SetCastle(const game::TeamCastle* castle) { m_Castle = castle; }
|
void SetCastle(const game::TeamCastle* castle) { m_Castle = castle; }
|
||||||
bool IsShown() { return m_Castle != nullptr; }
|
bool IsShown() { return m_Castle != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ namespace gui {
|
|||||||
|
|
||||||
class FrameMenu : public GuiWidget {
|
class FrameMenu : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
bool m_VSync;
|
bool m_VSync;
|
||||||
bool m_IsometricView;
|
bool m_IsometricView;
|
||||||
bool m_ShowDemoWindow;
|
bool m_ShowDemoWindow;
|
||||||
public:
|
public:
|
||||||
FrameMenu(client::Client* client);
|
FrameMenu(client::Client* client);
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ namespace gui {
|
|||||||
|
|
||||||
class GameMenu : public GuiWidget {
|
class GameMenu : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<SummonMenu> m_SummonMenu;
|
std::unique_ptr<SummonMenu> m_SummonMenu;
|
||||||
public:
|
public:
|
||||||
GameMenu(client::Client* client);
|
GameMenu(client::Client* client);
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
private:
|
private:
|
||||||
void ShowTPS();
|
void ShowTPS();
|
||||||
void ShowStats();
|
void ShowStats();
|
||||||
void ShowPlayers();
|
void ShowPlayers();
|
||||||
void ShowLobbyProgress();
|
void ShowLobbyProgress();
|
||||||
void ShowTeamSelection();
|
void ShowTeamSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -10,19 +10,19 @@ namespace gui {
|
|||||||
|
|
||||||
class GuiManager {
|
class GuiManager {
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<GuiWidget>> m_Widgets;
|
std::vector<std::unique_ptr<GuiWidget>> m_Widgets;
|
||||||
public:
|
public:
|
||||||
GuiManager() {}
|
GuiManager() {}
|
||||||
|
|
||||||
void RenderWidgets() {
|
void RenderWidgets() {
|
||||||
for (auto& widget : m_Widgets) {
|
for (auto& widget : m_Widgets) {
|
||||||
widget->Render();
|
widget->Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddWidget(std::unique_ptr<GuiWidget>&& widget) {
|
void AddWidget(std::unique_ptr<GuiWidget>&& widget) {
|
||||||
m_Widgets.push_back(std::move(widget));
|
m_Widgets.push_back(std::move(widget));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ namespace gui {
|
|||||||
|
|
||||||
class GuiWidget {
|
class GuiWidget {
|
||||||
protected:
|
protected:
|
||||||
client::Client* m_Client;
|
client::Client* m_Client;
|
||||||
public:
|
public:
|
||||||
GuiWidget(client::Client* client) : m_Client(client) {}
|
GuiWidget(client::Client* client) : m_Client(client) {}
|
||||||
|
|
||||||
client::Client* GetClient() { return m_Client; }
|
client::Client* GetClient() { return m_Client; }
|
||||||
|
|
||||||
virtual void Render() = 0;
|
virtual void Render() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
13
include/render/gui/ImGuiTeamColor.h
Normal file
13
include/render/gui/ImGuiTeamColor.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "render/gui/imgui/imgui.h"
|
||||||
|
#include "game/Team.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
ImVec4 GetImGuiTeamColor(game::TeamColor color);
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
|
|
||||||
9
include/render/gui/LifeProgress.h
Normal file
9
include/render/gui/LifeProgress.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
extern void RenderLifeProgress(float progress);
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
@@ -13,24 +13,24 @@ namespace gui {
|
|||||||
|
|
||||||
class MainMenu : public GuiWidget {
|
class MainMenu : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
bool m_TriedToConnect = false;
|
bool m_TriedToConnect = false;
|
||||||
bool m_TriedToCreate = false;
|
bool m_TriedToCreate = false;
|
||||||
std::string m_ConnectAddress;
|
std::string m_ConnectAddress;
|
||||||
int m_ConnectPort;
|
int m_ConnectPort;
|
||||||
int m_ServerPort = 25565;
|
int m_ServerPort = 25565;
|
||||||
std::string m_WorldFilePath;
|
std::string m_WorldFilePath;
|
||||||
imgui_addons::ImGuiFileBrowser m_FileDialog;
|
imgui_addons::ImGuiFileBrowser m_FileDialog;
|
||||||
|
|
||||||
std::unique_ptr<server::Server> m_Server;
|
std::unique_ptr<server::Server> m_Server;
|
||||||
public:
|
public:
|
||||||
MainMenu(client::Client* client);
|
MainMenu(client::Client* client);
|
||||||
~MainMenu();
|
~MainMenu();
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
|
|
||||||
const server::Server* GetServer() const { return m_Server.get(); }
|
const server::Server* GetServer() const { return m_Server.get(); }
|
||||||
private:
|
private:
|
||||||
bool StartServer();
|
bool StartServer();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ namespace gui {
|
|||||||
|
|
||||||
class MobTooltip : public GuiWidget {
|
class MobTooltip : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
const game::Mob* m_Mob;
|
const game::Mob* m_Mob;
|
||||||
public:
|
public:
|
||||||
MobTooltip(client::Client* client);
|
MobTooltip(client::Client* client);
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
|
|
||||||
void SetMob(const game::Mob* mob) { m_Mob = mob; }
|
void SetMob(const game::Mob* mob) { m_Mob = mob; }
|
||||||
bool IsShown() { return m_Mob != nullptr; }
|
bool IsShown() { return m_Mob != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -10,16 +10,20 @@ namespace gui {
|
|||||||
|
|
||||||
class SummonMenu : public GuiWidget {
|
class SummonMenu : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
bool m_MenuOpened;
|
bool m_MenuOpened;
|
||||||
int m_ImageWidth = 100;
|
int m_ImageWidth = 100;
|
||||||
static constexpr int m_MobTypeCount = static_cast<std::size_t>(td::game::MobType::MOB_COUNT);
|
float m_Cooldown;
|
||||||
std::array<int, static_cast<std::size_t>(m_MobTypeCount)> m_Values;
|
float m_LastCooldown;
|
||||||
|
static constexpr int m_MobTypeCount = static_cast<std::size_t>(td::game::MobType::MOB_COUNT);
|
||||||
|
std::array<int, static_cast<std::size_t>(m_MobTypeCount)> m_Values;
|
||||||
public:
|
public:
|
||||||
SummonMenu(client::Client* client);
|
SummonMenu(client::Client* client);
|
||||||
|
|
||||||
virtual void Render();
|
void SetCooldown(float cooldown);
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
private:
|
private:
|
||||||
void SetSummonMax(int valueIndex);
|
void SetSummonMax(int valueIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -28,21 +28,21 @@ class Renderer;
|
|||||||
|
|
||||||
class TowerGui {
|
class TowerGui {
|
||||||
private:
|
private:
|
||||||
SDL_Window* m_Window;
|
SDL_Window* m_Window;
|
||||||
SDL_GLContext m_GlContext;
|
SDL_GLContext m_GlContext;
|
||||||
td::render::Renderer* m_Renderer;
|
td::render::Renderer* m_Renderer;
|
||||||
td::gui::GuiManager m_GuiManager;
|
td::gui::GuiManager m_GuiManager;
|
||||||
std::unique_ptr<td::client::Client> m_Client;
|
std::unique_ptr<td::client::Client> m_Client;
|
||||||
public:
|
public:
|
||||||
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
|
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
|
||||||
~TowerGui();
|
~TowerGui();
|
||||||
|
|
||||||
void Render();
|
void Render();
|
||||||
private:
|
private:
|
||||||
void InitWidgets();
|
void InitWidgets();
|
||||||
void Tick();
|
void Tick();
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -2,26 +2,26 @@
|
|||||||
|
|
||||||
#include "GuiWidget.h"
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include "Defines.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
class TowerPlacePopup : public GuiWidget {
|
class TowerPlacePopup : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
glm::vec2 m_ClickWorldPos;
|
Vec2f m_ClickWorldPos;
|
||||||
public:
|
public:
|
||||||
TowerPlacePopup(client::Client* client);
|
TowerPlacePopup(client::Client* client);
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
|
|
||||||
void SetClickPos(const glm::vec2& worldPos);
|
void SetClickPos(const Vec2f& worldPos);
|
||||||
private:
|
private:
|
||||||
static constexpr float m_TowerPopupTileWidth = 200.0f;
|
static constexpr float m_TowerPopupTileWidth = 200.0f;
|
||||||
static constexpr float m_TowerPopupTileHeight = 200.0f;
|
static constexpr float m_TowerPopupTileHeight = 200.0f;
|
||||||
|
|
||||||
static constexpr float m_PlaceTowerButtonWidth = 150.0f;
|
static constexpr float m_PlaceTowerButtonWidth = 150.0f;
|
||||||
static constexpr float m_PlaceTowerButtonHeight = 35.0f;
|
static constexpr float m_PlaceTowerButtonHeight = 35.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
32
include/render/gui/TowerUpgradePopup.h
Normal file
32
include/render/gui/TowerUpgradePopup.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include "Defines.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class TowerUpgradePopup : public GuiWidget {
|
||||||
|
private:
|
||||||
|
Vec2f m_ClickWorldPos;
|
||||||
|
bool m_ShouldBeClosed;
|
||||||
|
bool m_Opened;
|
||||||
|
public:
|
||||||
|
TowerUpgradePopup(client::Client* client);
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
|
||||||
|
void SetClickPos(const Vec2f& worldPos);
|
||||||
|
|
||||||
|
bool IsPopupOpened();
|
||||||
|
private:
|
||||||
|
static constexpr float m_TowerPopupTileWidth = 200.0f;
|
||||||
|
static constexpr float m_TowerPopupTileHeight = 200.0f;
|
||||||
|
|
||||||
|
static constexpr float m_PlaceTowerButtonWidth = 150.0f;
|
||||||
|
static constexpr float m_PlaceTowerButtonHeight = 35.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
@@ -2,27 +2,34 @@
|
|||||||
|
|
||||||
#include "GuiWidget.h"
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
#include "updater/Updater.h"
|
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
class Updater;
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
class UpdateMenu : public GuiWidget {
|
class UpdateMenu : public GuiWidget {
|
||||||
private:
|
private:
|
||||||
bool m_Opened;
|
bool m_Opened;
|
||||||
std::string m_Error;
|
std::string m_Error;
|
||||||
utils::Updater m_Updater;
|
std::unique_ptr<utils::Updater> m_Updater;
|
||||||
std::shared_future<bool> m_UpdateAvailable;
|
std::shared_future<bool> m_UpdateAvailable;
|
||||||
public:
|
public:
|
||||||
UpdateMenu(client::Client* client);
|
UpdateMenu(client::Client* client);
|
||||||
|
virtual ~UpdateMenu();
|
||||||
|
|
||||||
virtual void Render();
|
virtual void Render();
|
||||||
private:
|
private:
|
||||||
void CheckUpdates();
|
void CheckUpdates();
|
||||||
bool IsUpdateChecked();
|
bool IsUpdateChecked();
|
||||||
void RenderErrorPopup();
|
void RenderErrorPopup();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ namespace render {
|
|||||||
namespace WorldLoader {
|
namespace WorldLoader {
|
||||||
|
|
||||||
struct RenderData {
|
struct RenderData {
|
||||||
std::vector<float> positions;
|
std::vector<float> positions;
|
||||||
std::vector<float> colors;
|
std::vector<float> colors;
|
||||||
};
|
};
|
||||||
|
|
||||||
GL::VertexArray LoadMobModel();
|
GL::VertexArray LoadMobModel();
|
||||||
|
|||||||
@@ -6,24 +6,22 @@ namespace td {
|
|||||||
namespace shader {
|
namespace shader {
|
||||||
|
|
||||||
class EntityShader : public ShaderProgram {
|
class EntityShader : public ShaderProgram {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_LocationCam = 0;
|
unsigned int m_LocationProjectionMatrix = 0;
|
||||||
unsigned int m_LocationZoom = 0;
|
unsigned int m_LocationViewMatrix = 0;
|
||||||
unsigned int m_LocationAspectRatio = 0;
|
unsigned int m_LocationPosition = 0;
|
||||||
unsigned int m_LocationTranslation = 0;
|
unsigned int m_LocationColorEffect = 0;
|
||||||
unsigned int m_LocationViewtype = 0;
|
|
||||||
protected:
|
protected:
|
||||||
virtual void GetAllUniformLocation();
|
virtual void GetAllUniformLocation();
|
||||||
public:
|
public:
|
||||||
EntityShader();
|
EntityShader();
|
||||||
|
|
||||||
void LoadShader();
|
void LoadShader();
|
||||||
void SetCamPos(const glm::vec2& camPos);
|
|
||||||
void SetZoom(float zoom);
|
void SetColorEffect(const Vec3f& color);
|
||||||
void SetAspectRatio(float aspectRatio);
|
void SetProjectionMatrix(const Mat4f& proj) const;
|
||||||
void SetModelPos(const glm::vec2& modelPos);
|
void SetViewMatrix(const Mat4f& view) const;
|
||||||
void SetIsometricView(float isometric);
|
void SetModelPos(const Vec3f& pos) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shader
|
} // namespace shader
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <glm/glm.hpp>
|
#include "Defines.h"
|
||||||
#include "render/GL.h"
|
#include "render/GL.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
@@ -24,11 +24,10 @@ protected:
|
|||||||
|
|
||||||
void LoadFloat(unsigned int location, float value) const;
|
void LoadFloat(unsigned int location, float value) const;
|
||||||
void LoadInt(unsigned int location, int value) const;
|
void LoadInt(unsigned int location, int value) const;
|
||||||
void LoadVector(unsigned int location, const glm::vec2& vector) const;
|
void LoadVector(unsigned int location, const Vec2f& vector) const;
|
||||||
void LoadVector(unsigned int location, const glm::vec3& vector) const;
|
void LoadVector(unsigned int location, const Vec3f& vector) const;
|
||||||
void LoadVector(unsigned int location, const glm::vec4& vector) const;
|
|
||||||
void LoadBoolean(unsigned int location, bool value) const;
|
void LoadBoolean(unsigned int location, bool value) const;
|
||||||
void LoadMatrix(unsigned int location, const glm::mat4& matrix) const;
|
void LoadMat4(unsigned int location, const Mat4f& mat) const;
|
||||||
void CleanUp() const;
|
void CleanUp() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -7,16 +7,15 @@ namespace shader {
|
|||||||
|
|
||||||
class WorldShader : public ShaderProgram {
|
class WorldShader : public ShaderProgram {
|
||||||
private:
|
private:
|
||||||
unsigned int m_LocationCam = 0, m_LocationZoom = 0, m_LocationAspectRatio = 0, m_LocationViewtype = 0;
|
unsigned int m_LocationProjection = 0, m_LocationView = 0;
|
||||||
protected:
|
protected:
|
||||||
void GetAllUniformLocation();
|
void GetAllUniformLocation();
|
||||||
public:
|
public:
|
||||||
WorldShader();
|
WorldShader();
|
||||||
void LoadShader();
|
void LoadShader();
|
||||||
void SetCamPos(const glm::vec2& camPos);
|
|
||||||
void SetZoom(float zoom);
|
void SetProjectionMatrix(const Mat4f& proj) const;
|
||||||
void SetAspectRatio(float aspectRatio);
|
void SetViewMatrix(const Mat4f& view) const;
|
||||||
void SetIsometricView(float isometric);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shader
|
} // namespace shader
|
||||||
|
|||||||
@@ -2,42 +2,42 @@
|
|||||||
|
|
||||||
#include "misc/DataBuffer.h"
|
#include "misc/DataBuffer.h"
|
||||||
|
|
||||||
#define TD_VERSION "alpha-0.2.0"
|
#define TD_VERSION "alpha-0.3.0"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
class Updater {
|
class Updater {
|
||||||
private:
|
private:
|
||||||
float m_Progress;
|
float m_Progress;
|
||||||
bool m_DownloadComplete;
|
bool m_DownloadComplete;
|
||||||
bool m_FileWrited;
|
bool m_FileWrited;
|
||||||
bool m_CancelDownload;
|
bool m_CancelDownload;
|
||||||
DataBuffer m_FileBuffer;
|
DataBuffer m_FileBuffer;
|
||||||
std::string m_LastVersion;
|
std::string m_LastVersion;
|
||||||
public:
|
public:
|
||||||
Updater() : m_Progress(0), m_DownloadComplete(false), m_FileWrited(false), m_CancelDownload(false) {}
|
Updater() : m_Progress(0), m_DownloadComplete(false), m_FileWrited(false), m_CancelDownload(false) {}
|
||||||
|
|
||||||
bool CheckUpdate();
|
bool CheckUpdate();
|
||||||
void DownloadUpdate();
|
void DownloadUpdate();
|
||||||
void CancelDownload() { m_CancelDownload = true; m_Progress = 0.0f; m_DownloadComplete = false; }
|
void CancelDownload() { m_CancelDownload = true; m_Progress = 0.0f; m_DownloadComplete = false; }
|
||||||
bool WriteFile();
|
bool WriteFile();
|
||||||
|
|
||||||
void ClearCache() { m_FileBuffer.Clear(); }
|
void ClearCache() { m_FileBuffer.Clear(); }
|
||||||
|
|
||||||
float GetDownloadProgress() { return m_Progress; }
|
float GetDownloadProgress() { return m_Progress; }
|
||||||
bool IsDownloadComplete() { return m_DownloadComplete; }
|
bool IsDownloadComplete() { return m_DownloadComplete; }
|
||||||
bool IsFileWrited() { return m_FileWrited; }
|
bool IsFileWrited() { return m_FileWrited; }
|
||||||
|
|
||||||
static std::string GetLocalFilePath();
|
static std::string GetLocalFilePath();
|
||||||
static void RemoveOldFile();
|
static void RemoveOldFile();
|
||||||
|
|
||||||
static std::string GetCurrentVersion() { return TD_VERSION; }
|
static std::string GetCurrentVersion() { return TD_VERSION; }
|
||||||
std::string GetLastVersion() { return m_LastVersion; }
|
std::string GetLastVersion() { return m_LastVersion; }
|
||||||
|
|
||||||
bool CanUpdate();
|
bool CanUpdate();
|
||||||
private:
|
private:
|
||||||
std::string GetDownloadFileURL();
|
std::string GetDownloadFileURL();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|||||||
@@ -21,19 +21,19 @@ extern "C"
|
|||||||
|
|
||||||
int main(int argc, const char* args[]) {
|
int main(int argc, const char* args[]) {
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
// setup signal handling
|
// setup signal handling
|
||||||
backward::SignalHandling sh;
|
backward::SignalHandling sh;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// remove the outdated binary
|
// remove the outdated binary
|
||||||
td::utils::Updater::RemoveOldFile();
|
td::utils::Updater::RemoveOldFile();
|
||||||
|
|
||||||
Display::Create();
|
Display::Create();
|
||||||
while (!Display::IsCloseRequested()) {
|
while (!Display::IsCloseRequested()) {
|
||||||
Display::PollEvents();
|
Display::PollEvents();
|
||||||
Display::Render();
|
Display::Render();
|
||||||
Display::Update();
|
Display::Update();
|
||||||
}
|
}
|
||||||
Display::Destroy();
|
Display::Destroy();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -12,25 +12,25 @@ Game::~Game() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Game::Tick(std::uint64_t delta) {
|
void Game::Tick(std::uint64_t delta) {
|
||||||
if (m_GameState == GameState::Game) {
|
if (m_GameState == GameState::Game) {
|
||||||
m_World->Tick(delta);
|
m_World->Tick(delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* Game::GetPlayerById(PlayerID id) {
|
Player* Game::GetPlayerById(PlayerID id) {
|
||||||
auto it = m_Players.find(id);
|
auto it = m_Players.find(id);
|
||||||
|
|
||||||
if (it == m_Players.end()) return nullptr;
|
if (it == m_Players.end()) return nullptr;
|
||||||
|
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Player* Game::GetPlayerById(PlayerID id) const {
|
const Player* Game::GetPlayerById(PlayerID id) const {
|
||||||
auto it = m_Players.find(id);
|
auto it = m_Players.find(id);
|
||||||
|
|
||||||
if (it == m_Players.end()) return nullptr;
|
if (it == m_Players.end()) return nullptr;
|
||||||
|
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -29,44 +29,44 @@ Connexion::Connexion(protocol::PacketDispatcher* dispatcher, network::TCPSocket&
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Connexion::UpdateSocket() {
|
bool Connexion::UpdateSocket() {
|
||||||
if (m_Socket.GetStatus() != network::Socket::Connected)
|
if (m_Socket.GetStatus() != network::Socket::Connected)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
DataBuffer buffer;
|
DataBuffer buffer;
|
||||||
m_Socket.Receive(buffer, sizeof(std::uint64_t));
|
m_Socket.Receive(buffer, sizeof(std::uint64_t));
|
||||||
if (buffer.GetSize() == 0)
|
if (buffer.GetSize() == 0)
|
||||||
break;
|
break;
|
||||||
std::uint64_t packetLenght;
|
std::uint64_t packetLenght;
|
||||||
buffer >> packetLenght;
|
buffer >> packetLenght;
|
||||||
|
|
||||||
m_Socket.Receive(buffer, packetLenght);
|
m_Socket.Receive(buffer, packetLenght);
|
||||||
|
|
||||||
DataBuffer decompressed = utils::Decompress(buffer, packetLenght);
|
DataBuffer decompressed = utils::Decompress(buffer, packetLenght);
|
||||||
|
|
||||||
protocol::PacketType packetType;
|
protocol::PacketType packetType;
|
||||||
decompressed >> packetType;
|
decompressed >> packetType;
|
||||||
|
|
||||||
PacketPtr packet = protocol::PacketFactory::CreatePacket(packetType, decompressed);
|
PacketPtr packet = protocol::PacketFactory::CreatePacket(packetType, decompressed);
|
||||||
GetDispatcher()->Dispatch(packet);
|
GetDispatcher()->Dispatch(packet);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Connexion::Connect(const std::string& address, std::uint16_t port) {
|
bool Connexion::Connect(const std::string& address, std::uint16_t port) {
|
||||||
if (!m_Socket.Connect(address, port)) {
|
if (!m_Socket.Connect(address, port)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_Socket.SetBlocking(false);
|
m_Socket.SetBlocking(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connexion::SendPacket(const protocol::Packet* packet) {
|
void Connexion::SendPacket(const protocol::Packet* packet) {
|
||||||
network::SendPacket(packet->Serialize(), m_Socket);
|
network::SendPacket(packet->Serialize(), m_Socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connexion::CloseConnection() {
|
void Connexion::CloseConnection() {
|
||||||
m_Socket.Disconnect();
|
m_Socket.Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
Connexion::~Connexion() {
|
Connexion::~Connexion() {
|
||||||
|
|||||||
@@ -9,251 +9,252 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
bool Mob::IsImmuneTo(TowerType type) {
|
bool Mob::IsImmuneTo(TowerType type) {
|
||||||
return std::find(GetTowerImmunities().begin(), GetTowerImmunities().end(), type) != GetTowerImmunities().end();
|
return std::find(GetTowerImmunities().begin(), GetTowerImmunities().end(), type) != GetTowerImmunities().end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::IsImmuneTo(EffectType type) {
|
bool Mob::IsImmuneTo(EffectType type) {
|
||||||
return std::find(GetEffectImmunities().begin(), GetEffectImmunities().end(), type) != GetEffectImmunities().end();
|
return std::find(GetEffectImmunities().begin(), GetEffectImmunities().end(), type) != GetEffectImmunities().end();
|
||||||
}
|
}
|
||||||
|
|
||||||
EffectDuration& Mob::GetEffect(EffectType effectType) {
|
EffectDuration& Mob::GetEffect(EffectType effectType) {
|
||||||
return *std::find_if(m_Effects.begin(), m_Effects.end(), [&effectType](EffectDuration effect) { return effect.type == effectType;});
|
return *std::find_if(m_Effects.begin(), m_Effects.end(), [&effectType](EffectDuration effect) { return effect.type == effectType;});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::AddEffect(EffectType effectType, float durationSec, Tower* tower) {
|
void Mob::AddEffect(EffectType effectType, float durationSec, Tower* tower) {
|
||||||
if (IsImmuneTo(effectType))
|
if (IsImmuneTo(effectType))
|
||||||
return;
|
return;
|
||||||
if (HasEffect(effectType)) {
|
if (HasEffect(effectType)) {
|
||||||
EffectDuration& effect = GetEffect(effectType);
|
EffectDuration& effect = GetEffect(effectType);
|
||||||
if (effect.duration < durationSec)
|
if (effect.duration < durationSec)
|
||||||
effect.duration = durationSec; // Setting new duration if it's greater then the actual
|
effect.duration = durationSec; // Setting new duration if it's greater then the actual
|
||||||
} else {
|
} else {
|
||||||
m_Effects.push_back({ effectType, durationSec, tower });
|
m_Effects.push_back({ effectType, durationSec, tower });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::AttackCastle(std::uint64_t delta, World* world) {
|
void Mob::AttackCastle(std::uint64_t delta, World* world) {
|
||||||
if (!HasReachedEnemyCastle()) return;
|
if (!HasReachedEnemyCastle()) return;
|
||||||
|
|
||||||
if (m_AttackTimer.Update(delta)) {
|
if (m_AttackTimer.Update(delta)) {
|
||||||
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobCastleDamage, this, m_CastleTarget, GetStats()->GetDamage());
|
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobCastleDamage, this, m_CastleTarget, GetStats()->GetDamage());
|
||||||
m_AttackTimer.ApplyCooldown();
|
m_AttackTimer.ApplyCooldown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::Walk(std::uint64_t delta, World* world) {
|
void Mob::Walk(std::uint64_t delta, World* world) {
|
||||||
float mobWalkSpeed = GetStats()->GetMovementSpeed();
|
float mobWalkSpeed = GetStats()->GetMovementSpeed();
|
||||||
|
|
||||||
float walkAmount = mobWalkSpeed * (static_cast<float>(delta) / 1000.0f);
|
float walkAmount = mobWalkSpeed * (static_cast<float>(delta) / 1000.0f);
|
||||||
|
|
||||||
if (HasEffect(EffectType::Slowness))
|
if (HasEffect(EffectType::Slowness))
|
||||||
walkAmount *= 0.70; // walk 30% slower
|
walkAmount *= 0.70; // walk 30% slower
|
||||||
|
|
||||||
switch (GetDirection()) {
|
switch (GetDirection()) {
|
||||||
case Direction::NegativeX: {
|
case Direction::NegativeX: {
|
||||||
SetCenterX(GetCenterX() - walkAmount);
|
SetCenterX(GetCenterX() - walkAmount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Direction::PositiveX: {
|
case Direction::PositiveX: {
|
||||||
SetCenterX(GetCenterX() + walkAmount);
|
SetCenterX(GetCenterX() + walkAmount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Direction::NegativeY: {
|
case Direction::NegativeY: {
|
||||||
SetCenterY(GetCenterY() - walkAmount);
|
SetCenterY(GetCenterY() - walkAmount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Direction::PositiveY: {
|
case Direction::PositiveY: {
|
||||||
SetCenterY(GetCenterY() + walkAmount);
|
SetCenterY(GetCenterY() + walkAmount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::Move(std::uint64_t delta, World* world) {
|
void Mob::Move(std::uint64_t delta, World* world) {
|
||||||
TilePtr tile = world->GetTile(GetCenter().GetX(), GetCenter().GetY());
|
TilePtr tile = world->GetTile(GetCenter().GetX(), GetCenter().GetY());
|
||||||
|
|
||||||
if (tile != nullptr && tile->GetType() == TileType::Walk) {
|
if (tile != nullptr && tile->GetType() == TileType::Walk) {
|
||||||
WalkableTilePtr walkTile = std::static_pointer_cast<WalkableTile>(tile);
|
WalkableTilePtr walkTile = std::static_pointer_cast<WalkableTile>(tile);
|
||||||
ChangeDirection(*walkTile, world);
|
ChangeDirection(*walkTile, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasReachedEnemyCastle()) return;
|
if (HasReachedEnemyCastle()) return;
|
||||||
|
|
||||||
Walk(delta, world);
|
Walk(delta, world);
|
||||||
|
|
||||||
TeamColor mobTeam = world->GetPlayerById(GetSender())->GetTeamColor();
|
TeamColor mobTeam = world->GetPlayerById(GetSender())->GetTeamColor();
|
||||||
|
|
||||||
TeamCastle* enemyCastle = nullptr;
|
TeamCastle* enemyCastle = nullptr;
|
||||||
|
|
||||||
if (mobTeam == TeamColor::Red) {
|
if (mobTeam == TeamColor::Red) {
|
||||||
enemyCastle = &world->GetBlueTeam().GetCastle();
|
enemyCastle = &world->GetBlueTeam().GetCastle();
|
||||||
} else if (mobTeam == TeamColor::Blue) {
|
} else if (mobTeam == TeamColor::Blue) {
|
||||||
enemyCastle = &world->GetRedTeam().GetCastle();
|
enemyCastle = &world->GetRedTeam().GetCastle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsTouchingCastle(*enemyCastle)) {
|
if (IsTouchingCastle(*enemyCastle)) {
|
||||||
MoveBack(*enemyCastle, world);
|
MoveBack(*enemyCastle, world);
|
||||||
SetMobReachedCastle(enemyCastle);
|
SetMobReachedCastle(enemyCastle);
|
||||||
|
|
||||||
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobTouchCastle, this, enemyCastle);
|
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobTouchCastle, this, enemyCastle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::MoveBack(const TeamCastle& enemyCastle, World* world) {
|
void Mob::MoveBack(const TeamCastle& enemyCastle, World* world) {
|
||||||
switch (GetDirection()) {
|
switch (GetDirection()) {
|
||||||
case Direction::NegativeX: {
|
case Direction::NegativeX: {
|
||||||
SetCenterX(enemyCastle.GetBottomRight().GetX() + GetWidth() / 2.0f);
|
SetCenterX(enemyCastle.GetBottomRight().GetX() + GetWidth() / 2.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Direction::PositiveX: {
|
case Direction::PositiveX: {
|
||||||
SetCenterX(enemyCastle.GetTopLeft().GetX() - GetWidth() / 2.0f);
|
SetCenterX(enemyCastle.GetTopLeft().GetX() - GetWidth() / 2.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Direction::NegativeY: {
|
case Direction::NegativeY: {
|
||||||
SetCenterY(enemyCastle.GetBottomRight().GetY() + GetHeight() / 2.0f);
|
SetCenterY(enemyCastle.GetBottomRight().GetY() + GetHeight() / 2.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Direction::PositiveY: {
|
case Direction::PositiveY: {
|
||||||
SetCenterY(enemyCastle.GetTopLeft().GetY() - GetHeight() / 2.0f);
|
SetCenterY(enemyCastle.GetTopLeft().GetY() - GetHeight() / 2.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ChangeDirection(const WalkableTile& tile, World* world) {
|
void Mob::ChangeDirection(const WalkableTile& tile, World* world) {
|
||||||
if (GetDirection() == tile.direction) return;
|
if (GetDirection() == tile.direction) return;
|
||||||
|
|
||||||
float tileX = static_cast<float>(static_cast<std::int32_t>(GetCenterX()));
|
float tileX = static_cast<float>(static_cast<std::int32_t>(GetCenterX()));
|
||||||
float tileY = static_cast<float>(static_cast<std::int32_t>(GetCenterY()));
|
float tileY = static_cast<float>(static_cast<std::int32_t>(GetCenterY()));
|
||||||
|
|
||||||
switch (GetDirection()) {
|
switch (GetDirection()) {
|
||||||
|
|
||||||
case Direction::PositiveY: {
|
case Direction::PositiveY: {
|
||||||
if (tile.direction == Direction::NegativeX) {
|
if (tile.direction == Direction::NegativeX) {
|
||||||
if (GetTileY() > GetTileX()) {
|
if (GetTileY() > GetTileX()) {
|
||||||
SetCenterY(tileY + GetTileX());
|
SetCenterY(tileY + GetTileX());
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
} else { // tile->direction = Direction::PositiveX
|
} else { // tile->direction = Direction::PositiveX
|
||||||
if (GetTileY() > 1 - GetTileX()) {
|
if (GetTileY() > 1 - GetTileX()) {
|
||||||
SetCenterY(tileY + (1 - GetTileX()));
|
SetCenterY(tileY + (1 - GetTileX()));
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Direction::NegativeY: {
|
case Direction::NegativeY: {
|
||||||
if (tile.direction == Direction::PositiveX) {
|
if (tile.direction == Direction::PositiveX) {
|
||||||
if (GetTileY() < GetTileX()) {
|
if (GetTileY() < GetTileX()) {
|
||||||
SetCenterY(tileY + GetTileX());
|
SetCenterY(tileY + GetTileX());
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
} else { // tile.direction = Direction::NegativeX
|
} else { // tile.direction = Direction::NegativeX
|
||||||
if (GetTileY() < 1 - GetTileX()) {
|
if (GetTileY() < 1 - GetTileX()) {
|
||||||
SetCenterY(tileY + (1 - GetTileX()));
|
SetCenterY(tileY + (1 - GetTileX()));
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Direction::PositiveX: {
|
case Direction::PositiveX: {
|
||||||
if (tile.direction == Direction::NegativeY) {
|
if (tile.direction == Direction::NegativeY) {
|
||||||
if (GetTileX() > GetTileY()) {
|
if (GetTileX() > GetTileY()) {
|
||||||
SetCenterX(tileX + GetTileY());
|
SetCenterX(tileX + GetTileY());
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
} else { // tile.direction = Direction::PositiveY
|
} else { // tile.direction = Direction::PositiveY
|
||||||
if (GetTileX() > 1 - GetTileY()) {
|
if (GetTileX() > 1 - GetTileY()) {
|
||||||
SetCenterX(tileX + (1 - GetTileY()));
|
SetCenterX(tileX + (1 - GetTileY()));
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Direction::NegativeX: {
|
case Direction::NegativeX: {
|
||||||
if (tile.direction == Direction::PositiveY) {
|
if (tile.direction == Direction::PositiveY) {
|
||||||
if (GetTileX() < GetTileY()) {
|
if (GetTileX() < GetTileY()) {
|
||||||
SetCenterX(tileX + GetTileY());
|
SetCenterX(tileX + GetTileY());
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
} else { // tile.direction = Direction::NegativeY
|
} else { // tile.direction = Direction::NegativeY
|
||||||
if (GetTileX() < 1 - GetTileY()) {
|
if (GetTileX() < 1 - GetTileY()) {
|
||||||
SetCenterX(tileX + (1 - GetTileY()));
|
SetCenterX(tileX + (1 - GetTileY()));
|
||||||
SetDirection(tile.direction);
|
SetDirection(tile.direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::IsTouchingCastle(const TeamCastle& enemyCastle) const {
|
bool Mob::IsTouchingCastle(const TeamCastle& enemyCastle) const {
|
||||||
return enemyCastle.CollidesWith(*this);
|
return enemyCastle.CollidesWith(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::Tick(std::uint64_t delta, World* world) {
|
void Mob::Tick(std::uint64_t delta, World* world) {
|
||||||
UpdateEffects(delta, world);
|
m_HitCooldown = std::max(0.0f, m_HitCooldown - static_cast<float>(delta / 1000.0f));
|
||||||
Move(delta, world);
|
UpdateEffects(delta, world);
|
||||||
AttackCastle(delta, world);
|
Move(delta, world);
|
||||||
|
AttackCastle(delta, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::UpdateEffects(std::uint64_t delta, World* world) {
|
void Mob::UpdateEffects(std::uint64_t delta, World* world) {
|
||||||
float deltaSec = static_cast<float>(delta / 1000.0f);
|
float deltaSec = static_cast<float>(delta / 1000.0f);
|
||||||
for (std::size_t i = 0; i < m_Effects.size(); i++) {
|
for (std::size_t i = 0; i < m_Effects.size(); i++) {
|
||||||
EffectDuration& effect = m_Effects[i];
|
EffectDuration& effect = m_Effects[i];
|
||||||
effect.duration -= deltaSec;
|
effect.duration -= deltaSec;
|
||||||
if (effect.duration < 0) { // effect has gone
|
if (effect.duration < 0) { // effect has gone
|
||||||
m_Effects.erase(m_Effects.begin() + static_cast<int>(i));
|
m_Effects.erase(m_Effects.begin() + static_cast<int>(i));
|
||||||
switch (effect.type) {
|
switch (effect.type) {
|
||||||
case EffectType::Fire: {
|
case EffectType::Fire: {
|
||||||
m_EffectFireTimer.Reset();
|
m_EffectFireTimer.Reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EffectType::Poison: {
|
case EffectType::Poison: {
|
||||||
m_EffectPoisonTimer.Reset();
|
m_EffectPoisonTimer.Reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EffectType::Heal: {
|
case EffectType::Heal: {
|
||||||
m_EffectHealTimer.Reset();
|
m_EffectHealTimer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HasEffect(EffectType::Fire)) {
|
if (HasEffect(EffectType::Fire)) {
|
||||||
if (m_EffectFireTimer.Update(delta)) {
|
if (m_EffectFireTimer.Update(delta)) {
|
||||||
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, this, 3.0f, GetEffect(EffectType::Fire).tower);
|
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, this, 3.0f, GetEffect(EffectType::Fire).tower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HasEffect(EffectType::Poison)) {
|
if (HasEffect(EffectType::Poison)) {
|
||||||
if (m_EffectPoisonTimer.Update(delta)) {
|
if (m_EffectPoisonTimer.Update(delta)) {
|
||||||
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, this, 1.0f, GetEffect(EffectType::Poison).tower);
|
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, this, 1.0f, GetEffect(EffectType::Poison).tower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HasEffect(EffectType::Heal)) {
|
if (HasEffect(EffectType::Heal)) {
|
||||||
if (m_EffectFireTimer.Update(delta)) {
|
if (m_EffectFireTimer.Update(delta)) {
|
||||||
Heal(10);
|
Heal(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::HasEffect(EffectType type) {
|
bool Mob::HasEffect(EffectType type) {
|
||||||
return std::find_if(m_Effects.begin(), m_Effects.end(), [&type](EffectDuration effect) { return effect.type == type;}) != m_Effects.end();
|
return std::find_if(m_Effects.begin(), m_Effects.end(), [&type](EffectDuration effect) { return effect.type == type;}) != m_Effects.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -262,248 +263,248 @@ bool Mob::HasEffect(EffectType type) {
|
|||||||
typedef std::pair<MobType, std::uint8_t> MobKey;
|
typedef std::pair<MobType, std::uint8_t> MobKey;
|
||||||
|
|
||||||
static const std::map<MobKey, MobStats> MobConstants = {
|
static const std::map<MobKey, MobStats> MobConstants = {
|
||||||
// damage speed size money_cost exp_cost exp_reward max_health
|
// damage speed size money_cost exp_cost exp_reward max_health
|
||||||
{{MobType::Zombie, 1},{MobStats{1, 1.6, {1, 1}, 15, 0, 7, 40}}},
|
{{MobType::Zombie, 1},{MobStats{1, 1.6, {1, 1}, 15, 0, 7, 40}}},
|
||||||
{{MobType::Zombie, 2},{MobStats{1, 1.6, {1, 1}, 18, 88, 9, 56}}},
|
{{MobType::Zombie, 2},{MobStats{1, 1.6, {1, 1}, 18, 88, 9, 56}}},
|
||||||
{{MobType::Zombie, 3},{MobStats{1, 1.6, {1, 1}, 22, 153, 10, 78}}},
|
{{MobType::Zombie, 3},{MobStats{1, 1.6, {1, 1}, 22, 153, 10, 78}}},
|
||||||
{{MobType::Zombie, 4},{MobStats{1.5, 1.6, {1, 1}, 26, 268, 13, 110}}},
|
{{MobType::Zombie, 4},{MobStats{1.5, 1.6, {1, 1}, 26, 268, 13, 110}}},
|
||||||
{{MobType::Zombie, 5},{MobStats{2, 1.6, {1, 1}, 31, 469, 15, 154}}},
|
{{MobType::Zombie, 5},{MobStats{2, 1.6, {1, 1}, 31, 469, 15, 154}}},
|
||||||
|
|
||||||
{{MobType::Spider, 1},{MobStats{1, 1.6, {1, 1}, 25, 100, 15, 80}}},
|
{{MobType::Spider, 1},{MobStats{1, 1.6, {1, 1}, 25, 100, 15, 80}}},
|
||||||
{{MobType::Spider, 2},{MobStats{1, 2, {1, 1}, 30, 175, 16, 112}}},
|
{{MobType::Spider, 2},{MobStats{1, 2, {1, 1}, 30, 175, 16, 112}}},
|
||||||
{{MobType::Spider, 3},{MobStats{1.5, 2, {1, 1}, 36, 306, 18, 157}}},
|
{{MobType::Spider, 3},{MobStats{1.5, 2, {1, 1}, 36, 306, 18, 157}}},
|
||||||
{{MobType::Spider, 4},{MobStats{2.5, 2, {1, 1}, 43, 536, 19, 222}}},
|
{{MobType::Spider, 4},{MobStats{2.5, 2, {1, 1}, 43, 536, 19, 222}}},
|
||||||
{{MobType::Spider, 5},{MobStats{1.5, 2.5, {1, 1}, 52, 938, 22, 307}}},
|
{{MobType::Spider, 5},{MobStats{1.5, 2.5, {1, 1}, 52, 938, 22, 307}}},
|
||||||
|
|
||||||
{{MobType::Skeleton, 1},{MobStats{1, 1.6, {1, 1}, 120, 200, 30, 350}}},
|
{{MobType::Skeleton, 1},{MobStats{1, 1.6, {1, 1}, 120, 200, 30, 350}}},
|
||||||
{{MobType::Skeleton, 2},{MobStats{1, 1.6, {1, 1}, 144, 350, 33, 490}}},
|
{{MobType::Skeleton, 2},{MobStats{1, 1.6, {1, 1}, 144, 350, 33, 490}}},
|
||||||
{{MobType::Skeleton, 3},{MobStats{1, 1.6, {1, 1}, 173, 613, 36, 686}}},
|
{{MobType::Skeleton, 3},{MobStats{1, 1.6, {1, 1}, 173, 613, 36, 686}}},
|
||||||
{{MobType::Skeleton, 4},{MobStats{1.5, 1.6, {1, 1}, 225, 1072, 40, 960}}},
|
{{MobType::Skeleton, 4},{MobStats{1.5, 1.6, {1, 1}, 225, 1072, 40, 960}}},
|
||||||
{{MobType::Skeleton, 5},{MobStats{2, 1.6, {1, 1}, 255, 1876, 43, 1345}}},
|
{{MobType::Skeleton, 5},{MobStats{2, 1.6, {1, 1}, 255, 1876, 43, 1345}}},
|
||||||
|
|
||||||
{{MobType::Pigman, 1},{MobStats{1, 2, {1, 1}, 100, 150, 22, 150}}},
|
{{MobType::Pigman, 1},{MobStats{1, 2, {1, 1}, 100, 150, 22, 150}}},
|
||||||
{{MobType::Pigman, 2},{MobStats{1, 2, {1, 1}, 120, 263, 24, 210}}},
|
{{MobType::Pigman, 2},{MobStats{1, 2, {1, 1}, 120, 263, 24, 210}}},
|
||||||
{{MobType::Pigman, 3},{MobStats{1, 2, {1, 1}, 144, 459, 25, 297}}},
|
{{MobType::Pigman, 3},{MobStats{1, 2, {1, 1}, 144, 459, 25, 297}}},
|
||||||
{{MobType::Pigman, 4},{MobStats{1, 2, {1, 1}, 173, 804, 25, 412}}},
|
{{MobType::Pigman, 4},{MobStats{1, 2, {1, 1}, 173, 804, 25, 412}}},
|
||||||
{{MobType::Pigman, 5},{MobStats{1.5, 2, {1, 1}, 207, 1407, 27, 576}}},
|
{{MobType::Pigman, 5},{MobStats{1.5, 2, {1, 1}, 207, 1407, 27, 576}}},
|
||||||
|
|
||||||
{{MobType::Creeper, 1},{MobStats{1, 2, {1, 1}, 250, 325, 46, 350}}},
|
{{MobType::Creeper, 1},{MobStats{1, 2, {1, 1}, 250, 325, 46, 350}}},
|
||||||
{{MobType::Creeper, 2},{MobStats{1, 2, {1, 1}, 290, 550, 49, 460}}},
|
{{MobType::Creeper, 2},{MobStats{1, 2, {1, 1}, 290, 550, 49, 460}}},
|
||||||
{{MobType::Creeper, 3},{MobStats{2, 2, {1, 1}, 350, 800, 55, 630}}},
|
{{MobType::Creeper, 3},{MobStats{2, 2, {1, 1}, 350, 800, 55, 630}}},
|
||||||
{{MobType::Creeper, 4},{MobStats{3, 2, {1, 1}, 420, 1300, 61, 900}}},
|
{{MobType::Creeper, 4},{MobStats{3, 2, {1, 1}, 420, 1300, 61, 900}}},
|
||||||
{{MobType::Creeper, 5},{MobStats{4, 2, {1, 1}, 510, 1850, 67, 1250}}},
|
{{MobType::Creeper, 5},{MobStats{4, 2, {1, 1}, 510, 1850, 67, 1250}}},
|
||||||
|
|
||||||
{{MobType::Silverfish, 1},{MobStats{1, 1.6, {1, 1}, 38, 125, 18, 120}}},
|
{{MobType::Silverfish, 1},{MobStats{1, 1.6, {1, 1}, 38, 125, 18, 120}}},
|
||||||
{{MobType::Silverfish, 2},{MobStats{1, 1.6, {1, 1}, 50, 230, 19, 170}}},
|
{{MobType::Silverfish, 2},{MobStats{1, 1.6, {1, 1}, 50, 230, 19, 170}}},
|
||||||
{{MobType::Silverfish, 3},{MobStats{1, 1.6, {1, 1}, 75, 340, 25, 225}}},
|
{{MobType::Silverfish, 3},{MobStats{1, 1.6, {1, 1}, 75, 340, 25, 225}}},
|
||||||
{{MobType::Silverfish, 4},{MobStats{1.5, 1.6, {1, 1}, 170, 700, 33, 310}}},
|
{{MobType::Silverfish, 4},{MobStats{1.5, 1.6, {1, 1}, 170, 700, 33, 310}}},
|
||||||
{{MobType::Silverfish, 5},{MobStats{1.5, 1.6, {1, 1}, 200, 1800, 36, 390}}},
|
{{MobType::Silverfish, 5},{MobStats{1.5, 1.6, {1, 1}, 200, 1800, 36, 390}}},
|
||||||
|
|
||||||
{{MobType::Blaze, 1},{MobStats{1, 1.6, {1, 1}, 500, 500, 105, 410}}},
|
{{MobType::Blaze, 1},{MobStats{1, 1.6, {1, 1}, 500, 500, 105, 410}}},
|
||||||
{{MobType::Blaze, 2},{MobStats{1, 1.6, {1, 1}, 600, 875, 111, 574}}},
|
{{MobType::Blaze, 2},{MobStats{1, 1.6, {1, 1}, 600, 875, 111, 574}}},
|
||||||
{{MobType::Blaze, 3},{MobStats{1, 1.6, {1, 1}, 720, 1531, 115, 804}}},
|
{{MobType::Blaze, 3},{MobStats{1, 1.6, {1, 1}, 720, 1531, 115, 804}}},
|
||||||
{{MobType::Blaze, 4},{MobStats{1.5, 1.6, {1, 1}, 864, 2680, 121, 1125}}},
|
{{MobType::Blaze, 4},{MobStats{1.5, 1.6, {1, 1}, 864, 2680, 121, 1125}}},
|
||||||
{{MobType::Blaze, 5},{MobStats{2, 1.6, {1, 1}, 1037, 4689, 127, 1575}}},
|
{{MobType::Blaze, 5},{MobStats{2, 1.6, {1, 1}, 1037, 4689, 127, 1575}}},
|
||||||
|
|
||||||
{{MobType::Witch, 1},{MobStats{1, 1.6, {1, 1}, 150, 300, 37, 300}}},
|
{{MobType::Witch, 1},{MobStats{1, 1.6, {1, 1}, 150, 300, 37, 300}}},
|
||||||
{{MobType::Witch, 2},{MobStats{1, 1.6, {1, 1}, 165, 525, 39, 405}}},
|
{{MobType::Witch, 2},{MobStats{1, 1.6, {1, 1}, 165, 525, 39, 405}}},
|
||||||
{{MobType::Witch, 3},{MobStats{1, 1.6, {1, 1}, 182, 918, 42, 547}}},
|
{{MobType::Witch, 3},{MobStats{1, 1.6, {1, 1}, 182, 918, 42, 547}}},
|
||||||
{{MobType::Witch, 4},{MobStats{1.5, 1.6, {1, 1}, 200, 1606, 43, 738}}},
|
{{MobType::Witch, 4},{MobStats{1.5, 1.6, {1, 1}, 200, 1606, 43, 738}}},
|
||||||
{{MobType::Witch, 5},{MobStats{2, 1.6, {1, 1}, 220, 2810, 45, 996}}},
|
{{MobType::Witch, 5},{MobStats{2, 1.6, {1, 1}, 220, 2810, 45, 996}}},
|
||||||
|
|
||||||
{{MobType::Slime, 1},{MobStats{1, 0.8, {1, 1}, 1500, 1000, 300, 800}}},
|
{{MobType::Slime, 1},{MobStats{1, 0.8, {1, 1}, 1500, 1000, 300, 800}}},
|
||||||
{{MobType::Slime, 2},{MobStats{1.5, 0.8, {1, 1}, 1800, 1750, 314, 880}}},
|
{{MobType::Slime, 2},{MobStats{1.5, 0.8, {1, 1}, 1800, 1750, 314, 880}}},
|
||||||
{{MobType::Slime, 3},{MobStats{2, 0.8, {1, 1}, 2160, 3063, 330, 968}}},
|
{{MobType::Slime, 3},{MobStats{2, 0.8, {1, 1}, 2160, 3063, 330, 968}}},
|
||||||
{{MobType::Slime, 4},{MobStats{2.5, 0.8, {1, 1}, 2592, 5359, 348, 1065}}},
|
{{MobType::Slime, 4},{MobStats{2.5, 0.8, {1, 1}, 2592, 5359, 348, 1065}}},
|
||||||
{{MobType::Slime, 5},{MobStats{3, 0.8, {1, 1}, 3110, 9379, 366, 1171}}},
|
{{MobType::Slime, 5},{MobStats{3, 0.8, {1, 1}, 3110, 9379, 366, 1171}}},
|
||||||
|
|
||||||
{{MobType::Giant, 1},{MobStats{10, 0.8, {1, 1}, 4000, 2250, 600, 6250}}},
|
{{MobType::Giant, 1},{MobStats{10, 0.8, {1, 1}, 4000, 2250, 600, 6250}}},
|
||||||
{{MobType::Giant, 2},{MobStats{20, 0.8, {1, 1}, 4500, 4000, 612, 9375}}},
|
{{MobType::Giant, 2},{MobStats{20, 0.8, {1, 1}, 4500, 4000, 612, 9375}}},
|
||||||
{{MobType::Giant, 3},{MobStats{30, 0.8, {1, 1}, 5062, 7250, 624, 14062}}},
|
{{MobType::Giant, 3},{MobStats{30, 0.8, {1, 1}, 5062, 7250, 624, 14062}}},
|
||||||
{{MobType::Giant, 4},{MobStats{40, 0.8, {1, 1}, 5695, 12500, 636, 21093}}},
|
{{MobType::Giant, 4},{MobStats{40, 0.8, {1, 1}, 5695, 12500, 636, 21093}}},
|
||||||
{{MobType::Giant, 5},{MobStats{50, 0.8, {1, 1}, 6407, 22000, 648, 31640}}},
|
{{MobType::Giant, 5},{MobStats{50, 0.8, {1, 1}, 6407, 22000, 648, 31640}}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const MobStats* GetMobStats(MobType type, std::uint8_t level) {
|
const MobStats* GetMobStats(MobType type, std::uint8_t level) {
|
||||||
return &MobConstants.at(MobKey{ type, level });
|
return &MobConstants.at(MobKey{ type, level });
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::map<MobKey, TowerImmunities> MobsTowerImmunities = {
|
static const std::map<MobKey, TowerImmunities> MobsTowerImmunities = {
|
||||||
{{MobType::Zombie, 1},{}},
|
{{MobType::Zombie, 1},{}},
|
||||||
{{MobType::Zombie, 2},{}},
|
{{MobType::Zombie, 2},{}},
|
||||||
{{MobType::Zombie, 3},{}},
|
{{MobType::Zombie, 3},{}},
|
||||||
{{MobType::Zombie, 4},{}},
|
{{MobType::Zombie, 4},{}},
|
||||||
{{MobType::Zombie, 5},{}},
|
{{MobType::Zombie, 5},{}},
|
||||||
|
|
||||||
{{MobType::Spider, 1},{}},
|
{{MobType::Spider, 1},{}},
|
||||||
{{MobType::Spider, 2},{}},
|
{{MobType::Spider, 2},{}},
|
||||||
{{MobType::Spider, 3},{}},
|
{{MobType::Spider, 3},{}},
|
||||||
{{MobType::Spider, 4},{TowerType::Archer, TowerType::Artillery, TowerType::Leach, TowerType::Necromancer, TowerType::Poison, TowerType::Quake, TowerType::Sorcerer, TowerType::Turret, TowerType::Zeus}},
|
{{MobType::Spider, 4},{TowerType::Archer, TowerType::Artillery, TowerType::Leach, TowerType::Necromancer, TowerType::Poison, TowerType::Quake, TowerType::Sorcerer, TowerType::Turret, TowerType::Zeus}},
|
||||||
{{MobType::Spider, 5},{TowerType::Archer, TowerType::Artillery, TowerType::Leach, TowerType::Necromancer, TowerType::Poison, TowerType::Quake, TowerType::Sorcerer, TowerType::Turret, TowerType::Zeus}},
|
{{MobType::Spider, 5},{TowerType::Archer, TowerType::Artillery, TowerType::Leach, TowerType::Necromancer, TowerType::Poison, TowerType::Quake, TowerType::Sorcerer, TowerType::Turret, TowerType::Zeus}},
|
||||||
|
|
||||||
{{MobType::Skeleton, 1},{}},
|
{{MobType::Skeleton, 1},{}},
|
||||||
{{MobType::Skeleton, 2},{}},
|
{{MobType::Skeleton, 2},{}},
|
||||||
{{MobType::Skeleton, 3},{}},
|
{{MobType::Skeleton, 3},{}},
|
||||||
{{MobType::Skeleton, 4},{}},
|
{{MobType::Skeleton, 4},{}},
|
||||||
{{MobType::Skeleton, 5},{}},
|
{{MobType::Skeleton, 5},{}},
|
||||||
|
|
||||||
{{MobType::Pigman, 1},{TowerType::Zeus}},
|
{{MobType::Pigman, 1},{TowerType::Zeus}},
|
||||||
{{MobType::Pigman, 2},{TowerType::Zeus}},
|
{{MobType::Pigman, 2},{TowerType::Zeus}},
|
||||||
{{MobType::Pigman, 3},{TowerType::Zeus}},
|
{{MobType::Pigman, 3},{TowerType::Zeus}},
|
||||||
{{MobType::Pigman, 4},{TowerType::Zeus}},
|
{{MobType::Pigman, 4},{TowerType::Zeus}},
|
||||||
{{MobType::Pigman, 5},{TowerType::Zeus}},
|
{{MobType::Pigman, 5},{TowerType::Zeus}},
|
||||||
|
|
||||||
{{MobType::Creeper, 1},{}},
|
{{MobType::Creeper, 1},{}},
|
||||||
{{MobType::Creeper, 2},{}},
|
{{MobType::Creeper, 2},{}},
|
||||||
{{MobType::Creeper, 3},{}},
|
{{MobType::Creeper, 3},{}},
|
||||||
{{MobType::Creeper, 4},{}},
|
{{MobType::Creeper, 4},{}},
|
||||||
{{MobType::Creeper, 5},{}},
|
{{MobType::Creeper, 5},{}},
|
||||||
|
|
||||||
{{MobType::Silverfish, 1},{}},
|
{{MobType::Silverfish, 1},{}},
|
||||||
{{MobType::Silverfish, 2},{}},
|
{{MobType::Silverfish, 2},{}},
|
||||||
{{MobType::Silverfish, 3},{}},
|
{{MobType::Silverfish, 3},{}},
|
||||||
{{MobType::Silverfish, 4},{}},
|
{{MobType::Silverfish, 4},{}},
|
||||||
{{MobType::Silverfish, 5},{}},
|
{{MobType::Silverfish, 5},{}},
|
||||||
|
|
||||||
{{MobType::Blaze, 1},{}},
|
{{MobType::Blaze, 1},{}},
|
||||||
{{MobType::Blaze, 2},{}},
|
{{MobType::Blaze, 2},{}},
|
||||||
{{MobType::Blaze, 3},{}},
|
{{MobType::Blaze, 3},{}},
|
||||||
{{MobType::Blaze, 4},{}},
|
{{MobType::Blaze, 4},{}},
|
||||||
{{MobType::Blaze, 5},{}},
|
{{MobType::Blaze, 5},{}},
|
||||||
|
|
||||||
{{MobType::Witch, 1},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
{{MobType::Witch, 1},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
||||||
{{MobType::Witch, 2},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
{{MobType::Witch, 2},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
||||||
{{MobType::Witch, 3},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
{{MobType::Witch, 3},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
||||||
{{MobType::Witch, 4},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
{{MobType::Witch, 4},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
||||||
{{MobType::Witch, 5},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
{{MobType::Witch, 5},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}},
|
||||||
|
|
||||||
{{MobType::Slime, 1},{}},
|
{{MobType::Slime, 1},{}},
|
||||||
{{MobType::Slime, 2},{}},
|
{{MobType::Slime, 2},{}},
|
||||||
{{MobType::Slime, 3},{}},
|
{{MobType::Slime, 3},{}},
|
||||||
{{MobType::Slime, 4},{}},
|
{{MobType::Slime, 4},{}},
|
||||||
{{MobType::Slime, 5},{}},
|
{{MobType::Slime, 5},{}},
|
||||||
|
|
||||||
{{MobType::Giant, 1},{}},
|
{{MobType::Giant, 1},{}},
|
||||||
{{MobType::Giant, 2},{}},
|
{{MobType::Giant, 2},{}},
|
||||||
{{MobType::Giant, 3},{}},
|
{{MobType::Giant, 3},{}},
|
||||||
{{MobType::Giant, 4},{}},
|
{{MobType::Giant, 4},{}},
|
||||||
{{MobType::Giant, 5},{}},
|
{{MobType::Giant, 5},{}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level) {
|
const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level) {
|
||||||
return MobsTowerImmunities.at({ type, level });
|
return MobsTowerImmunities.at({ type, level });
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::map<MobKey, EffectImmunities> MobsEffectImmunities = {
|
static const std::map<MobKey, EffectImmunities> MobsEffectImmunities = {
|
||||||
{{MobType::Zombie, 1},{}},
|
{{MobType::Zombie, 1},{}},
|
||||||
{{MobType::Zombie, 2},{}},
|
{{MobType::Zombie, 2},{}},
|
||||||
{{MobType::Zombie, 3},{}},
|
{{MobType::Zombie, 3},{}},
|
||||||
{{MobType::Zombie, 4},{}},
|
{{MobType::Zombie, 4},{}},
|
||||||
{{MobType::Zombie, 5},{}},
|
{{MobType::Zombie, 5},{}},
|
||||||
|
|
||||||
{{MobType::Spider, 1},{}},
|
{{MobType::Spider, 1},{}},
|
||||||
{{MobType::Spider, 2},{}},
|
{{MobType::Spider, 2},{}},
|
||||||
{{MobType::Spider, 3},{}},
|
{{MobType::Spider, 3},{}},
|
||||||
{{MobType::Spider, 4},{}},
|
{{MobType::Spider, 4},{}},
|
||||||
{{MobType::Spider, 5},{}},
|
{{MobType::Spider, 5},{}},
|
||||||
|
|
||||||
{{MobType::Skeleton, 1},{}},
|
{{MobType::Skeleton, 1},{}},
|
||||||
{{MobType::Skeleton, 2},{}},
|
{{MobType::Skeleton, 2},{}},
|
||||||
{{MobType::Skeleton, 3},{}},
|
{{MobType::Skeleton, 3},{}},
|
||||||
{{MobType::Skeleton, 4},{EffectType::Fire}},
|
{{MobType::Skeleton, 4},{EffectType::Fire}},
|
||||||
{{MobType::Skeleton, 5},{EffectType::Fire}},
|
{{MobType::Skeleton, 5},{EffectType::Fire}},
|
||||||
|
|
||||||
{{MobType::Pigman, 1},{EffectType::Fire}},
|
{{MobType::Pigman, 1},{EffectType::Fire}},
|
||||||
{{MobType::Pigman, 2},{EffectType::Fire}},
|
{{MobType::Pigman, 2},{EffectType::Fire}},
|
||||||
{{MobType::Pigman, 3},{EffectType::Fire}},
|
{{MobType::Pigman, 3},{EffectType::Fire}},
|
||||||
{{MobType::Pigman, 4},{EffectType::Fire}},
|
{{MobType::Pigman, 4},{EffectType::Fire}},
|
||||||
{{MobType::Pigman, 5},{EffectType::Fire}},
|
{{MobType::Pigman, 5},{EffectType::Fire}},
|
||||||
|
|
||||||
{{MobType::Creeper, 1},{}},
|
{{MobType::Creeper, 1},{}},
|
||||||
{{MobType::Creeper, 2},{}},
|
{{MobType::Creeper, 2},{}},
|
||||||
{{MobType::Creeper, 3},{}},
|
{{MobType::Creeper, 3},{}},
|
||||||
{{MobType::Creeper, 4},{}},
|
{{MobType::Creeper, 4},{}},
|
||||||
{{MobType::Creeper, 5},{}},
|
{{MobType::Creeper, 5},{}},
|
||||||
|
|
||||||
{{MobType::Silverfish, 1},{}},
|
{{MobType::Silverfish, 1},{}},
|
||||||
{{MobType::Silverfish, 2},{}},
|
{{MobType::Silverfish, 2},{}},
|
||||||
{{MobType::Silverfish, 3},{}},
|
{{MobType::Silverfish, 3},{}},
|
||||||
{{MobType::Silverfish, 4},{EffectType::Fire}},
|
{{MobType::Silverfish, 4},{EffectType::Fire}},
|
||||||
{{MobType::Silverfish, 5},{EffectType::Fire}},
|
{{MobType::Silverfish, 5},{EffectType::Fire}},
|
||||||
|
|
||||||
{{MobType::Blaze, 1},{EffectType::Fire}},
|
{{MobType::Blaze, 1},{EffectType::Fire}},
|
||||||
{{MobType::Blaze, 2},{EffectType::Fire}},
|
{{MobType::Blaze, 2},{EffectType::Fire}},
|
||||||
{{MobType::Blaze, 3},{EffectType::Fire}},
|
{{MobType::Blaze, 3},{EffectType::Fire}},
|
||||||
{{MobType::Blaze, 4},{EffectType::Fire}},
|
{{MobType::Blaze, 4},{EffectType::Fire}},
|
||||||
{{MobType::Blaze, 5},{EffectType::Fire}},
|
{{MobType::Blaze, 5},{EffectType::Fire}},
|
||||||
|
|
||||||
{{MobType::Witch, 1},{}},
|
{{MobType::Witch, 1},{}},
|
||||||
{{MobType::Witch, 2},{}},
|
{{MobType::Witch, 2},{}},
|
||||||
{{MobType::Witch, 3},{}},
|
{{MobType::Witch, 3},{}},
|
||||||
{{MobType::Witch, 4},{}},
|
{{MobType::Witch, 4},{}},
|
||||||
{{MobType::Witch, 5},{}},
|
{{MobType::Witch, 5},{}},
|
||||||
|
|
||||||
{{MobType::Slime, 1},{}},
|
{{MobType::Slime, 1},{}},
|
||||||
{{MobType::Slime, 2},{}},
|
{{MobType::Slime, 2},{}},
|
||||||
{{MobType::Slime, 3},{}},
|
{{MobType::Slime, 3},{}},
|
||||||
{{MobType::Slime, 4},{EffectType::Fire}},
|
{{MobType::Slime, 4},{EffectType::Fire}},
|
||||||
{{MobType::Slime, 5},{EffectType::Fire}},
|
{{MobType::Slime, 5},{EffectType::Fire}},
|
||||||
|
|
||||||
{{MobType::Giant, 1},{EffectType::Stun}},
|
{{MobType::Giant, 1},{EffectType::Stun}},
|
||||||
{{MobType::Giant, 2},{EffectType::Stun}},
|
{{MobType::Giant, 2},{EffectType::Stun}},
|
||||||
{{MobType::Giant, 3},{EffectType::Stun}},
|
{{MobType::Giant, 3},{EffectType::Stun}},
|
||||||
{{MobType::Giant, 4},{EffectType::Stun}},
|
{{MobType::Giant, 4},{EffectType::Stun}},
|
||||||
{{MobType::Giant, 5},{EffectType::Stun}},
|
{{MobType::Giant, 5},{EffectType::Stun}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level) {
|
const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level) {
|
||||||
return MobsEffectImmunities.at({ type, level });
|
return MobsEffectImmunities.at({ type, level });
|
||||||
}
|
}
|
||||||
|
|
||||||
MobPtr MobFactory::CreateMob(MobID mobId, MobType mobType, std::uint8_t mobLevel, PlayerID mobSender) {
|
MobPtr MobFactory::CreateMob(MobID mobId, MobType mobType, std::uint8_t mobLevel, PlayerID mobSender) {
|
||||||
using MobCreator = std::function<std::shared_ptr<Mob>(MobID, std::uint8_t, PlayerID)>;
|
using MobCreator = std::function<std::shared_ptr<Mob>(MobID, std::uint8_t, PlayerID)>;
|
||||||
|
|
||||||
static const std::map<MobType, MobCreator> mobFactory = {
|
static const std::map<MobType, MobCreator> mobFactory = {
|
||||||
{MobType::Zombie, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Zombie>(id, level, sender);} },
|
{MobType::Zombie, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Zombie>(id, level, sender);} },
|
||||||
{MobType::Spider, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Spider>(id, level, sender);} },
|
{MobType::Spider, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Spider>(id, level, sender);} },
|
||||||
{MobType::Skeleton, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Skeleton>(id, level, sender);} },
|
{MobType::Skeleton, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Skeleton>(id, level, sender);} },
|
||||||
{MobType::Pigman, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<PigMan>(id, level, sender);} },
|
{MobType::Pigman, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<PigMan>(id, level, sender);} },
|
||||||
{MobType::Creeper, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Creeper>(id, level, sender);} },
|
{MobType::Creeper, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Creeper>(id, level, sender);} },
|
||||||
{MobType::Silverfish, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Silverfish>(id, level, sender);} },
|
{MobType::Silverfish, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Silverfish>(id, level, sender);} },
|
||||||
{MobType::Blaze, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Blaze>(id, level, sender);} },
|
{MobType::Blaze, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Blaze>(id, level, sender);} },
|
||||||
{MobType::Witch, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Witch>(id, level, sender);} },
|
{MobType::Witch, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Witch>(id, level, sender);} },
|
||||||
{MobType::Slime, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Slime>(id, level, sender);} },
|
{MobType::Slime, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Slime>(id, level, sender);} },
|
||||||
{MobType::Giant, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Giant>(id, level, sender);} },
|
{MobType::Giant, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared<Giant>(id, level, sender);} },
|
||||||
};
|
};
|
||||||
|
|
||||||
return mobFactory.at(mobType)(mobId, mobLevel, mobSender);
|
return mobFactory.at(mobType)(mobId, mobLevel, mobSender);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MobFactory::GetMobName(MobType type) {
|
std::string MobFactory::GetMobName(MobType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MobType::Zombie:
|
case MobType::Zombie:
|
||||||
return "Zombie";
|
return "Zombie";
|
||||||
case MobType::Spider:
|
case MobType::Spider:
|
||||||
return "Spider";
|
return "Spider";
|
||||||
case MobType::Skeleton:
|
case MobType::Skeleton:
|
||||||
return "Skeleton";
|
return "Skeleton";
|
||||||
case MobType::Pigman:
|
case MobType::Pigman:
|
||||||
return "Pigman";
|
return "Pigman";
|
||||||
case MobType::Creeper:
|
case MobType::Creeper:
|
||||||
return "Creeper";
|
return "Creeper";
|
||||||
case MobType::Silverfish:
|
case MobType::Silverfish:
|
||||||
return "Silverfish";
|
return "Silverfish";
|
||||||
case MobType::Blaze:
|
case MobType::Blaze:
|
||||||
return "Blaze";
|
return "Blaze";
|
||||||
case MobType::Witch:
|
case MobType::Witch:
|
||||||
return "Witch";
|
return "Witch";
|
||||||
case MobType::Slime:
|
case MobType::Slime:
|
||||||
return "Slime";
|
return "Slime";
|
||||||
case MobType::Giant:
|
case MobType::Giant:
|
||||||
return "Giant";
|
return "Giant";
|
||||||
default:
|
default:
|
||||||
return "Unknow";
|
return "Unknow";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ namespace game {
|
|||||||
Team::Team(TeamColor color) : m_Color(color), m_TeamCastle(this) {}
|
Team::Team(TeamColor color) : m_Color(color), m_TeamCastle(this) {}
|
||||||
|
|
||||||
void Team::AddPlayer(Player* newPlayer) {
|
void Team::AddPlayer(Player* newPlayer) {
|
||||||
m_Players.push_back(newPlayer);
|
m_Players.push_back(newPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Team::RemovePlayer(const Player* player) {
|
void Team::RemovePlayer(const Player* player) {
|
||||||
m_Players.erase(std::find(m_Players.begin(), m_Players.end(), player));
|
m_Players.erase(std::find(m_Players.begin(), m_Players.end(), player));
|
||||||
}
|
}
|
||||||
|
|
||||||
TeamColor Team::GetColor() const {
|
TeamColor Team::GetColor() const {
|
||||||
return m_Color;
|
return m_Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t Team::GetPlayerCount() const {
|
std::uint8_t Team::GetPlayerCount() const {
|
||||||
return m_Players.size();
|
return m_Players.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,118 +7,118 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
bool Tower::IsMobInRange(MobPtr mob) {
|
bool Tower::IsMobInRange(MobPtr mob) {
|
||||||
if (mob->IsDead())
|
if (mob->IsDead())
|
||||||
return false;
|
return false;
|
||||||
return mob->CollidesWith(*this);
|
return mob->CollidesWith(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::pair<TowerType, TowerLevel>, TowerStats> TowerConstants = {
|
const std::map<std::pair<TowerType, TowerLevel>, TowerStats> TowerConstants = {
|
||||||
// // rate damage range
|
// // rate damage range
|
||||||
{{TowerType::Archer, {1, TowerPath::Base}}, {2, 5, 10}},
|
{{TowerType::Archer, {1, TowerPath::Base}}, {2, 5, 10}},
|
||||||
|
|
||||||
{{TowerType::Archer, {2, TowerPath::Top}}, {1, 0, 12}},
|
{{TowerType::Archer, {2, TowerPath::Top}}, {1, 0, 12}},
|
||||||
{{TowerType::Archer, {3, TowerPath::Top}}, {1, 0, 13}},
|
{{TowerType::Archer, {3, TowerPath::Top}}, {1, 0, 13}},
|
||||||
{{TowerType::Archer, {4, TowerPath::Top}}, {0.8, 0, 15}},
|
{{TowerType::Archer, {4, TowerPath::Top}}, {0.8, 0, 15}},
|
||||||
|
|
||||||
{{TowerType::Archer, {2, TowerPath::Bottom}}, {2, 10, 12}},
|
{{TowerType::Archer, {2, TowerPath::Bottom}}, {2, 10, 12}},
|
||||||
{{TowerType::Archer, {3, TowerPath::Bottom}}, {2, 10, 13}},
|
{{TowerType::Archer, {3, TowerPath::Bottom}}, {2, 10, 13}},
|
||||||
{{TowerType::Archer, {4, TowerPath::Bottom}}, {2, 10, 15}},
|
{{TowerType::Archer, {4, TowerPath::Bottom}}, {2, 10, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Ice, {1, TowerPath::Base}}, {1, 0, 10}},
|
{{TowerType::Ice, {1, TowerPath::Base}}, {1, 0, 10}},
|
||||||
{{TowerType::Ice, {2, TowerPath::Base}}, {1, 0, 12}},
|
{{TowerType::Ice, {2, TowerPath::Base}}, {1, 0, 12}},
|
||||||
{{TowerType::Ice, {3, TowerPath::Base}}, {1, 0, 13}},
|
{{TowerType::Ice, {3, TowerPath::Base}}, {1, 0, 13}},
|
||||||
{{TowerType::Ice, {4, TowerPath::Base}}, {1, 1, 15}},
|
{{TowerType::Ice, {4, TowerPath::Base}}, {1, 1, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Sorcerer, {1, TowerPath::Base}}, {5, 0, 10}},
|
{{TowerType::Sorcerer, {1, TowerPath::Base}}, {5, 0, 10}},
|
||||||
{{TowerType::Sorcerer, {2, TowerPath::Base}}, {4, 0, 12}},
|
{{TowerType::Sorcerer, {2, TowerPath::Base}}, {4, 0, 12}},
|
||||||
|
|
||||||
{{TowerType::Sorcerer, {3, TowerPath::Top}}, {4, 0, 14}},
|
{{TowerType::Sorcerer, {3, TowerPath::Top}}, {4, 0, 14}},
|
||||||
{{TowerType::Sorcerer, {4, TowerPath::Top}}, {4, 0, 15}},
|
{{TowerType::Sorcerer, {4, TowerPath::Top}}, {4, 0, 15}},
|
||||||
|
|
||||||
{{TowerType::Sorcerer, {3, TowerPath::Bottom}}, {4, 0, 14}},
|
{{TowerType::Sorcerer, {3, TowerPath::Bottom}}, {4, 0, 14}},
|
||||||
{{TowerType::Sorcerer, {4, TowerPath::Bottom}}, {4, 0, 15}},
|
{{TowerType::Sorcerer, {4, TowerPath::Bottom}}, {4, 0, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Zeus, {1, TowerPath::Base}}, {5, 0, 10}},
|
{{TowerType::Zeus, {1, TowerPath::Base}}, {5, 0, 10}},
|
||||||
{{TowerType::Zeus, {2, TowerPath::Base}}, {4, 0, 12}},
|
{{TowerType::Zeus, {2, TowerPath::Base}}, {4, 0, 12}},
|
||||||
|
|
||||||
{{TowerType::Zeus, {3, TowerPath::Top}}, {0, 0, 0}},
|
{{TowerType::Zeus, {3, TowerPath::Top}}, {0, 0, 0}},
|
||||||
{{TowerType::Zeus, {4, TowerPath::Top}}, {0, 0, 0}},
|
{{TowerType::Zeus, {4, TowerPath::Top}}, {0, 0, 0}},
|
||||||
|
|
||||||
{{TowerType::Zeus, {3, TowerPath::Bottom}}, {1.2, 0, 14}},
|
{{TowerType::Zeus, {3, TowerPath::Bottom}}, {1.2, 0, 14}},
|
||||||
{{TowerType::Zeus, {4, TowerPath::Bottom}}, {0.8, 0, 15}},
|
{{TowerType::Zeus, {4, TowerPath::Bottom}}, {0.8, 0, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Mage, {1, TowerPath::Base}}, {5, 0, 10}},
|
{{TowerType::Mage, {1, TowerPath::Base}}, {5, 0, 10}},
|
||||||
{{TowerType::Mage, {2, TowerPath::Base}}, {4, 0, 12}},
|
{{TowerType::Mage, {2, TowerPath::Base}}, {4, 0, 12}},
|
||||||
{{TowerType::Mage, {3, TowerPath::Base}}, {3, 0, 13}},
|
{{TowerType::Mage, {3, TowerPath::Base}}, {3, 0, 13}},
|
||||||
{{TowerType::Mage, {4, TowerPath::Base}}, {1, 30, 15}},
|
{{TowerType::Mage, {4, TowerPath::Base}}, {1, 30, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Artillery, {1, TowerPath::Base}}, {7, 0, 10}},
|
{{TowerType::Artillery, {1, TowerPath::Base}}, {7, 0, 10}},
|
||||||
{{TowerType::Artillery, {2, TowerPath::Base}}, {7, 0, 12}},
|
{{TowerType::Artillery, {2, TowerPath::Base}}, {7, 0, 12}},
|
||||||
|
|
||||||
{{TowerType::Artillery, {3, TowerPath::Top}}, {7, 0, 13}},
|
{{TowerType::Artillery, {3, TowerPath::Top}}, {7, 0, 13}},
|
||||||
{{TowerType::Artillery, {4, TowerPath::Top}}, {7, 0, 15}},
|
{{TowerType::Artillery, {4, TowerPath::Top}}, {7, 0, 15}},
|
||||||
|
|
||||||
{{TowerType::Artillery, {3, TowerPath::Bottom}}, {5, 0, 13}},
|
{{TowerType::Artillery, {3, TowerPath::Bottom}}, {5, 0, 13}},
|
||||||
{{TowerType::Artillery, {4, TowerPath::Bottom}}, {4, 0, 15}},
|
{{TowerType::Artillery, {4, TowerPath::Bottom}}, {4, 0, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Quake, {1, TowerPath::Base}}, {5, 5, 10}},
|
{{TowerType::Quake, {1, TowerPath::Base}}, {5, 5, 10}},
|
||||||
{{TowerType::Quake, {2, TowerPath::Base}}, {4, 7, 12}},
|
{{TowerType::Quake, {2, TowerPath::Base}}, {4, 7, 12}},
|
||||||
{{TowerType::Quake, {3, TowerPath::Base}}, {3, 9, 13}},
|
{{TowerType::Quake, {3, TowerPath::Base}}, {3, 9, 13}},
|
||||||
{{TowerType::Quake, {4, TowerPath::Base}}, {2, 11, 15}},
|
{{TowerType::Quake, {4, TowerPath::Base}}, {2, 11, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Poison, {1, TowerPath::Base}}, {5, 0, 10}},
|
{{TowerType::Poison, {1, TowerPath::Base}}, {5, 0, 10}},
|
||||||
{{TowerType::Poison, {2, TowerPath::Base}}, {5, 0, 12}},
|
{{TowerType::Poison, {2, TowerPath::Base}}, {5, 0, 12}},
|
||||||
|
|
||||||
{{TowerType::Poison, {3, TowerPath::Top}}, {6, 0, 13}},
|
{{TowerType::Poison, {3, TowerPath::Top}}, {6, 0, 13}},
|
||||||
{{TowerType::Poison, {4, TowerPath::Top}}, {5, 0, 15}},
|
{{TowerType::Poison, {4, TowerPath::Top}}, {5, 0, 15}},
|
||||||
|
|
||||||
{{TowerType::Poison, {3, TowerPath::Bottom}}, {5, 10, 13}},
|
{{TowerType::Poison, {3, TowerPath::Bottom}}, {5, 10, 13}},
|
||||||
{{TowerType::Poison, {4, TowerPath::Bottom}}, {6, 20, 15}},
|
{{TowerType::Poison, {4, TowerPath::Bottom}}, {6, 20, 15}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Leach, {1, TowerPath::Base}}, {0, 0, 0}},
|
{{TowerType::Leach, {1, TowerPath::Base}}, {0, 0, 0}},
|
||||||
{{TowerType::Leach, {2, TowerPath::Base}}, {0, 0, 0}},
|
{{TowerType::Leach, {2, TowerPath::Base}}, {0, 0, 0}},
|
||||||
{{TowerType::Leach, {3, TowerPath::Base}}, {0, 0, 0}},
|
{{TowerType::Leach, {3, TowerPath::Base}}, {0, 0, 0}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Turret, {1, TowerPath::Base}}, {0.5, 0, 0}},
|
{{TowerType::Turret, {1, TowerPath::Base}}, {0.5, 0, 0}},
|
||||||
|
|
||||||
{{TowerType::Turret, {2, TowerPath::Top}}, {0, 0, 0}},
|
{{TowerType::Turret, {2, TowerPath::Top}}, {0, 0, 0}},
|
||||||
{{TowerType::Turret, {3, TowerPath::Top}}, {0, 0, 0}},
|
{{TowerType::Turret, {3, TowerPath::Top}}, {0, 0, 0}},
|
||||||
|
|
||||||
{{TowerType::Turret, {2, TowerPath::Bottom}}, {0, 0, 0}},
|
{{TowerType::Turret, {2, TowerPath::Bottom}}, {0, 0, 0}},
|
||||||
{{TowerType::Turret, {3, TowerPath::Bottom}}, {0, 0, 0}},
|
{{TowerType::Turret, {3, TowerPath::Bottom}}, {0, 0, 0}},
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
{{TowerType::Necromancer, {1, TowerPath::Base}}, {2, 0, 11}},
|
{{TowerType::Necromancer, {1, TowerPath::Base}}, {2, 0, 11}},
|
||||||
{{TowerType::Necromancer, {2, TowerPath::Base}}, {1, 0, 14}},
|
{{TowerType::Necromancer, {2, TowerPath::Base}}, {1, 0, 14}},
|
||||||
|
|
||||||
{{TowerType::Necromancer, {3, TowerPath::Top}}, {1, 0, 15}},
|
{{TowerType::Necromancer, {3, TowerPath::Top}}, {1, 0, 15}},
|
||||||
|
|
||||||
{{TowerType::Necromancer, {3, TowerPath::Bottom}}, {0, 30, 0}},
|
{{TowerType::Necromancer, {3, TowerPath::Bottom}}, {0, 30, 0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TowerStats* GetTowerStats(TowerType type, TowerLevel level) {
|
const TowerStats* GetTowerStats(TowerType type, TowerLevel level) {
|
||||||
auto it = TowerConstants.find({ type, level });
|
auto it = TowerConstants.find({ type, level });
|
||||||
if (it == TowerConstants.end()) return nullptr;
|
if (it == TowerConstants.end()) return nullptr;
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -126,21 +126,21 @@ const TowerStats* GetTowerStats(TowerType type, TowerLevel level) {
|
|||||||
|
|
||||||
|
|
||||||
static const std::map<TowerType, TowerInfo> TowerInfoConstants = {
|
static const std::map<TowerType, TowerInfo> TowerInfoConstants = {
|
||||||
{TowerType::Archer, {"Archer", "Shoot projectiles", false}},
|
{TowerType::Archer, {"Archer", "Shoot projectiles", false}},
|
||||||
{TowerType::Artillery, {"Artillery", "Explosion", false}},
|
{TowerType::Artillery, {"Artillery", "Explosion", false}},
|
||||||
{TowerType::Ice, {"Ice", "Slow down enemies", false}},
|
{TowerType::Ice, {"Ice", "Slow down enemies", false}},
|
||||||
{TowerType::Leach, {"Leach", "Shoot projectiles", true}},
|
{TowerType::Leach, {"Leach", "Shoot projectiles", true}},
|
||||||
{TowerType::Mage, {"Mage", "Set enemies on fire", false}},
|
{TowerType::Mage, {"Mage", "Set enemies on fire", false}},
|
||||||
{TowerType::Necromancer, {"Necromancer", "Summon troops", true}},
|
{TowerType::Necromancer, {"Necromancer", "Summon troops", true}},
|
||||||
{TowerType::Poison, {"Poison", "Poison enemies", false}},
|
{TowerType::Poison, {"Poison", "Poison enemies", false}},
|
||||||
{TowerType::Quake, {"Quake", "Shoot projectiles", false}},
|
{TowerType::Quake, {"Quake", "Shoot projectiles", false}},
|
||||||
{TowerType::Sorcerer, {"Sorcerer", "Summon friendly troops", false}},
|
{TowerType::Sorcerer, {"Sorcerer", "Summon friendly troops", false}},
|
||||||
{TowerType::Turret, {"Turret", "Shoot arrow very fast", true}},
|
{TowerType::Turret, {"Turret", "Shoot arrow very fast", true}},
|
||||||
{TowerType::Zeus, {"Zeus", "Strike lightning", false}},
|
{TowerType::Zeus, {"Zeus", "Strike lightning", false}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TowerInfo& GetTowerInfo(TowerType type) {
|
const TowerInfo& GetTowerInfo(TowerType type) {
|
||||||
return TowerInfoConstants.at(type);
|
return TowerInfoConstants.at(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,168 +152,54 @@ namespace TowerFactory {
|
|||||||
using TowerCreator = std::function<std::shared_ptr<Tower>(TowerID, std::int32_t, std::int32_t, PlayerID)>;
|
using TowerCreator = std::function<std::shared_ptr<Tower>(TowerID, std::int32_t, std::int32_t, PlayerID)>;
|
||||||
|
|
||||||
static const std::map<TowerType, TowerCreator> towerFactory = {
|
static const std::map<TowerType, TowerCreator> towerFactory = {
|
||||||
{TowerType::Archer, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<ArcherTower>(id, x, y , builder);} },
|
{TowerType::Archer, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<ArcherTower>(id, x, y , builder);} },
|
||||||
{TowerType::Artillery, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<ArtilleryTower>(id, x, y , builder);} },
|
{TowerType::Artillery, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<ArtilleryTower>(id, x, y , builder);} },
|
||||||
{TowerType::Ice, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<IceTower>(id, x, y , builder);} },
|
{TowerType::Ice, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<IceTower>(id, x, y , builder);} },
|
||||||
{TowerType::Mage, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<MageTower>(id, x, y , builder);} },
|
{TowerType::Mage, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<MageTower>(id, x, y , builder);} },
|
||||||
{TowerType::Poison, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<PoisonTower>(id, x, y , builder);} },
|
{TowerType::Poison, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<PoisonTower>(id, x, y , builder);} },
|
||||||
{TowerType::Quake, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<QuakeTower>(id, x, y , builder);} },
|
{TowerType::Quake, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<QuakeTower>(id, x, y , builder);} },
|
||||||
{TowerType::Sorcerer, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<SorcererTower>(id, x, y , builder);} },
|
{TowerType::Sorcerer, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<SorcererTower>(id, x, y , builder);} },
|
||||||
{TowerType::Zeus, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<ZeusTower>(id, x, y , builder);} },
|
{TowerType::Zeus, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<ZeusTower>(id, x, y , builder);} },
|
||||||
{TowerType::Leach, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<LeachTower>(id, x, y , builder);} },
|
{TowerType::Leach, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<LeachTower>(id, x, y , builder);} },
|
||||||
{TowerType::Necromancer, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<NecromancerTower>(id, x, y , builder);} },
|
{TowerType::Necromancer, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<NecromancerTower>(id, x, y , builder);} },
|
||||||
{TowerType::Turret, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<TurretTower>(id, x, y , builder);} },
|
{TowerType::Turret, [](TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) -> TowerPtr {return std::make_shared<TurretTower>(id, x, y , builder);} },
|
||||||
};
|
};
|
||||||
|
|
||||||
TowerPtr CreateTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) {
|
TowerPtr CreateTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder) {
|
||||||
return towerFactory.at(type)(id, x, y, builder);
|
return towerFactory.at(type)(id, x, y, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetTowerName(TowerType type) {
|
std::string GetTowerName(TowerType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
case TowerType::Archer:
|
case TowerType::Archer:
|
||||||
return "Archer";
|
return "Archer";
|
||||||
case TowerType::Artillery:
|
case TowerType::Artillery:
|
||||||
return "Artillery";
|
return "Artillery";
|
||||||
case TowerType::Ice:
|
case TowerType::Ice:
|
||||||
return "Ice";
|
return "Ice";
|
||||||
case TowerType::Mage:
|
case TowerType::Mage:
|
||||||
return "Mage";
|
return "Mage";
|
||||||
case TowerType::Poison:
|
case TowerType::Poison:
|
||||||
return "Poison";
|
return "Poison";
|
||||||
case TowerType::Quake:
|
case TowerType::Quake:
|
||||||
return "Quake";
|
return "Quake";
|
||||||
case TowerType::Sorcerer:
|
case TowerType::Sorcerer:
|
||||||
return "Sorcerer";
|
return "Sorcerer";
|
||||||
case TowerType::Zeus:
|
case TowerType::Zeus:
|
||||||
return "Zeus";
|
return "Zeus";
|
||||||
case TowerType::Leach:
|
case TowerType::Leach:
|
||||||
return "Leach";
|
return "Leach";
|
||||||
case TowerType::Necromancer:
|
case TowerType::Necromancer:
|
||||||
return "Necromancer";
|
return "Necromancer";
|
||||||
case TowerType::Turret:
|
case TowerType::Turret:
|
||||||
return "Turret";
|
return "Turret";
|
||||||
default:
|
default:
|
||||||
return "Unknow";
|
return "Unknow";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace TowerFactory
|
} // namespace TowerFactory
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ArcherTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
if (m_Timer.Update(delta)) {
|
|
||||||
std::uint8_t arrowsShot = 0;
|
|
||||||
bool explosiveArrows = GetLevel().GetPath() == TowerPath::Bottom;
|
|
||||||
std::uint8_t arrows = explosiveArrows ? 2 : GetLevel().GetLevel();
|
|
||||||
for (MobPtr mob : world->GetMobList()) {
|
|
||||||
if (IsMobInRange(mob)) {
|
|
||||||
world->GetWorldNotifier().NotifyListeners(&WorldListener::OnArcherTowerShot, mob, this);
|
|
||||||
m_Timer.ApplyCooldown();
|
|
||||||
arrowsShot++;
|
|
||||||
if (arrowsShot >= arrows)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IceTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
if (m_Timer.Update(delta)) {
|
|
||||||
float damage = GetStats()->GetDamage();
|
|
||||||
for (MobPtr mob : world->GetMobList()) {
|
|
||||||
if (IsMobInRange(mob)) {
|
|
||||||
mob->AddEffect(EffectType::Slowness, 1, this); // slowness for 1s every second
|
|
||||||
if (damage > 0)
|
|
||||||
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, mob.get(), damage, this);
|
|
||||||
m_Timer.ApplyCooldown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MageTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
if (m_Timer.Update(delta)) {
|
|
||||||
for (MobPtr mob : world->GetMobList()) {
|
|
||||||
if (IsMobInRange(mob)) {
|
|
||||||
mob->AddEffect(EffectType::Fire, GetLevel().GetLevel() * 3, this);
|
|
||||||
m_Timer.ApplyCooldown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PoisonTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
if (m_Timer.Update(delta)) {
|
|
||||||
for (MobPtr mob : world->GetMobList()) {
|
|
||||||
if (IsMobInRange(mob)) {
|
|
||||||
if (GetLevel().GetPath() == TowerPath::Bottom) {
|
|
||||||
world->GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, mob.get(), GetStats()->GetDamage(), this);
|
|
||||||
} else {
|
|
||||||
float durationSec;
|
|
||||||
switch (GetLevel().GetLevel()) {
|
|
||||||
case 1:
|
|
||||||
durationSec = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
durationSec = 15;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
durationSec = 30;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
durationSec = 1e10; // about 3 million hours. It should be enough
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
durationSec = 0; // how did we get there ?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mob->AddEffect(EffectType::Poison, durationSec, this);
|
|
||||||
}
|
|
||||||
m_Timer.ApplyCooldown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuakeTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZeusTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArtilleryTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SorcererTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LeachTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TurretTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void NecromancerTower::Tick(std::uint64_t delta, World* world) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "game/World.h"
|
#include "game/World.h"
|
||||||
#include "protocol/PacketDispatcher.h"
|
#include "protocol/PacketDispatcher.h"
|
||||||
#include "protocol/Protocol.h"
|
#include "protocol/Protocol.h"
|
||||||
|
#include "protocol/packets/WorldBeginDataPacket.h"
|
||||||
|
#include "protocol/packets/WorldDataPacket.h"
|
||||||
#include "game/BaseGame.h"
|
#include "game/BaseGame.h"
|
||||||
#include "misc/Random.h"
|
#include "misc/Random.h"
|
||||||
#include "misc/Compression.h"
|
#include "misc/Compression.h"
|
||||||
@@ -12,312 +14,312 @@ namespace td {
|
|||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
World::World(Game* game) : m_Game(game) {
|
World::World(Game* game) : m_Game(game) {
|
||||||
GetWorldNotifier().BindListener(this);
|
GetWorldNotifier().BindListener(this);
|
||||||
GetMobNotifier().BindListener(this);
|
GetMobNotifier().BindListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TilePtr World::GetTile(std::int32_t x, std::int32_t y) const {
|
TilePtr World::GetTile(std::int32_t x, std::int32_t y) const {
|
||||||
std::int16_t chunkX = x / Chunk::ChunkWidth;
|
std::int16_t chunkX = x / Chunk::ChunkWidth;
|
||||||
std::int16_t chunkY = y / Chunk::ChunkHeight;
|
std::int16_t chunkY = y / Chunk::ChunkHeight;
|
||||||
|
|
||||||
std::uint16_t subChunkX = std::abs(x % Chunk::ChunkWidth);
|
std::uint16_t subChunkX = std::abs(x % Chunk::ChunkWidth);
|
||||||
std::uint16_t subChunkY = std::abs(y % Chunk::ChunkHeight);
|
std::uint16_t subChunkY = std::abs(y % Chunk::ChunkHeight);
|
||||||
|
|
||||||
auto chunkIt = m_Chunks.find({ chunkX, chunkY });
|
auto chunkIt = m_Chunks.find({ chunkX, chunkY });
|
||||||
if (chunkIt == m_Chunks.end())
|
if (chunkIt == m_Chunks.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
ChunkPtr chunk = chunkIt->second;
|
ChunkPtr chunk = chunkIt->second;
|
||||||
|
|
||||||
return GetTilePtr(chunk->GetTileIndex(subChunkY * Chunk::ChunkWidth + subChunkX));
|
return GetTilePtr(chunk->GetTileIndex(subChunkY * Chunk::ChunkWidth + subChunkX));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::LoadMap(const protocol::WorldBeginDataPacket* worldHeader) {
|
bool World::LoadMap(const protocol::WorldBeginDataPacket* worldHeader) {
|
||||||
m_TowerPlacePalette = worldHeader->GetTowerTilePalette();
|
m_TowerPlacePalette = worldHeader->GetTowerTilePalette();
|
||||||
m_WalkablePalette = worldHeader->GetWalkableTileColor();
|
m_WalkablePalette = worldHeader->GetWalkableTileColor();
|
||||||
m_DecorationPalette = worldHeader->GetDecorationPalette();
|
m_DecorationPalette = worldHeader->GetDecorationPalette();
|
||||||
m_Background = worldHeader->GetBackgroundColor();
|
m_Background = worldHeader->GetBackgroundColor();
|
||||||
|
|
||||||
GetRedTeam().GetSpawn() = worldHeader->GetRedSpawn();
|
GetRedTeam().GetSpawn() = worldHeader->GetRedSpawn();
|
||||||
GetBlueTeam().GetSpawn() = worldHeader->GetBlueSpawn();
|
GetBlueTeam().GetSpawn() = worldHeader->GetBlueSpawn();
|
||||||
|
|
||||||
m_SpawnColorPalette = worldHeader->GetSpawnPalette();
|
m_SpawnColorPalette = worldHeader->GetSpawnPalette();
|
||||||
|
|
||||||
GetRedTeam().GetCastle() = worldHeader->GetRedCastle();
|
GetRedTeam().GetCastle() = worldHeader->GetRedCastle();
|
||||||
GetRedTeam().GetCastle().SetTeam(&GetRedTeam());
|
GetRedTeam().GetCastle().SetTeam(&GetRedTeam());
|
||||||
|
|
||||||
GetBlueTeam().GetCastle() = worldHeader->GetBlueCastle();
|
GetBlueTeam().GetCastle() = worldHeader->GetBlueCastle();
|
||||||
GetBlueTeam().GetCastle().SetTeam(&GetBlueTeam());
|
GetBlueTeam().GetCastle().SetTeam(&GetBlueTeam());
|
||||||
|
|
||||||
m_TilePalette = worldHeader->GetTilePalette();
|
m_TilePalette = worldHeader->GetTilePalette();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::LoadMap(const protocol::WorldDataPacket* worldData) {
|
bool World::LoadMap(const protocol::WorldDataPacket* worldData) {
|
||||||
m_Chunks = worldData->GetChunks();
|
m_Chunks = worldData->GetChunks();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::LoadMapFromFile(const std::string& fileName) {
|
bool World::LoadMapFromFile(const std::string& fileName) {
|
||||||
DataBuffer buffer;
|
DataBuffer buffer;
|
||||||
if (!buffer.ReadFile(fileName)) {
|
if (!buffer.ReadFile(fileName)) {
|
||||||
utils::LOGE(utils::format("Failed to load map from file %s", fileName.c_str()));
|
utils::LOGE(utils::format("Failed to load map from file %s", fileName.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::LOG(utils::format("Read file : %s (File size : %u)", fileName.c_str(), buffer.GetSize()));
|
utils::LOG(utils::format("Read file : %s (File size : %u)", fileName.c_str(), buffer.GetSize()));
|
||||||
|
|
||||||
DataBuffer mapHeaderPacketBuffer = utils::Decompress(buffer);
|
DataBuffer mapHeaderPacketBuffer = utils::Decompress(buffer);
|
||||||
DataBuffer mapDataPacketBuffer = utils::Decompress(buffer);
|
DataBuffer mapDataPacketBuffer = utils::Decompress(buffer);
|
||||||
|
|
||||||
protocol::WorldBeginDataPacket headerPacket;
|
protocol::WorldBeginDataPacket headerPacket;
|
||||||
headerPacket.Deserialize(mapHeaderPacketBuffer);
|
headerPacket.Deserialize(mapHeaderPacketBuffer);
|
||||||
|
|
||||||
protocol::WorldDataPacket dataPacket;
|
protocol::WorldDataPacket dataPacket;
|
||||||
dataPacket.Deserialize(mapDataPacketBuffer);
|
dataPacket.Deserialize(mapDataPacketBuffer);
|
||||||
|
|
||||||
LoadMap(&headerPacket);
|
LoadMap(&headerPacket);
|
||||||
LoadMap(&dataPacket);
|
LoadMap(&dataPacket);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::SaveMap(const std::string& fileName) const {
|
bool World::SaveMap(const std::string& fileName) const {
|
||||||
protocol::WorldBeginDataPacket headerPacket(this);
|
protocol::WorldBeginDataPacket headerPacket(this);
|
||||||
protocol::WorldDataPacket dataPacket(this);
|
protocol::WorldDataPacket dataPacket(this);
|
||||||
|
|
||||||
DataBuffer mapHeaderCompressed = utils::Compress(headerPacket.Serialize(false));
|
DataBuffer mapHeaderCompressed = utils::Compress(headerPacket.Serialize(false));
|
||||||
DataBuffer mapDataCompressed = utils::Compress(dataPacket.Serialize(false));
|
DataBuffer mapDataCompressed = utils::Compress(dataPacket.Serialize(false));
|
||||||
|
|
||||||
utils::LOG(utils::format("Header Packet Size : %u", mapHeaderCompressed.GetSize()));
|
utils::LOG(utils::format("Header Packet Size : %u", mapHeaderCompressed.GetSize()));
|
||||||
utils::LOG(utils::format("World Data Packet Size : %u", mapDataCompressed.GetSize()));
|
utils::LOG(utils::format("World Data Packet Size : %u", mapDataCompressed.GetSize()));
|
||||||
|
|
||||||
DataBuffer buffer = mapHeaderCompressed << mapDataCompressed;
|
DataBuffer buffer = mapHeaderCompressed << mapDataCompressed;
|
||||||
utils::LOG(utils::format("Total Size : %u", buffer.GetSize()));
|
utils::LOG(utils::format("Total Size : %u", buffer.GetSize()));
|
||||||
return buffer.WriteFile(fileName);
|
return buffer.WriteFile(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::Tick(std::uint64_t delta) {
|
void World::Tick(std::uint64_t delta) {
|
||||||
if (m_Game->GetGameState() != GameState::Game) return;
|
if (m_Game->GetGameState() != GameState::Game) return;
|
||||||
|
|
||||||
TickMobs(delta);
|
TickMobs(delta);
|
||||||
for (TowerPtr tower : m_Towers) {
|
for (TowerPtr tower : m_Towers) {
|
||||||
tower->Tick(delta, this);
|
tower->Tick(delta, this);
|
||||||
}
|
}
|
||||||
CleanDeadMobs();
|
CleanDeadMobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir) {
|
void World::SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir) {
|
||||||
MobPtr mob = MobFactory::CreateMob(id, type, level, sender);
|
MobPtr mob = MobFactory::CreateMob(id, type, level, sender);
|
||||||
mob->SetCenter({ x, y });
|
mob->SetCenter({ x, y });
|
||||||
mob->SetDirection(dir);
|
mob->SetDirection(dir);
|
||||||
m_Mobs.push_back(mob);
|
m_Mobs.push_back(mob);
|
||||||
GetMobNotifier().NotifyListeners(&MobListener::OnMobSpawn, mob.get());
|
GetMobNotifier().NotifyListeners(&MobListener::OnMobSpawn, mob.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TowerPtr World::PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder) {
|
TowerPtr World::PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder) {
|
||||||
TowerPtr tower = TowerFactory::CreateTower(type, id, x, y, builder);
|
TowerPtr tower = TowerFactory::CreateTower(type, id, x, y, builder);
|
||||||
m_Towers.push_back(tower);
|
m_Towers.push_back(tower);
|
||||||
return tower;
|
return tower;
|
||||||
}
|
}
|
||||||
|
|
||||||
TowerPtr World::RemoveTower(TowerID towerId) {
|
TowerPtr World::RemoveTower(TowerID towerId) {
|
||||||
auto it = std::find_if(m_Towers.begin(), m_Towers.end(), [towerId](TowerPtr tower) { return tower->GetID() == towerId;});
|
auto it = std::find_if(m_Towers.begin(), m_Towers.end(), [towerId](TowerPtr tower) { return tower->GetID() == towerId;});
|
||||||
if (it == m_Towers.end()) return nullptr;
|
if (it == m_Towers.end()) return nullptr;
|
||||||
|
|
||||||
TowerPtr tower = *it;
|
TowerPtr tower = *it;
|
||||||
|
|
||||||
m_Towers.erase(it);
|
m_Towers.erase(it);
|
||||||
|
|
||||||
return tower;
|
return tower;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::TickMobs(std::uint64_t delta) {
|
void World::TickMobs(std::uint64_t delta) {
|
||||||
for (MobPtr mob : m_Mobs) {
|
for (MobPtr mob : m_Mobs) {
|
||||||
mob->Tick(delta, this);
|
mob->Tick(delta, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Color* World::GetTileColor(TilePtr tile) const {
|
const Color* World::GetTileColor(TilePtr tile) const {
|
||||||
switch (tile->GetType()) {
|
switch (tile->GetType()) {
|
||||||
case TileType::Tower: {
|
case TileType::Tower: {
|
||||||
TowerTile* towerTile = dynamic_cast<TowerTile*>(tile.get());
|
TowerTile* towerTile = dynamic_cast<TowerTile*>(tile.get());
|
||||||
return &m_TowerPlacePalette[towerTile->color_palette_ref];
|
return &m_TowerPlacePalette[towerTile->color_palette_ref];
|
||||||
}
|
}
|
||||||
case TileType::Walk: {
|
case TileType::Walk: {
|
||||||
return &m_WalkablePalette;
|
return &m_WalkablePalette;
|
||||||
}
|
}
|
||||||
case TileType::Decoration: {
|
case TileType::Decoration: {
|
||||||
DecorationTile* towerTile = dynamic_cast<DecorationTile*>(tile.get());
|
DecorationTile* towerTile = dynamic_cast<DecorationTile*>(tile.get());
|
||||||
return &m_DecorationPalette[towerTile->color_palette_ref];
|
return &m_DecorationPalette[towerTile->color_palette_ref];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID playerID) const {
|
bool World::CanPlaceLittleTower(const Vec2f& worldPos, PlayerID playerID) const {
|
||||||
TilePtr tile = GetTile(worldPos.x, worldPos.y);
|
TilePtr tile = GetTile(worldPos.x, worldPos.y);
|
||||||
const Player& player = m_Game->GetPlayers()[playerID];
|
const Player& player = m_Game->GetPlayers()[playerID];
|
||||||
|
|
||||||
if (tile == nullptr) {
|
if (tile == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile->GetType() == game::TileType::Tower) {
|
if (tile->GetType() == game::TileType::Tower) {
|
||||||
const TowerTile* towerTile = dynamic_cast<TowerTile*>(tile.get());
|
const TowerTile* towerTile = dynamic_cast<TowerTile*>(tile.get());
|
||||||
if (towerTile->team_owner != player.GetTeamColor())
|
if (towerTile->team_owner != player.GetTeamColor())
|
||||||
return false;
|
return false;
|
||||||
for (int x = -1; x < 2; x++) {
|
for (int x = -1; x < 2; x++) {
|
||||||
for (int y = -1; y < 2; y++) {
|
for (int y = -1; y < 2; y++) {
|
||||||
game::TilePtr adjacentTile = GetTile(worldPos.x + x, worldPos.y + y);
|
game::TilePtr adjacentTile = GetTile(worldPos.x + x, worldPos.y + y);
|
||||||
if (adjacentTile == nullptr || adjacentTile->GetType() != game::TileType::Tower || GetTower({ worldPos.x + x, worldPos.y + y }) != nullptr) {
|
if (adjacentTile == nullptr || adjacentTile->GetType() != game::TileType::Tower || GetTower({ worldPos.x + x, worldPos.y + y }) != nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::CanPlaceBigTower(const glm::vec2& worldPos, PlayerID playerID) const {
|
bool World::CanPlaceBigTower(const Vec2f& worldPos, PlayerID playerID) const {
|
||||||
if (!CanPlaceLittleTower(worldPos, playerID)) return false;
|
if (!CanPlaceLittleTower(worldPos, playerID)) return false;
|
||||||
|
|
||||||
TilePtr tile = GetTile(worldPos.x, worldPos.y);
|
TilePtr tile = GetTile(worldPos.x, worldPos.y);
|
||||||
const Player& player = m_Game->GetPlayers()[playerID];
|
const Player& player = m_Game->GetPlayers()[playerID];
|
||||||
|
|
||||||
if (tile == nullptr) {
|
if (tile == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile->GetType() == game::TileType::Tower) {
|
if (tile->GetType() == game::TileType::Tower) {
|
||||||
const TowerTile* towerTile = dynamic_cast<const TowerTile*>(tile.get());
|
const TowerTile* towerTile = dynamic_cast<const TowerTile*>(tile.get());
|
||||||
if (towerTile->team_owner != player.GetTeamColor())
|
if (towerTile->team_owner != player.GetTeamColor())
|
||||||
return false;
|
return false;
|
||||||
for (int x = -2; x < 3; x++) {
|
for (int x = -2; x < 3; x++) {
|
||||||
for (int y = -2; y < 3; y++) {
|
for (int y = -2; y < 3; y++) {
|
||||||
game::TilePtr adjacentTile = GetTile(worldPos.x + x, worldPos.y + y);
|
game::TilePtr adjacentTile = GetTile(worldPos.x + x, worldPos.y + y);
|
||||||
if (adjacentTile == nullptr || adjacentTile->GetType() != game::TileType::Tower || GetTower({ worldPos.x + x, worldPos.y + y }) != nullptr) {
|
if (adjacentTile == nullptr || adjacentTile->GetType() != game::TileType::Tower || GetTower({ worldPos.x + x, worldPos.y + y }) != nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::CleanDeadMobs() {
|
void World::CleanDeadMobs() {
|
||||||
// safely remove mobs when unused
|
// safely remove mobs when unused
|
||||||
for (std::size_t i = 0; i < m_Mobs.size(); i++) {
|
for (std::size_t i = 0; i < m_Mobs.size(); i++) {
|
||||||
MobPtr mob = m_Mobs[i];
|
MobPtr mob = m_Mobs[i];
|
||||||
if (mob->IsDead()) {
|
if (mob->IsDead()) {
|
||||||
m_Mobs.erase(m_Mobs.begin() + static_cast<int>(i));
|
m_Mobs.erase(m_Mobs.begin() + static_cast<int>(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TowerPtr World::GetTower(const glm::vec2& position) const {
|
TowerPtr World::GetTower(const Vec2f& position) const {
|
||||||
for (TowerPtr tower : m_Towers) {
|
for (TowerPtr tower : m_Towers) {
|
||||||
if (tower->GetSize() == TowerSize::Big) {
|
if (tower->GetSize() == TowerSize::Big) {
|
||||||
if (tower->GetCenterX() - 2.5f < position.x && tower->GetCenterX() + 2.5f > position.x &&
|
if (tower->GetCenterX() - 2.5f < position.x && tower->GetCenterX() + 2.5f > position.x &&
|
||||||
tower->GetCenterY() - 2.5f < position.y && tower->GetCenterY() + 2.5f > position.y) {
|
tower->GetCenterY() - 2.5f < position.y && tower->GetCenterY() + 2.5f > position.y) {
|
||||||
return tower;
|
return tower;
|
||||||
}
|
}
|
||||||
} else { // little tower
|
} else { // little tower
|
||||||
if (tower->GetCenterX() - 1.5f < position.x && tower->GetCenterX() + 1.5f > position.x &&
|
if (tower->GetCenterX() - 1.5f < position.x && tower->GetCenterX() + 1.5f > position.x &&
|
||||||
tower->GetCenterY() - 1.5f < position.y && tower->GetCenterY() + 1.5f > position.y) {
|
tower->GetCenterY() - 1.5f < position.y && tower->GetCenterY() + 1.5f > position.y) {
|
||||||
return tower;
|
return tower;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TowerPtr World::GetTowerById(TowerID towerID) {
|
TowerPtr World::GetTowerById(TowerID towerID) {
|
||||||
auto it = std::find_if(m_Towers.begin(), m_Towers.end(), [towerID](TowerPtr tower) { return tower->GetID() == towerID;});
|
auto it = std::find_if(m_Towers.begin(), m_Towers.end(), [towerID](TowerPtr tower) { return tower->GetID() == towerID;});
|
||||||
if (it == m_Towers.end()) return nullptr;
|
if (it == m_Towers.end()) return nullptr;
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::OnArcherTowerShot(MobPtr tarGet, ArcherTower* shooter) {
|
void World::OnArcherTowerShot(MobPtr tarGet, ArcherTower* shooter) {
|
||||||
bool fireArrows = shooter->GetLevel().GetPath() == TowerPath::Bottom;
|
bool fireArrows = shooter->GetLevel().GetPath() == TowerPath::Bottom;
|
||||||
bool explosiveArrows = shooter->GetLevel().GetLevel() == 4 && fireArrows;
|
bool explosiveArrows = shooter->GetLevel().GetLevel() == 4 && fireArrows;
|
||||||
|
|
||||||
GetWorldNotifier().NotifyListeners(&WorldListener::OnArrowShot, tarGet, fireArrows, shooter);
|
GetWorldNotifier().NotifyListeners(&WorldListener::OnArrowShot, tarGet, fireArrows, shooter);
|
||||||
if (explosiveArrows) {
|
if (explosiveArrows) {
|
||||||
GetWorldNotifier().NotifyListeners(&WorldListener::OnExplosion, utils::shape::Circle{ tarGet->GetCenterX(), tarGet->GetCenterY(), ArcherTower::ExplosionRadius }, shooter->GetStats()->GetDamage(), shooter);
|
GetWorldNotifier().NotifyListeners(&WorldListener::OnExplosion, utils::shape::Circle{ tarGet->GetCenterX(), tarGet->GetCenterY(), ArcherTower::ExplosionRadius }, shooter->GetStats()->GetDamage(), shooter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::OnArrowShot(MobPtr tarGet, bool fireArrow, Tower* shooter) {
|
void World::OnArrowShot(MobPtr tarGet, bool fireArrow, Tower* shooter) {
|
||||||
GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, tarGet.get(), shooter->GetStats()->GetDamage(), shooter);
|
GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, tarGet.get(), shooter->GetStats()->GetDamage(), shooter);
|
||||||
if (fireArrow) {
|
if (fireArrow) {
|
||||||
tarGet->AddEffect(EffectType::Fire, ArcherTower::FireDurationSec, shooter);
|
tarGet->AddEffect(EffectType::Fire, ArcherTower::FireDurationSec, shooter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {
|
void World::OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {
|
||||||
for (MobPtr mob : m_Mobs) {
|
for (MobPtr mob : m_Mobs) {
|
||||||
if (mob->IsAlive() && mob->CollidesWith(explosion)) {
|
if (mob->IsAlive() && mob->CollidesWith(explosion)) {
|
||||||
// linear distance damage reduction
|
// linear distance damage reduction
|
||||||
float explosionDamage = mob->Distance(explosion) / explosion.GetRadius() * centerDamage;
|
float explosionDamage = mob->Distance(explosion) / explosion.GetRadius() * centerDamage;
|
||||||
GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, mob.get(), explosionDamage, shooter);
|
GetMobNotifier().NotifyListeners(&MobListener::OnMobDamage, mob.get(), explosionDamage, shooter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {
|
void World::OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {
|
||||||
enemyCastle->Damage(damage);
|
enemyCastle->Damage(damage);
|
||||||
if (enemyCastle->GetLife() <= 0) {
|
if (enemyCastle->GetLife() <= 0) {
|
||||||
m_Game->NotifyListeners(&GameListener::OnGameEnd);
|
m_Game->NotifyListeners(&GameListener::OnGameEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::OnMobDamage(Mob* tarGet, float damage, Tower* source) {
|
void World::OnMobDamage(Mob* tarGet, float damage, Tower* source) {
|
||||||
tarGet->Damage(damage, source);
|
tarGet->Damage(damage, source);
|
||||||
if (tarGet->IsDead()) {
|
if (tarGet->IsDead()) {
|
||||||
GetMobNotifier().NotifyListeners(&MobListener::OnMobDie, tarGet);
|
GetMobNotifier().NotifyListeners(&MobListener::OnMobDie, tarGet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Team& World::GetRedTeam() {
|
Team& World::GetRedTeam() {
|
||||||
return m_Game->GetRedTeam();
|
return m_Game->GetRedTeam();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Team& World::GetRedTeam() const {
|
const Team& World::GetRedTeam() const {
|
||||||
return m_Game->GetRedTeam();
|
return m_Game->GetRedTeam();
|
||||||
}
|
}
|
||||||
|
|
||||||
Team& World::GetBlueTeam() {
|
Team& World::GetBlueTeam() {
|
||||||
return m_Game->GetBlueTeam();
|
return m_Game->GetBlueTeam();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Team& World::GetBlueTeam() const {
|
const Team& World::GetBlueTeam() const {
|
||||||
return m_Game->GetBlueTeam();
|
return m_Game->GetBlueTeam();
|
||||||
}
|
}
|
||||||
|
|
||||||
Team& World::GetTeam(TeamColor team) {
|
Team& World::GetTeam(TeamColor team) {
|
||||||
return m_Game->GetTeam(team);
|
return m_Game->GetTeam(team);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Team& World::GetTeam(TeamColor team) const {
|
const Team& World::GetTeam(TeamColor team) const {
|
||||||
return m_Game->GetTeam(team);
|
return m_Game->GetTeam(team);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Player* World::GetPlayerById(PlayerID id) const {
|
const Player* World::GetPlayerById(PlayerID id) const {
|
||||||
return m_Game->GetPlayerById(id);
|
return m_Game->GetPlayerById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TeamList& World::GetTeams() const {
|
const TeamList& World::GetTeams() const {
|
||||||
return m_Game->GetTeams();
|
return m_Game->GetTeams();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace game
|
} // namespace game
|
||||||
|
|||||||
@@ -1,77 +1,83 @@
|
|||||||
#include "game/client/Client.h"
|
#include "game/client/Client.h"
|
||||||
#include "misc/Format.h"
|
#include "misc/Format.h"
|
||||||
|
|
||||||
|
#include "protocol/packets/DisconnectPacket.h"
|
||||||
|
#include "protocol/packets/PlaceTowerPacket.h"
|
||||||
|
#include "protocol/packets/RemoveTowerPacket.h"
|
||||||
|
#include "protocol/packets/SelectTeamPacket.h"
|
||||||
|
#include "protocol/packets/UpgradeTowerPacket.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
bool Client::Connect(const network::IPAddresses& addresses, std::uint16_t port) {
|
bool Client::Connect(const network::IPAddresses& addresses, std::uint16_t port) {
|
||||||
for (const network::IPAddress& address : addresses) {
|
for (const network::IPAddress& address : addresses) {
|
||||||
if (address.IsValid() && m_Connexion.Connect(address.ToString(), port)) {
|
if (address.IsValid() && m_Connexion.Connect(address.ToString(), port)) {
|
||||||
m_Connected = true;
|
m_Connected = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
utils::LOGE("Failed to connect !");
|
utils::LOGE("Failed to connect !");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SelectTeam(game::TeamColor team) {
|
void Client::SelectTeam(game::TeamColor team) {
|
||||||
if (!m_Connected)
|
if (!m_Connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
protocol::SelectTeamPacket packet(team);
|
protocol::SelectTeamPacket packet(team);
|
||||||
m_Connexion.SendPacket(&packet);
|
m_Connexion.SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::CloseConnection() {
|
void Client::CloseConnection() {
|
||||||
if (!m_Connected)
|
if (!m_Connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_Connected = false;
|
m_Connected = false;
|
||||||
|
|
||||||
protocol::DisconnectPacket packet;
|
protocol::DisconnectPacket packet;
|
||||||
m_Connexion.SendPacket(&packet);
|
m_Connexion.SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Tick(std::uint64_t delta) {
|
void Client::Tick(std::uint64_t delta) {
|
||||||
if (!m_Connected)
|
if (!m_Connected)
|
||||||
return;
|
return;
|
||||||
m_Connected = m_Connexion.UpdateSocket();
|
m_Connected = m_Connexion.UpdateSocket();
|
||||||
if (!m_Connected) {
|
if (!m_Connected) {
|
||||||
utils::LOG(utils::format("Disconnected ! (Reason : %s)", m_Connexion.GetDisconnectReason().c_str()));
|
utils::LOG(utils::format("Disconnected ! (Reason : %s)", m_Connexion.GetDisconnectReason().c_str()));
|
||||||
Reset();
|
Reset();
|
||||||
} else {
|
} else {
|
||||||
m_Game->Tick(delta);
|
m_Game->Tick(delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Render() {
|
void Client::Render() {
|
||||||
m_Game->RenderWorld();
|
m_Game->RenderWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Reset() {
|
void Client::Reset() {
|
||||||
m_Game.reset(0);
|
m_Game.reset(0);
|
||||||
m_Game = std::make_unique<ClientGame>(this);
|
m_Game = std::make_unique<ClientGame>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendMobs(const std::vector<protocol::MobSend>& mobSends) {
|
void Client::SendMobs(const std::vector<protocol::MobSend>& mobSends) {
|
||||||
protocol::SendMobsPacket packet(mobSends);
|
protocol::SendMobsPacket packet(mobSends);
|
||||||
m_Connexion.SendPacket(&packet);
|
m_Connexion.SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::PlaceTower(game::TowerType type, const glm::vec2& position) {
|
void Client::PlaceTower(game::TowerType type, const Vec2f& position) {
|
||||||
protocol::PlaceTowerPacket packet(position.x, position.y, type);
|
protocol::PlaceTowerPacket packet(position.x, position.y, type);
|
||||||
m_Connexion.SendPacket(&packet);
|
m_Connexion.SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::UpgradeTower(game::TowerID tower, game::TowerLevel level) {
|
void Client::UpgradeTower(game::TowerID tower, game::TowerLevel level) {
|
||||||
protocol::UpgradeTowerPacket packet(tower, level);
|
protocol::UpgradeTowerPacket packet(tower, level);
|
||||||
m_Connexion.SendPacket(&packet);
|
m_Connexion.SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::RemoveTower(game::TowerID tower) {
|
void Client::RemoveTower(game::TowerID tower) {
|
||||||
protocol::RemoveTowerPacket packet(tower);
|
protocol::RemoveTowerPacket packet(tower);
|
||||||
m_Connexion.SendPacket(&packet);
|
m_Connexion.SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -1,47 +1,54 @@
|
|||||||
#include "game/client/ClientConnexion.h"
|
#include "game/client/ClientConnexion.h"
|
||||||
#include "render/WorldRenderer.h"
|
#include "render/WorldRenderer.h"
|
||||||
|
|
||||||
|
#include "protocol/packets/ConnectionInfoPacket.h"
|
||||||
|
#include "protocol/packets/DisconnectPacket.h"
|
||||||
|
#include "protocol/packets/KeepAlivePacket.h"
|
||||||
|
#include "protocol/packets/PlayerLoginPacket.h"
|
||||||
|
#include "protocol/packets/ServerTpsPacket.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
ClientConnexion::ClientConnexion() : Connexion(&m_Dispatcher), m_ServerTPS(0) {
|
ClientConnexion::ClientConnexion() : Connexion(&m_Dispatcher), m_ServerTPS(0) {
|
||||||
RegisterHandlers();
|
RegisterHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnexion::RegisterHandlers() {
|
void ClientConnexion::RegisterHandlers() {
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnectionInfo, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnectionInfo, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::ServerTps, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::ServerTps, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
|
void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
|
||||||
protocol::KeepAlivePacket keepAlivePacket(packet->GetAliveID());
|
protocol::KeepAlivePacket keepAlivePacket(packet->GetAliveID());
|
||||||
SendPacket(&keepAlivePacket);
|
SendPacket(&keepAlivePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
|
void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
|
||||||
m_ConnectionID = packet->GetConnectionID();
|
m_ConnectionID = packet->GetConnectionID();
|
||||||
Login();
|
Login();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnexion::HandlePacket(const protocol::ServerTpsPacket* packet) {
|
void ClientConnexion::HandlePacket(const protocol::ServerTpsPacket* packet) {
|
||||||
m_ServerTPS = packet->GetTPS();
|
m_ServerTPS = packet->GetTPS();
|
||||||
m_Ping = utils::GetTime() - packet->GetPacketSendTime();
|
m_ServerMSPT = packet->GetMSPT();
|
||||||
|
m_Ping = utils::GetTime() - packet->GetPacketSendTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnexion::Login() {
|
void ClientConnexion::Login() {
|
||||||
td::protocol::PlayerLoginPacket loginPacket("Persson" + std::to_string(m_ConnectionID));
|
td::protocol::PlayerLoginPacket loginPacket("Persson" + std::to_string(static_cast<unsigned int>(m_ConnectionID)));
|
||||||
SendPacket(&loginPacket);
|
SendPacket(&loginPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClientConnexion::UpdateSocket() {
|
bool ClientConnexion::UpdateSocket() {
|
||||||
return Connexion::UpdateSocket();
|
return Connexion::UpdateSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
|
void ClientConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
|
||||||
m_DisconnectReason = packet->GetReason();
|
m_DisconnectReason = packet->GetReason();
|
||||||
CloseConnection();
|
CloseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -2,116 +2,126 @@
|
|||||||
#include "protocol/PacketDispatcher.h"
|
#include "protocol/PacketDispatcher.h"
|
||||||
#include "game/client/Client.h"
|
#include "game/client/Client.h"
|
||||||
|
|
||||||
|
#include "protocol/packets/ConnectionInfoPacket.h"
|
||||||
|
#include "protocol/packets/PlayerJoinPacket.h"
|
||||||
|
#include "protocol/packets/PlayerListPacket.h"
|
||||||
|
#include "protocol/packets/PlayerLeavePacket.h"
|
||||||
|
#include "protocol/packets/UpdatePlayerTeamPacket.h"
|
||||||
|
#include "protocol/packets/UpdateLobbyTimePacket.h"
|
||||||
|
#include "protocol/packets/UpdateGameStatePacket.h"
|
||||||
|
#include "protocol/packets/UpdateMoneyPacket.h"
|
||||||
|
#include "protocol/packets/UpdateExpPacket.h"
|
||||||
|
#include "protocol/packets/DisconnectPacket.h"
|
||||||
|
#include "protocol/packets/WorldDataPacket.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
ClientGame::ClientGame(Client* client) : protocol::PacketHandler(client->GetConnexion().GetDispatcher()),
|
ClientGame::ClientGame(Client* client) : protocol::PacketHandler(client->GetConnexion().GetDispatcher()),
|
||||||
game::Game(&m_WorldClient), m_Client(client), m_Renderer(client->GetRenderer()), m_WorldClient(this),
|
game::Game(&m_WorldClient), m_Client(client), m_Renderer(client->GetRenderer()), m_WorldClient(this),
|
||||||
m_WorldRenderer(&m_WorldClient, this) {
|
m_WorldRenderer(&m_WorldClient, this) {
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnectionInfo, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnectionInfo, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerJoin, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerJoin, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLeave, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLeave, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdatePlayerTeam, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdatePlayerTeam, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateLobbyTime, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateLobbyTime, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateGameState, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateGameState, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateMoney, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateMoney, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateEXP, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateEXP, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientGame::~ClientGame() {
|
ClientGame::~ClientGame() {
|
||||||
GetDispatcher()->UnregisterHandler(this);
|
GetDispatcher()->UnregisterHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::Tick(std::uint64_t delta) {
|
void ClientGame::Tick(std::uint64_t delta) {
|
||||||
game::Game::Tick(delta);
|
game::Game::Tick(delta);
|
||||||
m_WorldRenderer.Update();
|
m_WorldRenderer.Update();
|
||||||
if (m_GameState == game::GameState::Lobby && m_LobbyTime > 0) {
|
|
||||||
m_LobbyTime -= delta;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
|
||||||
game::Player player(packet->GetPlayerID());
|
game::Player player(packet->GetPlayerID());
|
||||||
player.SetName(packet->GetPlayerName());
|
player.SetName(packet->GetPlayerName());
|
||||||
|
|
||||||
m_Players.insert({ player.GetID(), player });
|
m_Players.insert({ player.GetID(), player });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::PlayerLeavePacket* packet) {
|
void ClientGame::HandlePacket(const protocol::PlayerLeavePacket* packet) {
|
||||||
game::Player* player = &m_Players[packet->GetPlayerID()];
|
game::Player* player = &m_Players[packet->GetPlayerID()];
|
||||||
if (player->GetTeamColor() != game::TeamColor::None) {
|
if (player->GetTeamColor() != game::TeamColor::None) {
|
||||||
m_Teams[(std::size_t)player->GetTeamColor()].RemovePlayer(player);
|
m_Teams[static_cast<std::size_t>(player->GetTeamColor())].RemovePlayer(player);
|
||||||
}
|
}
|
||||||
m_Players.erase(player->GetID());
|
m_Players.erase(player->GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
|
||||||
for (auto pair : packet->GetPlayers()) {
|
for (auto pair : packet->GetPlayers()) {
|
||||||
std::uint8_t playerID = pair.first;
|
std::uint8_t playerID = pair.first;
|
||||||
protocol::PlayerInfo playerInfo = pair.second;
|
protocol::PlayerInfo playerInfo = pair.second;
|
||||||
game::Player player(playerID);
|
game::Player player(playerID);
|
||||||
player.SetName(playerInfo.name);
|
player.SetName(playerInfo.name);
|
||||||
player.SetTeamColor(playerInfo.team);
|
player.SetTeamColor(playerInfo.team);
|
||||||
m_Players.insert({ playerID, player });
|
m_Players.insert({ playerID, player });
|
||||||
if (player.GetTeamColor() != game::TeamColor::None) {
|
if (player.GetTeamColor() != game::TeamColor::None) {
|
||||||
m_Teams[(std::size_t)player.GetTeamColor()].AddPlayer(&m_Players[playerID]);
|
m_Teams[static_cast<std::size_t>(player.GetTeamColor())].AddPlayer(&m_Players[playerID]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_Player = &m_Players[m_ConnexionID];
|
m_Player = &m_Players[m_ConnexionID];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::UpdatePlayerTeamPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::UpdatePlayerTeamPacket* packet) {
|
||||||
game::Player* player = &m_Players[packet->GetPlayerID()];
|
game::Player* player = &m_Players[packet->GetPlayerID()];
|
||||||
if (player->GetTeamColor() == game::TeamColor::None) { //join a team
|
if (player->GetTeamColor() == game::TeamColor::None) { //join a team
|
||||||
GetTeam(packet->GetSelectedTeam()).AddPlayer(player);
|
GetTeam(packet->GetSelectedTeam()).AddPlayer(player);
|
||||||
} else if (packet->GetSelectedTeam() == game::TeamColor::None) { // leave a team
|
} else if (packet->GetSelectedTeam() == game::TeamColor::None) { // leave a team
|
||||||
GetTeam(player->GetTeamColor()).RemovePlayer(player);
|
GetTeam(player->GetTeamColor()).RemovePlayer(player);
|
||||||
} else { // change team
|
} else { // change team
|
||||||
GetTeam(player->GetTeamColor()).RemovePlayer(player);
|
GetTeam(player->GetTeamColor()).RemovePlayer(player);
|
||||||
GetTeam(packet->GetSelectedTeam()).AddPlayer(player);
|
GetTeam(packet->GetSelectedTeam()).AddPlayer(player);
|
||||||
}
|
}
|
||||||
player->SetTeamColor(packet->GetSelectedTeam());
|
player->SetTeamColor(packet->GetSelectedTeam());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::UpdateGameStatePacket* packet) {
|
void ClientGame::HandlePacket(const protocol::UpdateGameStatePacket* packet) {
|
||||||
SetGameState(packet->GetGameState());
|
SetGameState(packet->GetGameState());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
|
||||||
m_ConnexionID = packet->GetConnectionID();
|
m_ConnexionID = packet->GetConnectionID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::UpdateLobbyTimePacket* packet) {
|
void ClientGame::HandlePacket(const protocol::UpdateLobbyTimePacket* packet) {
|
||||||
m_LobbyTime = packet->GetRemainingTime();
|
m_GameStartTime = packet->GetStartTime();
|
||||||
|
m_LobbyStartTime = utils::GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::UpdateMoneyPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::UpdateMoneyPacket* packet) {
|
||||||
m_Player->SetGold(packet->GetGold());
|
m_Player->SetGold(packet->GetGold());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::UpdateExpPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::UpdateExpPacket* packet) {
|
||||||
m_Player->SetExp(packet->GetExp());
|
m_Player->SetExp(packet->GetExp());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::DisconnectPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::DisconnectPacket* packet) {
|
||||||
m_GameState = game::GameState::Disconnected;
|
m_GameState = game::GameState::Disconnected;
|
||||||
m_Renderer->SetBackgroundColor({ 0, 0, 0 });
|
m_Renderer->SetBackgroundColor({ 0, 0, 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::HandlePacket(const protocol::WorldDataPacket* packet) {
|
void ClientGame::HandlePacket(const protocol::WorldDataPacket* packet) {
|
||||||
m_WorldRenderer.LoadModels();
|
m_WorldRenderer.LoadModels();
|
||||||
// set cam pos to player spawn
|
// set cam pos to player spawn
|
||||||
const game::Spawn& spawn = m_World->GetTeam(m_Player->GetTeamColor()).GetSpawn();
|
const game::Spawn& spawn = m_World->GetTeam(m_Player->GetTeamColor()).GetSpawn();
|
||||||
m_WorldRenderer.SetCamPos(spawn.GetCenterX(), spawn.GetCenterY());
|
m_WorldRenderer.SetCamPos(spawn.GetCenterX(), spawn.GetCenterY());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientGame::RenderWorld() {
|
void ClientGame::RenderWorld() {
|
||||||
if (m_GameState == game::GameState::Game || m_GameState == game::GameState::EndGame) {
|
if (m_GameState == game::GameState::Game || m_GameState == game::GameState::EndGame) {
|
||||||
m_WorldRenderer.Render();
|
m_WorldRenderer.Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -3,73 +3,82 @@
|
|||||||
#include "game/client/ClientGame.h"
|
#include "game/client/ClientGame.h"
|
||||||
#include "render/WorldRenderer.h"
|
#include "render/WorldRenderer.h"
|
||||||
|
|
||||||
|
#include "protocol/packets/WorldAddTowerPacket.h"
|
||||||
|
#include "protocol/packets/WorldBeginDataPacket.h"
|
||||||
|
#include "protocol/packets/WorldDataPacket.h"
|
||||||
|
#include "protocol/packets/SpawnMobPacket.h"
|
||||||
|
#include "protocol/packets/UpgradeTowerPacket.h"
|
||||||
|
#include "protocol/packets/RemoveTowerPacket.h"
|
||||||
|
#include "protocol/packets/UpdateCastleLifePacket.h"
|
||||||
|
#include "protocol/packets/UpdateMobStatesPacket.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::PacketHandler(game->GetDispatcher()), m_Game(game) {
|
WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::PacketHandler(game->GetDispatcher()), m_Game(game) {
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldAddTower, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldAddTower, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldBeginData, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldBeginData, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateCastleLife, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateCastleLife, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateMobStates, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateMobStates, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) {
|
||||||
LoadMap(packet);
|
LoadMap(packet);
|
||||||
if (m_Game->GetGameState() == game::GameState::Game) {
|
if (m_Game->GetGameState() == game::GameState::Game) {
|
||||||
const game::Color& backgroundColor = GetBackgroundColor();
|
const Color& backgroundColor = GetBackgroundColor();
|
||||||
m_Game->GetRenderer()->SetBackgroundColor({ static_cast<float>(backgroundColor.r / 255.0f), static_cast<float>(backgroundColor.g / 255.0f),
|
m_Game->GetRenderer()->SetBackgroundColor({ static_cast<float>(backgroundColor.r / 255.0f), static_cast<float>(backgroundColor.g / 255.0f),
|
||||||
static_cast<float>(backgroundColor.b / 255.0f) });
|
static_cast<float>(backgroundColor.b / 255.0f) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::WorldDataPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::WorldDataPacket* packet) {
|
||||||
LoadMap(packet);
|
LoadMap(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::SpawnMobPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::SpawnMobPacket* packet) {
|
||||||
SpawnMobAt(packet->GetMobID(), packet->GetMobType(), packet->GetMobLevel(), packet->GetSender(),
|
SpawnMobAt(packet->GetMobID(), packet->GetMobType(), packet->GetMobLevel(), packet->GetSender(),
|
||||||
packet->GetMobX(), packet->GetMobY(), packet->GetMobDirection());
|
packet->GetMobX(), packet->GetMobY(), packet->GetMobDirection());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::UpgradeTowerPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::UpgradeTowerPacket* packet) {
|
||||||
game::TowerPtr tower = GetTowerById(packet->GetTowerID());
|
game::TowerPtr tower = GetTowerById(packet->GetTowerID());
|
||||||
if (tower == nullptr) return; // this should not happen but who knows ?
|
if (tower == nullptr) return; // this should not happen but who knows ?
|
||||||
tower->Upgrade(packet->GetTowerLevel().GetLevel(), packet->GetTowerLevel().GetPath());
|
tower->Upgrade(packet->GetTowerLevel().GetLevel(), packet->GetTowerLevel().GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) {
|
||||||
game::TowerPtr newTower = PlaceTowerAt(packet->GetTowerID(), packet->GetTowerType(), packet->GetTowerX(), packet->GetTowerY(), packet->GetBuilder());
|
game::TowerPtr newTower = PlaceTowerAt(packet->GetTowerID(), packet->GetTowerType(), packet->GetTowerX(), packet->GetTowerY(), packet->GetBuilder());
|
||||||
|
|
||||||
GetWorldNotifier().NotifyListeners(&WorldListener::OnTowerAdd, newTower);
|
GetWorldNotifier().NotifyListeners(&WorldListener::OnTowerAdd, newTower);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) {
|
||||||
game::TowerPtr tower = RemoveTower(packet->GetTowerID());
|
game::TowerPtr tower = RemoveTower(packet->GetTowerID());
|
||||||
|
|
||||||
if (tower != nullptr) {
|
if (tower != nullptr) {
|
||||||
GetWorldNotifier().NotifyListeners(&WorldListener::OnTowerRemove, tower);
|
GetWorldNotifier().NotifyListeners(&WorldListener::OnTowerRemove, tower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::UpdateMobStatesPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::UpdateMobStatesPacket* packet) {
|
||||||
for (auto mobState : packet->GetMobStates()) {
|
for (auto mobState : packet->GetMobStates()) {
|
||||||
game::MobID mobId = mobState.GetMobId();
|
game::MobID mobId = mobState.GetMobId();
|
||||||
auto it = std::find_if(GetMobList().begin(), GetMobList().end(), [mobId](game::MobPtr mob) { return mob->GetMobID() == mobId; });
|
auto it = std::find_if(GetMobList().begin(), GetMobList().end(), [mobId](game::MobPtr mob) { return mob->GetMobID() == mobId; });
|
||||||
if (it != GetMobList().end()) {
|
if (it != GetMobList().end()) {
|
||||||
game::MobPtr& mob = *it;
|
game::MobPtr& mob = *it;
|
||||||
mob->SetCenter(mobState.GetMobPosition());
|
mob->SetCenter(mobState.GetMobPosition());
|
||||||
mob->SetDirection(mobState.GetMobDirection());
|
mob->SetDirection(mobState.GetMobDirection());
|
||||||
mob->SetHealth(mobState.GetMobLife());
|
mob->SetHealth(mobState.GetMobLife());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::UpdateCastleLifePacket* packet) {
|
void WorldClient::HandlePacket(const protocol::UpdateCastleLifePacket* packet) {
|
||||||
GetTeam(packet->GetTeamColor()).GetCastle().SetLife(packet->GetCastleLife());
|
GetTeam(packet->GetTeamColor()).GetCastle().SetLife(packet->GetCastleLife());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "game/server/Lobby.h"
|
#include "game/server/Lobby.h"
|
||||||
#include "game/server/Server.h"
|
#include "game/server/Server.h"
|
||||||
|
|
||||||
|
#include "protocol/packets/UpdateLobbyTimePacket.h"
|
||||||
|
|
||||||
#include "misc/Time.h"
|
#include "misc/Time.h"
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
@@ -13,17 +15,17 @@ namespace td {
|
|||||||
namespace server {
|
namespace server {
|
||||||
|
|
||||||
/*static constexpr std::uint8_t timeNotifications[] = {
|
/*static constexpr std::uint8_t timeNotifications[] = {
|
||||||
2 * 60, // 2 min
|
2 * 60, // 2 min
|
||||||
60 + 30, // 1 min 30 s
|
60 + 30, // 1 min 30 s
|
||||||
60, // 1 min
|
60, // 1 min
|
||||||
30, // 30 s
|
30, // 30 s
|
||||||
15, // 15 s
|
15, // 15 s
|
||||||
10, // 10 s
|
10, // 10 s
|
||||||
5, // 5 s
|
5, // 5 s
|
||||||
4, // 4 s
|
4, // 4 s
|
||||||
3, // 3 s
|
3, // 3 s
|
||||||
2, // 2 s
|
2, // 2 s
|
||||||
1, // 1 s
|
1, // 1 s
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
Lobby::Lobby(Server* server) : m_Server(server), m_Timer(1000, std::bind(&Lobby::SendTimeRemaining, this)) {
|
Lobby::Lobby(Server* server) : m_Server(server), m_Timer(1000, std::bind(&Lobby::SendTimeRemaining, this)) {
|
||||||
@@ -31,50 +33,55 @@ Lobby::Lobby(Server* server) : m_Server(server), m_Timer(1000, std::bind(&Lobby:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Lobby::Tick() {
|
void Lobby::Tick() {
|
||||||
if (m_GameStarted || m_StartTimerTime == 0)
|
if (m_GameStarted || m_StartTime == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (utils::GetTime() - m_StartTimerTime >= LobbyWaitingTime) {
|
if (utils::GetTime() >= m_StartTime) {
|
||||||
m_Server->GetGame().NotifyListeners(&game::GameListener::OnGameBegin);
|
m_Server->GetGame().NotifyListeners(&game::GameListener::OnGameBegin);
|
||||||
m_GameStarted = true;
|
m_GameStarted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Timer.Update();
|
//m_Timer.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lobby::SendTimeRemaining() {
|
void Lobby::SendTimeRemaining() {
|
||||||
protocol::UpdateLobbyTimePacket packet(LobbyWaitingTime - (utils::GetTime() - m_StartTimerTime)); // converting second to millis
|
protocol::UpdateLobbyTimePacket packet(m_StartTime);
|
||||||
m_Server->BroadcastPacket(&packet);
|
m_Server->BroadcastPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lobby::OnPlayerJoin(std::uint8_t playerID) {
|
void Lobby::OnPlayerJoin(std::uint8_t playerID) {
|
||||||
if (m_GameStarted)
|
if (m_GameStarted)
|
||||||
return;
|
return;
|
||||||
utils::LOG("(Server) Player Joined Lobby !");
|
|
||||||
m_Players.push_back(playerID);
|
utils::LOG("(Server) Player Joined Lobby !");
|
||||||
if (m_Players.size() == MIN_PLAYER_WAITING) { // start timer if a second player join the match
|
m_Players.push_back(playerID);
|
||||||
m_StartTimerTime = utils::GetTime();
|
|
||||||
m_Timer.Reset();
|
if (m_Players.size() == MIN_PLAYER_WAITING) { // start timer if a second player join the match
|
||||||
SendTimeRemaining();
|
m_StartTime = utils::GetTime() + static_cast<std::uint64_t>(LobbyWaitingTime);
|
||||||
}
|
m_Timer.Reset();
|
||||||
|
SendTimeRemaining();
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify player that just arrived
|
||||||
|
protocol::UpdateLobbyTimePacket packet(m_StartTime);
|
||||||
|
m_Server->GetConnexions().at(playerID).SendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lobby::OnPlayerLeave(std::uint8_t playerID) {
|
void Lobby::OnPlayerLeave(std::uint8_t playerID) {
|
||||||
if (m_GameStarted)
|
if (m_GameStarted)
|
||||||
return;
|
return;
|
||||||
utils::LOG("(Server) Player Leaved Lobby !");
|
utils::LOG("(Server) Player Leaved Lobby !");
|
||||||
|
|
||||||
auto it = std::find(m_Players.begin(), m_Players.end(), playerID);
|
auto it = std::find(m_Players.begin(), m_Players.end(), playerID);
|
||||||
if (it == m_Players.end())
|
if (it == m_Players.end())
|
||||||
return;
|
return;
|
||||||
m_Players.erase(it);
|
m_Players.erase(it);
|
||||||
|
|
||||||
if (m_Players.size() == 1) {
|
if (m_Players.size() == 1) {
|
||||||
protocol::UpdateLobbyTimePacket packet(0);
|
m_StartTime = 0; // reset timer if there is only one player left
|
||||||
m_Server->BroadcastPacket(&packet);
|
SendTimeRemaining();
|
||||||
m_StartTimerTime = 0; // reset timer if there is only one player left
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
@@ -1,145 +1,154 @@
|
|||||||
#include "game/server/Server.h"
|
#include "game/server/Server.h"
|
||||||
#include "protocol/PacketFactory.h"
|
#include "protocol/PacketFactory.h"
|
||||||
|
|
||||||
|
#include "protocol/packets/DisconnectPacket.h"
|
||||||
|
#include "protocol/packets/ServerTpsPacket.h"
|
||||||
|
#include "protocol/packets/PlayerLeavePacket.h"
|
||||||
|
|
||||||
#include "misc/Format.h"
|
#include "misc/Format.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace server {
|
namespace server {
|
||||||
|
|
||||||
Server::Server(const std::string& worldFilePath) : m_ServerRunning(false) {
|
Server::Server(const std::string& worldFilePath) : m_ServerRunning(false) {
|
||||||
m_Game.GetWorld()->LoadMapFromFile(worldFilePath);
|
m_Game.GetWorld()->LoadMapFromFile(worldFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server() {
|
Server::~Server() {
|
||||||
if (m_Thread.joinable())
|
if (m_Thread.joinable())
|
||||||
m_Thread.join();
|
m_Thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::StartThread() {
|
void Server::StartThread() {
|
||||||
m_Thread = std::thread([this]() {
|
m_Thread = std::thread([this]() {
|
||||||
std::uint64_t lastTime = td::utils::GetTime();
|
std::uint64_t lastTime = td::utils::GetTime();
|
||||||
while (m_ServerRunning) {
|
while (m_ServerRunning) {
|
||||||
std::uint64_t time = td::utils::GetTime();
|
std::uint64_t time = td::utils::GetTime();
|
||||||
|
|
||||||
std::uint64_t delta = time - lastTime;
|
std::uint64_t delta = time - lastTime;
|
||||||
|
|
||||||
if (delta >= SERVER_TICK) {
|
if (delta >= SERVER_TICK) {
|
||||||
Tick(delta);
|
Tick(delta);
|
||||||
lastTime = td::utils::GetTime();
|
lastTime = td::utils::GetTime();
|
||||||
std::uint64_t sleepTime = SERVER_TICK - (delta - SERVER_TICK);
|
m_TickCounter.SetMSPT(lastTime - time);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
|
std::uint64_t sleepTime = SERVER_TICK - (delta - SERVER_TICK);
|
||||||
}
|
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Clean();
|
Clean();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Close() {
|
void Server::Close() {
|
||||||
StopThread();
|
StopThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::StopThread() {
|
void Server::StopThread() {
|
||||||
m_ServerRunning = false;
|
m_ServerRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::Start(std::uint16_t port) {
|
bool Server::Start(std::uint16_t port) {
|
||||||
if (!m_Listener.Listen(port, 10)) {
|
if (!m_Listener.Listen(port, 10)) {
|
||||||
utils::LOGE(utils::format("Failed to bind port %u !", port));
|
utils::LOGE(utils::format("Failed to bind port %u !", port));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!m_Listener.SetBlocking(false)) {
|
if (!m_Listener.SetBlocking(false)) {
|
||||||
utils::LOGE("Failed to block server socket !");
|
utils::LOGE("Failed to block server socket !");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
utils::LOG(utils::format("Server started at port %u !", port));
|
utils::LOG(utils::format("Server started at port %u !", port));
|
||||||
m_TickCounter.Reset();
|
m_TickCounter.Reset();
|
||||||
m_ServerRunning = true;
|
m_ServerRunning = true;
|
||||||
StartThread();
|
StartThread();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Clean() {
|
void Server::Clean() {
|
||||||
m_Listener.Close();
|
m_Listener.Close();
|
||||||
m_Listener.Destroy();
|
m_Listener.Destroy();
|
||||||
|
|
||||||
m_Connections.clear();
|
m_Connections.clear();
|
||||||
GetPlayers().clear();
|
GetPlayers().clear();
|
||||||
|
|
||||||
utils::LOG("Server successfully stopped !");
|
utils::LOG("Server successfully stopped !");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Stop() {
|
void Server::Stop() {
|
||||||
if (!m_ServerRunning)
|
if (!m_ServerRunning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
protocol::DisconnectPacket packet("Server closed");
|
protocol::DisconnectPacket packet("Server closed");
|
||||||
BroadcastPacket(&packet);
|
BroadcastPacket(&packet);
|
||||||
|
|
||||||
StopThread();
|
StopThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Tick(std::uint64_t delta) {
|
void Server::Tick(std::uint64_t delta) {
|
||||||
Accept();
|
Accept();
|
||||||
UpdateSockets();
|
UpdateSockets();
|
||||||
m_Lobby.Tick();
|
m_Lobby.Tick();
|
||||||
m_Game.Tick(delta);
|
m_Game.Tick(delta);
|
||||||
if (m_TickCounter.Update()) {
|
if (m_TickCounter.Update()) {
|
||||||
protocol::ServerTpsPacket packet(m_TickCounter.GetTPS(), utils::GetTime());
|
protocol::ServerTpsPacket packet(m_TickCounter.GetTPS(), m_TickCounter.GetMSPT(), utils::GetTime());
|
||||||
BroadcastPacket(&packet);
|
BroadcastPacket(&packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Accept() {
|
void Server::Accept() {
|
||||||
static std::uint8_t newPlayerID = 0;
|
static std::uint8_t newPlayerID = 0;
|
||||||
network::TCPSocket newSocket;
|
network::TCPSocket newSocket;
|
||||||
if (m_Listener.Accept(newSocket)) {
|
if (m_Listener.Accept(newSocket)) {
|
||||||
ServerConnexion con(newSocket, newPlayerID);
|
ServerConnexion con(newSocket, newPlayerID);
|
||||||
m_Connections.insert(std::move(ConnexionMap::value_type{ newPlayerID, std::move(con) }));
|
m_Connections.insert(std::move(ConnexionMap::value_type{ newPlayerID, std::move(con) }));
|
||||||
OnPlayerJoin(newPlayerID);
|
OnPlayerJoin(newPlayerID);
|
||||||
m_Connections[newPlayerID].SetServer(this);
|
m_Connections[newPlayerID].SetServer(this);
|
||||||
newPlayerID++;
|
newPlayerID++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::UpdateSockets() {
|
void Server::UpdateSockets() {
|
||||||
std::int16_t closedConnexionID = -1;
|
std::int16_t closedConnexionID = -1;
|
||||||
for (auto& connection : m_Connections) {
|
for (auto& connection : m_Connections) {
|
||||||
ServerConnexion& con = connection.second;
|
ServerConnexion& con = connection.second;
|
||||||
if (con.GetSocketStatus() != network::Socket::Status::Connected) {
|
if (con.GetSocketStatus() != network::Socket::Status::Connected) {
|
||||||
closedConnexionID = connection.first;
|
closedConnexionID = connection.first;
|
||||||
} else {
|
} else {
|
||||||
con.UpdateSocket();
|
con.UpdateSocket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closedConnexionID != -1) {
|
if (closedConnexionID != -1) {
|
||||||
RemoveConnexion(closedConnexionID);
|
RemoveConnexion(closedConnexionID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::BroadcastPacket(const protocol::Packet* packet) {
|
void Server::BroadcastPacket(const protocol::Packet* packet) {
|
||||||
for (auto& connection : m_Connections) {
|
for (auto& connection : m_Connections) {
|
||||||
ServerConnexion& con = connection.second;
|
ServerConnexion& con = connection.second;
|
||||||
con.SendPacket(packet);
|
con.SendPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::RemoveConnexion(std::uint8_t connexionID) {
|
void Server::RemoveConnexion(std::uint8_t connexionID) {
|
||||||
GetPlayers().erase(GetPlayers().find(connexionID));
|
GetPlayers().erase(GetPlayers().find(connexionID));
|
||||||
m_Connections.erase(connexionID);
|
m_Connections.erase(connexionID);
|
||||||
m_Lobby.OnPlayerLeave(connexionID);
|
m_Lobby.OnPlayerLeave(connexionID);
|
||||||
OnPlayerLeave(connexionID);
|
OnPlayerLeave(connexionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::OnPlayerJoin(std::uint8_t id) {
|
void Server::OnPlayerJoin(std::uint8_t id) {
|
||||||
m_Lobby.OnPlayerJoin(id);
|
m_Lobby.OnPlayerJoin(id);
|
||||||
|
|
||||||
GetPlayers().insert({ id, game::Player{id} });
|
GetPlayers().insert({ id, game::Player{id} });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::OnPlayerLeave(std::uint8_t id) {
|
void Server::OnPlayerLeave(std::uint8_t id) {
|
||||||
protocol::PlayerLeavePacket packet(id);
|
protocol::PlayerLeavePacket packet(id);
|
||||||
BroadcastPacket(&packet);
|
BroadcastPacket(&packet);
|
||||||
|
|
||||||
|
if (GetPlayers().empty()) {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user