Compare commits
271 Commits
alpha-0.0.
...
actions
| Author | SHA1 | Date | |
|---|---|---|---|
| 8392a53bcb | |||
| de30c3bc96 | |||
| 4324bad41b | |||
| 7271681175 | |||
| 9afe4e6250 | |||
| ddc658be12 | |||
| 3b99463213 | |||
| b0114e4ddf | |||
| 8fc1b70288 | |||
| 28803c2848 | |||
| 179151c90c | |||
| 0f1947e43e | |||
| 59e449b665 | |||
| 5fff416d42 | |||
| 0b00fd02c2 | |||
| c4810bd878 | |||
| 7c1909584f | |||
| 4b47a44b0d | |||
| 6ba6c0b21d | |||
| b9f14cb830 | |||
| 80baf2b59f | |||
| 8b0b1371e5 | |||
| fbef0cc660 | |||
| 8c181e5353 | |||
| c36db6b15f | |||
| 3c3a68f1d1 | |||
| fb2f1343c8 | |||
| c4143be864 | |||
| 6ca5afe81c | |||
| 6a65358e37 | |||
| aac3410755 | |||
| eff94cf05c | |||
| 5e97a0ac1c | |||
| 6cfa32a2c2 | |||
| 3282af2752 | |||
| 4511676dc6 | |||
| 06f5e3038a | |||
| 9496e03cf0 | |||
| 3afdaccff1 | |||
| 3fdb5ce45e | |||
| 8e9a90259d | |||
| c3eee424b6 | |||
| a4e1d4a84d | |||
| 3b62da6489 | |||
| 6c5d5f4921 | |||
| 2cc571c0ce | |||
| ae84abc14d | |||
| 171005b06a | |||
| cdb6753d52 | |||
| 746f2cd383 | |||
| 4050ef8322 | |||
| dd91750e28 | |||
| edc6f40799 | |||
| bfd22b9de0 | |||
| 695ef540f2 | |||
| 331d95573d | |||
| 26ccf3334d | |||
| 3360f4acdb | |||
| 8ead200eb7 | |||
| d5e24635c7 | |||
| 3defa497b6 | |||
| a241589025 | |||
| 911fe7cc10 | |||
| a6a71cb487 | |||
| 3e8cf5e290 | |||
| c62f114087 | |||
| 237c6d9981 | |||
| ece20e0e1f | |||
| 3eecfa7df1 | |||
| 80bdf130dc | |||
| 4338fd3895 | |||
| 3a334b3227 | |||
| 186ca76345 | |||
| da3439cc03 | |||
| 5a1f71e5c0 | |||
| 93d587d463 | |||
| bad65f89d0 | |||
| 3c04810496 | |||
| ec538c1783 | |||
| 01bd4621b3 | |||
| 2ef4f091f1 | |||
| bc4e1f1f35 | |||
| 7c4ed3910f | |||
| 90c834cc49 | |||
| d23761dc10 | |||
| 3d8fd2e519 | |||
| 4bd32e8d0b | |||
| 09bba12814 | |||
| bb76e9493f | |||
|
|
808ef7b3f6 | ||
|
|
23938a0cb5 | ||
|
|
5631efcf9e | ||
|
|
8e7b446003 | ||
|
|
51ec035490 | ||
| 1f94ae2586 | |||
| 7b8c13612c | |||
| a36716d8e4 | |||
| debf9e974c | |||
| 380ecf3a27 | |||
| b3157be641 | |||
| 1e3b672897 | |||
| d1aa5cd8aa | |||
| dbe91b52fd | |||
| 7ab8c79fdf | |||
| 8f2a22762a | |||
| f0c3325141 | |||
| 1d00e0098a | |||
| ee5a27ac54 | |||
| 49a5a09537 | |||
| f9f80fc4fb | |||
| 4997715672 | |||
| 3fe480d121 | |||
| c46226c1ae | |||
| 8630421734 | |||
| 60b81003c0 | |||
| 7986e55846 | |||
| 0c0fd155ed | |||
| 7f650f282c | |||
| 118a04cd01 | |||
| d529c79150 | |||
| ddbba997e5 | |||
| 50c17e8ed1 | |||
| 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 | ||
| fd2288ac3c | |||
| 660952aed3 | |||
| 243b153309 | |||
| 73fa10d8d6 | |||
| 0b8a7d8db7 | |||
| e2ec9d6a3b | |||
| eb5b3c8ce2 | |||
| ddbba7399d | |||
| 9ce1f4a1a8 | |||
| ea4349af4c | |||
| d6fbb58da8 | |||
| 66376eaeda | |||
| 85eb9bbc32 | |||
| bbb84c0061 | |||
| 2f1161959b | |||
| f506307653 | |||
| 40f0d50991 | |||
| 663ad60ee3 | |||
| 3fbb6acac7 | |||
| 377e98f583 | |||
| ef9712629f | |||
| ed481de03e | |||
| 7d667d9c5e | |||
| 16006adc6e | |||
| 19062b5c77 | |||
| d3c6ff3988 | |||
| 31a0027bfc | |||
| d4b1805998 | |||
| b84f1fd302 | |||
| 98f73f467d | |||
| dc8a4ce947 | |||
| 113a831f39 | |||
| f906aa1bf0 | |||
| 1bbf607b22 | |||
| d5b42caf39 | |||
| d3edc0cb6c | |||
| 87e4e65843 | |||
| 7509cc1bf2 | |||
| 6df59b1487 | |||
| 553b2f6aad | |||
| 916fa0e7c0 | |||
| bc271bc01e | |||
| 97a33e5517 | |||
| bdebabb79e | |||
| 387cff36ad | |||
| 790237a1b5 | |||
| 840d5edbe4 | |||
| 36a9e1921c | |||
| 784c558840 | |||
| 5d366b6f6c | |||
| f70661694b | |||
| 36a1ab0572 | |||
| 409268b604 | |||
| 174d144d26 | |||
| 360258e4cf | |||
| 2148c0050c | |||
| 61166023df | |||
| e7bf22cea6 | |||
| f09f79198d | |||
| 8c19d3cc3c | |||
| 208892d266 | |||
| 4384806cf0 | |||
| 1a091baeaf | |||
| 43f21ffd44 | |||
| 24617c539f | |||
| 4611a198c9 | |||
| d40ffe8f6c | |||
| 384b7ad51e | |||
| fd9b448fa4 | |||
| c4a2b08416 | |||
| a241d7691b | |||
| 0af4cd506c | |||
| 6b5c56b37d | |||
| 1474220a77 | |||
| a802b5cef5 | |||
| 7e91b863da | |||
| 129bb47286 | |||
| e4a9c5f763 | |||
| 78cf2d0f18 | |||
| 00d2b5394f | |||
| 00414abe61 | |||
| cb847d0edd | |||
| 2da0bd9b79 | |||
| cf9633c061 | |||
| 7a6fdc30b6 |
25
.gitea/workflows/linux.yaml
Normal file
25
.gitea/workflows/linux.yaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: Linux arm64
|
||||||
|
run-name: Build And Test
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build:
|
||||||
|
runs-on: ubuntu-test
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Packages cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ github.workspace }}/build/.packages
|
||||||
|
|
||||||
|
- name: XMake config
|
||||||
|
run: xmake f -p linux -y
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: xmake
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: xmake test
|
||||||
56
include/client/Client.h
Normal file
56
include/client/Client.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "client/ClientConnexion.h"
|
||||||
|
#include "client/game/ClientGame.h"
|
||||||
|
|
||||||
|
#include "td/game/Team.h"
|
||||||
|
#include "td/game/Player.h"
|
||||||
|
|
||||||
|
#include "td/protocol/Protocol.h"
|
||||||
|
#include "td/protocol/packets/SendMobsPacket.h"
|
||||||
|
|
||||||
|
#include "client/render/Renderer.h"
|
||||||
|
|
||||||
|
#include "td/network/Network.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class Client {
|
||||||
|
private:
|
||||||
|
render::Renderer* m_Renderer;
|
||||||
|
ClientConnexion m_Connexion;
|
||||||
|
std::unique_ptr<ClientGame> m_Game;
|
||||||
|
bool m_Connected;
|
||||||
|
public:
|
||||||
|
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 ClientConnexion& GetConnexion() const { return m_Connexion; }
|
||||||
|
render::Renderer* GetRenderer() const { return m_Renderer; }
|
||||||
|
|
||||||
|
ClientGame& GetGame() { return *m_Game; }
|
||||||
|
ClientConnexion& GetConnexion() { return m_Connexion; }
|
||||||
|
|
||||||
|
const game::Player* GetPlayer() { return m_Game->GetPlayer(); }
|
||||||
|
|
||||||
|
void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
bool Connect(const network::IPAddresses& addresses, std::uint16_t port);
|
||||||
|
void CloseConnection();
|
||||||
|
|
||||||
|
bool IsConnected() const { return m_Connexion.GetSocketStatus() == network::Socket::Connected; }
|
||||||
|
|
||||||
|
void SelectTeam(game::TeamColor team);
|
||||||
|
void SendMobs(const std::vector<protocol::MobSend>& mobSends);
|
||||||
|
void PlaceTower(game::TowerType type, const Vec2f& position);
|
||||||
|
void UpgradeTower(game::TowerID tower, game::TowerLevel level);
|
||||||
|
void RemoveTower(game::TowerID tower);
|
||||||
|
private:
|
||||||
|
void Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace td
|
||||||
39
include/client/ClientConnexion.h
Normal file
39
include/client/ClientConnexion.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/protocol/PacketHandler.h"
|
||||||
|
#include "td/network/TCPSocket.h"
|
||||||
|
#include "td/network/Connexion.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class ClientConnexion : public protocol::Connexion {
|
||||||
|
private:
|
||||||
|
std::uint8_t m_ConnectionID;
|
||||||
|
std::string m_DisconnectReason;
|
||||||
|
float m_ServerTPS;
|
||||||
|
float m_ServerMSPT;
|
||||||
|
int m_Ping = 0;
|
||||||
|
public:
|
||||||
|
ClientConnexion();
|
||||||
|
|
||||||
|
virtual bool UpdateSocket();
|
||||||
|
|
||||||
|
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::ServerTpsPacket* packet) override;
|
||||||
|
|
||||||
|
const std::string& GetDisconnectReason() const { return m_DisconnectReason; }
|
||||||
|
float GetServerTPS() const { return m_ServerTPS; }
|
||||||
|
float GetServerMSPT() const { return m_ServerMSPT; }
|
||||||
|
int GetServerPing() const { return m_Ping; }
|
||||||
|
|
||||||
|
REMOVE_COPY(ClientConnexion);
|
||||||
|
private:
|
||||||
|
void RegisterHandlers();
|
||||||
|
void Login();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace td
|
||||||
57
include/client/game/ClientGame.h
Normal file
57
include/client/game/ClientGame.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/BaseGame.h"
|
||||||
|
|
||||||
|
#include "td/protocol/PacketHandler.h"
|
||||||
|
|
||||||
|
#include "WorldClient.h"
|
||||||
|
|
||||||
|
#include "client/render/WorldRenderer.h"
|
||||||
|
#include "client/render/Renderer.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
|
||||||
|
class ClientGame : public protocol::PacketHandler, public game::Game {
|
||||||
|
private:
|
||||||
|
Client* m_Client;
|
||||||
|
std::uint8_t m_ConnexionID;
|
||||||
|
std::uint32_t m_LobbyTime = 0;
|
||||||
|
game::Player* m_Player = nullptr;
|
||||||
|
render::Renderer* m_Renderer;
|
||||||
|
client::WorldClient m_WorldClient;
|
||||||
|
render::WorldRenderer m_WorldRenderer;
|
||||||
|
public:
|
||||||
|
ClientGame(Client* client);
|
||||||
|
virtual ~ClientGame();
|
||||||
|
|
||||||
|
virtual void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
|
void RenderWorld();
|
||||||
|
|
||||||
|
std::uint32_t GetLobbyTime() const { return m_LobbyTime; }
|
||||||
|
const game::Player* GetPlayer() const { return m_Player; }
|
||||||
|
const WorldClient& GetWorld() const { return m_WorldClient; }
|
||||||
|
Client* GetClient() const { return m_Client; }
|
||||||
|
|
||||||
|
render::Renderer* GetRenderer() const { return m_Renderer; }
|
||||||
|
WorldClient& GetWorldClient() { return m_WorldClient; }
|
||||||
|
|
||||||
|
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdatePlayerTeamPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdateLobbyTimePacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdateMoneyPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdateExpPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace td
|
||||||
31
include/client/game/WorldClient.h
Normal file
31
include/client/game/WorldClient.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/World.h"
|
||||||
|
#include "td/protocol/PacketHandler.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class ClientGame;
|
||||||
|
|
||||||
|
class WorldClient : public game::World, public protocol::PacketHandler {
|
||||||
|
private:
|
||||||
|
ClientGame* m_Game;
|
||||||
|
public:
|
||||||
|
WorldClient(ClientGame* game);
|
||||||
|
virtual ~WorldClient();
|
||||||
|
|
||||||
|
virtual void HandlePacket(const protocol::WorldBeginDataPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::RemoveMobPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdateMobStatesPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpdateCastleLifePacket* packet) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace td
|
||||||
62
include/client/render/GL.h
Normal file
62
include/client/render/GL.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(TD_IMPL_OPENGL_ES2) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_ES3) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_LOADER_GL3W) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_LOADER_GLEW) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_LOADER_GLAD) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_LOADER_GLBINDING2) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_LOADER_GLBINDING3) \
|
||||||
|
&& !defined(TD_IMPL_OPENGL_LOADER_CUSTOM) \
|
||||||
|
&& !defined(__ANDROID__)
|
||||||
|
|
||||||
|
#if defined(__has_include)
|
||||||
|
|
||||||
|
#if __has_include(<GL/glew.h>)
|
||||||
|
#define TD_IMPL_OPENGL_LOADER_GLEW
|
||||||
|
#elif __has_include(<glad/glad.h>)
|
||||||
|
#define TD_IMPL_OPENGL_LOADER_GLAD
|
||||||
|
#elif __has_include(<GL/gl3w.h>)
|
||||||
|
#define TD_IMPL_OPENGL_LOADER_GL3W
|
||||||
|
#elif __has_include(<glbinding/glbinding.h>)
|
||||||
|
#define TD_IMPL_OPENGL_LOADER_GLBINDING3
|
||||||
|
#elif __has_include(<glbinding/Binding.h>)
|
||||||
|
#define TD_IMPL_OPENGL_LOADER_GLBINDING2
|
||||||
|
#else
|
||||||
|
#error "Cannot detect OpenGL loader!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Cannot detect loader with include detection !"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Include correct files
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GL3W)
|
||||||
|
#include <GL/gl3w.h> // Needs to be initialized with gl3wInit() in user's code
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLEW)
|
||||||
|
#include <GL/glew.h> // Needs to be initialized with glewInit() in user's code.
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLAD)
|
||||||
|
#include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code.
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||||
|
#ifndef GLFW_INCLUDE_NONE
|
||||||
|
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
||||||
|
#endif
|
||||||
|
#include <glbinding/Binding.h> // Needs to be initialized with glbinding::Binding::initialize() in user's code.
|
||||||
|
#include <glbinding/gl/gl.h>
|
||||||
|
using namespace gl;
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING3)
|
||||||
|
#ifndef GLFW_INCLUDE_NONE
|
||||||
|
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
||||||
|
#endif
|
||||||
|
#include <glbinding/glbinding.h>// Needs to be initialized with glbinding::initialize() in user's code.
|
||||||
|
#include <glbinding/gl/gl.h>
|
||||||
|
using namespace gl;
|
||||||
|
#else
|
||||||
|
#include TD_IMPL_OPENGL_LOADER_CUSTOM
|
||||||
|
#endif
|
||||||
72
include/client/render/Renderer.h
Normal file
72
include/client/render/Renderer.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/Defines.h"
|
||||||
|
#include <memory>
|
||||||
|
#include "loader/GLLoader.h"
|
||||||
|
#include "client/render/shaders/WorldShader.h"
|
||||||
|
#include "client/render/shaders/EntityShader.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
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 {
|
||||||
|
public:
|
||||||
|
static constexpr float m_AnimationSpeed = 2.0f;
|
||||||
|
static constexpr float m_MouseSensitivity = 200.0f;
|
||||||
|
|
||||||
|
struct Model {
|
||||||
|
GL::VertexArray* vao;
|
||||||
|
Vec3f positon;
|
||||||
|
Vec3f color = { 1, 1, 1 };
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
std::unique_ptr<shader::WorldShader> m_WorldShader;
|
||||||
|
std::unique_ptr<shader::EntityShader> m_EntityShader;
|
||||||
|
|
||||||
|
Vec2i m_WindowSize;
|
||||||
|
|
||||||
|
Vec3f m_BackgroundColor;
|
||||||
|
|
||||||
|
Camera m_Camera {};
|
||||||
|
public:
|
||||||
|
Renderer();
|
||||||
|
~Renderer();
|
||||||
|
|
||||||
|
bool Init();
|
||||||
|
|
||||||
|
void Prepare();
|
||||||
|
void Resize(const int width, const int height);
|
||||||
|
|
||||||
|
void RenderVAO(const GL::VertexArray& vao);
|
||||||
|
void RenderModel(const Model& model);
|
||||||
|
|
||||||
|
void AddZoom(float zoom);
|
||||||
|
void SetCamAngularMovement(const Vec2f& mov);
|
||||||
|
void SetCamMovement(const Vec2f& lastCursorPos, const Vec2f& currentCursorPos);
|
||||||
|
void SetCamLook(const Vec2f& worldPos);
|
||||||
|
void ResetCamLook();
|
||||||
|
|
||||||
|
void SetBackgroundColor(const Vec3f& color) { m_BackgroundColor = color; }
|
||||||
|
|
||||||
|
Vec2f GetCursorWorldPos(const Vec2f& cursorPos, float windowWidth, float windowHeight);
|
||||||
|
private:
|
||||||
|
void InitShaders();
|
||||||
|
void SetCamPos(const Vec3f& newPos);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
38
include/client/render/VertexCache.h
Normal file
38
include/client/render/VertexCache.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include <unordered_map>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "client/render/loader/GLLoader.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
|
||||||
|
class VertexCache {
|
||||||
|
|
||||||
|
typedef std::vector<float> Vector;
|
||||||
|
|
||||||
|
struct DataIndex {
|
||||||
|
Vector position;
|
||||||
|
Vector color;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_VertexCount;
|
||||||
|
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
|
||||||
|
std::unique_ptr<GL::VertexArray> m_VertexArray;
|
||||||
|
public:
|
||||||
|
VertexCache() : m_VertexCount(0) {}
|
||||||
|
|
||||||
|
void AddData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
|
||||||
|
void RemoveData(std::uint64_t index);
|
||||||
|
void Clear();
|
||||||
|
void UpdateVertexArray();
|
||||||
|
|
||||||
|
const GL::VertexArray& GetVertexArray() const { return *m_VertexArray; }
|
||||||
|
bool IsEmpty() const { return m_VertexArray == nullptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
82
include/client/render/WorldRenderer.h
Normal file
82
include/client/render/WorldRenderer.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/World.h"
|
||||||
|
|
||||||
|
#include "client/render/Renderer.h"
|
||||||
|
#include "client/render/VertexCache.h"
|
||||||
|
|
||||||
|
#include "client/render/gui/TowerPlacePopup.h"
|
||||||
|
#include "client/render/gui/TowerUpgradePopup.h"
|
||||||
|
#include "client/render/gui/MobTooltip.h"
|
||||||
|
#include "client/render/gui/CastleTooltip.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class ClientGame;
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
class WorldRenderer : public game::WorldListener {
|
||||||
|
private:
|
||||||
|
client::ClientGame* m_Client;
|
||||||
|
Renderer* m_Renderer;
|
||||||
|
game::World* m_World;
|
||||||
|
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
|
||||||
|
Vec2f m_CamPos;
|
||||||
|
Vec2f m_CursorPos;
|
||||||
|
Vec2f m_HoldCursorPos;
|
||||||
|
Vec2f m_LastClicked;
|
||||||
|
float m_Zoom;
|
||||||
|
float m_CamSensibility = 1;
|
||||||
|
bool m_PopupOpened = false;
|
||||||
|
VertexCache m_TowersCache;
|
||||||
|
|
||||||
|
std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
|
||||||
|
std::unique_ptr<gui::TowerUpgradePopup> m_TowerUpgradePopup;
|
||||||
|
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
|
||||||
|
std::unique_ptr<gui::CastleTooltip> m_CastleTooltip;
|
||||||
|
public:
|
||||||
|
WorldRenderer(game::World* world, client::ClientGame* client);
|
||||||
|
~WorldRenderer();
|
||||||
|
|
||||||
|
void LoadModels();
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
void ResetCam();
|
||||||
|
void SetCamPos(float camX, float camY);
|
||||||
|
|
||||||
|
void MoveCam(float relativeX, float relativeY);
|
||||||
|
void ChangeZoom(float zoom);
|
||||||
|
|
||||||
|
// WorldListener
|
||||||
|
|
||||||
|
virtual void OnTowerAdd(game::TowerPtr tower);
|
||||||
|
virtual void OnTowerRemove(game::TowerPtr tower);
|
||||||
|
private:
|
||||||
|
void Click();
|
||||||
|
void RenderWorld() const;
|
||||||
|
void RenderTowers() const;
|
||||||
|
void RenderMobs() const;
|
||||||
|
void RenderTileSelect() const;
|
||||||
|
void RenderPopups();
|
||||||
|
void RenderMobTooltip() const;
|
||||||
|
void RenderCastleTooltip() const;
|
||||||
|
void DetectClick();
|
||||||
|
void DetectMobHovering() const;
|
||||||
|
void DetectCastleHovering() const;
|
||||||
|
void RenderTooltips() const;
|
||||||
|
void RemoveTower();
|
||||||
|
Vec2f GetCursorWorldPos() const;
|
||||||
|
Vec2f GetClickWorldPos() const;
|
||||||
|
|
||||||
|
void UpdateCursorPos();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
28
include/client/render/gui/CastleTooltip.h
Normal file
28
include/client/render/gui/CastleTooltip.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
class TeamCastle;
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class CastleTooltip : public GuiWidget {
|
||||||
|
private:
|
||||||
|
const game::TeamCastle* m_Castle;
|
||||||
|
public:
|
||||||
|
CastleTooltip(client::Client* client);
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
|
||||||
|
void SetCastle(const game::TeamCastle* castle) { m_Castle = castle; }
|
||||||
|
bool IsShown() { return m_Castle != nullptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
@@ -13,7 +13,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
FrameMenu(client::Client* client);
|
FrameMenu(client::Client* client);
|
||||||
|
|
||||||
virtual void render();
|
virtual void Render();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
29
include/client/render/gui/GameMenu.h
Normal file
29
include/client/render/gui/GameMenu.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SummonMenu.h"
|
||||||
|
#include "td/game/BaseGame.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class GameMenu : public GuiWidget, public game::GameListener {
|
||||||
|
private:
|
||||||
|
std::unique_ptr<SummonMenu> m_SummonMenu;
|
||||||
|
public:
|
||||||
|
GameMenu(client::Client* client);
|
||||||
|
|
||||||
|
virtual void OnGameBegin();
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
private:
|
||||||
|
void ShowTPS();
|
||||||
|
void ShowStats();
|
||||||
|
void ShowPlayers();
|
||||||
|
void ShowLobbyProgress();
|
||||||
|
void ShowTeamSelection();
|
||||||
|
|
||||||
|
void DisconnectButton();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
29
include/client/render/gui/GuiManager.h
Normal file
29
include/client/render/gui/GuiManager.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class GuiManager {
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<GuiWidget>> m_Widgets;
|
||||||
|
public:
|
||||||
|
GuiManager() {}
|
||||||
|
|
||||||
|
void RenderWidgets() {
|
||||||
|
for (auto& widget : m_Widgets) {
|
||||||
|
widget->Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddWidget(std::unique_ptr<GuiWidget>&& widget) {
|
||||||
|
m_Widgets.push_back(std::move(widget));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
@@ -14,9 +14,9 @@ protected:
|
|||||||
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/client/render/gui/ImGuiTeamColor.h
Normal file
13
include/client/render/gui/ImGuiTeamColor.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "client/render/gui/imgui/imgui.h"
|
||||||
|
#include "td/game/Team.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
ImVec4 GetImGuiTeamColor(game::TeamColor color);
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
|
|
||||||
9
include/client/render/gui/LifeProgress.h
Normal file
9
include/client/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
|
||||||
40
include/client/render/gui/MainMenu.h
Normal file
40
include/client/render/gui/MainMenu.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include "imgui/imgui_filebrowser.h"
|
||||||
|
|
||||||
|
#include "server/Server.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class ServerGui;
|
||||||
|
|
||||||
|
class MainMenu : public GuiWidget {
|
||||||
|
private:
|
||||||
|
bool m_TriedToConnect = false;
|
||||||
|
bool m_TriedToCreate = false;
|
||||||
|
std::string m_ConnectAddress;
|
||||||
|
int m_ConnectPort;
|
||||||
|
int m_ServerPort = 25565;
|
||||||
|
std::string m_WorldFilePath;
|
||||||
|
imgui_addons::ImGuiFileBrowser m_FileDialog;
|
||||||
|
|
||||||
|
std::unique_ptr<server::Server> m_Server;
|
||||||
|
std::unique_ptr<ServerGui> m_ServerGui;
|
||||||
|
public:
|
||||||
|
MainMenu(client::Client* client);
|
||||||
|
~MainMenu();
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
|
||||||
|
const server::Server* GetServer() const { return m_Server.get(); }
|
||||||
|
private:
|
||||||
|
bool StartServer();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
@@ -18,9 +18,10 @@ private:
|
|||||||
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
19
include/client/render/gui/ServerGui.h
Normal file
19
include/client/render/gui/ServerGui.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
#include "server/Server.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class ServerGui : public GuiWidget {
|
||||||
|
private:
|
||||||
|
server::Server* m_Server;
|
||||||
|
public:
|
||||||
|
ServerGui(client::Client* client, server::Server* server);
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
30
include/client/render/gui/SummonMenu.h
Normal file
30
include/client/render/gui/SummonMenu.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include "td/game/Mobs.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class SummonMenu : public GuiWidget {
|
||||||
|
private:
|
||||||
|
bool m_MenuOpened;
|
||||||
|
int m_ImageWidth = 100;
|
||||||
|
float m_Cooldown;
|
||||||
|
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:
|
||||||
|
SummonMenu(client::Client* client);
|
||||||
|
|
||||||
|
void SetCooldown(float cooldown);
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
private:
|
||||||
|
void SetSummonMax(int valueIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
49
include/client/render/gui/TowerGui.h
Normal file
49
include/client/render/gui/TowerGui.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* TowerGUI.h
|
||||||
|
*
|
||||||
|
* Created on: 5 nov. 2020
|
||||||
|
* Author: Persson-dev
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "client/render/gui/GuiManager.h"
|
||||||
|
|
||||||
|
struct SDL_Window;
|
||||||
|
typedef void* SDL_GLContext;
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
class Renderer;
|
||||||
|
|
||||||
|
class TowerGui {
|
||||||
|
private:
|
||||||
|
SDL_Window* m_Window;
|
||||||
|
SDL_GLContext m_GlContext;
|
||||||
|
td::render::Renderer* m_Renderer;
|
||||||
|
td::gui::GuiManager m_GuiManager;
|
||||||
|
std::unique_ptr<td::client::Client> m_Client;
|
||||||
|
public:
|
||||||
|
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
|
||||||
|
~TowerGui();
|
||||||
|
|
||||||
|
void Render();
|
||||||
|
private:
|
||||||
|
void InitWidgets();
|
||||||
|
void Tick();
|
||||||
|
void BeginFrame();
|
||||||
|
void EndFrame();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
28
include/client/render/gui/TowerPlacePopup.h
Normal file
28
include/client/render/gui/TowerPlacePopup.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include "td/Defines.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class TowerPlacePopup : public GuiWidget {
|
||||||
|
private:
|
||||||
|
Vec2f m_ClickWorldPos;
|
||||||
|
public:
|
||||||
|
TowerPlacePopup(client::Client* client);
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
|
||||||
|
void SetClickPos(const Vec2f& worldPos);
|
||||||
|
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
|
||||||
32
include/client/render/gui/TowerUpgradePopup.h
Normal file
32
include/client/render/gui/TowerUpgradePopup.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include "td/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
|
||||||
36
include/client/render/gui/UpdateMenu.h
Normal file
36
include/client/render/gui/UpdateMenu.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GuiWidget.h"
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
class Updater;
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
|
||||||
|
class UpdateMenu : public GuiWidget {
|
||||||
|
private:
|
||||||
|
bool m_Opened;
|
||||||
|
std::string m_Error;
|
||||||
|
std::unique_ptr<utils::Updater> m_Updater;
|
||||||
|
std::shared_future<bool> m_UpdateAvailable;
|
||||||
|
public:
|
||||||
|
UpdateMenu(client::Client* client);
|
||||||
|
virtual ~UpdateMenu();
|
||||||
|
|
||||||
|
virtual void Render();
|
||||||
|
private:
|
||||||
|
void CheckUpdates();
|
||||||
|
bool IsUpdateChecked();
|
||||||
|
void RenderErrorPopup();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace td
|
||||||
@@ -107,8 +107,20 @@ namespace ImGui
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#include "client/render/GL.h"
|
||||||
#define IMGUI_IMPL_OPENGL_ES3
|
|
||||||
#else
|
#if defined(__ANDROID__)
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_ES3
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GL3W)
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_GL3W
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLEW)
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_GLEW
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLAD)
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||||
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2
|
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2
|
||||||
|
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING3)
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3
|
||||||
|
#else
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
||||||
#endif
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef IMGUIFILEBROWSER_H
|
#ifndef IMGUIFILEBROWSER_H
|
||||||
#define IMGUIFILEBROWSER_H
|
#define IMGUIFILEBROWSER_H
|
||||||
|
|
||||||
#include "render/gui/imgui/imgui.h"
|
#include "client/render/gui/imgui/imgui.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -17,8 +17,9 @@
|
|||||||
namespace GL {
|
namespace GL {
|
||||||
|
|
||||||
struct VertexAttribPointer {
|
struct VertexAttribPointer {
|
||||||
unsigned int m_Index, m_Size;
|
unsigned int m_Index;
|
||||||
int m_Offset;
|
unsigned int m_Size;
|
||||||
|
unsigned int m_Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VertexBuffer {
|
class VertexBuffer {
|
||||||
@@ -27,6 +28,7 @@ private:
|
|||||||
std::vector<VertexAttribPointer> m_VertexAttribs;
|
std::vector<VertexAttribPointer> m_VertexAttribs;
|
||||||
public:
|
public:
|
||||||
REMOVE_COPY(VertexBuffer);
|
REMOVE_COPY(VertexBuffer);
|
||||||
|
|
||||||
VertexBuffer(VertexBuffer&& other) {
|
VertexBuffer(VertexBuffer&& other) {
|
||||||
m_VertexAttribs = std::move(other.m_VertexAttribs);
|
m_VertexAttribs = std::move(other.m_VertexAttribs);
|
||||||
m_ID = other.m_ID;
|
m_ID = other.m_ID;
|
||||||
@@ -34,12 +36,14 @@ public:
|
|||||||
other.m_ID = 0;
|
other.m_ID = 0;
|
||||||
other.m_DataStride = 0;
|
other.m_DataStride = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexBuffer(const std::vector<float>& data, unsigned int stride);
|
VertexBuffer(const std::vector<float>& data, unsigned int stride);
|
||||||
~VertexBuffer();
|
~VertexBuffer();
|
||||||
void bind() const;
|
|
||||||
void unbind() const;
|
void Bind() const;
|
||||||
void addVertexAttribPointer(unsigned int index, unsigned int coordinateSize, unsigned int offset);
|
void Unbind() const;
|
||||||
void bindVertexAttribs() const;
|
void AddVertexAttribPointer(unsigned int index, unsigned int coordinateSize, unsigned int offset);
|
||||||
|
void BindVertexAttribs() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VertexArray {
|
class VertexArray {
|
||||||
@@ -48,6 +52,7 @@ private:
|
|||||||
std::vector<VertexBuffer> m_VertexBuffers; //use to destroy vbos when become unused
|
std::vector<VertexBuffer> m_VertexBuffers; //use to destroy vbos when become unused
|
||||||
public:
|
public:
|
||||||
REMOVE_COPY(VertexArray);
|
REMOVE_COPY(VertexArray);
|
||||||
|
|
||||||
VertexArray(VertexArray&& other) {
|
VertexArray(VertexArray&& other) {
|
||||||
m_ID = other.m_ID;
|
m_ID = other.m_ID;
|
||||||
m_VertexCount = other.m_VertexCount;
|
m_VertexCount = other.m_VertexCount;
|
||||||
@@ -55,12 +60,14 @@ public:
|
|||||||
other.m_VertexCount = 0;
|
other.m_VertexCount = 0;
|
||||||
other.m_ID = 0;
|
other.m_ID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexArray(unsigned int vertexCount);
|
VertexArray(unsigned int vertexCount);
|
||||||
~VertexArray();
|
~VertexArray();
|
||||||
unsigned int getVertexCount() const { return m_VertexCount; }
|
|
||||||
void bindVertexBuffer(VertexBuffer& vbo);
|
unsigned int GetVertexCount() const { return m_VertexCount; }
|
||||||
void bind() const;
|
void BindVertexBuffer(VertexBuffer& vbo);
|
||||||
void unbind() const;
|
void Bind() const;
|
||||||
|
void Unbind() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
#define RENDER_LOADER_TEXTURELOADER_H_
|
#define RENDER_LOADER_TEXTURELOADER_H_
|
||||||
|
|
||||||
namespace TextureLoader {
|
namespace TextureLoader {
|
||||||
const unsigned int loadGLTexture(const char* fileName);
|
|
||||||
|
unsigned int LoadGLTexture(const char* fileName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
25
include/client/render/loader/WorldLoader.h
Normal file
25
include/client/render/loader/WorldLoader.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/World.h"
|
||||||
|
#include "GLLoader.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace render {
|
||||||
|
|
||||||
|
namespace WorldLoader {
|
||||||
|
|
||||||
|
struct RenderData {
|
||||||
|
std::vector<float> positions;
|
||||||
|
std::vector<float> colors;
|
||||||
|
};
|
||||||
|
|
||||||
|
GL::VertexArray LoadMobModel();
|
||||||
|
GL::VertexArray LoadWorldModel(const td::game::World* world);
|
||||||
|
GL::VertexArray LoadTileSelectModel();
|
||||||
|
RenderData LoadTowerModel(game::TowerPtr tower);
|
||||||
|
|
||||||
|
} // namespace WorldLoader
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace render
|
||||||
|
} // namespace td
|
||||||
28
include/client/render/shaders/EntityShader.h
Normal file
28
include/client/render/shaders/EntityShader.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace shader {
|
||||||
|
|
||||||
|
class EntityShader : public ShaderProgram {
|
||||||
|
private:
|
||||||
|
unsigned int m_LocationProjectionMatrix = 0;
|
||||||
|
unsigned int m_LocationViewMatrix = 0;
|
||||||
|
unsigned int m_LocationPosition = 0;
|
||||||
|
unsigned int m_LocationColorEffect = 0;
|
||||||
|
protected:
|
||||||
|
virtual void GetAllUniformLocation();
|
||||||
|
public:
|
||||||
|
EntityShader();
|
||||||
|
|
||||||
|
void LoadShader();
|
||||||
|
|
||||||
|
void SetColorEffect(const Vec3f& color);
|
||||||
|
void SetProjectionMatrix(const Mat4f& proj) const;
|
||||||
|
void SetViewMatrix(const Mat4f& view) const;
|
||||||
|
void SetModelPos(const Vec3f& pos) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace shader
|
||||||
|
} // namespace td
|
||||||
43
include/client/render/shaders/ShaderProgram.h
Executable file
43
include/client/render/shaders/ShaderProgram.h
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "td/Defines.h"
|
||||||
|
#include "client/render/GL.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace shader {
|
||||||
|
|
||||||
|
class ShaderProgram {
|
||||||
|
public:
|
||||||
|
ShaderProgram();
|
||||||
|
virtual ~ShaderProgram();
|
||||||
|
|
||||||
|
void Start() const;
|
||||||
|
void Stop() const;
|
||||||
|
|
||||||
|
void LoadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
|
||||||
|
void LoadProgram(const std::string& vertexSource, const std::string& fragmentSource);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void GetAllUniformLocation() = 0;
|
||||||
|
int GetUniformLocation(const std::string& uniformName) const;
|
||||||
|
|
||||||
|
void LoadFloat(unsigned int location, float value) const;
|
||||||
|
void LoadInt(unsigned int location, int value) const;
|
||||||
|
void LoadVector(unsigned int location, const Vec2f& vector) const;
|
||||||
|
void LoadVector(unsigned int location, const Vec3f& vector) const;
|
||||||
|
void LoadBoolean(unsigned int location, bool value) const;
|
||||||
|
void LoadMat4(unsigned int location, const Mat4f& mat) const;
|
||||||
|
void CleanUp() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int m_ProgramID;
|
||||||
|
unsigned int m_VertexShaderID;
|
||||||
|
unsigned int m_FragmentShaderID;
|
||||||
|
|
||||||
|
unsigned int LoadShaderFromFile(const std::string& file, GLenum type);
|
||||||
|
unsigned int LoadShader(const std::string& source, GLenum type);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace shader
|
||||||
|
} // namespace td
|
||||||
22
include/client/render/shaders/WorldShader.h
Normal file
22
include/client/render/shaders/WorldShader.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace shader {
|
||||||
|
|
||||||
|
class WorldShader : public ShaderProgram {
|
||||||
|
private:
|
||||||
|
unsigned int m_LocationProjection = 0, m_LocationView = 0;
|
||||||
|
protected:
|
||||||
|
void GetAllUniformLocation();
|
||||||
|
public:
|
||||||
|
WorldShader();
|
||||||
|
void LoadShader();
|
||||||
|
|
||||||
|
void SetProjectionMatrix(const Mat4f& proj) const;
|
||||||
|
void SetViewMatrix(const Mat4f& view) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace shader
|
||||||
|
} // namespace td
|
||||||
44
include/client/updater/Updater.h
Normal file
44
include/client/updater/Updater.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/misc/DataBuffer.h"
|
||||||
|
|
||||||
|
#define TD_VERSION "alpha-0.4.0"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
class Updater {
|
||||||
|
private:
|
||||||
|
float m_Progress;
|
||||||
|
bool m_DownloadComplete;
|
||||||
|
bool m_FileWrited;
|
||||||
|
bool m_CancelDownload;
|
||||||
|
DataBuffer m_FileBuffer;
|
||||||
|
std::string m_LastVersion;
|
||||||
|
public:
|
||||||
|
Updater() : m_Progress(0), m_DownloadComplete(false), m_FileWrited(false), m_CancelDownload(false) {}
|
||||||
|
|
||||||
|
bool CheckUpdate();
|
||||||
|
void DownloadUpdate();
|
||||||
|
void CancelDownload() { m_CancelDownload = true; m_Progress = 0.0f; m_DownloadComplete = false; }
|
||||||
|
bool WriteFile();
|
||||||
|
|
||||||
|
void ClearCache() { m_FileBuffer.Clear(); }
|
||||||
|
|
||||||
|
float GetDownloadProgress() { return m_Progress; }
|
||||||
|
bool IsDownloadComplete() { return m_DownloadComplete; }
|
||||||
|
bool IsFileWrited() { return m_FileWrited; }
|
||||||
|
|
||||||
|
static std::string GetLocalFilePath();
|
||||||
|
static void RemoveOldFile();
|
||||||
|
|
||||||
|
static std::string GetCurrentVersion() { return TD_VERSION; }
|
||||||
|
std::string GetLastVersion() { return m_LastVersion; }
|
||||||
|
|
||||||
|
bool CanUpdate();
|
||||||
|
private:
|
||||||
|
std::string GetDownloadFileURL();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
} // namespace td
|
||||||
31
include/client/window/Display.h
Normal file
31
include/client/window/Display.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Display.h
|
||||||
|
*
|
||||||
|
* Created on: 4 nov. 2020
|
||||||
|
* Author: simon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WINDOW_DISPLAY_H_
|
||||||
|
#define WINDOW_DISPLAY_H_
|
||||||
|
|
||||||
|
|
||||||
|
namespace Display {
|
||||||
|
|
||||||
|
bool Create();
|
||||||
|
void Render();
|
||||||
|
void Update();
|
||||||
|
void Destroy();
|
||||||
|
void PollEvents();
|
||||||
|
|
||||||
|
bool IsCloseRequested();
|
||||||
|
|
||||||
|
bool IsMouseDown(int button);
|
||||||
|
|
||||||
|
float GetAspectRatio();
|
||||||
|
int GetWindowWidth();
|
||||||
|
int GetWindowHeight();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WINDOW_DISPLAY_H_ */
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/Team.h"
|
|
||||||
#include "game/World.h"
|
|
||||||
#include "game/Player.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace game {
|
|
||||||
|
|
||||||
enum class GameState : std::uint8_t {
|
|
||||||
Lobby,
|
|
||||||
Game,
|
|
||||||
EndGame,
|
|
||||||
Disconnected,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<std::uint8_t, Player> PlayerList;
|
|
||||||
|
|
||||||
class Game {
|
|
||||||
protected:
|
|
||||||
World* m_World;
|
|
||||||
std::array<Team, 2> m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
|
|
||||||
GameState m_GameState = GameState::Lobby;
|
|
||||||
PlayerList m_Players;
|
|
||||||
public:
|
|
||||||
Game(World* world);
|
|
||||||
virtual ~Game();
|
|
||||||
|
|
||||||
virtual void tick(std::uint64_t delta);
|
|
||||||
|
|
||||||
Team& getRedTeam() { return m_Teams[(std::uint8_t)TeamColor::Red]; }
|
|
||||||
const Team& getRedTeam() const { return m_Teams[(std::uint8_t)TeamColor::Red]; }
|
|
||||||
|
|
||||||
Team& getBlueTeam() { return m_Teams[(std::uint8_t)TeamColor::Blue]; }
|
|
||||||
const Team& getBlueTeam() const { return m_Teams[(std::uint8_t)TeamColor::Blue]; }
|
|
||||||
|
|
||||||
Team& getTeam(TeamColor team) { return m_Teams[(std::uint8_t)team]; }
|
|
||||||
const Team& getTeam(TeamColor team) const { return m_Teams[(std::uint8_t)team]; }
|
|
||||||
|
|
||||||
GameState getGameState() const { return m_GameState; }
|
|
||||||
void setGameState(GameState gameState) { m_GameState = gameState; };
|
|
||||||
|
|
||||||
const World* getWorld() const { return m_World; }
|
|
||||||
World* getWorld() { return m_World; }
|
|
||||||
|
|
||||||
const PlayerList& getPlayers() const { return m_Players; }
|
|
||||||
PlayerList& getPlayers() { return m_Players; }
|
|
||||||
|
|
||||||
const Player& getPlayerById(PlayerID id) const { return m_Players.find(id)->second; }
|
|
||||||
Player& getPlayerById(PlayerID id) { return m_Players.find(id)->second; }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "network/TCPSocket.h"
|
|
||||||
#include "protocol/PacketHandler.h"
|
|
||||||
#include "protocol/PacketDispatcher.h"
|
|
||||||
#include "game/Player.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace protocol {
|
|
||||||
|
|
||||||
class Connexion : public protocol::PacketHandler {
|
|
||||||
protected:
|
|
||||||
protocol::PacketDispatcher m_Dispatcher;
|
|
||||||
private:
|
|
||||||
network::TCPSocket m_Socket;
|
|
||||||
public:
|
|
||||||
Connexion();
|
|
||||||
Connexion(Connexion&& move);
|
|
||||||
Connexion(protocol::PacketDispatcher* dispatcher);
|
|
||||||
Connexion(protocol::PacketDispatcher* dispatcher, network::TCPSocket& socket);
|
|
||||||
virtual ~Connexion();
|
|
||||||
|
|
||||||
virtual bool updateSocket();
|
|
||||||
void closeConnection();
|
|
||||||
|
|
||||||
bool connect(const std::string& address, std::uint16_t port);
|
|
||||||
|
|
||||||
network::Socket::Status getSocketStatus() const { return m_Socket.GetStatus(); }
|
|
||||||
|
|
||||||
void sendPacket(const protocol::Packet* packet);
|
|
||||||
|
|
||||||
REMOVE_COPY(Connexion);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace server
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Towers.h"
|
|
||||||
#include "Types.h"
|
|
||||||
#include "Team.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace game {
|
|
||||||
|
|
||||||
enum class EffectType : std::uint8_t {
|
|
||||||
Slowness = 0,
|
|
||||||
Stun,
|
|
||||||
Fire,
|
|
||||||
Poison,
|
|
||||||
Heal,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MobType : std::uint8_t {
|
|
||||||
Zombie = 0,
|
|
||||||
Spider,
|
|
||||||
Skeleton,
|
|
||||||
Pigman,
|
|
||||||
Creeper,
|
|
||||||
Silverfish,
|
|
||||||
Blaze,
|
|
||||||
Witch,
|
|
||||||
Slime,
|
|
||||||
Giant,
|
|
||||||
|
|
||||||
MOB_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::uint32_t MobID;
|
|
||||||
typedef std::uint8_t MobLevel;
|
|
||||||
typedef std::vector<TowerType> TowerImmunities;
|
|
||||||
typedef std::vector<EffectType> EffectImmunities;
|
|
||||||
|
|
||||||
class MobStats {
|
|
||||||
private:
|
|
||||||
float m_Damage;
|
|
||||||
float m_Speed;
|
|
||||||
glm::vec2 m_Size;
|
|
||||||
std::uint16_t m_MoneyCost;
|
|
||||||
std::uint16_t m_ExpCost;
|
|
||||||
std::uint16_t m_MaxLife;
|
|
||||||
std::uint16_t m_ExpReward;
|
|
||||||
public:
|
|
||||||
MobStats(float damage, float speed, glm::vec2 size, std::uint16_t moneyCost,
|
|
||||||
std::uint16_t expCost, std::uint16_t expReward,
|
|
||||||
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
|
|
||||||
m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
|
|
||||||
m_MaxLife(maxLife), m_ExpReward(expReward) {
|
|
||||||
}
|
|
||||||
|
|
||||||
float getDamage() const { return m_Damage; }
|
|
||||||
float getMovementSpeed() const { return m_Speed; }
|
|
||||||
const glm::vec2& getSize() const { return m_Size; }
|
|
||||||
std::uint16_t getMoneyCost() const { return m_MoneyCost; }
|
|
||||||
std::uint16_t getExpCost() const { return m_ExpCost; }
|
|
||||||
std::uint16_t getExpReward() const { return m_ExpReward; }
|
|
||||||
std::uint16_t getMaxLife() const { return m_MaxLife; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EffectDuration {
|
|
||||||
EffectType type;
|
|
||||||
float duration; // in seconds
|
|
||||||
const Tower* tower; // the tower that gived the effect
|
|
||||||
};
|
|
||||||
|
|
||||||
const MobStats* getMobStats(MobType type, std::uint8_t level);
|
|
||||||
const TowerImmunities& getMobTowerImmunities(MobType type, std::uint8_t level);
|
|
||||||
const EffectImmunities& getMobEffectImmunities(MobType type, std::uint8_t level);
|
|
||||||
|
|
||||||
class Mob : public utils::shape::Rectangle {
|
|
||||||
protected:
|
|
||||||
float m_Health;
|
|
||||||
private:
|
|
||||||
MobID m_ID;
|
|
||||||
PlayerID m_Sender;
|
|
||||||
MobLevel m_Level;
|
|
||||||
Direction m_Direction;
|
|
||||||
std::vector<EffectDuration> m_Effects;
|
|
||||||
const Tower* m_LastDamage; // the last tower that damaged the mob
|
|
||||||
bool m_HasReachedCastle; // if true, no need to walk anymore
|
|
||||||
|
|
||||||
utils::Timer m_EffectFireTimer;
|
|
||||||
utils::Timer m_EffectPoisonTimer;
|
|
||||||
utils::Timer m_EffectHealTimer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
|
|
||||||
m_HasReachedCastle(false), m_EffectFireTimer(1000), m_EffectPoisonTimer(1000),
|
|
||||||
m_EffectHealTimer(1000) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual MobType getType() const = 0;
|
|
||||||
|
|
||||||
virtual void tick(std::uint64_t delta);
|
|
||||||
|
|
||||||
virtual bool OnDeath(World* world) { return true; }
|
|
||||||
|
|
||||||
const TowerImmunities& getTowerImmunities() const { return getMobTowerImmunities(getType(), m_Level); }
|
|
||||||
const EffectImmunities& getEffectImmunities() const { return getMobEffectImmunities(getType(), m_Level); }
|
|
||||||
PlayerID getSender() const { return m_Sender; }
|
|
||||||
MobLevel getLevel() const { return m_Level; }
|
|
||||||
const MobStats* getStats() const { return getMobStats(getType(), m_Level); }
|
|
||||||
float getHealth() const { return m_Health; }
|
|
||||||
bool isDead() const { return m_Health <= 0; }
|
|
||||||
bool isAlive() const { return m_Health > 0; }
|
|
||||||
const Tower* getLastDamageTower() { return m_LastDamage; }
|
|
||||||
bool hasReachedEnemyCastle() { return m_HasReachedCastle; }
|
|
||||||
|
|
||||||
void damage(float dmg, const Tower* damager) { m_Health = std::max(0.0f, m_Health - dmg); m_LastDamage = damager; }
|
|
||||||
void heal(float heal) { m_Health = std::min(static_cast<float>(getStats()->getMaxLife()), m_Health + heal); }
|
|
||||||
void setMobReachedCastle() { m_HasReachedCastle = true; } // used when mob is in front of the castle
|
|
||||||
|
|
||||||
bool isImmuneTo(TowerType type);
|
|
||||||
|
|
||||||
bool isImmuneTo(EffectType type);
|
|
||||||
void addEffect(EffectType type, float durationSec, const 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
|
|
||||||
float getTileY() { return getCenterY() - static_cast<float>(static_cast<std::int32_t>(getCenterY())); } // returns a float between 0 and 1 excluded
|
|
||||||
|
|
||||||
Direction getDirection() const { return m_Direction; }
|
|
||||||
void setDirection(Direction dir) { m_Direction = dir; }
|
|
||||||
protected:
|
|
||||||
void initMob() {
|
|
||||||
m_Health = static_cast<float>(getStats()->getMaxLife());
|
|
||||||
setSize(getStats()->getSize().x, getStats()->getSize().y);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void updateEffects(std::uint64_t delta);
|
|
||||||
EffectDuration& getEffect(EffectType type);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Mob> MobPtr;
|
|
||||||
|
|
||||||
class Zombie : public Mob {
|
|
||||||
public:
|
|
||||||
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Zombie; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Spider : public Mob {
|
|
||||||
public:
|
|
||||||
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Spider; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Skeleton : public Mob {
|
|
||||||
public:
|
|
||||||
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Skeleton; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PigMan : public Mob {
|
|
||||||
public:
|
|
||||||
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Pigman; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Creeper : public Mob {
|
|
||||||
public:
|
|
||||||
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Creeper; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Silverfish : public Mob {
|
|
||||||
public:
|
|
||||||
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Silverfish; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Blaze : public Mob {
|
|
||||||
public:
|
|
||||||
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Blaze; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Witch : public Mob {
|
|
||||||
public:
|
|
||||||
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Witch; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Slime : public Mob {
|
|
||||||
public:
|
|
||||||
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Slime; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Giant : public Mob {
|
|
||||||
public:
|
|
||||||
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initMob(); }
|
|
||||||
|
|
||||||
virtual MobType getType() const { return MobType::Giant; }
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace MobFactory {
|
|
||||||
MobPtr createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
|
|
||||||
std::string getMobName(MobType type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "game/Team.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace game {
|
|
||||||
|
|
||||||
class Player {
|
|
||||||
private:
|
|
||||||
game::TeamColor m_TeamColor;
|
|
||||||
|
|
||||||
std::uint32_t m_Gold;
|
|
||||||
std::uint32_t m_Exp;
|
|
||||||
std::string m_Name;
|
|
||||||
std::uint8_t m_ID;
|
|
||||||
|
|
||||||
std::uint8_t m_GoldPerSecond;
|
|
||||||
|
|
||||||
bool m_GoldChanged;
|
|
||||||
bool m_ExpChanged;
|
|
||||||
public:
|
|
||||||
Player(std::uint8_t id = 0) : m_TeamColor(game::TeamColor::None), m_Gold(0), m_Exp(0), m_ID(id), m_GoldPerSecond(5),
|
|
||||||
m_GoldChanged(false), m_ExpChanged(false) {}
|
|
||||||
|
|
||||||
const std::string& getName() const { return m_Name; }
|
|
||||||
void setName(const std::string& name) { m_Name = name; }
|
|
||||||
|
|
||||||
game::TeamColor getTeamColor() const { return m_TeamColor; }
|
|
||||||
void setTeamColor(game::TeamColor teamColor) { m_TeamColor = teamColor; }
|
|
||||||
|
|
||||||
std::uint8_t getGoldPerSecond() const { return m_GoldPerSecond; }
|
|
||||||
void setGoldPerSecond(std::uint8_t goldPerSecond) { m_GoldPerSecond = goldPerSecond; }
|
|
||||||
|
|
||||||
std::uint32_t getGold() const { return m_Gold; }
|
|
||||||
void setGold(std::uint32_t gold) { m_GoldChanged = true; m_Gold = gold; }
|
|
||||||
void addGold(std::uint32_t gold) { m_GoldChanged = true; m_Gold += gold; }
|
|
||||||
void removeGold(std::uint32_t gold) { m_GoldChanged = true; m_Gold -= gold; }
|
|
||||||
|
|
||||||
std::uint32_t getExp() const { return m_Exp; }
|
|
||||||
void setExp(std::uint32_t exp) { m_ExpChanged = true; m_Exp = exp; }
|
|
||||||
void addExp(std::uint32_t exp) { m_ExpChanged = true; m_Exp += exp; }
|
|
||||||
void removeExp(std::uint32_t exp) { m_ExpChanged = true; m_Exp -= exp; }
|
|
||||||
|
|
||||||
bool hasGoldChanged() const { return m_GoldChanged; }
|
|
||||||
bool hasExpChanged() const { return m_ExpChanged; }
|
|
||||||
|
|
||||||
void updateGold() { m_GoldChanged = false; }
|
|
||||||
void updateExp() { m_ExpChanged = false; }
|
|
||||||
|
|
||||||
std::uint8_t getID() const { return m_ID; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Types.h"
|
|
||||||
|
|
||||||
#include "misc/Shapes.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace game {
|
|
||||||
|
|
||||||
class Player;
|
|
||||||
|
|
||||||
enum class TeamColor : std::int8_t {
|
|
||||||
None = -1,
|
|
||||||
Red,
|
|
||||||
Blue
|
|
||||||
};
|
|
||||||
|
|
||||||
class Spawn : public utils::shape::Rectangle {
|
|
||||||
private:
|
|
||||||
Direction m_Direction;
|
|
||||||
public:
|
|
||||||
Spawn(){
|
|
||||||
setWidth(5);
|
|
||||||
setHeight(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
Direction getDirection() const { return m_Direction; }
|
|
||||||
|
|
||||||
void setDirection(Direction direction) { m_Direction = direction; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TeamCastle : public utils::shape::Rectangle{
|
|
||||||
private:
|
|
||||||
float m_Life;
|
|
||||||
public:
|
|
||||||
TeamCastle() : m_Life(1000) {
|
|
||||||
setWidth(5);
|
|
||||||
setHeight(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
float getLife() const { return m_Life; }
|
|
||||||
|
|
||||||
void setLife(float life) { m_Life = life; }
|
|
||||||
void damage(float damage) { m_Life = std::max(0.0f, m_Life - damage); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Team {
|
|
||||||
private:
|
|
||||||
std::vector<Player*> m_Players;
|
|
||||||
TeamColor m_Color;
|
|
||||||
Spawn m_Spawn;
|
|
||||||
TeamCastle m_TeamCastle;
|
|
||||||
public:
|
|
||||||
Team(TeamColor color);
|
|
||||||
|
|
||||||
void addPlayer(Player* newPlayer);
|
|
||||||
void removePlayer(const Player* player);
|
|
||||||
|
|
||||||
TeamColor getColor() const;
|
|
||||||
|
|
||||||
const Spawn& getSpawn() const { return m_Spawn; }
|
|
||||||
Spawn& getSpawn() { return m_Spawn; }
|
|
||||||
|
|
||||||
const TeamCastle& getCastle() const { return m_TeamCastle; }
|
|
||||||
TeamCastle& getCastle() { return m_TeamCastle; }
|
|
||||||
|
|
||||||
std::uint8_t getPlayerCount() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "misc/Time.h"
|
|
||||||
#include "misc/Shapes.h"
|
|
||||||
|
|
||||||
#include "game/Types.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace game {
|
|
||||||
|
|
||||||
class World;
|
|
||||||
class Mob;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Mob> MobPtr;
|
|
||||||
|
|
||||||
enum class TowerType : std::uint8_t {
|
|
||||||
Archer = 0,
|
|
||||||
Ice,
|
|
||||||
Sorcerer,
|
|
||||||
Zeus,
|
|
||||||
Mage,
|
|
||||||
Artillery,
|
|
||||||
Quake,
|
|
||||||
Poison,
|
|
||||||
|
|
||||||
Leach,
|
|
||||||
Turret,
|
|
||||||
Necromancer,
|
|
||||||
|
|
||||||
TowerCount
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TowerSize : std::uint8_t {
|
|
||||||
Little = 3, // 3x3
|
|
||||||
Big = 5, // 5x5
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TowerPath : std::uint8_t {
|
|
||||||
Top = 0,
|
|
||||||
Base, // Base Path
|
|
||||||
Bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
class TowerStats {
|
|
||||||
private:
|
|
||||||
float m_Rate;
|
|
||||||
float m_Damage;
|
|
||||||
std::uint8_t m_Range;
|
|
||||||
public:
|
|
||||||
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage),
|
|
||||||
m_Range(range) {
|
|
||||||
}
|
|
||||||
|
|
||||||
float getDamageRate() const { return m_Rate; }
|
|
||||||
float getDamage() const { return m_Damage; }
|
|
||||||
std::uint8_t getRange() const { return m_Range; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class TowerLevel {
|
|
||||||
private:
|
|
||||||
// 1, 2, 3, 4
|
|
||||||
std::uint8_t m_Level : 3;
|
|
||||||
// 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path)
|
|
||||||
TowerPath m_Path : 2;
|
|
||||||
public:
|
|
||||||
TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {}
|
|
||||||
TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {}
|
|
||||||
|
|
||||||
std::uint8_t getLevel() const { return m_Level; }
|
|
||||||
TowerPath getPath() const { return m_Path; }
|
|
||||||
|
|
||||||
void setLevel(std::uint8_t level) { m_Level = level; }
|
|
||||||
void setPath(TowerPath path) { m_Path = path; }
|
|
||||||
|
|
||||||
// operator to sort maps
|
|
||||||
friend bool operator<(const TowerLevel& level, const TowerLevel& other) {
|
|
||||||
return level.getLevel() + static_cast<std::uint8_t>(level.getPath()) * 4 <
|
|
||||||
other.getLevel() + static_cast<std::uint8_t>(other.getPath()) * 4;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const TowerStats* getTowerStats(TowerType type, TowerLevel level);
|
|
||||||
|
|
||||||
typedef std::uint16_t TowerID;
|
|
||||||
|
|
||||||
class Tower : public utils::shape::Circle {
|
|
||||||
private:
|
|
||||||
TowerID m_ID;
|
|
||||||
TowerType m_Type;
|
|
||||||
TowerLevel m_Level{};
|
|
||||||
PlayerID m_Builder;
|
|
||||||
protected:
|
|
||||||
utils::CooldownTimer m_Timer;
|
|
||||||
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),
|
|
||||||
m_Timer(getStats()->getDamageRate() * 1000) { // converting seconds to millis
|
|
||||||
setRadius(getStats()->getRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual TowerType getType() const = 0;
|
|
||||||
virtual TowerSize getSize() const = 0;
|
|
||||||
virtual void tick(std::uint64_t delta, World* world) = 0;
|
|
||||||
|
|
||||||
void upgrade(std::uint8_t level, TowerPath path) {
|
|
||||||
m_Level.setLevel(level);
|
|
||||||
m_Level.setPath(path);
|
|
||||||
m_Timer.setCooldown(getStats()->getDamageRate() * 1000); // converting seconds to millis
|
|
||||||
m_Timer.reset();
|
|
||||||
setRadius(getStats()->getRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint16_t getID() const { return m_ID; }
|
|
||||||
const TowerLevel& getLevel() const { return m_Level; }
|
|
||||||
const TowerStats* getStats() const { return getTowerStats(m_Type, m_Level); }
|
|
||||||
PlayerID getBuilder() const { return m_Builder; }
|
|
||||||
|
|
||||||
bool isMobInRange(MobPtr mob);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Tower> TowerPtr;
|
|
||||||
|
|
||||||
namespace TowerFactory {
|
|
||||||
|
|
||||||
TowerPtr createTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder);
|
|
||||||
std::string getTowerName(TowerType type);
|
|
||||||
|
|
||||||
} // namespace TowerFactory
|
|
||||||
|
|
||||||
|
|
||||||
class TowerInfo {
|
|
||||||
private:
|
|
||||||
std::string m_Name, m_Description;
|
|
||||||
bool m_IsBigTower;
|
|
||||||
public:
|
|
||||||
TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)),
|
|
||||||
m_Description(std::move(description)), m_IsBigTower(big) {}
|
|
||||||
|
|
||||||
const std::string& getName() const { return m_Name; }
|
|
||||||
const std::string& getDescription() const { return m_Description; }
|
|
||||||
|
|
||||||
bool isBigTower() const { return m_IsBigTower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
const TowerInfo& getTowerInfo(TowerType type);
|
|
||||||
|
|
||||||
// ---------- Little Towers ----------
|
|
||||||
|
|
||||||
class LittleTower : public Tower {
|
|
||||||
public:
|
|
||||||
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 TowerType getType() const = 0;
|
|
||||||
virtual void tick(std::uint64_t delta, World* world) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ArcherTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
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;
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Archer; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class IceTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
IceTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Ice; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class MageTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
MageTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Mage; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class PoisonTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
PoisonTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Poison; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class QuakeTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
QuakeTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Quake; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ArtilleryTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
ArtilleryTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Artillery; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class SorcererTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
SorcererTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Sorcerer; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ZeusTower : public LittleTower {
|
|
||||||
public:
|
|
||||||
ZeusTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Zeus; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------- Big Towers ----------
|
|
||||||
|
|
||||||
class BigTower : public Tower {
|
|
||||||
public:
|
|
||||||
BigTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerSize getSize() const { return TowerSize::Big; }
|
|
||||||
|
|
||||||
virtual TowerType getType() const = 0;
|
|
||||||
virtual void tick(std::uint64_t delta, World* world) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TurretTower : public BigTower {
|
|
||||||
public:
|
|
||||||
TurretTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Turret; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class NecromancerTower : public BigTower {
|
|
||||||
public:
|
|
||||||
NecromancerTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Necromancer; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
class LeachTower : public BigTower {
|
|
||||||
public:
|
|
||||||
LeachTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, getType(), x, y, builder) {}
|
|
||||||
|
|
||||||
virtual TowerType getType() const { return TowerType::Leach; }
|
|
||||||
virtual void tick(std::uint64_t delta, World* world);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
#include "Mobs.h"
|
|
||||||
#include "Team.h"
|
|
||||||
|
|
||||||
#include "misc/ObjectNotifier.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace game {
|
|
||||||
typedef std::pair<std::int16_t, std::int16_t> ChunkCoord;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
namespace std {
|
|
||||||
template <>
|
|
||||||
struct hash<td::game::ChunkCoord> {
|
|
||||||
std::size_t operator()(const td::game::ChunkCoord& key) const {
|
|
||||||
// Compute individual hash values for first,
|
|
||||||
// second and third and combine them using XOR
|
|
||||||
// and bit shifting:
|
|
||||||
return ((std::hash<std::int16_t>()(key.first) ^ (std::hash<std::int16_t>()(key.second) << 1)) >> 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
|
|
||||||
namespace protocol {
|
|
||||||
|
|
||||||
class WorldBeginDataPacket;
|
|
||||||
class WorldDataPacket;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace game {
|
|
||||||
|
|
||||||
class Game;
|
|
||||||
|
|
||||||
enum class TileType : std::uint8_t {
|
|
||||||
None = 0,
|
|
||||||
Tower,
|
|
||||||
Walk,
|
|
||||||
Decoration,
|
|
||||||
/*Heal,
|
|
||||||
Lava,
|
|
||||||
Bedrock,
|
|
||||||
Freeze,
|
|
||||||
Ice,*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Color {
|
|
||||||
std::uint8_t r, g, b;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Tile {
|
|
||||||
virtual TileType getType() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TowerTile : Tile {
|
|
||||||
std::uint8_t color_palette_ref;
|
|
||||||
TeamColor team_owner;
|
|
||||||
|
|
||||||
virtual TileType getType() const { return TileType::Tower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WalkableTile : Tile {
|
|
||||||
Direction direction;
|
|
||||||
|
|
||||||
virtual TileType getType() const { return TileType::Walk; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DecorationTile : Tile {
|
|
||||||
std::uint16_t color_palette_ref;
|
|
||||||
|
|
||||||
virtual TileType getType() const { return TileType::Decoration; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Tile> TilePtr;
|
|
||||||
typedef std::vector<std::uint16_t> ChunkPalette;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<WalkableTile> WalkableTilePtr;
|
|
||||||
|
|
||||||
typedef std::array<std::uint16_t, 32 * 32> ChunkData;
|
|
||||||
typedef std::uint32_t TileIndex;
|
|
||||||
|
|
||||||
//32 x 32 area
|
|
||||||
struct Chunk {
|
|
||||||
enum { ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
|
|
||||||
// stores index of tile palette
|
|
||||||
ChunkData tiles{ 0 };
|
|
||||||
ChunkPalette palette;
|
|
||||||
|
|
||||||
TileIndex getTileIndex(std::uint16_t tileNumber) const {
|
|
||||||
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
|
|
||||||
if (chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
|
|
||||||
return 0;
|
|
||||||
return palette.at(chunkPaletteIndex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
|
||||||
|
|
||||||
typedef std::array<Color, 2> TowerTileColorPalette;
|
|
||||||
|
|
||||||
typedef std::vector<TilePtr> TilePalette;
|
|
||||||
|
|
||||||
typedef std::vector<MobPtr> MobList;
|
|
||||||
|
|
||||||
typedef std::array<Color, 2> SpawnColorPalette;
|
|
||||||
|
|
||||||
typedef std::vector<TowerPtr> TowerList;
|
|
||||||
|
|
||||||
class WorldListener {
|
|
||||||
public:
|
|
||||||
WorldListener(){}
|
|
||||||
|
|
||||||
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter){}
|
|
||||||
|
|
||||||
virtual void OnArrowShot(MobPtr target, Tower* shooter){}
|
|
||||||
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter){}
|
|
||||||
|
|
||||||
virtual void OnMobDamage(MobPtr target, float damage, Tower* damager){}
|
|
||||||
|
|
||||||
virtual void OnMobDead(MobPtr mob){}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef utils::ObjectNotifier<WorldListener> WorldNotifier;
|
|
||||||
|
|
||||||
class World : public WorldNotifier, public WorldListener{
|
|
||||||
protected:
|
|
||||||
TowerTileColorPalette m_TowerPlacePalette;
|
|
||||||
Color m_WalkablePalette;
|
|
||||||
std::vector<Color> m_DecorationPalette;
|
|
||||||
|
|
||||||
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
|
|
||||||
|
|
||||||
SpawnColorPalette m_SpawnColorPalette;
|
|
||||||
|
|
||||||
TilePalette m_TilePalette;
|
|
||||||
|
|
||||||
MobList m_Mobs;
|
|
||||||
|
|
||||||
TowerList m_Towers;
|
|
||||||
|
|
||||||
Game* m_Game;
|
|
||||||
public:
|
|
||||||
World(Game* game);
|
|
||||||
|
|
||||||
static constexpr std::uint8_t CastleWidth = 5, CastleHeight = 5;
|
|
||||||
|
|
||||||
bool loadMap(const protocol::WorldBeginDataPacket* worldHeader);
|
|
||||||
bool loadMap(const protocol::WorldDataPacket* worldData);
|
|
||||||
|
|
||||||
bool loadMapFromFile(const std::string& fileName);
|
|
||||||
bool saveMap(const std::string& fileName) const;
|
|
||||||
|
|
||||||
void tick(std::uint64_t delta);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
TilePtr getTile(std::int32_t x, std::int32_t y) const;
|
|
||||||
|
|
||||||
const TowerTileColorPalette& getTowerTileColorPalette() const { return m_TowerPlacePalette; }
|
|
||||||
const Color& getWalkableTileColor() const { return m_WalkablePalette; }
|
|
||||||
const std::vector<Color>& getDecorationPalette() const { return m_DecorationPalette; }
|
|
||||||
|
|
||||||
const TilePalette& getTilePalette() const { return m_TilePalette; }
|
|
||||||
|
|
||||||
TilePtr getTilePtr(TileIndex index) const {
|
|
||||||
if (index == 0)
|
|
||||||
return nullptr;
|
|
||||||
return m_TilePalette.at(index - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID player) const;
|
|
||||||
bool CanPlaceBigTower(const glm::vec2& worldPos, PlayerID player) const;
|
|
||||||
|
|
||||||
TowerPtr getTower(const glm::vec2& position) const; // returns null if no tower is here
|
|
||||||
|
|
||||||
const std::unordered_map<ChunkCoord, ChunkPtr>& getChunks() const { return m_Chunks; }
|
|
||||||
|
|
||||||
const Color& getSpawnColor(TeamColor color) const { return m_SpawnColorPalette[(std::size_t)color]; }
|
|
||||||
const SpawnColorPalette& getSpawnColors() const { return m_SpawnColorPalette; }
|
|
||||||
|
|
||||||
const MobList& getMobList() const { return m_Mobs; }
|
|
||||||
MobList& getMobList() { return m_Mobs; }
|
|
||||||
|
|
||||||
const Color* getTileColor(TilePtr tile) const;
|
|
||||||
|
|
||||||
Team& getRedTeam();
|
|
||||||
const Team& getRedTeam() const;
|
|
||||||
|
|
||||||
Team& getBlueTeam();
|
|
||||||
const Team& getBlueTeam() const;
|
|
||||||
|
|
||||||
Team& getTeam(TeamColor team);
|
|
||||||
const Team& getTeam(TeamColor team) const;
|
|
||||||
|
|
||||||
const TowerList& getTowers() const { return m_Towers; };
|
|
||||||
TowerPtr getTowerById(TowerID tower);
|
|
||||||
|
|
||||||
// WorldListener
|
|
||||||
|
|
||||||
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter);
|
|
||||||
|
|
||||||
virtual void OnArrowShot(MobPtr target, Tower* shooter);
|
|
||||||
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter);
|
|
||||||
|
|
||||||
virtual void OnMobDamage(MobPtr target, float damage, Tower* source);
|
|
||||||
private:
|
|
||||||
void moveMobs(std::uint64_t delta);
|
|
||||||
void moveMob(MobPtr mob, std::uint64_t delta);
|
|
||||||
void moveBackMob(MobPtr mob, const TeamCastle& castle);
|
|
||||||
void changeMobDirection(MobPtr mob, WalkableTilePtr tile);
|
|
||||||
bool isMobTouchingCastle(MobPtr mob, const TeamCastle& castle) const;
|
|
||||||
void tickMobs(std::uint64_t delta);
|
|
||||||
void cleanDeadMobs();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ClientConnexion.h"
|
|
||||||
#include "ClientGame.h"
|
|
||||||
|
|
||||||
#include "game/Team.h"
|
|
||||||
#include "game/Player.h"
|
|
||||||
|
|
||||||
#include "protocol/Protocol.h"
|
|
||||||
|
|
||||||
#include "render/Renderer.h"
|
|
||||||
|
|
||||||
#include "network/Network.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace client {
|
|
||||||
|
|
||||||
class Client {
|
|
||||||
private:
|
|
||||||
render::Renderer* m_Renderer;
|
|
||||||
ClientConnexion m_Connexion;
|
|
||||||
ClientGame m_Game;
|
|
||||||
bool m_Connected;
|
|
||||||
public:
|
|
||||||
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(this), m_Connected(false) {}
|
|
||||||
|
|
||||||
const ClientGame& getGame() const { return m_Game; }
|
|
||||||
const ClientConnexion& getConnexion() const { return m_Connexion; }
|
|
||||||
render::Renderer* getRenderer() const { return m_Renderer; }
|
|
||||||
|
|
||||||
ClientGame& getGame() { return m_Game; }
|
|
||||||
ClientConnexion& getConnexion() { return m_Connexion; }
|
|
||||||
|
|
||||||
void tick(std::uint64_t delta);
|
|
||||||
|
|
||||||
void render();
|
|
||||||
|
|
||||||
bool connect(const network::IPAddresses& addresses, std::uint16_t port);
|
|
||||||
void closeConnection();
|
|
||||||
|
|
||||||
bool isConnected() const { return m_Connexion.getSocketStatus() == network::Socket::Connected; }
|
|
||||||
|
|
||||||
void selectTeam(game::TeamColor team);
|
|
||||||
void sendMobs(const std::vector<protocol::MobSend>& mobSends);
|
|
||||||
void placeTower(game::TowerType type, const glm::vec2& position);
|
|
||||||
void upgradeTower(game::TowerID tower, game::TowerLevel level);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace client
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "protocol/PacketHandler.h"
|
|
||||||
#include "network/TCPSocket.h"
|
|
||||||
#include "game/Connexion.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace client {
|
|
||||||
|
|
||||||
class ClientConnexion : public protocol::Connexion {
|
|
||||||
private:
|
|
||||||
std::uint8_t m_ConnectionID;
|
|
||||||
std::string m_DisconnectReason;
|
|
||||||
float m_ServerTPS;
|
|
||||||
int m_Ping = 0;
|
|
||||||
public:
|
|
||||||
ClientConnexion();
|
|
||||||
|
|
||||||
virtual bool updateSocket();
|
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::KeepAlivePacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::DisconnectPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::ServerTpsPacket* packet);
|
|
||||||
|
|
||||||
const std::string& getDisconnectReason() const { return m_DisconnectReason; }
|
|
||||||
float getServerTPS() const { return m_ServerTPS; }
|
|
||||||
int getServerPing() const { return m_Ping; }
|
|
||||||
|
|
||||||
REMOVE_COPY(ClientConnexion);
|
|
||||||
private:
|
|
||||||
void registerHandlers();
|
|
||||||
void login();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace client
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/BaseGame.h"
|
|
||||||
|
|
||||||
#include "protocol/PacketHandler.h"
|
|
||||||
|
|
||||||
#include "WorldClient.h"
|
|
||||||
|
|
||||||
#include "render/WorldRenderer.h"
|
|
||||||
#include "render/Renderer.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace client {
|
|
||||||
|
|
||||||
class Client;
|
|
||||||
|
|
||||||
class ClientGame : public protocol::PacketHandler, public game::Game {
|
|
||||||
private:
|
|
||||||
Client* m_Client;
|
|
||||||
std::uint8_t m_ConnexionID;
|
|
||||||
std::uint32_t m_LobbyTime = 0;
|
|
||||||
game::Player* m_Player = nullptr;
|
|
||||||
render::Renderer* m_Renderer;
|
|
||||||
client::WorldClient m_WorldClient;
|
|
||||||
render::WorldRenderer m_WorldRenderer;
|
|
||||||
public:
|
|
||||||
ClientGame(Client* client);
|
|
||||||
virtual ~ClientGame();
|
|
||||||
|
|
||||||
virtual void tick(std::uint64_t delta);
|
|
||||||
|
|
||||||
void renderWorld();
|
|
||||||
|
|
||||||
std::uint32_t getLobbyTime() const { return m_LobbyTime; }
|
|
||||||
const game::Player* getPlayer() const { return m_Player; }
|
|
||||||
const WorldClient& getWorld() const { return m_WorldClient; }
|
|
||||||
Client* getClient() const { return m_Client; }
|
|
||||||
|
|
||||||
render::Renderer* getRenderer() const { return m_Renderer; }
|
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::PlayerListPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::UpdatePlayerTeamPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::UpdateLobbyTimePacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::UpdateMoneyPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::DisconnectPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::WorldDataPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace client
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/World.h"
|
|
||||||
#include "protocol/PacketHandler.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace client {
|
|
||||||
|
|
||||||
class ClientGame;
|
|
||||||
|
|
||||||
class WorldClient : public game::World, public protocol::PacketHandler {
|
|
||||||
private:
|
|
||||||
ClientGame* m_Game;
|
|
||||||
public:
|
|
||||||
WorldClient(ClientGame* game);
|
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::WorldBeginDataPacket* packet) override;
|
|
||||||
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
|
|
||||||
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
|
|
||||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
|
||||||
|
|
||||||
virtual void OnArrowShot(game::MobPtr target, game::Tower* shooter) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace client
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "misc/Time.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace server {
|
|
||||||
|
|
||||||
class Server;
|
|
||||||
|
|
||||||
class Lobby {
|
|
||||||
private:
|
|
||||||
Server* m_Server;
|
|
||||||
bool m_GameStarted = false;
|
|
||||||
std::uint64_t m_StartTimerTime = 0;
|
|
||||||
std::vector<std::uint8_t> m_Players;
|
|
||||||
utils::AutoTimer m_Timer;
|
|
||||||
public:
|
|
||||||
Lobby(Server* server);
|
|
||||||
|
|
||||||
void OnPlayerJoin(std::uint8_t playerID);
|
|
||||||
void OnPlayerLeave(std::uint8_t playerID);
|
|
||||||
|
|
||||||
void sendTimeRemaining();
|
|
||||||
|
|
||||||
void tick();
|
|
||||||
|
|
||||||
//static constexpr int LobbyWaitingTime = 2 * 60 * 1000; // in millis
|
|
||||||
static constexpr int LobbyWaitingTime = 5 * 1000; // in millis
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace server
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <map>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "network/TCPListener.h"
|
|
||||||
#include "protocol/Protocol.h"
|
|
||||||
#include "protocol/PacketDispatcher.h"
|
|
||||||
#include "protocol/PacketHandler.h"
|
|
||||||
#include "ServerGame.h"
|
|
||||||
#include "ServerConnexion.h"
|
|
||||||
#include "Lobby.h"
|
|
||||||
|
|
||||||
#define SERVER_TPS 20
|
|
||||||
#define SERVER_TICK 1000 / SERVER_TPS
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace server {
|
|
||||||
|
|
||||||
typedef std::map<std::uint8_t, ServerConnexion> ConnexionMap;
|
|
||||||
|
|
||||||
class TickCounter {
|
|
||||||
private:
|
|
||||||
float m_TPS;
|
|
||||||
std::uint64_t m_LastTPSTime;
|
|
||||||
std::uint8_t m_TickCount;
|
|
||||||
public:
|
|
||||||
TickCounter() {}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
m_TPS = SERVER_TPS;
|
|
||||||
m_LastTPSTime = utils::getTime();
|
|
||||||
m_TickCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool update() { // return true when tps is updated
|
|
||||||
m_TickCount++;
|
|
||||||
if (m_TickCount >= SERVER_TPS) {
|
|
||||||
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::getTime() - m_LastTPSTime;
|
|
||||||
m_TPS = (float)SERVER_TPS / (float)(timeElapsedSinceLast20Ticks / 1000.0f);
|
|
||||||
m_TickCount = 0;
|
|
||||||
m_LastTPSTime = td::utils::getTime();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getTPS() const { return m_TPS; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Server {
|
|
||||||
private:
|
|
||||||
network::TCPListener m_Listener;
|
|
||||||
ConnexionMap m_Connections;
|
|
||||||
ServerGame m_Game{ this };
|
|
||||||
Lobby m_Lobby{ this };
|
|
||||||
TickCounter m_TickCounter;
|
|
||||||
|
|
||||||
std::thread m_Thread;
|
|
||||||
bool m_ServerRunning;
|
|
||||||
public:
|
|
||||||
Server(const std::string& worldFilePath);
|
|
||||||
virtual ~Server() {}
|
|
||||||
|
|
||||||
bool start(std::uint16_t port);
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
void lauchGame();
|
|
||||||
|
|
||||||
void removeConnexion(std::uint8_t connexionID);
|
|
||||||
|
|
||||||
void broadcastPacket(const protocol::Packet* packet);
|
|
||||||
|
|
||||||
float getTPS() const { return m_TickCounter.getTPS(); }
|
|
||||||
|
|
||||||
const ServerGame& getGame() const { return m_Game; }
|
|
||||||
ServerGame& getGame() { return m_Game; }
|
|
||||||
|
|
||||||
const Lobby& getLobby() const { return m_Lobby; }
|
|
||||||
const ConnexionMap& getConnexions() const { return m_Connections; }
|
|
||||||
ConnexionMap& getConnexions() { return m_Connections; }
|
|
||||||
|
|
||||||
const game::PlayerList& getPlayers() const { return m_Game.getPlayers(); }
|
|
||||||
game::PlayerList& getPlayers() { return m_Game.getPlayers(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void accept();
|
|
||||||
void updateSockets();
|
|
||||||
|
|
||||||
void startThread();
|
|
||||||
void stopThread();
|
|
||||||
void tick(std::uint64_t delta);
|
|
||||||
|
|
||||||
void OnPlayerJoin(std::uint8_t id);
|
|
||||||
void OnPlayerLeave(std::uint8_t id);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace server
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "network/TCPSocket.h"
|
|
||||||
#include "protocol/PacketHandler.h"
|
|
||||||
#include "protocol/PacketDispatcher.h"
|
|
||||||
#include "game/Player.h"
|
|
||||||
#include "game/Connexion.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace server {
|
|
||||||
|
|
||||||
class Server;
|
|
||||||
|
|
||||||
struct KeepAlive
|
|
||||||
{
|
|
||||||
std::uint64_t keepAliveID = 0;
|
|
||||||
std::uint64_t sendTime;
|
|
||||||
bool recievedResponse = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ServerConnexion : public protocol::Connexion {
|
|
||||||
private:
|
|
||||||
Server* m_Server = nullptr;
|
|
||||||
std::uint8_t m_ID;
|
|
||||||
KeepAlive m_KeepAlive;
|
|
||||||
game::Player* m_Player;
|
|
||||||
public:
|
|
||||||
ServerConnexion();
|
|
||||||
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
|
|
||||||
ServerConnexion(ServerConnexion&& move);
|
|
||||||
virtual ~ServerConnexion();
|
|
||||||
|
|
||||||
void setServer(Server* server);
|
|
||||||
|
|
||||||
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::KeepAlivePacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::SelectTeamPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::DisconnectPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::SendMobsPacket* packet);
|
|
||||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
|
|
||||||
|
|
||||||
std::uint8_t getID() const { return m_ID; }
|
|
||||||
const game::Player* getPlayer() const { return m_Player; }
|
|
||||||
game::Player* getPlayer() { return m_Player; }
|
|
||||||
|
|
||||||
virtual bool updateSocket();
|
|
||||||
|
|
||||||
REMOVE_COPY(ServerConnexion);
|
|
||||||
private:
|
|
||||||
void registerHandlers();
|
|
||||||
void checkKeepAlive();
|
|
||||||
void sendKeepAlive();
|
|
||||||
void initConnection();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace server
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/BaseGame.h"
|
|
||||||
#include "misc/Time.h"
|
|
||||||
#include "ServerWorld.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace server {
|
|
||||||
|
|
||||||
class Server;
|
|
||||||
|
|
||||||
class ServerGame : public game::Game {
|
|
||||||
private:
|
|
||||||
Server* m_Server;
|
|
||||||
ServerWorld m_ServerWorld;
|
|
||||||
utils::AutoTimer m_GoldMineTimer{ 1000, std::bind(&ServerGame::updateGoldMines, this) };
|
|
||||||
public:
|
|
||||||
ServerGame(Server* server);
|
|
||||||
~ServerGame() {}
|
|
||||||
|
|
||||||
ServerWorld* getServerWorld() { return &m_ServerWorld; }
|
|
||||||
|
|
||||||
virtual void tick(std::uint64_t delta);
|
|
||||||
void startGame();
|
|
||||||
private:
|
|
||||||
void balanceTeams();
|
|
||||||
void updateGoldMines();
|
|
||||||
void updatePlayerStats();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace game
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/World.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace server {
|
|
||||||
|
|
||||||
class Server;
|
|
||||||
class ServerGame;
|
|
||||||
|
|
||||||
class ServerWorld : public game::World {
|
|
||||||
private:
|
|
||||||
game::MobID m_CurrentMobID;
|
|
||||||
game::TowerID m_CurrentTowerID;
|
|
||||||
Server* m_Server;
|
|
||||||
public:
|
|
||||||
ServerWorld(Server* server, ServerGame* game);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
virtual void OnArrowShot(game::MobPtr target, game::Tower* shooter) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace server
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
#ifndef MCLIB_COMMON_DATA_BUFFER_H_
|
|
||||||
#define MCLIB_COMMON_DATA_BUFFER_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
|
|
||||||
class DataBuffer {
|
|
||||||
private:
|
|
||||||
typedef std::vector<std::uint8_t> Data;
|
|
||||||
Data m_Buffer;
|
|
||||||
std::size_t m_ReadOffset = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Data::iterator iterator;
|
|
||||||
typedef Data::const_iterator const_iterator;
|
|
||||||
typedef Data::reference reference;
|
|
||||||
typedef Data::const_reference const_reference;
|
|
||||||
|
|
||||||
DataBuffer();
|
|
||||||
DataBuffer(const DataBuffer& other);
|
|
||||||
DataBuffer(const DataBuffer& other, std::size_t offset);
|
|
||||||
DataBuffer(DataBuffer&& other);
|
|
||||||
DataBuffer(const std::string& str);
|
|
||||||
|
|
||||||
DataBuffer& operator=(const DataBuffer& other);
|
|
||||||
DataBuffer& operator=(DataBuffer&& other);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Append(T data) {
|
|
||||||
std::size_t size = sizeof(data);
|
|
||||||
std::size_t end_pos = m_Buffer.size();
|
|
||||||
m_Buffer.resize(m_Buffer.size() + size);
|
|
||||||
memcpy(&m_Buffer[end_pos], &data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
DataBuffer& operator<<(T data) {
|
|
||||||
// Switch to big endian
|
|
||||||
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
|
||||||
Append(data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataBuffer& operator<<(std::string str) {
|
|
||||||
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataBuffer& operator<<(DataBuffer& data) {
|
|
||||||
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataBuffer& operator<<(const DataBuffer& data) {
|
|
||||||
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
DataBuffer& operator>>(T& data) {
|
|
||||||
assert(m_ReadOffset + sizeof(T) <= GetSize());
|
|
||||||
data = *(T*)&m_Buffer[m_ReadOffset];
|
|
||||||
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
|
||||||
m_ReadOffset += sizeof(T);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataBuffer& operator>>(DataBuffer& data) {
|
|
||||||
data.Resize(GetSize() - m_ReadOffset);
|
|
||||||
std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.end(), data.begin());
|
|
||||||
m_ReadOffset = m_Buffer.size();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataBuffer& operator>>(std::string& str) {
|
|
||||||
std::size_t stringSize = strlen((const char*)m_Buffer.data() + m_ReadOffset) + 1; // including null character
|
|
||||||
str.resize(stringSize);
|
|
||||||
std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.begin() + m_ReadOffset + stringSize, str.begin());
|
|
||||||
m_ReadOffset += stringSize;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadSome(char* buffer, std::size_t amount) {
|
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
|
||||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer);
|
|
||||||
m_ReadOffset += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
|
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
|
||||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer);
|
|
||||||
m_ReadOffset += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadSome(DataBuffer& buffer, std::size_t amount) {
|
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
|
||||||
buffer.Resize(amount);
|
|
||||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer.begin());
|
|
||||||
m_ReadOffset += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadSome(std::string& buffer, std::size_t amount) {
|
|
||||||
assert(m_ReadOffset + amount <= GetSize());
|
|
||||||
buffer.resize(amount);
|
|
||||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer.begin());
|
|
||||||
m_ReadOffset += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resize(std::size_t size) {
|
|
||||||
m_Buffer.resize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reserve(std::size_t amount) {
|
|
||||||
m_Buffer.reserve(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase(iterator it) {
|
|
||||||
m_Buffer.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() {
|
|
||||||
m_Buffer.clear();
|
|
||||||
m_ReadOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsFinished() const {
|
|
||||||
return m_ReadOffset >= m_Buffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint8_t* data() {
|
|
||||||
return m_Buffer.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::uint8_t* data() const {
|
|
||||||
return m_Buffer.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t GetReadOffset() const { return m_ReadOffset; }
|
|
||||||
void SetReadOffset(std::size_t pos);
|
|
||||||
|
|
||||||
std::string ToString() const;
|
|
||||||
std::size_t GetSize() const;
|
|
||||||
bool IsEmpty() const;
|
|
||||||
std::size_t GetRemaining() const;
|
|
||||||
|
|
||||||
iterator begin();
|
|
||||||
iterator end();
|
|
||||||
const_iterator begin() const;
|
|
||||||
const_iterator end() const;
|
|
||||||
|
|
||||||
reference operator[](Data::size_type i) { return m_Buffer[i]; }
|
|
||||||
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
|
|
||||||
|
|
||||||
bool ReadFile(const std::string& fileName);
|
|
||||||
bool WriteFile(const std::string& fileName);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
|
|
||||||
|
|
||||||
} // ns td
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace utils {
|
|
||||||
|
|
||||||
constexpr float PI = 3.14159274101257324219;
|
|
||||||
|
|
||||||
/* Sine functions */
|
|
||||||
|
|
||||||
float easeInSine(float x);
|
|
||||||
float easeOutSine(float x);
|
|
||||||
float easeInOutSine(float x);
|
|
||||||
|
|
||||||
/* Cubic functions */
|
|
||||||
|
|
||||||
float easeInCubic(float x);
|
|
||||||
float easeOutCubic(float x);
|
|
||||||
float easeInOutCubic(float x);
|
|
||||||
|
|
||||||
/* Quint functions */
|
|
||||||
|
|
||||||
float easeInQuint(float x);
|
|
||||||
float easeOutQuint(float x);
|
|
||||||
float easeInOutQuint(float x);
|
|
||||||
|
|
||||||
/* Circ functions */
|
|
||||||
|
|
||||||
float easeInCirc(float x);
|
|
||||||
float easeOutCirc(float x);
|
|
||||||
float easeInOutCirc(float x);
|
|
||||||
|
|
||||||
/* Elastic functions */
|
|
||||||
|
|
||||||
float easeInElastic(float x);
|
|
||||||
float easeOutElastic(float x);
|
|
||||||
float easeInOutElastic(float x);
|
|
||||||
|
|
||||||
/* Quad functions */
|
|
||||||
|
|
||||||
float easeInQuad(float x);
|
|
||||||
float easeOutQuad(float x);
|
|
||||||
float easeInOutQuad(float x);
|
|
||||||
|
|
||||||
/* Quart functions */
|
|
||||||
|
|
||||||
float easeInQuart(float x);
|
|
||||||
float easeOutQuart(float x);
|
|
||||||
float easeInOutQuart(float x);
|
|
||||||
|
|
||||||
/* Expo functions */
|
|
||||||
|
|
||||||
float easeInExpo(float x);
|
|
||||||
float easeOutExpo(float x);
|
|
||||||
float easeInOutExpo(float x);
|
|
||||||
|
|
||||||
/* Back functions */
|
|
||||||
|
|
||||||
float easeInBack(float x);
|
|
||||||
float easeOutBack(float x);
|
|
||||||
float easeInOutBack(float x);
|
|
||||||
|
|
||||||
/* Bounce functions */
|
|
||||||
|
|
||||||
float easeInBounce(float x);
|
|
||||||
float easeOutBounce(float x);
|
|
||||||
float easeInOutBounce(float x);
|
|
||||||
|
|
||||||
} // namespace utils
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace utils {
|
|
||||||
|
|
||||||
template <typename Listener>
|
|
||||||
class ObjectNotifier {
|
|
||||||
protected:
|
|
||||||
std::vector<Listener*> m_Listeners;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void bindListener(Listener* listener) {
|
|
||||||
m_Listeners.push_back(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unbindListener(Listener* listener) {
|
|
||||||
auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);
|
|
||||||
|
|
||||||
if(iter == m_Listeners.end()) return;
|
|
||||||
|
|
||||||
m_Listeners.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Func, typename... Args>
|
|
||||||
void notifyListeners(Func function, Args... args) {
|
|
||||||
for (Listener* listener : m_Listeners)
|
|
||||||
std::bind(function, listener, args...)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace utils
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace utils {
|
|
||||||
|
|
||||||
template<typename NumberType>
|
|
||||||
NumberType getRandomInt(NumberType min, NumberType max) {
|
|
||||||
std::random_device randomDevice;
|
|
||||||
std::mt19937 generator(randomDevice());
|
|
||||||
std::uniform_int_distribution<NumberType> distrib(min, max);
|
|
||||||
return distrib(generator);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NumberType>
|
|
||||||
NumberType getRandomReal(NumberType min, NumberType max) {
|
|
||||||
std::random_device randomDevice;
|
|
||||||
std::mt19937 generator(randomDevice());
|
|
||||||
std::uniform_real_distribution<NumberType> distrib(min, max);
|
|
||||||
return distrib(generator);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace utils
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace utils {
|
|
||||||
namespace shape {
|
|
||||||
|
|
||||||
class Point {
|
|
||||||
private:
|
|
||||||
float m_X, m_Y;
|
|
||||||
public:
|
|
||||||
Point() : m_X(0), m_Y(0) {}
|
|
||||||
Point(float x, float y) : m_X(x), m_Y(y) {}
|
|
||||||
|
|
||||||
float getX() const { return m_X; }
|
|
||||||
float getY() const { return m_Y; }
|
|
||||||
|
|
||||||
void setX(float x) { m_X = x; }
|
|
||||||
void setY(float y) { m_Y = y; }
|
|
||||||
|
|
||||||
float distance(const Point& point) const;
|
|
||||||
float distanceSquared(const Point& point) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Circle;
|
|
||||||
|
|
||||||
class Rectangle {
|
|
||||||
private:
|
|
||||||
Point m_Center;
|
|
||||||
float m_Width, m_Height;
|
|
||||||
public:
|
|
||||||
Rectangle() {}
|
|
||||||
|
|
||||||
const Point& getCenter() const { return m_Center; }
|
|
||||||
float getCenterX() const { return m_Center.getX(); }
|
|
||||||
float getCenterY() const { return m_Center.getY(); }
|
|
||||||
|
|
||||||
float getWidth() const { return m_Width; }
|
|
||||||
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 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 setCenterX(float x) { m_Center.setX(x); }
|
|
||||||
void setCenterY(float y) { m_Center.setY(y); }
|
|
||||||
|
|
||||||
void setSize(float width, float height) { setWidth(width); setHeight(height); }
|
|
||||||
void setWidth(float width) { m_Width = width; }
|
|
||||||
void setHeight(float height) { m_Height = height; }
|
|
||||||
|
|
||||||
bool collidesWith(const Point& point) const;
|
|
||||||
bool collidesWith(const Rectangle& rect) const;
|
|
||||||
bool collidesWith(const Circle& circle) const;
|
|
||||||
|
|
||||||
// distance from the closest side of the rectangle
|
|
||||||
float distance(const Circle& circle) const;
|
|
||||||
float distanceSquared(const Circle& circle) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Circle {
|
|
||||||
private:
|
|
||||||
Point m_Center;
|
|
||||||
float m_Radius;
|
|
||||||
public:
|
|
||||||
Circle(float x, float y, float radius) : m_Center(x, y), m_Radius(radius) {}
|
|
||||||
Circle() : m_Radius(0) {}
|
|
||||||
|
|
||||||
const Point& getCenter() const { return m_Center; }
|
|
||||||
float getCenterX() const { return m_Center.getX(); }
|
|
||||||
float getCenterY() const { return m_Center.getY(); }
|
|
||||||
|
|
||||||
float getRadius() const { return m_Radius; }
|
|
||||||
|
|
||||||
void setCenter(const Point& center) { m_Center = center; }
|
|
||||||
void setCenterX(float x) { m_Center.setX(x); }
|
|
||||||
void setCenterY(float y) { m_Center.setY(y); }
|
|
||||||
|
|
||||||
void setRadius(float radius) { m_Radius = radius; }
|
|
||||||
|
|
||||||
bool collidesWith(const Point& point) const;
|
|
||||||
bool collidesWith(const Rectangle& rect) const;
|
|
||||||
bool collidesWith(const Circle& circle) const;
|
|
||||||
|
|
||||||
// distance from the closest side of the rectangle
|
|
||||||
float distance(const Rectangle& rect) const;
|
|
||||||
float distanceSquared(const Rectangle& rect) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace shape
|
|
||||||
} // namespace utils
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace utils {
|
|
||||||
|
|
||||||
std::uint64_t getTime();
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::function<void()> TimerExecFunction;
|
|
||||||
|
|
||||||
// utililty class to call function at regular period of time
|
|
||||||
class AutoTimer {
|
|
||||||
private:
|
|
||||||
std::uint64_t m_Interval;
|
|
||||||
TimerExecFunction m_Function;
|
|
||||||
|
|
||||||
std::uint64_t m_LastTime = getTime();
|
|
||||||
std::uint64_t m_InternalTime = 0;
|
|
||||||
public:
|
|
||||||
AutoTimer() : m_Interval(0), 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) {}
|
|
||||||
|
|
||||||
void update();
|
|
||||||
void update(std::uint64_t delta);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void setInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
|
|
||||||
std::uint64_t getInterval() const { return m_Interval; }
|
|
||||||
|
|
||||||
void setCallbackFunction(TimerExecFunction newCallback) { m_Function = newCallback; }
|
|
||||||
TimerExecFunction getCallbackFunction() const { return m_Function; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// utililty class to call function at regular period of time
|
|
||||||
class Timer {
|
|
||||||
private:
|
|
||||||
std::uint64_t m_Interval; // in millis
|
|
||||||
std::uint64_t m_InternalTime = 0;
|
|
||||||
public:
|
|
||||||
Timer() : m_Interval(0) {}
|
|
||||||
Timer(std::uint64_t interval) : m_Interval(interval) {}
|
|
||||||
|
|
||||||
bool update(std::uint64_t delta);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void setInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
|
|
||||||
std::uint64_t getInterval() const { return m_Interval; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// utililty class to call function at regular period of time with a cooldown (used for towers)
|
|
||||||
class CooldownTimer {
|
|
||||||
private:
|
|
||||||
std::uint64_t m_Cooldown; // in millis
|
|
||||||
std::uint64_t m_CooldownTime;
|
|
||||||
public:
|
|
||||||
CooldownTimer() : m_Cooldown(0), m_CooldownTime(0) {}
|
|
||||||
CooldownTimer(std::uint64_t cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
|
|
||||||
|
|
||||||
bool update(std::uint64_t delta);
|
|
||||||
|
|
||||||
void applyCooldown();
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void setCooldown(std::uint64_t newCooldown) { m_CooldownTime = newCooldown; }
|
|
||||||
std::uint64_t getCooldown() const { return m_CooldownTime; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace utils
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#ifndef NETWORK_IPADDRESS_H_
|
|
||||||
#define NETWORK_IPADDRESS_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace network {
|
|
||||||
|
|
||||||
/* IPv4 address */
|
|
||||||
class IPAddress {
|
|
||||||
private:
|
|
||||||
std::uint32_t m_Address;
|
|
||||||
bool m_Valid;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/* Create an invalid address */
|
|
||||||
IPAddress() noexcept;
|
|
||||||
|
|
||||||
/* Initialize by string IP */
|
|
||||||
IPAddress(const std::string& str);
|
|
||||||
|
|
||||||
/* Initialize by string IP */
|
|
||||||
IPAddress(const std::wstring& str);
|
|
||||||
|
|
||||||
/* Initialize by octets */
|
|
||||||
IPAddress(std::uint8_t octet1, std::uint8_t octet2, std::uint8_t octet3, std::uint8_t octet4) noexcept;
|
|
||||||
|
|
||||||
/* Get the specific octet. 1-4 */
|
|
||||||
std::uint8_t GetOctet(std::uint8_t num) const;
|
|
||||||
|
|
||||||
/* Set the specific octet. 1-4 */
|
|
||||||
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. */
|
|
||||||
bool IsValid() const noexcept { return m_Valid; }
|
|
||||||
|
|
||||||
std::string ToString() const;
|
|
||||||
|
|
||||||
static IPAddress LocalAddress();
|
|
||||||
|
|
||||||
bool operator==(const IPAddress& right);
|
|
||||||
bool operator!=(const IPAddress& right);
|
|
||||||
bool operator==(bool b);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<IPAddress> IPAddresses;
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const IPAddress& addr);
|
|
||||||
std::wostream& operator<<(std::wostream& os, const IPAddress& addr);
|
|
||||||
|
|
||||||
} // ns network
|
|
||||||
} // ns td
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
#ifndef NETWORK_SOCKET_H_
|
|
||||||
#define NETWORK_SOCKET_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "misc/DataBuffer.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define closesocket close
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef INVALID_SOCKET
|
|
||||||
#define INVALID_SOCKET -1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define REMOVE_COPY(className) \
|
|
||||||
className(const className &) = delete;\
|
|
||||||
className& operator=(const className &) = delete
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace network {
|
|
||||||
|
|
||||||
class IPAddress;
|
|
||||||
|
|
||||||
typedef int SocketHandle;
|
|
||||||
|
|
||||||
class Socket {
|
|
||||||
public:
|
|
||||||
enum Status { Connected, Disconnected, Error };
|
|
||||||
enum Type { TCP, UDP };
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_Blocking;
|
|
||||||
Type m_Type;
|
|
||||||
Status m_Status;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
SocketHandle m_Handle;
|
|
||||||
|
|
||||||
Socket(Type type);
|
|
||||||
void SetStatus(Status status);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~Socket();
|
|
||||||
|
|
||||||
Socket(Socket&& rhs) = default;
|
|
||||||
Socket& operator=(Socket&& rhs) = default;
|
|
||||||
|
|
||||||
bool SetBlocking(bool block);
|
|
||||||
bool IsBlocking() const noexcept;
|
|
||||||
|
|
||||||
Type GetType() const noexcept;
|
|
||||||
Status GetStatus() const noexcept;
|
|
||||||
SocketHandle GetHandle() const noexcept;
|
|
||||||
|
|
||||||
bool Connect(const std::string& ip, std::uint16_t port);
|
|
||||||
virtual bool Connect(const IPAddress& address, std::uint16_t port) = 0;
|
|
||||||
|
|
||||||
void Disconnect();
|
|
||||||
|
|
||||||
std::size_t Send(const std::string& data);
|
|
||||||
std::size_t Send(DataBuffer& buffer);
|
|
||||||
|
|
||||||
virtual std::size_t Send(const uint8_t* data, std::size_t size) = 0;
|
|
||||||
virtual DataBuffer Receive(std::size_t amount) = 0;
|
|
||||||
|
|
||||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<Socket> SocketPtr;
|
|
||||||
|
|
||||||
} // ns network
|
|
||||||
} // ns td
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "TCPSocket.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace network {
|
|
||||||
|
|
||||||
class TCPListener {
|
|
||||||
int m_Handle;
|
|
||||||
std::uint16_t m_Port;
|
|
||||||
int m_MaxConnections;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TCPListener();
|
|
||||||
~TCPListener();
|
|
||||||
|
|
||||||
bool listen(std::uint16_t port, int maxConnections);
|
|
||||||
bool accept(TCPSocket& newSocket);
|
|
||||||
|
|
||||||
void destroy();
|
|
||||||
bool close();
|
|
||||||
bool setBlocking(bool blocking);
|
|
||||||
|
|
||||||
std::uint16_t getListeningPort() const {
|
|
||||||
return m_Port;
|
|
||||||
}
|
|
||||||
int getMaximumConnections() const {
|
|
||||||
return m_MaxConnections;
|
|
||||||
}
|
|
||||||
|
|
||||||
REMOVE_COPY(TCPListener);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace network
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#ifndef NETWORK_TCP_SOCKET_H_
|
|
||||||
#define NETWORK_TCP_SOCKET_H_
|
|
||||||
|
|
||||||
#include "network/IPAddress.h"
|
|
||||||
#include "network/Socket.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace network {
|
|
||||||
|
|
||||||
class TCPListener;
|
|
||||||
|
|
||||||
class TCPSocket : public Socket {
|
|
||||||
private:
|
|
||||||
IPAddress m_RemoteIP;
|
|
||||||
uint16_t m_Port;
|
|
||||||
sockaddr_in m_RemoteAddr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TCPSocket();
|
|
||||||
TCPSocket(TCPSocket&& other);
|
|
||||||
|
|
||||||
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 DataBuffer Receive(std::size_t amount);
|
|
||||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
|
|
||||||
|
|
||||||
REMOVE_COPY(TCPSocket);
|
|
||||||
|
|
||||||
friend class TCPListener;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SendPacket(const DataBuffer& data, network::TCPSocket& socket);
|
|
||||||
|
|
||||||
} // ns network
|
|
||||||
} // ns td
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#ifndef NETWORK_UDP_SOCKET_H_
|
|
||||||
#define NETWORK_UDP_SOCKET_H_
|
|
||||||
|
|
||||||
#include "network/IPAddress.h"
|
|
||||||
#include "network/Socket.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace network {
|
|
||||||
|
|
||||||
class UDPSocket : public Socket {
|
|
||||||
private:
|
|
||||||
IPAddress m_RemoteIP;
|
|
||||||
uint16_t m_Port;
|
|
||||||
sockaddr_in m_RemoteAddr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
UDPSocket();
|
|
||||||
|
|
||||||
bool Connect(const IPAddress& address, std::uint16_t port);
|
|
||||||
std::size_t Send(const std::uint8_t* data, std::size_t size);
|
|
||||||
DataBuffer Receive(std::size_t amount);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // ns network
|
|
||||||
} // ns td
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "protocol/Protocol.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace protocol {
|
|
||||||
|
|
||||||
class PacketHandler;
|
|
||||||
|
|
||||||
class PacketDispatcher {
|
|
||||||
private:
|
|
||||||
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PacketDispatcher() = default;
|
|
||||||
|
|
||||||
PacketDispatcher(const PacketDispatcher& rhs) = delete;
|
|
||||||
PacketDispatcher& operator=(const PacketDispatcher& rhs) = delete;
|
|
||||||
PacketDispatcher(PacketDispatcher&& rhs) = delete;
|
|
||||||
PacketDispatcher& operator=(PacketDispatcher&& rhs) = delete;
|
|
||||||
|
|
||||||
void Dispatch(const PacketPtr& packet);
|
|
||||||
|
|
||||||
void RegisterHandler(PacketType type, PacketHandler* handler);
|
|
||||||
void UnregisterHandler(PacketType type, PacketHandler* handler);
|
|
||||||
void UnregisterHandler(PacketHandler* handler);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace protocol
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "protocol/Protocol.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace protocol {
|
|
||||||
|
|
||||||
class PacketDispatcher;
|
|
||||||
|
|
||||||
class PacketHandler {
|
|
||||||
private:
|
|
||||||
PacketDispatcher* m_Dispatcher;
|
|
||||||
public:
|
|
||||||
PacketHandler(PacketDispatcher* dispatcher) : m_Dispatcher(dispatcher) {}
|
|
||||||
virtual ~PacketHandler() {}
|
|
||||||
|
|
||||||
PacketDispatcher* GetDispatcher() { return m_Dispatcher; }
|
|
||||||
|
|
||||||
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const WorldBeginDataPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const WorldDataPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const KeepAlivePacket* packet) {}
|
|
||||||
virtual void HandlePacket(const UpdateMoneyPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const UpdateExpPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const UpdateLobbyTimePacket* packet) {}
|
|
||||||
virtual void HandlePacket(const UpdateGameStatePacket* packet) {}
|
|
||||||
virtual void HandlePacket(const PlayerListPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const PlayerJoinPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const PlayerLeavePacket* packet) {}
|
|
||||||
virtual void HandlePacket(const ConnexionInfoPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const SelectTeamPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const UpdatePlayerTeamPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const DisconnectPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const ServerTpsPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const SpawnMobPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const PlaceTowerPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const WorldAddTowerPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const WorldRemoveTowerPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const SendMobsPacket* packet) {}
|
|
||||||
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace protocol
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,517 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "misc/DataBuffer.h"
|
|
||||||
#include "game/World.h"
|
|
||||||
#include "game/BaseGame.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace protocol {
|
|
||||||
|
|
||||||
class PacketHandler;
|
|
||||||
|
|
||||||
enum class PacketType : std::uint8_t {
|
|
||||||
// client --> server
|
|
||||||
PlayerLogin = 0,
|
|
||||||
SelectTeam,
|
|
||||||
SpawnMob,
|
|
||||||
SendMobs,
|
|
||||||
PlaceTower,
|
|
||||||
|
|
||||||
// client <-- server
|
|
||||||
PlayerJoin,
|
|
||||||
PlayerLeave,
|
|
||||||
WorldBeginData,
|
|
||||||
WorldData,
|
|
||||||
UpdateMoney,
|
|
||||||
UpdateEXP,
|
|
||||||
UpdateLobbyTime,
|
|
||||||
UpdateGameState,
|
|
||||||
PlayerList,
|
|
||||||
ConnectionInfo,
|
|
||||||
UpdatePlayerTeam,
|
|
||||||
ServerTps,
|
|
||||||
WorldAddTower,
|
|
||||||
WorldRemoveTower,
|
|
||||||
|
|
||||||
// client <--> server
|
|
||||||
KeepAlive,
|
|
||||||
Disconnect,
|
|
||||||
UpgradeTower,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WorldHeader {
|
|
||||||
game::TowerTileColorPalette m_TowerPlacePalette;
|
|
||||||
game::Color m_WalkablePalette;
|
|
||||||
std::vector<game::Color> m_DecorationPalette;
|
|
||||||
|
|
||||||
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 {
|
|
||||||
public:
|
|
||||||
Packet() {}
|
|
||||||
virtual ~Packet() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize() const = 0;
|
|
||||||
virtual void Deserialize(DataBuffer& data) = 0;
|
|
||||||
virtual void Dispatch(PacketHandler* handler) const = 0;
|
|
||||||
|
|
||||||
virtual PacketType getType() const = 0;
|
|
||||||
std::uint8_t getID() const { return (std::uint8_t)getType(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::unique_ptr<Packet> PacketPtr;
|
|
||||||
|
|
||||||
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() 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() 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() 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::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; }
|
|
||||||
|
|
||||||
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
|
|
||||||
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() 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() 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() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize() 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() 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() 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() 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() 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() 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() 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() 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() 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() 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() 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;
|
|
||||||
game::MobLevel mobLevel;
|
|
||||||
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() 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() 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() 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() 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 WorldRemoveTowerPacket : public Packet {
|
|
||||||
private:
|
|
||||||
game::TowerID m_TowerID;
|
|
||||||
public:
|
|
||||||
WorldRemoveTowerPacket() {}
|
|
||||||
WorldRemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
|
|
||||||
virtual ~WorldRemoveTowerPacket() {}
|
|
||||||
|
|
||||||
virtual DataBuffer Serialize() 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::WorldRemoveTower; }
|
|
||||||
};
|
|
||||||
|
|
||||||
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() 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; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#include <GLES3/gl3.h>
|
|
||||||
#else
|
|
||||||
#include "glbinding/gl/gl.h"
|
|
||||||
using namespace gl;
|
|
||||||
#endif
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Renderer.h
|
|
||||||
*
|
|
||||||
* Created on: 4 nov. 2020
|
|
||||||
* Author: simon
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RENDER_RENDERER_H_
|
|
||||||
#define RENDER_RENDERER_H_
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <memory>
|
|
||||||
#include "loader/GLLoader.h"
|
|
||||||
#include "render/shaders/WorldShader.h"
|
|
||||||
#include "render/shaders/EntityShader.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace render {
|
|
||||||
|
|
||||||
class Renderer {
|
|
||||||
public:
|
|
||||||
static constexpr float m_AnimationSpeed = 2.0f;
|
|
||||||
|
|
||||||
struct Model {
|
|
||||||
GL::VertexArray* vao;
|
|
||||||
glm::vec2 positon;
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
std::unique_ptr<WorldShader> m_WorldShader;
|
|
||||||
std::unique_ptr<EntityShader> m_EntityShader;
|
|
||||||
|
|
||||||
bool m_IsometricView = true;
|
|
||||||
float m_IsometricShade = m_IsometricView;
|
|
||||||
glm::vec2 m_CamPos{};
|
|
||||||
public:
|
|
||||||
Renderer();
|
|
||||||
~Renderer();
|
|
||||||
|
|
||||||
bool init();
|
|
||||||
|
|
||||||
void prepare();
|
|
||||||
void resize(const int width, const int height);
|
|
||||||
|
|
||||||
void renderVAO(const GL::VertexArray& vao);
|
|
||||||
void renderModel(const Model& model);
|
|
||||||
|
|
||||||
void setZoom(float zoom);
|
|
||||||
void setCamMovement(const glm::vec2& mov);
|
|
||||||
void setCamPos(const glm::vec2& newPos);
|
|
||||||
void setIsometricView(bool isometric); // false = 2D true = Isometric
|
|
||||||
|
|
||||||
glm::vec2 getCursorWorldPos(const glm::vec2& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight);
|
|
||||||
private:
|
|
||||||
void updateIsometricView();
|
|
||||||
void updateIsometricFade();
|
|
||||||
void initShader();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace render
|
|
||||||
} // namespace td
|
|
||||||
|
|
||||||
#endif /* RENDER_RENDERER_H_ */
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#include <unordered_map>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "render/loader/GLLoader.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace render {
|
|
||||||
|
|
||||||
|
|
||||||
class VertexCache {
|
|
||||||
|
|
||||||
typedef std::vector<float> Vector;
|
|
||||||
typedef std::pair<Vector::iterator, Vector::iterator> ElementsIndex;
|
|
||||||
typedef std::pair<ElementsIndex, ElementsIndex> DataIndex;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Vector m_Positions;
|
|
||||||
Vector m_Colors;
|
|
||||||
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
|
|
||||||
std::unique_ptr<GL::VertexArray> m_VertexArray;
|
|
||||||
public:
|
|
||||||
void addData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
|
|
||||||
void removeData(std::uint64_t index);
|
|
||||||
void clear();
|
|
||||||
void updateVertexArray();
|
|
||||||
|
|
||||||
const GL::VertexArray& getVertexArray() const { return *m_VertexArray; }
|
|
||||||
bool isEmpty() const { return m_VertexArray == nullptr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace render
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/World.h"
|
|
||||||
|
|
||||||
#include "render/Renderer.h"
|
|
||||||
#include "render/VertexCache.h"
|
|
||||||
|
|
||||||
#include "render/gui/TowerPlacePopup.h"
|
|
||||||
#include "render/gui/MobTooltip.h"
|
|
||||||
|
|
||||||
#include "render/gui/imgui/imgui.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
|
|
||||||
namespace client {
|
|
||||||
|
|
||||||
class ClientGame;
|
|
||||||
|
|
||||||
} // namespace client
|
|
||||||
|
|
||||||
|
|
||||||
namespace render {
|
|
||||||
|
|
||||||
class WorldRenderer {
|
|
||||||
private:
|
|
||||||
client::ClientGame* m_Client;
|
|
||||||
Renderer* m_Renderer;
|
|
||||||
game::World* m_World;
|
|
||||||
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
|
|
||||||
glm::vec2 m_CamPos;
|
|
||||||
glm::vec2 m_CursorPos;
|
|
||||||
glm::vec2 m_HoldCursorPos;
|
|
||||||
glm::vec2 m_LastClicked;
|
|
||||||
float m_Zoom;
|
|
||||||
float m_CamSensibility = 1;
|
|
||||||
bool m_PopupOpened = false;
|
|
||||||
VertexCache m_TowersCache;
|
|
||||||
|
|
||||||
std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
|
|
||||||
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
|
|
||||||
public:
|
|
||||||
WorldRenderer(game::World* world, client::ClientGame* client);
|
|
||||||
~WorldRenderer();
|
|
||||||
|
|
||||||
void loadModels();
|
|
||||||
|
|
||||||
void addTower(game::TowerPtr tower);
|
|
||||||
void removeTower(game::TowerPtr tower);
|
|
||||||
|
|
||||||
static ImVec4 getImGuiTeamColor(game::TeamColor color);
|
|
||||||
|
|
||||||
void update();
|
|
||||||
void render();
|
|
||||||
|
|
||||||
void setCamPos(float camX, float camY);
|
|
||||||
|
|
||||||
void moveCam(float relativeX, float relativeY, float aspectRatio);
|
|
||||||
void changeZoom(float zoom);
|
|
||||||
private:
|
|
||||||
void click();
|
|
||||||
void renderWorld() const;
|
|
||||||
void renderTowers() const;
|
|
||||||
void renderMobs() const;
|
|
||||||
void renderTileSelect() const;
|
|
||||||
void renderPopups();
|
|
||||||
void renderTowerUpgradePopup();
|
|
||||||
void renderMobTooltip() const;
|
|
||||||
void detectClick();
|
|
||||||
void detectMobHovering() const;
|
|
||||||
glm::vec2 getCursorWorldPos() const;
|
|
||||||
glm::vec2 getClickWorldPos() const;
|
|
||||||
|
|
||||||
void updateCursorPos();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace render
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "SummonMenu.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class GameMenu : public GuiWidget {
|
|
||||||
private:
|
|
||||||
std::unique_ptr<SummonMenu> m_SummonMenu;
|
|
||||||
public:
|
|
||||||
GameMenu(client::Client* client);
|
|
||||||
|
|
||||||
virtual void render();
|
|
||||||
private:
|
|
||||||
void showTPS();
|
|
||||||
void showStats();
|
|
||||||
void showPlayers();
|
|
||||||
void showLobbyProgress();
|
|
||||||
void showTeamSelection();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gui
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GuiWidget.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class GuiManager {
|
|
||||||
private:
|
|
||||||
std::vector<std::shared_ptr<GuiWidget>> m_Widgets;
|
|
||||||
public:
|
|
||||||
void renderWidgets() {
|
|
||||||
for (auto widget : m_Widgets) {
|
|
||||||
widget->render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addWidgets(const std::shared_ptr<GuiWidget>& widget) {
|
|
||||||
m_Widgets.push_back(std::move(widget));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gui
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GuiWidget.h"
|
|
||||||
|
|
||||||
#include "imgui/imgui_filebrowser.h"
|
|
||||||
|
|
||||||
#include "game/server/Server.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class MainMenu : public GuiWidget {
|
|
||||||
private:
|
|
||||||
bool m_TriedToConnect = false;
|
|
||||||
bool m_TriedToCreate = false;
|
|
||||||
std::string m_ConnectAddress;
|
|
||||||
int m_ConnectPort;
|
|
||||||
int m_ServerPort = 25565;
|
|
||||||
std::string m_WorldFilePath;
|
|
||||||
imgui_addons::ImGuiFileBrowser m_FileDialog;
|
|
||||||
|
|
||||||
std::unique_ptr<server::Server> m_Server;
|
|
||||||
public:
|
|
||||||
MainMenu(client::Client* client);
|
|
||||||
~MainMenu();
|
|
||||||
|
|
||||||
virtual void render();
|
|
||||||
|
|
||||||
const server::Server* getServer() const { return m_Server.get(); }
|
|
||||||
private:
|
|
||||||
bool startServer();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gui
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GuiWidget.h"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include "game/Mobs.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class SummonMenu : public GuiWidget {
|
|
||||||
private:
|
|
||||||
bool m_MenuOpened;
|
|
||||||
int m_ImageWidth = 100;
|
|
||||||
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:
|
|
||||||
SummonMenu(client::Client* client);
|
|
||||||
|
|
||||||
virtual void render();
|
|
||||||
private:
|
|
||||||
void setSummonMax(int valueIndex);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gui
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* TowerGUI.h
|
|
||||||
*
|
|
||||||
* Created on: 5 nov. 2020
|
|
||||||
* Author: Persson-dev
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
struct SDL_Window;
|
|
||||||
typedef void* SDL_GLContext;
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
|
|
||||||
namespace client {
|
|
||||||
|
|
||||||
class Client;
|
|
||||||
|
|
||||||
} // namespace client
|
|
||||||
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class MainMenu;
|
|
||||||
class GameMenu;
|
|
||||||
class FrameMenu;
|
|
||||||
class UpdateMenu;
|
|
||||||
|
|
||||||
} // namespace gui
|
|
||||||
|
|
||||||
namespace render {
|
|
||||||
|
|
||||||
class Renderer;
|
|
||||||
|
|
||||||
class TowerGui {
|
|
||||||
private:
|
|
||||||
SDL_Window* m_Window;
|
|
||||||
SDL_GLContext m_GlContext;
|
|
||||||
td::render::Renderer* m_Renderer;
|
|
||||||
std::unique_ptr<td::client::Client> m_Client;
|
|
||||||
std::unique_ptr<td::gui::MainMenu> m_MainMenu;
|
|
||||||
std::unique_ptr<td::gui::GameMenu> m_GameMenu;
|
|
||||||
std::unique_ptr<td::gui::FrameMenu> m_FrameMenu;
|
|
||||||
std::unique_ptr<td::gui::UpdateMenu> m_UpdateMenu;
|
|
||||||
public:
|
|
||||||
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
|
|
||||||
~TowerGui();
|
|
||||||
|
|
||||||
void render();
|
|
||||||
private:
|
|
||||||
void initWidgets();
|
|
||||||
void tick();
|
|
||||||
void beginFrame();
|
|
||||||
void endFrame();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace render
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GuiWidget.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class TowerPlacePopup : public GuiWidget {
|
|
||||||
private:
|
|
||||||
glm::vec2 m_ClickWorldPos;
|
|
||||||
public:
|
|
||||||
TowerPlacePopup(client::Client* client);
|
|
||||||
|
|
||||||
virtual void render();
|
|
||||||
|
|
||||||
void setClickPos(const glm::vec2& worldPos);
|
|
||||||
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
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GuiWidget.h"
|
|
||||||
|
|
||||||
#include "updater/Updater.h"
|
|
||||||
|
|
||||||
#include <future>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
class UpdateMenu : public GuiWidget {
|
|
||||||
private:
|
|
||||||
bool m_Opened;
|
|
||||||
std::string m_Error;
|
|
||||||
utils::Updater m_Updater;
|
|
||||||
std::shared_future<bool> m_UpdateAvailable;
|
|
||||||
public:
|
|
||||||
UpdateMenu(client::Client* client);
|
|
||||||
|
|
||||||
virtual void render();
|
|
||||||
private:
|
|
||||||
void checkUpdates();
|
|
||||||
bool isUpdateChecked();
|
|
||||||
void renderErrorPopup();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gui
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "game/World.h"
|
|
||||||
#include "GLLoader.h"
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace render {
|
|
||||||
|
|
||||||
namespace WorldLoader {
|
|
||||||
|
|
||||||
struct RenderData {
|
|
||||||
std::vector<float> positions;
|
|
||||||
std::vector<float> colors;
|
|
||||||
};
|
|
||||||
|
|
||||||
GL::VertexArray loadMobModel();
|
|
||||||
GL::VertexArray loadWorldModel(const td::game::World* world);
|
|
||||||
GL::VertexArray loadTileSelectModel();
|
|
||||||
RenderData loadTowerModel(game::TowerPtr tower);
|
|
||||||
|
|
||||||
} // namespace WorldLoader
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace render
|
|
||||||
} // namespace td
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ShaderProgram.h"
|
|
||||||
|
|
||||||
class EntityShader : public ShaderProgram {
|
|
||||||
private:
|
|
||||||
unsigned int location_cam = 0, location_zoom = 0, location_aspect_ratio = 0, location_translation = 0, location_viewtype = 0;
|
|
||||||
protected:
|
|
||||||
void getAllUniformLocation();
|
|
||||||
public:
|
|
||||||
EntityShader();
|
|
||||||
void loadShader();
|
|
||||||
void setCamPos(const glm::vec2& camPos);
|
|
||||||
void setZoom(float zoom);
|
|
||||||
void setAspectRatio(float aspectRatio);
|
|
||||||
void setModelPos(const glm::vec2& modelPos);
|
|
||||||
void setIsometricView(float isometric);
|
|
||||||
};
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* ShaderProgram.h
|
|
||||||
*
|
|
||||||
* Created on: 31 janv. 2020
|
|
||||||
* Author: simon
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RENDER_SHADERS_SHADERPROGRAM_H_
|
|
||||||
#define RENDER_SHADERS_SHADERPROGRAM_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include "render/GL.h"
|
|
||||||
|
|
||||||
class ShaderProgram {
|
|
||||||
public:
|
|
||||||
ShaderProgram();
|
|
||||||
virtual ~ShaderProgram();
|
|
||||||
void start() const;
|
|
||||||
void stop() const;
|
|
||||||
void loadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
|
|
||||||
void loadProgram(const std::string& vertexSource, const std::string& fragmentSource);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void getAllUniformLocation() = 0;
|
|
||||||
int getUniformLocation(const std::string& uniformName)const;
|
|
||||||
void loadFloat(const int location, const float value)const;
|
|
||||||
void loadInt(const int& location, const int& value)const;
|
|
||||||
void loadVector(const int& location, const glm::vec2& vector)const;
|
|
||||||
void loadVector(const int& location, const glm::vec3& vector)const;
|
|
||||||
void loadVector(const int& location, const glm::vec4& vector)const;
|
|
||||||
void loadBoolean(const int& location, const bool& value)const;
|
|
||||||
void loadMatrix(const int& location, const glm::mat4& matrix);
|
|
||||||
void cleanUp() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int programID;
|
|
||||||
unsigned int vertexShaderID;
|
|
||||||
unsigned int fragmentShaderID;
|
|
||||||
int loadShaderFromFile(const std::string& file, GLenum type);
|
|
||||||
int loadShader(const std::string& source, GLenum type);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* RENDER_SHADERS_SHADERPROGRAM_H_ */
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* GameShader.h
|
|
||||||
*
|
|
||||||
* Created on: 4 nov. 2020
|
|
||||||
* Author: simon
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RENDER_SHADERS_GAMESHADER_H_
|
|
||||||
#define RENDER_SHADERS_GAMESHADER_H_
|
|
||||||
|
|
||||||
#include "ShaderProgram.h"
|
|
||||||
|
|
||||||
class WorldShader : public ShaderProgram {
|
|
||||||
private:
|
|
||||||
unsigned int location_cam = 0, location_zoom = 0, location_aspect_ratio = 0, location_viewtype = 0;
|
|
||||||
protected:
|
|
||||||
void getAllUniformLocation();
|
|
||||||
public:
|
|
||||||
WorldShader();
|
|
||||||
void loadShader();
|
|
||||||
void setCamPos(const glm::vec2& camPos);
|
|
||||||
void setZoom(float zoom);
|
|
||||||
void setAspectRatio(float aspectRatio);
|
|
||||||
void setIsometricView(float isometric);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* RENDER_SHADERS_GAMESHADER_H_ */
|
|
||||||
36
include/server/Lobby.h
Normal file
36
include/server/Lobby.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "td/misc/Time.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
|
||||||
|
class Lobby {
|
||||||
|
private:
|
||||||
|
Server* m_Server;
|
||||||
|
bool m_LobbyOpened = false;
|
||||||
|
std::uint64_t m_StartTimerTime = 0;
|
||||||
|
std::vector<std::uint8_t> m_Players;
|
||||||
|
utils::AutoTimer m_Timer;
|
||||||
|
public:
|
||||||
|
Lobby(Server* server);
|
||||||
|
|
||||||
|
void OnPlayerJoin(std::uint8_t playerID);
|
||||||
|
void OnPlayerLeave(std::uint8_t playerID);
|
||||||
|
|
||||||
|
void OpenLobby();
|
||||||
|
|
||||||
|
void SendTimeRemaining();
|
||||||
|
|
||||||
|
void Tick();
|
||||||
|
|
||||||
|
//static constexpr int LobbyWaitingTime = 2 * 60 * 1000; // in millis
|
||||||
|
static constexpr int LobbyWaitingTime = 5 * 1000; // in millis
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace td
|
||||||
112
include/server/Server.h
Normal file
112
include/server/Server.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "td/network/TCPListener.h"
|
||||||
|
#include "td/protocol/Protocol.h"
|
||||||
|
#include "td/protocol/PacketDispatcher.h"
|
||||||
|
#include "td/protocol/PacketHandler.h"
|
||||||
|
#include "server/game/ServerGame.h"
|
||||||
|
#include "server/ServerConnexion.h"
|
||||||
|
#include "server/Lobby.h"
|
||||||
|
|
||||||
|
#define SERVER_TPS 20
|
||||||
|
#define SERVER_TICK 1000 / SERVER_TPS
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
typedef std::map<std::uint8_t, ServerConnexion> ConnexionMap;
|
||||||
|
|
||||||
|
class TickCounter {
|
||||||
|
private:
|
||||||
|
float m_TPS;
|
||||||
|
float m_MSPT;
|
||||||
|
std::uint64_t m_LastTPSTime;
|
||||||
|
std::uint8_t m_TickCount;
|
||||||
|
public:
|
||||||
|
TickCounter() {}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
m_TPS = SERVER_TPS;
|
||||||
|
m_LastTPSTime = utils::GetTime();
|
||||||
|
m_TickCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Update() { // return true when tps is updated
|
||||||
|
m_TickCount++;
|
||||||
|
if (m_TickCount >= SERVER_TPS) {
|
||||||
|
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::GetTime() - m_LastTPSTime;
|
||||||
|
m_TPS = static_cast<float>(SERVER_TPS) / static_cast<float>(timeElapsedSinceLast20Ticks / 1000.0f);
|
||||||
|
m_TickCount = 0;
|
||||||
|
m_LastTPSTime = td::utils::GetTime();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetTPS() const { return m_TPS; }
|
||||||
|
float GetMSPT() const { return m_MSPT; }
|
||||||
|
|
||||||
|
void SetMSPT(float mspt) { m_MSPT = mspt; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Server {
|
||||||
|
private:
|
||||||
|
network::TCPListener m_Listener;
|
||||||
|
ConnexionMap m_Connections;
|
||||||
|
ServerGame m_Game{ this };
|
||||||
|
Lobby m_Lobby{ this };
|
||||||
|
TickCounter m_TickCounter;
|
||||||
|
|
||||||
|
std::thread m_Thread;
|
||||||
|
bool m_ServerRunning;
|
||||||
|
public:
|
||||||
|
Server();
|
||||||
|
virtual ~Server();
|
||||||
|
|
||||||
|
bool Start(std::uint16_t port, bool blocking);
|
||||||
|
void Stop(); // force the server to stop
|
||||||
|
void Close(); // at the end of a game
|
||||||
|
|
||||||
|
void Restart(); // go back to lobby state
|
||||||
|
|
||||||
|
bool LoadMap(const std::string& worldFilePath);
|
||||||
|
bool IsMapLoaded();
|
||||||
|
|
||||||
|
void RemoveConnexion(std::uint8_t connexionID);
|
||||||
|
|
||||||
|
void BroadcastPacket(const protocol::Packet* packet);
|
||||||
|
|
||||||
|
float GetMSPT() const { return m_TickCounter.GetMSPT(); }
|
||||||
|
float GetTPS() const { return m_TickCounter.GetTPS(); }
|
||||||
|
|
||||||
|
bool IsRunning() { return m_ServerRunning; }
|
||||||
|
|
||||||
|
const ServerGame& GetGame() const { return m_Game; }
|
||||||
|
ServerGame& GetGame() { return m_Game; }
|
||||||
|
|
||||||
|
const Lobby& GetLobby() const { return m_Lobby; }
|
||||||
|
const ConnexionMap& GetConnexions() const { return m_Connections; }
|
||||||
|
ConnexionMap& GetConnexions() { return m_Connections; }
|
||||||
|
|
||||||
|
const game::PlayerList& GetPlayers() const { return m_Game.GetPlayers(); }
|
||||||
|
game::PlayerList& GetPlayers() { return m_Game.GetPlayers(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Accept();
|
||||||
|
void UpdateSockets();
|
||||||
|
|
||||||
|
void Clean();
|
||||||
|
void StartThread();
|
||||||
|
void StopThread();
|
||||||
|
void ServerLoop();
|
||||||
|
void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
|
void OnPlayerJoin(std::uint8_t id);
|
||||||
|
void OnPlayerLeave(std::uint8_t id);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace td
|
||||||
59
include/server/ServerConnexion.h
Normal file
59
include/server/ServerConnexion.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/network/TCPSocket.h"
|
||||||
|
#include "td/protocol/PacketHandler.h"
|
||||||
|
#include "td/protocol/PacketDispatcher.h"
|
||||||
|
#include "td/game/Player.h"
|
||||||
|
#include "td/network/Connexion.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
|
||||||
|
struct KeepAlive {
|
||||||
|
std::uint64_t keepAliveID = 0;
|
||||||
|
std::uint64_t sendTime;
|
||||||
|
bool recievedResponse = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ServerConnexion : public protocol::Connexion {
|
||||||
|
private:
|
||||||
|
Server* m_Server = nullptr;
|
||||||
|
std::uint8_t m_ID;
|
||||||
|
KeepAlive m_KeepAlive;
|
||||||
|
game::Player* m_Player;
|
||||||
|
public:
|
||||||
|
ServerConnexion();
|
||||||
|
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
|
||||||
|
ServerConnexion(ServerConnexion&& move);
|
||||||
|
virtual ~ServerConnexion();
|
||||||
|
|
||||||
|
void SetServer(Server* server);
|
||||||
|
|
||||||
|
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::SelectTeamPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::SendMobsPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
||||||
|
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
||||||
|
|
||||||
|
std::uint8_t GetID() const { return m_ID; }
|
||||||
|
const game::Player* GetPlayer() const { return m_Player; }
|
||||||
|
game::Player* GetPlayer() { return m_Player; }
|
||||||
|
|
||||||
|
virtual bool UpdateSocket();
|
||||||
|
|
||||||
|
REMOVE_COPY(ServerConnexion);
|
||||||
|
private:
|
||||||
|
void RegisterHandlers();
|
||||||
|
void CheckKeepAlive();
|
||||||
|
void SendKeepAlive();
|
||||||
|
void InitConnection();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace td
|
||||||
48
include/server/game/ServerGame.h
Normal file
48
include/server/game/ServerGame.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/BaseGame.h"
|
||||||
|
#include "td/misc/Time.h"
|
||||||
|
#include "ServerWorld.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
|
||||||
|
class ServerGame : public game::Game, public game::GameListener {
|
||||||
|
private:
|
||||||
|
Server* m_Server;
|
||||||
|
ServerWorld m_ServerWorld;
|
||||||
|
utils::AutoTimer m_GoldMineTimer;
|
||||||
|
utils::AutoTimer m_MobStatesTimer;
|
||||||
|
utils::CooldownTimer m_EndGameCooldown;
|
||||||
|
public:
|
||||||
|
ServerGame(Server* server);
|
||||||
|
~ServerGame() {}
|
||||||
|
|
||||||
|
ServerWorld* GetServerWorld() { return &m_ServerWorld; }
|
||||||
|
|
||||||
|
virtual void Tick(std::uint64_t delta);
|
||||||
|
virtual void Reset() override;
|
||||||
|
|
||||||
|
void StartGame();
|
||||||
|
|
||||||
|
// GameListener
|
||||||
|
|
||||||
|
virtual void OnGameStateUpdate(game::GameState newState) override;
|
||||||
|
virtual void OnGameBegin() override;
|
||||||
|
virtual void OnGameEnd() override;
|
||||||
|
virtual void OnGameClose() override;
|
||||||
|
|
||||||
|
virtual void OnPlayerJoin(game::PlayerID id) override;
|
||||||
|
virtual void OnPlayerLeave(game::PlayerID id) override;
|
||||||
|
private:
|
||||||
|
void BalanceTeams();
|
||||||
|
void InitPlayerStats();
|
||||||
|
void UpdateMobStates();
|
||||||
|
void UpdateGoldMines();
|
||||||
|
void UpdatePlayerStats();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
30
include/server/game/ServerWorld.h
Normal file
30
include/server/game/ServerWorld.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/World.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
class ServerGame;
|
||||||
|
|
||||||
|
class ServerWorld : public game::World {
|
||||||
|
private:
|
||||||
|
game::MobID m_CurrentMobID;
|
||||||
|
game::TowerID m_CurrentTowerID;
|
||||||
|
Server* m_Server;
|
||||||
|
public:
|
||||||
|
static constexpr float MobSpawnBorder = 0.01f;
|
||||||
|
|
||||||
|
ServerWorld(Server* server, ServerGame* game);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
virtual void OnMobDie(game::Mob* mob) override;
|
||||||
|
virtual void OnMobCastleDamage(game::Mob* damager, game::TeamCastle* enemyCastle, float damage) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace td
|
||||||
151
include/td/Defines.h
Normal file
151
include/td/Defines.h
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define SAFE_CHECK(expr) if(!(expr)) return
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
75
include/td/game/BaseGame.h
Normal file
75
include/td/game/BaseGame.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/game/Team.h"
|
||||||
|
#include "td/game/World.h"
|
||||||
|
#include "td/game/Player.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
enum class GameState : std::uint8_t {
|
||||||
|
Lobby,
|
||||||
|
Game,
|
||||||
|
EndGame,
|
||||||
|
Disconnected,
|
||||||
|
Closed
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::uint8_t, Player> PlayerList;
|
||||||
|
|
||||||
|
class GameListener {
|
||||||
|
public:
|
||||||
|
virtual void OnPlayerJoin(PlayerID player) {}
|
||||||
|
virtual void OnPlayerLeave(PlayerID player) {}
|
||||||
|
|
||||||
|
virtual void OnGameStateUpdate(GameState newState) {}
|
||||||
|
virtual void OnGameBegin() {}
|
||||||
|
virtual void OnGameEnd() {}
|
||||||
|
virtual void OnGameClose() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef utils::ObjectNotifier<GameListener> GameNotifier;
|
||||||
|
|
||||||
|
class Game : public GameNotifier {
|
||||||
|
protected:
|
||||||
|
World* m_World;
|
||||||
|
TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
|
||||||
|
GameState m_GameState = GameState::Lobby;
|
||||||
|
PlayerList m_Players;
|
||||||
|
public:
|
||||||
|
Game(World* world);
|
||||||
|
virtual ~Game();
|
||||||
|
|
||||||
|
virtual void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
|
virtual void Reset();
|
||||||
|
|
||||||
|
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)]; }
|
||||||
|
|
||||||
|
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)]; }
|
||||||
|
|
||||||
|
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)]; }
|
||||||
|
|
||||||
|
GameState GetGameState() const { return m_GameState; }
|
||||||
|
void SetGameState(GameState gameState) { m_GameState = gameState; };
|
||||||
|
|
||||||
|
const World* GetWorld() const { return m_World; }
|
||||||
|
World* GetWorld() { return m_World; }
|
||||||
|
|
||||||
|
const PlayerList& GetPlayers() const { return m_Players; }
|
||||||
|
PlayerList& GetPlayers() { return m_Players; }
|
||||||
|
|
||||||
|
const Player* GetPlayerById(PlayerID id) const;
|
||||||
|
Player* GetPlayerById(PlayerID id);
|
||||||
|
|
||||||
|
const TeamList& GetTeams() const { return m_Teams; }
|
||||||
|
|
||||||
|
void RemovePlayer(PlayerID pId);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
@@ -10,12 +10,12 @@
|
|||||||
|
|
||||||
namespace GameManager {
|
namespace GameManager {
|
||||||
|
|
||||||
void render();
|
void Render();
|
||||||
void init();
|
void Init();
|
||||||
void destroy();
|
void Destroy();
|
||||||
void tick();
|
void Tick();
|
||||||
|
|
||||||
void startServer();
|
void StartServer();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
262
include/td/game/Mobs.h
Normal file
262
include/td/game/Mobs.h
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/Defines.h"
|
||||||
|
#include "Towers.h"
|
||||||
|
#include "Types.h"
|
||||||
|
#include "Team.h"
|
||||||
|
|
||||||
|
#include "td/misc/ObjectNotifier.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
struct WalkableTile;
|
||||||
|
|
||||||
|
enum class EffectType : std::uint8_t {
|
||||||
|
Slowness = 0,
|
||||||
|
Stun,
|
||||||
|
Fire,
|
||||||
|
Poison,
|
||||||
|
Heal,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MobType : std::uint8_t {
|
||||||
|
Zombie = 0,
|
||||||
|
Spider,
|
||||||
|
Skeleton,
|
||||||
|
Pigman,
|
||||||
|
Creeper,
|
||||||
|
Silverfish,
|
||||||
|
Blaze,
|
||||||
|
Witch,
|
||||||
|
Slime,
|
||||||
|
Giant,
|
||||||
|
|
||||||
|
MOB_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::uint32_t MobID;
|
||||||
|
typedef std::uint8_t MobLevel;
|
||||||
|
typedef std::vector<TowerType> TowerImmunities;
|
||||||
|
typedef std::vector<EffectType> EffectImmunities;
|
||||||
|
|
||||||
|
class MobStats {
|
||||||
|
private:
|
||||||
|
float m_Damage;
|
||||||
|
float m_Speed;
|
||||||
|
Vec2f m_Size;
|
||||||
|
std::uint16_t m_MoneyCost;
|
||||||
|
std::uint16_t m_ExpCost;
|
||||||
|
std::uint16_t m_MaxLife;
|
||||||
|
std::uint16_t m_ExpReward;
|
||||||
|
public:
|
||||||
|
MobStats(float damage, float speed, Vec2f size, std::uint16_t moneyCost,
|
||||||
|
std::uint16_t expCost, std::uint16_t expReward,
|
||||||
|
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
|
||||||
|
m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
|
||||||
|
m_MaxLife(maxLife), m_ExpReward(expReward) {
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetDamage() const { return m_Damage; }
|
||||||
|
float GetMovementSpeed() const { return m_Speed; }
|
||||||
|
const Vec2f& GetSize() const { return m_Size; }
|
||||||
|
std::uint16_t GetMoneyCost() const { return m_MoneyCost; }
|
||||||
|
std::uint16_t GetExpCost() const { return m_ExpCost; }
|
||||||
|
std::uint16_t GetExpReward() const { return m_ExpReward; }
|
||||||
|
std::uint16_t GetMaxLife() const { return m_MaxLife; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EffectDuration {
|
||||||
|
EffectType type;
|
||||||
|
float duration; // in seconds
|
||||||
|
Tower* tower; // the tower that gived the effect
|
||||||
|
};
|
||||||
|
|
||||||
|
const MobStats* GetMobStats(MobType type, std::uint8_t level);
|
||||||
|
const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level);
|
||||||
|
const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level);
|
||||||
|
|
||||||
|
class Mob : public utils::shape::Rectangle {
|
||||||
|
protected:
|
||||||
|
float m_Health;
|
||||||
|
private:
|
||||||
|
MobID m_ID;
|
||||||
|
PlayerID m_Sender;
|
||||||
|
MobLevel m_Level;
|
||||||
|
Direction m_Direction;
|
||||||
|
std::vector<EffectDuration> m_Effects;
|
||||||
|
const Tower* m_LastDamage; // the last tower that damaged the mob
|
||||||
|
float m_HitCooldown;
|
||||||
|
|
||||||
|
utils::Timer m_EffectFireTimer;
|
||||||
|
utils::Timer m_EffectPoisonTimer;
|
||||||
|
utils::Timer m_EffectHealTimer;
|
||||||
|
|
||||||
|
TeamCastle* m_CastleTarget;
|
||||||
|
utils::CooldownTimer m_AttackTimer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mob(MobID id, MobLevel level, PlayerID sender) : m_ID(id), m_Sender(sender), m_Level(level),
|
||||||
|
m_HitCooldown(0), m_EffectFireTimer(1000), m_EffectPoisonTimer(1000),
|
||||||
|
m_EffectHealTimer(1000), m_CastleTarget(nullptr), m_AttackTimer(1000) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual MobType GetType() const = 0;
|
||||||
|
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
|
||||||
|
virtual bool OnDeath(World* world) { return true; }
|
||||||
|
|
||||||
|
MobID GetMobID() const { return m_ID; }
|
||||||
|
const TowerImmunities& GetTowerImmunities() const { return GetMobTowerImmunities(GetType(), m_Level); }
|
||||||
|
const EffectImmunities& GetEffectImmunities() const { return GetMobEffectImmunities(GetType(), m_Level); }
|
||||||
|
PlayerID GetSender() const { return m_Sender; }
|
||||||
|
MobLevel GetLevel() const { return m_Level; }
|
||||||
|
const MobStats* GetStats() const { return GetMobStats(GetType(), m_Level); }
|
||||||
|
void SetHealth(float newHealth) { m_Health = newHealth; }
|
||||||
|
float GetHealth() const { return m_Health; }
|
||||||
|
bool IsDead() const { return m_Health <= 0; }
|
||||||
|
bool IsAlive() const { return m_Health > 0; }
|
||||||
|
const Tower* GetLastDamageTower() { return m_LastDamage; }
|
||||||
|
bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; }
|
||||||
|
|
||||||
|
void Damage(float dmg, const Tower* damager) {
|
||||||
|
m_Health = std::max(0.0f, m_Health - dmg);
|
||||||
|
m_LastDamage = damager;
|
||||||
|
m_HitCooldown = 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Heal(float heal) {
|
||||||
|
m_Health = std::min(static_cast<float>(GetStats()->GetMaxLife()), m_Health + heal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle
|
||||||
|
|
||||||
|
bool IsImmuneTo(TowerType type);
|
||||||
|
|
||||||
|
bool IsImmuneTo(EffectType type);
|
||||||
|
void AddEffect(EffectType type, float durationSec, Tower* tower);
|
||||||
|
bool HasEffect(EffectType type);
|
||||||
|
|
||||||
|
bool HasTakenDamage() { return m_HitCooldown > 0; }
|
||||||
|
|
||||||
|
float GetTileX() { return GetCenterX() - static_cast<float>(static_cast<std::int32_t>(GetCenterX())); } // returns a float between 0 and 1 excluded
|
||||||
|
float GetTileY() { return GetCenterY() - static_cast<float>(static_cast<std::int32_t>(GetCenterY())); } // returns a float between 0 and 1 excluded
|
||||||
|
|
||||||
|
Direction GetDirection() const { return m_Direction; }
|
||||||
|
void SetDirection(Direction dir) { m_Direction = dir; }
|
||||||
|
protected:
|
||||||
|
void InitMob() {
|
||||||
|
m_Health = static_cast<float>(GetStats()->GetMaxLife());
|
||||||
|
SetSize(GetStats()->GetSize().x, GetStats()->GetSize().y);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void UpdateEffects(std::uint64_t delta, World* world);
|
||||||
|
void AttackCastle(std::uint64_t delta, World* world);
|
||||||
|
void Move(std::uint64_t delta, World* world);
|
||||||
|
void Walk(std::uint64_t delta, World* world);
|
||||||
|
void MoveBack(const TeamCastle& castle, World* world);
|
||||||
|
void ChangeDirection(const WalkableTile& tile, World* world);
|
||||||
|
bool IsTouchingCastle(const TeamCastle& castle) const;
|
||||||
|
EffectDuration& GetEffect(EffectType type);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Mob> MobPtr;
|
||||||
|
|
||||||
|
class Zombie : public Mob {
|
||||||
|
public:
|
||||||
|
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Zombie; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Spider : public Mob {
|
||||||
|
public:
|
||||||
|
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Spider; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Skeleton : public Mob {
|
||||||
|
public:
|
||||||
|
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Skeleton; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class PigMan : public Mob {
|
||||||
|
public:
|
||||||
|
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Pigman; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Creeper : public Mob {
|
||||||
|
public:
|
||||||
|
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Creeper; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Silverfish : public Mob {
|
||||||
|
public:
|
||||||
|
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Silverfish; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Blaze : public Mob {
|
||||||
|
public:
|
||||||
|
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Blaze; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Witch : public Mob {
|
||||||
|
public:
|
||||||
|
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Witch; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Slime : public Mob {
|
||||||
|
public:
|
||||||
|
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Slime; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Giant : public Mob {
|
||||||
|
public:
|
||||||
|
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
|
||||||
|
|
||||||
|
virtual MobType GetType() const { return MobType::Giant; }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace MobFactory {
|
||||||
|
|
||||||
|
MobPtr CreateMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
|
||||||
|
std::string GetMobName(MobType type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MobListener {
|
||||||
|
public:
|
||||||
|
virtual void OnMobSpawn(Mob* mob) {}
|
||||||
|
virtual void OnMobDie(Mob* mob) {}
|
||||||
|
|
||||||
|
virtual void OnMobDamage(Mob* target, float damage, Tower* damager) {}
|
||||||
|
|
||||||
|
virtual void OnMobTouchCastle(Mob* damager, TeamCastle* enemyCastle) {}
|
||||||
|
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef utils::ObjectNotifier<MobListener> MobNotifier;
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
|
|
||||||
51
include/td/game/Player.h
Normal file
51
include/td/game/Player.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "td/game/Team.h"
|
||||||
|
#include "td/game/PlayerUpgrades.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
class Player {
|
||||||
|
private:
|
||||||
|
TeamColor m_TeamColor;
|
||||||
|
PlayerUpgrades m_Upgrades;
|
||||||
|
|
||||||
|
std::uint32_t m_Gold;
|
||||||
|
std::uint32_t m_Exp;
|
||||||
|
std::string m_Name;
|
||||||
|
PlayerID m_ID;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void SetName(const std::string& name) { m_Name = name; }
|
||||||
|
|
||||||
|
TeamColor GetTeamColor() const { return m_TeamColor; }
|
||||||
|
void SetTeamColor(TeamColor teamColor) { m_TeamColor = teamColor; }
|
||||||
|
|
||||||
|
std::uint32_t GetGold() const { return m_Gold; }
|
||||||
|
void SetGold(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; }
|
||||||
|
|
||||||
|
std::uint32_t GetExp() const { return m_Exp; }
|
||||||
|
void SetExp(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; }
|
||||||
|
|
||||||
|
const PlayerUpgrades& getUpgrades() const { return m_Upgrades; }
|
||||||
|
PlayerUpgrades& getUpgrades() { return m_Upgrades; }
|
||||||
|
|
||||||
|
bool HasEnoughGold(std::uint32_t gold) const { return m_Gold >= gold; }
|
||||||
|
bool HasEnoughExp(std::uint32_t exp) const { return m_Exp >= exp; }
|
||||||
|
|
||||||
|
PlayerID GetID() const { return m_ID; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
34
include/td/game/PlayerUpgrades.h
Normal file
34
include/td/game/PlayerUpgrades.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Mobs.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
class PlayerUpgrades {
|
||||||
|
private:
|
||||||
|
std::uint8_t m_ClickerLevel;
|
||||||
|
std::uint8_t m_GoldPerSecond;
|
||||||
|
std::array<std::uint8_t, static_cast<std::size_t>(MobType::MOB_COUNT)> m_MobsUpgradeLevel;
|
||||||
|
public:
|
||||||
|
static const int MAX_MOB_LEVEL = 5;
|
||||||
|
static const int MAX_CLICKER_LEVEL = 3;
|
||||||
|
|
||||||
|
PlayerUpgrades() : m_ClickerLevel(1), m_GoldPerSecond(5) {}
|
||||||
|
|
||||||
|
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 GetGoldPerSecond() const { return m_GoldPerSecond; }
|
||||||
|
|
||||||
|
|
||||||
|
void UpgradeMob(MobType mob) {
|
||||||
|
std::uint8_t& mobLevel = m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob));
|
||||||
|
mobLevel = std::min(mobLevel + 1, MAX_MOB_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpgradeClicker() { m_ClickerLevel = std::min(m_ClickerLevel + 1, MAX_CLICKER_LEVEL); }
|
||||||
|
void SetGoldPerSecond(std::uint8_t goldPerSecond) { m_GoldPerSecond = goldPerSecond; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
93
include/td/game/Team.h
Normal file
93
include/td/game/Team.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#include "td/misc/Shapes.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
class Player;
|
||||||
|
|
||||||
|
enum class TeamColor : std::int8_t {
|
||||||
|
None = -1,
|
||||||
|
Red,
|
||||||
|
Blue
|
||||||
|
};
|
||||||
|
|
||||||
|
class Spawn : public utils::shape::Rectangle {
|
||||||
|
private:
|
||||||
|
Direction m_Direction;
|
||||||
|
public:
|
||||||
|
Spawn() {
|
||||||
|
SetWidth(5);
|
||||||
|
SetHeight(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction GetDirection() const { return m_Direction; }
|
||||||
|
|
||||||
|
void SetDirection(Direction direction) { m_Direction = direction; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Team;
|
||||||
|
|
||||||
|
class TeamCastle : public utils::shape::Rectangle {
|
||||||
|
private:
|
||||||
|
const Team* m_Team;
|
||||||
|
float m_Life;
|
||||||
|
public:
|
||||||
|
static constexpr int CastleMaxLife = 1000;
|
||||||
|
|
||||||
|
TeamCastle(const Team* team) : m_Team(team), m_Life(CastleMaxLife) {
|
||||||
|
SetWidth(5);
|
||||||
|
SetHeight(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamCastle() : TeamCastle(nullptr) {}
|
||||||
|
|
||||||
|
float GetLife() const { return m_Life; }
|
||||||
|
|
||||||
|
const Team* GetTeam() const { return m_Team; }
|
||||||
|
void SetTeam(const Team* team) { m_Team = team; }
|
||||||
|
|
||||||
|
void SetLife(float life) { m_Life = life; }
|
||||||
|
void Damage(float damage) { m_Life = std::max(0.0f, m_Life - damage); }
|
||||||
|
|
||||||
|
void SetShape(utils::shape::Rectangle rect) {
|
||||||
|
SetCenter(rect.GetCenter());
|
||||||
|
SetSize(rect.GetSize());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Team {
|
||||||
|
private:
|
||||||
|
std::vector<Player*> m_Players;
|
||||||
|
TeamColor m_Color;
|
||||||
|
Spawn m_Spawn;
|
||||||
|
TeamCastle m_TeamCastle;
|
||||||
|
public:
|
||||||
|
Team(TeamColor color);
|
||||||
|
|
||||||
|
void AddPlayer(Player* newPlayer);
|
||||||
|
void RemovePlayer(const Player* player);
|
||||||
|
void ClearPlayers();
|
||||||
|
|
||||||
|
TeamColor GetColor() const;
|
||||||
|
|
||||||
|
const Spawn& GetSpawn() const { return m_Spawn; }
|
||||||
|
Spawn& GetSpawn() { return m_Spawn; }
|
||||||
|
|
||||||
|
const TeamCastle& GetCastle() const { return m_TeamCastle; }
|
||||||
|
TeamCastle& GetCastle() { return m_TeamCastle; }
|
||||||
|
|
||||||
|
std::uint8_t GetPlayerCount() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::array<Team, 2> TeamList;
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
266
include/td/game/Towers.h
Normal file
266
include/td/game/Towers.h
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "td/misc/Time.h"
|
||||||
|
#include "td/misc/Shapes.h"
|
||||||
|
|
||||||
|
#include "td/game/Types.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
class World;
|
||||||
|
class Mob;
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Mob> MobPtr;
|
||||||
|
|
||||||
|
enum class TowerType : std::uint8_t {
|
||||||
|
Archer = 0,
|
||||||
|
Ice,
|
||||||
|
Sorcerer,
|
||||||
|
Zeus,
|
||||||
|
Mage,
|
||||||
|
Artillery,
|
||||||
|
Quake,
|
||||||
|
Poison,
|
||||||
|
|
||||||
|
Leach,
|
||||||
|
Turret,
|
||||||
|
Necromancer,
|
||||||
|
|
||||||
|
TowerCount
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TowerSize : std::uint8_t {
|
||||||
|
Little = 3, // 3x3
|
||||||
|
Big = 5, // 5x5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TowerPath : std::uint8_t {
|
||||||
|
Top = 0,
|
||||||
|
Base, // Base Path
|
||||||
|
Bottom
|
||||||
|
};
|
||||||
|
|
||||||
|
class TowerStats {
|
||||||
|
private:
|
||||||
|
float m_Rate;
|
||||||
|
float m_Damage;
|
||||||
|
std::uint8_t m_Range;
|
||||||
|
public:
|
||||||
|
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage),
|
||||||
|
m_Range(range) {
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetDamageRate() const { return m_Rate; }
|
||||||
|
float GetDamage() const { return m_Damage; }
|
||||||
|
std::uint8_t GetRange() const { return m_Range; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TowerLevel {
|
||||||
|
private:
|
||||||
|
// 1, 2, 3, 4
|
||||||
|
std::uint8_t m_Level : 3;
|
||||||
|
// 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path)
|
||||||
|
TowerPath m_Path : 2;
|
||||||
|
public:
|
||||||
|
TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {}
|
||||||
|
TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {}
|
||||||
|
|
||||||
|
std::uint8_t GetLevel() const { return m_Level; }
|
||||||
|
TowerPath GetPath() const { return m_Path; }
|
||||||
|
|
||||||
|
void SetLevel(std::uint8_t level) { m_Level = level; }
|
||||||
|
void SetPath(TowerPath path) { m_Path = path; }
|
||||||
|
|
||||||
|
// operator to sort maps
|
||||||
|
friend bool operator<(const TowerLevel& level, const TowerLevel& other) {
|
||||||
|
return level.GetLevel() + static_cast<std::uint8_t>(level.GetPath()) * 4 <
|
||||||
|
other.GetLevel() + static_cast<std::uint8_t>(other.GetPath()) * 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const TowerStats* GetTowerStats(TowerType type, TowerLevel level);
|
||||||
|
|
||||||
|
typedef std::uint16_t TowerID;
|
||||||
|
|
||||||
|
class Tower : public utils::shape::Circle {
|
||||||
|
private:
|
||||||
|
TowerID m_ID;
|
||||||
|
TowerType m_Type;
|
||||||
|
TowerLevel m_Level{};
|
||||||
|
PlayerID m_Builder;
|
||||||
|
protected:
|
||||||
|
utils::CooldownTimer m_Timer;
|
||||||
|
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),
|
||||||
|
m_Timer(GetStats()->GetDamageRate() * 1000) { // converting seconds to millis
|
||||||
|
SetRadius(GetStats()->GetRange());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const = 0;
|
||||||
|
virtual TowerSize GetSize() const = 0;
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
||||||
|
|
||||||
|
void Upgrade(std::uint8_t level, TowerPath path) {
|
||||||
|
m_Level.SetLevel(level);
|
||||||
|
m_Level.SetPath(path);
|
||||||
|
m_Timer.SetCooldown(GetStats()->GetDamageRate() * 1000); // converting seconds to millis
|
||||||
|
m_Timer.Reset();
|
||||||
|
SetRadius(GetStats()->GetRange());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint16_t GetID() const { return m_ID; }
|
||||||
|
const TowerLevel& GetLevel() const { return m_Level; }
|
||||||
|
const TowerStats* GetStats() const { return GetTowerStats(m_Type, m_Level); }
|
||||||
|
PlayerID GetBuilder() const { return m_Builder; }
|
||||||
|
|
||||||
|
bool IsMobInRange(MobPtr mob);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Tower> TowerPtr;
|
||||||
|
|
||||||
|
namespace TowerFactory {
|
||||||
|
|
||||||
|
TowerPtr CreateTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder);
|
||||||
|
std::string GetTowerName(TowerType type);
|
||||||
|
|
||||||
|
} // namespace TowerFactory
|
||||||
|
|
||||||
|
|
||||||
|
class TowerInfo {
|
||||||
|
private:
|
||||||
|
std::string m_Name, m_Description;
|
||||||
|
bool m_IsBigTower;
|
||||||
|
public:
|
||||||
|
TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)),
|
||||||
|
m_Description(std::move(description)), m_IsBigTower(big) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& GetName() const { return m_Name; }
|
||||||
|
const std::string& GetDescription() const { return m_Description; }
|
||||||
|
|
||||||
|
bool IsBigTower() const { return m_IsBigTower; }
|
||||||
|
};
|
||||||
|
|
||||||
|
const TowerInfo& GetTowerInfo(TowerType type);
|
||||||
|
|
||||||
|
// ---------- Little Towers ----------
|
||||||
|
|
||||||
|
class LittleTower : public Tower {
|
||||||
|
public:
|
||||||
|
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 TowerType GetType() const = 0;
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ArcherTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
ArcherTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
constexpr static float ExplosionRadius = 1.5f;
|
||||||
|
constexpr static float FireDurationSec = 10.0f;
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Archer; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IceTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
IceTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Ice; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MageTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
MageTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Mage; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PoisonTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
PoisonTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Poison; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class QuakeTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
QuakeTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Quake; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ArtilleryTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
ArtilleryTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Artillery; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SorcererTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
SorcererTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Sorcerer; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ZeusTower : public LittleTower {
|
||||||
|
public:
|
||||||
|
ZeusTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Zeus; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- Big Towers ----------
|
||||||
|
|
||||||
|
class BigTower : public Tower {
|
||||||
|
public:
|
||||||
|
BigTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerSize GetSize() const { return TowerSize::Big; }
|
||||||
|
|
||||||
|
virtual TowerType GetType() const = 0;
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TurretTower : public BigTower {
|
||||||
|
public:
|
||||||
|
TurretTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Turret; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NecromancerTower : public BigTower {
|
||||||
|
public:
|
||||||
|
NecromancerTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Necromancer; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
class LeachTower : public BigTower {
|
||||||
|
public:
|
||||||
|
LeachTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
|
||||||
|
|
||||||
|
virtual TowerType GetType() const { return TowerType::Leach; }
|
||||||
|
virtual void Tick(std::uint64_t delta, World* world);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
// include Log for every files
|
||||||
|
#include "td/misc/Log.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
250
include/td/game/World.h
Normal file
250
include/td/game/World.h
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "Mobs.h"
|
||||||
|
#include "Team.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
struct ChunkCoord {
|
||||||
|
std::int16_t x, y;
|
||||||
|
|
||||||
|
friend bool operator==(const td::game::ChunkCoord& first, const td::game::ChunkCoord& other) {
|
||||||
|
return first.x == other.x && first.y == other.y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <>
|
||||||
|
struct hash<td::game::ChunkCoord> {
|
||||||
|
std::size_t operator()(const td::game::ChunkCoord& key) const noexcept {
|
||||||
|
return std::hash<std::int16_t>()(key.x << 16 | key.y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class WorldBeginDataPacket;
|
||||||
|
class WorldDataPacket;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
class Game;
|
||||||
|
|
||||||
|
enum class TileType : std::uint8_t {
|
||||||
|
None = 0,
|
||||||
|
Tower,
|
||||||
|
Walk,
|
||||||
|
Decoration,
|
||||||
|
/*Heal,
|
||||||
|
Lava,
|
||||||
|
Bedrock,
|
||||||
|
Freeze,
|
||||||
|
Ice,*/
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr Color BLACK{ 0, 0, 0 };
|
||||||
|
static constexpr Color WHITE{ 255, 255, 255 };
|
||||||
|
|
||||||
|
static constexpr Color RED{ 255, 0, 0 };
|
||||||
|
static constexpr Color GREEN{ 0, 255, 0 };
|
||||||
|
static constexpr Color BLUE{ 0, 0, 255 };
|
||||||
|
|
||||||
|
struct Tile {
|
||||||
|
virtual TileType GetType() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TowerTile : Tile {
|
||||||
|
std::uint8_t color_palette_ref;
|
||||||
|
TeamColor team_owner;
|
||||||
|
|
||||||
|
virtual TileType GetType() const { return TileType::Tower; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WalkableTile : Tile {
|
||||||
|
Direction direction;
|
||||||
|
|
||||||
|
virtual TileType GetType() const { return TileType::Walk; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DecorationTile : Tile {
|
||||||
|
std::uint16_t color_palette_ref;
|
||||||
|
|
||||||
|
virtual TileType GetType() const { return TileType::Decoration; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Tile> TilePtr;
|
||||||
|
typedef std::vector<std::uint16_t> ChunkPalette;
|
||||||
|
|
||||||
|
typedef std::shared_ptr<WalkableTile> WalkableTilePtr;
|
||||||
|
|
||||||
|
typedef std::uint32_t TileIndex;
|
||||||
|
|
||||||
|
//32 x 32 area
|
||||||
|
struct Chunk {
|
||||||
|
enum { ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
|
||||||
|
typedef std::array<std::uint16_t, ChunkSize> ChunkData;
|
||||||
|
|
||||||
|
// stores index of tile palette
|
||||||
|
ChunkData tiles{ 0 };
|
||||||
|
ChunkPalette palette;
|
||||||
|
|
||||||
|
TileIndex GetTileIndex(std::uint16_t tileNumber) const {
|
||||||
|
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
|
||||||
|
if (chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
|
||||||
|
return 0;
|
||||||
|
return palette.at(chunkPaletteIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||||
|
|
||||||
|
typedef std::array<Color, 2> TowerTileColorPalette;
|
||||||
|
|
||||||
|
typedef std::vector<TilePtr> TilePalette;
|
||||||
|
|
||||||
|
typedef std::vector<MobPtr> MobList;
|
||||||
|
|
||||||
|
typedef std::array<Color, 2> SpawnColorPalette;
|
||||||
|
|
||||||
|
typedef std::vector<TowerPtr> TowerList;
|
||||||
|
|
||||||
|
class WorldListener {
|
||||||
|
public:
|
||||||
|
WorldListener() {}
|
||||||
|
|
||||||
|
virtual void OnTowerAdd(TowerPtr tower) {}
|
||||||
|
virtual void OnTowerRemove(TowerPtr tower) {}
|
||||||
|
|
||||||
|
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) {}
|
||||||
|
|
||||||
|
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {}
|
||||||
|
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef utils::ObjectNotifier<WorldListener> WorldNotifier;
|
||||||
|
|
||||||
|
class World : public WorldListener, public MobListener {
|
||||||
|
protected:
|
||||||
|
TowerTileColorPalette m_TowerPlacePalette;
|
||||||
|
Color m_WalkablePalette;
|
||||||
|
std::vector<Color> m_DecorationPalette;
|
||||||
|
Color m_Background;
|
||||||
|
|
||||||
|
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
|
||||||
|
|
||||||
|
SpawnColorPalette m_SpawnColorPalette;
|
||||||
|
|
||||||
|
TilePalette m_TilePalette;
|
||||||
|
|
||||||
|
MobList m_Mobs;
|
||||||
|
|
||||||
|
TowerList m_Towers;
|
||||||
|
|
||||||
|
Game* m_Game;
|
||||||
|
|
||||||
|
WorldNotifier m_WorldNotifier;
|
||||||
|
MobNotifier m_MobNotifier;
|
||||||
|
public:
|
||||||
|
World(Game* game);
|
||||||
|
|
||||||
|
bool LoadMap(const protocol::WorldBeginDataPacket* worldHeader);
|
||||||
|
bool LoadMap(const protocol::WorldDataPacket* worldData);
|
||||||
|
|
||||||
|
bool LoadMapFromFile(const std::string& fileName);
|
||||||
|
bool SaveMap(const std::string& fileName) const;
|
||||||
|
|
||||||
|
void Tick(std::uint64_t delta);
|
||||||
|
|
||||||
|
void Reset(); // clear mobs and towers
|
||||||
|
|
||||||
|
void SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
||||||
|
MobPtr RemoveMob(MobID id);
|
||||||
|
|
||||||
|
TowerPtr PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
|
||||||
|
TowerPtr RemoveTower(TowerID id);
|
||||||
|
|
||||||
|
TilePtr GetTile(std::int32_t x, std::int32_t y) const;
|
||||||
|
|
||||||
|
const TowerTileColorPalette& GetTowerTileColorPalette() const { return m_TowerPlacePalette; }
|
||||||
|
const Color& GetWalkableTileColor() const { return m_WalkablePalette; }
|
||||||
|
const std::vector<Color>& GetDecorationPalette() const { return m_DecorationPalette; }
|
||||||
|
const Color& GetBackgroundColor() const { return m_Background; }
|
||||||
|
|
||||||
|
const TilePalette& GetTilePalette() const { return m_TilePalette; }
|
||||||
|
|
||||||
|
TilePtr GetTilePtr(TileIndex index) const {
|
||||||
|
if (index == 0)
|
||||||
|
return nullptr;
|
||||||
|
return m_TilePalette.at(index - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanPlaceLittleTower(const Vec2f& worldPos, PlayerID player) const;
|
||||||
|
bool CanPlaceBigTower(const Vec2f& worldPos, PlayerID player) const;
|
||||||
|
|
||||||
|
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 Color& GetSpawnColor(TeamColor color) const { return m_SpawnColorPalette[static_cast<std::size_t>(color)]; }
|
||||||
|
const SpawnColorPalette& GetSpawnColors() const { return m_SpawnColorPalette; }
|
||||||
|
|
||||||
|
const MobList& GetMobList() const { return m_Mobs; }
|
||||||
|
MobList& GetMobList() { return m_Mobs; }
|
||||||
|
|
||||||
|
const Color* GetTileColor(TilePtr tile) const;
|
||||||
|
|
||||||
|
Team& GetRedTeam();
|
||||||
|
const Team& GetRedTeam() const;
|
||||||
|
|
||||||
|
Team& GetBlueTeam();
|
||||||
|
const Team& GetBlueTeam() const;
|
||||||
|
|
||||||
|
Team& GetTeam(TeamColor team);
|
||||||
|
const Team& GetTeam(TeamColor team) const;
|
||||||
|
|
||||||
|
const TeamList& GetTeams() const;
|
||||||
|
|
||||||
|
TowerList& GetTowers() { return m_Towers; }
|
||||||
|
const TowerList& GetTowers() const { return m_Towers; }
|
||||||
|
|
||||||
|
TowerPtr GetTowerById(TowerID tower);
|
||||||
|
|
||||||
|
const Player* GetPlayerById(PlayerID id) const;
|
||||||
|
|
||||||
|
WorldNotifier& GetWorldNotifier() { return m_WorldNotifier; }
|
||||||
|
MobNotifier& GetMobNotifier() { return m_MobNotifier; }
|
||||||
|
|
||||||
|
// WorldListener
|
||||||
|
|
||||||
|
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) override;
|
||||||
|
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) override;
|
||||||
|
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) override;
|
||||||
|
|
||||||
|
// MobListener
|
||||||
|
|
||||||
|
virtual void OnMobDamage(Mob* target, float damage, Tower* source) override;
|
||||||
|
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void TickMobs(std::uint64_t delta);
|
||||||
|
void CleanDeadMobs();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
4465
include/td/misc/Backward.hpp
Normal file
4465
include/td/misc/Backward.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,9 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
std::uint64_t Inflate(const std::string& source, std::string& dest);
|
||||||
|
std::uint64_t Deflate(const std::string& source, std::string& dest);
|
||||||
|
|
||||||
DataBuffer Compress(const DataBuffer& buffer);
|
DataBuffer Compress(const DataBuffer& buffer);
|
||||||
DataBuffer Decompress(DataBuffer& buffer);
|
DataBuffer Decompress(DataBuffer& buffer);
|
||||||
DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength);
|
DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength);
|
||||||
177
include/td/misc/DataBuffer.h
Normal file
177
include/td/misc/DataBuffer.h
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class DataBuffer {
|
||||||
|
private:
|
||||||
|
typedef std::vector<std::uint8_t> Data;
|
||||||
|
Data m_Buffer;
|
||||||
|
std::size_t m_ReadOffset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Data::iterator iterator;
|
||||||
|
typedef Data::const_iterator const_iterator;
|
||||||
|
typedef Data::reference reference;
|
||||||
|
typedef Data::const_reference const_reference;
|
||||||
|
|
||||||
|
DataBuffer();
|
||||||
|
DataBuffer(const DataBuffer& other);
|
||||||
|
DataBuffer(const DataBuffer& other, Data::difference_type offset);
|
||||||
|
DataBuffer(DataBuffer&& other);
|
||||||
|
DataBuffer(const std::string& str);
|
||||||
|
|
||||||
|
DataBuffer& operator=(const DataBuffer& other);
|
||||||
|
DataBuffer& operator=(DataBuffer&& other);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Append(T data) {
|
||||||
|
std::size_t size = sizeof(data);
|
||||||
|
std::size_t end_pos = m_Buffer.size();
|
||||||
|
m_Buffer.resize(m_Buffer.size() + size);
|
||||||
|
memcpy(&m_Buffer[end_pos], &data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DataBuffer& operator<<(T data) {
|
||||||
|
// Switch to big endian
|
||||||
|
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
||||||
|
Append(data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer& operator<<(std::string str) {
|
||||||
|
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer& operator<<(DataBuffer& data) {
|
||||||
|
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer& operator<<(const DataBuffer& data) {
|
||||||
|
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DataBuffer& operator>>(T& data) {
|
||||||
|
assert(m_ReadOffset + sizeof(T) <= GetSize());
|
||||||
|
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
|
||||||
|
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
||||||
|
m_ReadOffset += sizeof(T);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer& operator>>(DataBuffer& data) {
|
||||||
|
data.Resize(GetSize() - m_ReadOffset);
|
||||||
|
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
|
||||||
|
m_ReadOffset = m_Buffer.size();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer& operator>>(std::string& str) {
|
||||||
|
std::size_t stringSize = strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
|
||||||
|
str.resize(stringSize);
|
||||||
|
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_ReadOffset += stringSize;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSome(const char* buffer, std::size_t amount) {
|
||||||
|
std::size_t end_pos = m_Buffer.size();
|
||||||
|
m_Buffer.resize(m_Buffer.size() + amount);
|
||||||
|
memcpy(m_Buffer.data() + end_pos, buffer, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
|
||||||
|
std::size_t end_pos = m_Buffer.size();
|
||||||
|
m_Buffer.resize(m_Buffer.size() + amount);
|
||||||
|
memcpy(m_Buffer.data() + end_pos, buffer, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadSome(char* buffer, std::size_t amount) {
|
||||||
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
|
||||||
|
m_ReadOffset += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
|
||||||
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
|
||||||
|
m_ReadOffset += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadSome(DataBuffer& buffer, std::size_t amount) {
|
||||||
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
|
buffer.Resize(amount);
|
||||||
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
|
||||||
|
m_ReadOffset += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadSome(std::string& buffer, std::size_t amount) {
|
||||||
|
assert(m_ReadOffset + amount <= GetSize());
|
||||||
|
buffer.resize(amount);
|
||||||
|
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
|
||||||
|
m_ReadOffset += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resize(std::size_t size) {
|
||||||
|
m_Buffer.resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reserve(std::size_t amount) {
|
||||||
|
m_Buffer.reserve(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(iterator it) {
|
||||||
|
m_Buffer.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
m_Buffer.clear();
|
||||||
|
m_ReadOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsFinished() const {
|
||||||
|
return m_ReadOffset >= m_Buffer.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t* data() {
|
||||||
|
return m_Buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::uint8_t* data() const {
|
||||||
|
return m_Buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t GetReadOffset() const { return m_ReadOffset; }
|
||||||
|
void SetReadOffset(std::size_t pos);
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
|
std::size_t GetSize() const;
|
||||||
|
bool IsEmpty() const;
|
||||||
|
std::size_t GetRemaining() const;
|
||||||
|
|
||||||
|
iterator begin();
|
||||||
|
iterator end();
|
||||||
|
const_iterator begin() const;
|
||||||
|
const_iterator end() const;
|
||||||
|
|
||||||
|
reference operator[](Data::size_type i) { return m_Buffer[i]; }
|
||||||
|
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
|
||||||
|
|
||||||
|
bool ReadFile(const std::string& fileName);
|
||||||
|
bool WriteFile(const std::string& fileName);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
|
||||||
|
|
||||||
|
} // ns td
|
||||||
69
include/td/misc/Easing.h
Normal file
69
include/td/misc/Easing.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
constexpr float PI = 3.14159274101257324219;
|
||||||
|
|
||||||
|
/* Sine functions */
|
||||||
|
|
||||||
|
float EaseInSine(float x);
|
||||||
|
float EaseOutSine(float x);
|
||||||
|
float EaseInOutSine(float x);
|
||||||
|
|
||||||
|
/* Cubic functions */
|
||||||
|
|
||||||
|
float EaseInCubic(float x);
|
||||||
|
float EaseOutCubic(float x);
|
||||||
|
float EaseInOutCubic(float x);
|
||||||
|
|
||||||
|
/* Quint functions */
|
||||||
|
|
||||||
|
float EaseInQuint(float x);
|
||||||
|
float EaseOutQuint(float x);
|
||||||
|
float EaseInOutQuint(float x);
|
||||||
|
|
||||||
|
/* Circ functions */
|
||||||
|
|
||||||
|
float EaseInCirc(float x);
|
||||||
|
float EaseOutCirc(float x);
|
||||||
|
float EaseInOutCirc(float x);
|
||||||
|
|
||||||
|
/* Elastic functions */
|
||||||
|
|
||||||
|
float EaseInElastic(float x);
|
||||||
|
float EaseOutElastic(float x);
|
||||||
|
float EaseInOutElastic(float x);
|
||||||
|
|
||||||
|
/* Quad functions */
|
||||||
|
|
||||||
|
float EaseInQuad(float x);
|
||||||
|
float EaseOutQuad(float x);
|
||||||
|
float EaseInOutQuad(float x);
|
||||||
|
|
||||||
|
/* Quart functions */
|
||||||
|
|
||||||
|
float EaseInQuart(float x);
|
||||||
|
float EaseOutQuart(float x);
|
||||||
|
float EaseInOutQuart(float x);
|
||||||
|
|
||||||
|
/* Expo functions */
|
||||||
|
|
||||||
|
float EaseInExpo(float x);
|
||||||
|
float EaseOutExpo(float x);
|
||||||
|
float EaseInOutExpo(float x);
|
||||||
|
|
||||||
|
/* Back functions */
|
||||||
|
|
||||||
|
float EaseInBack(float x);
|
||||||
|
float EaseOutBack(float x);
|
||||||
|
float EaseInOutBack(float x);
|
||||||
|
|
||||||
|
/* Bounce functions */
|
||||||
|
|
||||||
|
float EaseInBounce(float x);
|
||||||
|
float EaseOutBounce(float x);
|
||||||
|
float EaseInOutBounce(float x);
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
} // namespace td
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user