feat: implement basic tower placement
This commit is contained in:
@@ -18,7 +18,9 @@ enum class TowerType : std::uint8_t{
|
|||||||
|
|
||||||
Leach,
|
Leach,
|
||||||
Turret,
|
Turret,
|
||||||
Necromancer
|
Necromancer,
|
||||||
|
|
||||||
|
TowerCount
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TowerSize : bool{
|
enum class TowerSize : bool{
|
||||||
@@ -64,8 +66,8 @@ public:
|
|||||||
|
|
||||||
// operator to sort maps
|
// operator to sort maps
|
||||||
friend bool operator<(const TowerLevel& level, const TowerLevel& other){
|
friend bool operator<(const TowerLevel& level, const TowerLevel& other){
|
||||||
return level.getLevel() * (std::uint8_t)level.getPath() <
|
return level.getLevel() * static_cast<std::uint8_t>(level.getPath()) <
|
||||||
other.getLevel() * (std::uint8_t)other.getPath();
|
other.getLevel() * static_cast<std::uint8_t>(other.getPath());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,14 @@ private:
|
|||||||
ClientGame m_Game;
|
ClientGame m_Game;
|
||||||
bool m_Connected;
|
bool m_Connected;
|
||||||
public:
|
public:
|
||||||
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(m_Connexion.GetDispatcher(), m_Renderer), m_Connected(false){}
|
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(this), m_Connected(false){}
|
||||||
|
|
||||||
const ClientGame& getGame() const{ return m_Game; }
|
const ClientGame& getGame() const{ return m_Game; }
|
||||||
const ClientConnexion& getConnexion() const{ return m_Connexion; }
|
const ClientConnexion& getConnexion() const{ return m_Connexion; }
|
||||||
|
render::Renderer* getRenderer() const {return m_Renderer;}
|
||||||
|
|
||||||
|
ClientGame& getGame(){ return m_Game; }
|
||||||
|
ClientConnexion& getConnexion(){ return m_Connexion; }
|
||||||
|
|
||||||
void tick(std::uint64_t delta);
|
void tick(std::uint64_t delta);
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,11 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
|
||||||
class ClientGame : public protocol::PacketHandler, public game::Game{
|
class ClientGame : public protocol::PacketHandler, public game::Game{
|
||||||
private:
|
private:
|
||||||
|
Client* m_Client;
|
||||||
std::uint8_t m_ConnexionID;
|
std::uint8_t m_ConnexionID;
|
||||||
std::uint32_t m_LobbyTime = 0;
|
std::uint32_t m_LobbyTime = 0;
|
||||||
game::Player* m_Player = nullptr;
|
game::Player* m_Player = nullptr;
|
||||||
@@ -21,7 +24,7 @@ private:
|
|||||||
client::WorldClient m_WorldClient;
|
client::WorldClient m_WorldClient;
|
||||||
render::WorldRenderer m_WorldRenderer;
|
render::WorldRenderer m_WorldRenderer;
|
||||||
public:
|
public:
|
||||||
ClientGame(protocol::PacketDispatcher* dispatcher, render::Renderer* renderer);
|
ClientGame(Client* client);
|
||||||
virtual ~ClientGame();
|
virtual ~ClientGame();
|
||||||
|
|
||||||
virtual void tick(std::uint64_t delta);
|
virtual void tick(std::uint64_t delta);
|
||||||
@@ -31,6 +34,13 @@ public:
|
|||||||
std::uint32_t getLobbyTime() const{return m_LobbyTime;}
|
std::uint32_t getLobbyTime() const{return m_LobbyTime;}
|
||||||
const game::Player* getPlayer() const{return m_Player;}
|
const game::Player* getPlayer() const{return m_Player;}
|
||||||
|
|
||||||
|
render::Renderer* getRenderer() const {return m_Renderer;}
|
||||||
|
|
||||||
|
void PlaceTower(game::TowerType type, const glm::vec2& position);
|
||||||
|
|
||||||
|
bool CanPlaceLittleTower(const glm::vec2& worldPos);
|
||||||
|
bool CanPlaceBigTower(const glm::vec2& worldPos);
|
||||||
|
|
||||||
virtual void HandlePacket(protocol::ConnexionInfoPacket* packet);
|
virtual void HandlePacket(protocol::ConnexionInfoPacket* packet);
|
||||||
virtual void HandlePacket(protocol::PlayerJoinPacket* packet);
|
virtual void HandlePacket(protocol::PlayerJoinPacket* packet);
|
||||||
virtual void HandlePacket(protocol::PlayerLeavePacket* packet);
|
virtual void HandlePacket(protocol::PlayerLeavePacket* packet);
|
||||||
|
|||||||
26
include/game/client/TowersInfo.h
Normal file
26
include/game/client/TowersInfo.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "game/Towers.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
@@ -16,6 +16,7 @@ public:
|
|||||||
|
|
||||||
virtual void HandlePacket(protocol::WorldBeginDataPacket* packet);
|
virtual void HandlePacket(protocol::WorldBeginDataPacket* packet);
|
||||||
virtual void HandlePacket(protocol::WorldDataPacket* packet);
|
virtual void HandlePacket(protocol::WorldDataPacket* packet);
|
||||||
|
virtual void HandlePacket(protocol::WorldAddTowerPacket* packet);
|
||||||
virtual void HandlePacket(protocol::SpawnMobPacket* packet);
|
virtual void HandlePacket(protocol::SpawnMobPacket* packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public:
|
|||||||
virtual void HandlePacket(protocol::KeepAlivePacket* packet);
|
virtual void HandlePacket(protocol::KeepAlivePacket* packet);
|
||||||
virtual void HandlePacket(protocol::SelectTeamPacket* packet);
|
virtual void HandlePacket(protocol::SelectTeamPacket* packet);
|
||||||
virtual void HandlePacket(protocol::DisconnectPacket* packet);
|
virtual void HandlePacket(protocol::DisconnectPacket* packet);
|
||||||
|
virtual void HandlePacket(protocol::PlaceTowerPacket* packet);
|
||||||
|
|
||||||
std::uint8_t getID() const{return m_ID;}
|
std::uint8_t getID() const{return m_ID;}
|
||||||
const game::Player* getPlayer() const{return m_Player;}
|
const game::Player* getPlayer() const{return m_Player;}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public:
|
|||||||
virtual void HandlePacket(DisconnectPacket* packet){}
|
virtual void HandlePacket(DisconnectPacket* packet){}
|
||||||
virtual void HandlePacket(ServerTpsPacket* packet){}
|
virtual void HandlePacket(ServerTpsPacket* packet){}
|
||||||
virtual void HandlePacket(SpawnMobPacket* packet){}
|
virtual void HandlePacket(SpawnMobPacket* packet){}
|
||||||
|
virtual void HandlePacket(PlaceTowerPacket* packet){}
|
||||||
|
virtual void HandlePacket(WorldAddTowerPacket* packet){}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ enum class PacketType : std::uint8_t{
|
|||||||
UpdatePlayerTeam,
|
UpdatePlayerTeam,
|
||||||
ServerTps,
|
ServerTps,
|
||||||
SpawnMob,
|
SpawnMob,
|
||||||
|
PlaceTower,
|
||||||
|
WorldAddTower
|
||||||
};
|
};
|
||||||
|
|
||||||
class Packet{
|
class Packet{
|
||||||
@@ -380,5 +382,49 @@ public:
|
|||||||
virtual PacketType getType() const{ return PacketType::SpawnMob; }
|
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);
|
||||||
|
|
||||||
|
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:
|
||||||
|
std::int32_t m_TowerX, m_TowerY;
|
||||||
|
game::TowerType m_TowerType;
|
||||||
|
game::PlayerID m_Builder;
|
||||||
|
public:
|
||||||
|
WorldAddTowerPacket(){}
|
||||||
|
WorldAddTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) :
|
||||||
|
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);
|
||||||
|
|
||||||
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,36 +7,51 @@
|
|||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
namespace client{
|
||||||
|
|
||||||
|
class ClientGame;
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
class WorldRenderer{
|
class WorldRenderer{
|
||||||
private:
|
private:
|
||||||
|
client::ClientGame* m_Client;
|
||||||
Renderer* m_Renderer;
|
Renderer* m_Renderer;
|
||||||
game::World* m_World;
|
game::World* m_World;
|
||||||
std::unique_ptr<GL::VAO> m_WorldVao, m_MobVao, m_SelectTileVao;
|
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
|
||||||
glm::vec2 m_CamPos;
|
glm::vec2 m_CamPos;
|
||||||
glm::vec2 m_CursorPos;
|
glm::vec2 m_CursorPos;
|
||||||
|
glm::vec2 m_HoldCursorPos;
|
||||||
float m_Zoom = 1;
|
float m_Zoom = 1;
|
||||||
float m_CamSensibility = 1;
|
float m_CamSensibility = 1;
|
||||||
|
bool m_TowerPlacePopupOpened = false;
|
||||||
public:
|
public:
|
||||||
WorldRenderer(game::World* world, Renderer* renderer);
|
WorldRenderer(game::World* world, client::ClientGame* client);
|
||||||
~WorldRenderer();
|
~WorldRenderer();
|
||||||
|
|
||||||
void loadModels();
|
void loadModels();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
void render() const;
|
void render();
|
||||||
|
|
||||||
void setCamPos(float camX, float camY);
|
void setCamPos(float camX, float camY);
|
||||||
|
|
||||||
void moveCam(float relativeX, float relativeY, float aspectRatio);
|
void moveCam(float relativeX, float relativeY, float aspectRatio);
|
||||||
void changeZoom(float zoom);
|
void changeZoom(float zoom);
|
||||||
void click(int mouseX, int mouseY);
|
|
||||||
private:
|
private:
|
||||||
|
void click();
|
||||||
void renderWorld() const;
|
void renderWorld() const;
|
||||||
void renderTowers() const;
|
void renderTowers() const;
|
||||||
void renderMobs() const;
|
void renderMobs() const;
|
||||||
void renderTileSelect() const;
|
void renderTileSelect() const;
|
||||||
|
void renderPopups() const;
|
||||||
|
void detectClick();
|
||||||
|
glm::vec2 getCursorWorldPos() const;
|
||||||
|
glm::vec2 getClickWorldPos() const;
|
||||||
|
|
||||||
void updateCursorPos();
|
void updateCursorPos();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
#include "game/client/ClientGame.h"
|
#include "game/client/ClientGame.h"
|
||||||
#include "protocol/PacketDispatcher.h"
|
#include "protocol/PacketDispatcher.h"
|
||||||
//#include "game/Team.h"
|
//#include "game/Team.h"
|
||||||
|
#include "game/client/Client.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
ClientGame::ClientGame(protocol::PacketDispatcher* dispatcher, render::Renderer* renderer): protocol::PacketHandler(dispatcher),
|
ClientGame::ClientGame(Client* client): protocol::PacketHandler(client->getConnexion().GetDispatcher()),
|
||||||
game::Game(&m_WorldClient), m_Renderer(renderer), m_WorldClient(this), m_WorldRenderer(&m_WorldClient, m_Renderer){
|
game::Game(&m_WorldClient), m_Client(client), m_Renderer(client->getRenderer()), m_WorldClient(this),
|
||||||
|
m_WorldRenderer(&m_WorldClient, this){
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnectionInfo, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnectionInfo, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerJoin, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerJoin, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
|
||||||
@@ -111,5 +113,54 @@ void ClientGame::renderWorld(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientGame::PlaceTower(game::TowerType type, const glm::vec2& position){
|
||||||
|
protocol::PlaceTowerPacket packet(position.x, position.y, type);
|
||||||
|
m_Client->getConnexion().sendPacket(&packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientGame::CanPlaceLittleTower(const glm::vec2& worldPos){
|
||||||
|
game::TilePtr tile = m_WorldClient.getTile(worldPos.x, worldPos.y);
|
||||||
|
|
||||||
|
if(tile == nullptr){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tile->getType() == game::TileType::Tower){
|
||||||
|
for(int x = -1; x < 2; x++){
|
||||||
|
for(int y = -1; y < 2; y++){
|
||||||
|
game::TilePtr adjacentTile = m_WorldClient.getTile(worldPos.x + x, worldPos.y + y);
|
||||||
|
if(adjacentTile == nullptr || adjacentTile->getType() != game::TileType::Tower){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientGame::CanPlaceBigTower(const glm::vec2& worldPos){
|
||||||
|
game::TilePtr tile = m_WorldClient.getTile(worldPos.x, worldPos.y);
|
||||||
|
|
||||||
|
if(tile == nullptr){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tile->getType() == game::TileType::Tower){
|
||||||
|
for(int x = -2; x < 3; x++){
|
||||||
|
for(int y = -2; y < 3; y++){
|
||||||
|
game::TilePtr adjacentTile = m_WorldClient.getTile(worldPos.x + x, worldPos.y + y);
|
||||||
|
if(adjacentTile == nullptr || adjacentTile->getType() != game::TileType::Tower){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
27
src/game/client/TowersInfo.cpp
Normal file
27
src/game/client/TowersInfo.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "game/client/TowersInfo.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace game {
|
||||||
|
|
||||||
|
static const std::map<TowerType, TowerInfo> TowerInfoConstants = {
|
||||||
|
{TowerType::Archer, {"Archer", "Shoot projectiles", false}},
|
||||||
|
{TowerType::Artillery, {"Artillery", "Explosion", false}},
|
||||||
|
{TowerType::Ice, {"Ice", "Slow down enemies", false}},
|
||||||
|
{TowerType::Leach, {"Leach", "Shoot projectiles", true}},
|
||||||
|
{TowerType::Mage, {"Mage", "Set enemies on fire", false}},
|
||||||
|
{TowerType::Necromancer, {"Necromancer", "Summon troops", true}},
|
||||||
|
{TowerType::Poison, {"Poison", "Poison enemies", false}},
|
||||||
|
{TowerType::Quake, {"Quake", "Shoot projectiles", false}},
|
||||||
|
{TowerType::Sorcerer, {"Sorcerer", "Summon friendly troops", false}},
|
||||||
|
{TowerType::Turret, {"Turret", "Shoot arrow very fast", true}},
|
||||||
|
{TowerType::Zeus, {"Zeus", "Strike lightning", false}},
|
||||||
|
};
|
||||||
|
|
||||||
|
const TowerInfo& getTowerInfo(TowerType type){
|
||||||
|
return TowerInfoConstants.at(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace game
|
||||||
|
} // namespace td
|
||||||
@@ -9,6 +9,7 @@ namespace client{
|
|||||||
WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::PacketHandler(game->GetDispatcher()), m_Game(game){
|
WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::PacketHandler(game->GetDispatcher()), m_Game(game){
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldBeginData, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldBeginData, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
||||||
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldAddTower, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +21,10 @@ void WorldClient::HandlePacket(protocol::WorldDataPacket* packet){
|
|||||||
loadMap(packet);
|
loadMap(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldClient::HandlePacket(protocol::WorldAddTowerPacket* packet){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(protocol::SpawnMobPacket* packet){
|
void WorldClient::HandlePacket(protocol::SpawnMobPacket* packet){
|
||||||
spawnMobAt(packet->getMobID(), packet->getMobType(), packet->getMobLevel(), packet->getSender(),
|
spawnMobAt(packet->getMobID(), packet->getMobType(), packet->getMobLevel(), packet->getSender(),
|
||||||
packet->getMobX(), packet->getMobY(), packet->getMobDirection());
|
packet->getMobX(), packet->getMobY(), packet->getMobDirection());
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ void ServerConnexion::registerHandlers(){
|
|||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::SelectTeam, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::SelectTeam, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
|
||||||
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlaceTower, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerConnexion::updateSocket(){
|
bool ServerConnexion::updateSocket(){
|
||||||
@@ -143,6 +144,11 @@ void ServerConnexion::initConnection(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerConnexion::HandlePacket(protocol::PlaceTowerPacket* packet){
|
||||||
|
// process packet
|
||||||
|
protocol::WorldAddTowerPacket addTowerPacket(packet->getTowerX(), packet->getTowerY(), packet->getTowerType(), m_ID);
|
||||||
|
m_Server->broadcastPacket(&addTowerPacket);
|
||||||
|
}
|
||||||
|
|
||||||
ServerConnexion::~ServerConnexion(){
|
ServerConnexion::~ServerConnexion(){
|
||||||
if (GetDispatcher() != nullptr)
|
if (GetDispatcher() != nullptr)
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ static std::map<PacketType, PacketCreator> packets = {
|
|||||||
{PacketType::Disconnect, []() -> Packet* {return new DisconnectPacket(); } },
|
{PacketType::Disconnect, []() -> Packet* {return new DisconnectPacket(); } },
|
||||||
{PacketType::ServerTps, []() -> Packet* {return new ServerTpsPacket(); } },
|
{PacketType::ServerTps, []() -> Packet* {return new ServerTpsPacket(); } },
|
||||||
{PacketType::SpawnMob, []() -> Packet* {return new SpawnMobPacket(); } },
|
{PacketType::SpawnMob, []() -> Packet* {return new SpawnMobPacket(); } },
|
||||||
|
{PacketType::PlaceTower, []() -> Packet* {return new PlaceTowerPacket(); } },
|
||||||
|
{PacketType::WorldAddTower, []() -> Packet* {return new WorldAddTowerPacket(); } },
|
||||||
};
|
};
|
||||||
|
|
||||||
Packet* createPacket(PacketType type, DataBuffer& buffer){
|
Packet* createPacket(PacketType type, DataBuffer& buffer){
|
||||||
|
|||||||
@@ -391,6 +391,26 @@ void SpawnMobPacket::Deserialize(DataBuffer& data){
|
|||||||
>> m_Sender >> m_MobX >> m_MobY;
|
>> m_Sender >> m_MobX >> m_MobY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataBuffer PlaceTowerPacket::Serialize() const{
|
||||||
|
DataBuffer data;
|
||||||
|
data << getID() << m_TowerX << m_TowerY << m_TowerType;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaceTowerPacket::Deserialize(DataBuffer& data){
|
||||||
|
data >> m_TowerX >> m_TowerY >> m_TowerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer WorldAddTowerPacket::Serialize() const{
|
||||||
|
DataBuffer data;
|
||||||
|
data << getID() << m_TowerX << m_TowerY << m_TowerType << m_Builder;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldAddTowerPacket::Deserialize(DataBuffer& data){
|
||||||
|
data >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder;
|
||||||
|
}
|
||||||
|
|
||||||
REGISTER_DISPATCH_CLASS(PlayerLoginPacket);
|
REGISTER_DISPATCH_CLASS(PlayerLoginPacket);
|
||||||
REGISTER_DISPATCH_CLASS(WorldBeginDataPacket);
|
REGISTER_DISPATCH_CLASS(WorldBeginDataPacket);
|
||||||
REGISTER_DISPATCH_CLASS(WorldDataPacket);
|
REGISTER_DISPATCH_CLASS(WorldDataPacket);
|
||||||
@@ -408,6 +428,8 @@ REGISTER_DISPATCH_CLASS(UpdatePlayerTeamPacket);
|
|||||||
REGISTER_DISPATCH_CLASS(DisconnectPacket);
|
REGISTER_DISPATCH_CLASS(DisconnectPacket);
|
||||||
REGISTER_DISPATCH_CLASS(ServerTpsPacket);
|
REGISTER_DISPATCH_CLASS(ServerTpsPacket);
|
||||||
REGISTER_DISPATCH_CLASS(SpawnMobPacket);
|
REGISTER_DISPATCH_CLASS(SpawnMobPacket);
|
||||||
|
REGISTER_DISPATCH_CLASS(PlaceTowerPacket);
|
||||||
|
REGISTER_DISPATCH_CLASS(WorldAddTowerPacket);
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
} // namespace td
|
} // namespace td
|
||||||
@@ -3,13 +3,15 @@
|
|||||||
#include "render/Renderer.h"
|
#include "render/Renderer.h"
|
||||||
#include "../render/gui/imgui/imgui.h"
|
#include "../render/gui/imgui/imgui.h"
|
||||||
#include "window/Display.h"
|
#include "window/Display.h"
|
||||||
|
#include "game/client/TowersInfo.h"
|
||||||
|
#include "game/client/ClientGame.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
void WorldRenderer::loadModels(){
|
void WorldRenderer::loadModels() {
|
||||||
std::cout << "World Created !\n";
|
std::cout << "World Created !\n";
|
||||||
m_WorldVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::loadWorldModel(m_World)));
|
m_WorldVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::loadWorldModel(m_World)));
|
||||||
m_MobVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::loadMobModel()));
|
m_MobVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::loadMobModel()));
|
||||||
@@ -17,103 +19,147 @@ void WorldRenderer::loadModels(){
|
|||||||
std::cout << "Vertex Count : " << m_WorldVao->getVertexCount() << std::endl;
|
std::cout << "Vertex Count : " << m_WorldVao->getVertexCount() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldRenderer::WorldRenderer(game::World* world, Renderer* renderer) : m_Renderer(renderer), m_World(world) {
|
WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m_Client(client), m_Renderer(m_Client->getRenderer()), m_World(world) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::updateCursorPos(){
|
void WorldRenderer::updateCursorPos() {
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
m_CursorPos = getCursorWorldPos();
|
||||||
|
|
||||||
float mouseX = io.MousePos.x;
|
|
||||||
float mouseY = io.MousePos.y;
|
|
||||||
|
|
||||||
m_CursorPos = m_Renderer->getCursorWorldPos({mouseX, mouseY}, Display::getAspectRatio(), m_Zoom, Display::getWindowWidth(), Display::getWindowHeight());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::update(){
|
void WorldRenderer::update() {
|
||||||
if(m_WorldVao == nullptr)
|
if (m_WorldVao == nullptr)
|
||||||
return;
|
return;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
if(io.MouseDown[0] && !ImGui::IsAnyItemActive()){
|
if (io.MouseDown[0] && !ImGui::IsAnyItemActive()) {
|
||||||
ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
||||||
const float relativeX = mouseDelta.x / (float) Display::getWindowWidth() * 2;
|
const float relativeX = mouseDelta.x / (float)Display::getWindowWidth() * 2;
|
||||||
const float relativeY = mouseDelta.y / (float) Display::getWindowHeight() * 2;
|
const float relativeY = mouseDelta.y / (float)Display::getWindowHeight() * 2;
|
||||||
moveCam(relativeX, relativeY, Display::getAspectRatio());
|
moveCam(relativeX, relativeY, Display::getAspectRatio());
|
||||||
}
|
}
|
||||||
if(io.MouseWheel != 0){
|
if (io.MouseWheel != 0) {
|
||||||
changeZoom(io.MouseWheel);
|
changeZoom(io.MouseWheel);
|
||||||
}
|
}
|
||||||
updateCursorPos();
|
updateCursorPos();
|
||||||
|
if (ImGui::IsMouseClicked(0)) {
|
||||||
|
if (!m_TowerPlacePopupOpened) {
|
||||||
|
m_HoldCursorPos = { io.MousePos.x, io.MousePos.y };
|
||||||
|
} else {
|
||||||
|
m_TowerPlacePopupOpened = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::renderWorld() const{
|
void WorldRenderer::renderWorld() const {
|
||||||
m_Renderer->renderVAO(*m_WorldVao);
|
m_Renderer->renderVAO(*m_WorldVao);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::renderMobs() const{
|
void WorldRenderer::renderMobs() const {
|
||||||
for(game::MobPtr mob : m_World->getMobList()){
|
for (game::MobPtr mob : m_World->getMobList()) {
|
||||||
Renderer::Model model;
|
Renderer::Model model;
|
||||||
model.vao = m_MobVao.get();
|
model.vao = m_MobVao.get();
|
||||||
model.positon = {mob->getX(), mob->getY()};
|
model.positon = { mob->getX(), mob->getY() };
|
||||||
m_Renderer->renderModel(model);
|
m_Renderer->renderModel(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::renderTowers() const{
|
void WorldRenderer::renderTowers() const {
|
||||||
Renderer::Model tileSelectModel;
|
Renderer::Model tileSelectModel;
|
||||||
tileSelectModel.vao = m_SelectTileVao.get();
|
tileSelectModel.vao = m_SelectTileVao.get();
|
||||||
tileSelectModel.positon = {(int) m_CursorPos.x, (int) m_CursorPos.y};
|
tileSelectModel.positon = { (int)m_CursorPos.x, (int)m_CursorPos.y };
|
||||||
|
|
||||||
m_Renderer->renderModel(tileSelectModel);
|
m_Renderer->renderModel(tileSelectModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::renderTileSelect() const{
|
void WorldRenderer::renderTileSelect() const {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::render() const{
|
void WorldRenderer::render() {
|
||||||
if(m_WorldVao == nullptr)
|
if (m_WorldVao == nullptr)
|
||||||
return;
|
return;
|
||||||
renderWorld();
|
renderWorld();
|
||||||
renderMobs();
|
renderMobs();
|
||||||
renderTowers();
|
renderTowers();
|
||||||
renderTileSelect();
|
renderTileSelect();
|
||||||
|
detectClick();
|
||||||
|
renderPopups();
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldRenderer::~WorldRenderer(){
|
WorldRenderer::~WorldRenderer() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::moveCam(float relativeX, float relativeY, float aspectRatio){
|
void WorldRenderer::moveCam(float relativeX, float relativeY, float aspectRatio) {
|
||||||
if(m_WorldVao == nullptr)
|
if (m_WorldVao == nullptr)
|
||||||
return;
|
return;
|
||||||
float movementX = -relativeX / m_Zoom * aspectRatio;
|
float movementX = -relativeX / m_Zoom * aspectRatio;
|
||||||
float movementY = relativeY / m_Zoom;
|
float movementY = relativeY / m_Zoom;
|
||||||
m_Renderer->setCamMovement({movementX, movementY});
|
m_Renderer->setCamMovement({ movementX, movementY });
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::changeZoom(float zoomStep){
|
void WorldRenderer::changeZoom(float zoomStep) {
|
||||||
if(m_WorldVao == nullptr)
|
if (m_WorldVao == nullptr)
|
||||||
return;
|
return;
|
||||||
static float sensibility = 1.5f;
|
static float sensibility = 1.5f;
|
||||||
if (zoomStep < 0){
|
if (zoomStep < 0) {
|
||||||
m_Zoom /= -zoomStep * sensibility;
|
m_Zoom /= -zoomStep * sensibility;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
m_Zoom *= zoomStep * sensibility;
|
m_Zoom *= zoomStep * sensibility;
|
||||||
}
|
}
|
||||||
m_Renderer->setZoom(m_Zoom);
|
m_Renderer->setZoom(m_Zoom);
|
||||||
m_Renderer->setCamMovement({});
|
m_Renderer->setCamMovement({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::click(int mouseX, int mouseY){
|
void WorldRenderer::click() {
|
||||||
if(m_WorldVao == nullptr)
|
if (m_Client->CanPlaceLittleTower(getClickWorldPos())) {
|
||||||
return;
|
ImGui::OpenPopup("TowerPlace");
|
||||||
|
m_TowerPlacePopupOpened = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::setCamPos(float camX, float camY){
|
void WorldRenderer::setCamPos(float camX, float camY) {
|
||||||
m_CamPos = {camX, camY};
|
m_CamPos = { camX, camY };
|
||||||
m_Renderer->setCamPos(m_CamPos);
|
m_Renderer->setCamPos(m_CamPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldRenderer::renderPopups() const {
|
||||||
|
if (ImGui::BeginPopup("TowerPlace")) {
|
||||||
|
for (int i = 0; i < (int)game::TowerType::TowerCount; i++) {
|
||||||
|
game::TowerType towerType = game::TowerType(i);
|
||||||
|
const game::TowerInfo& towerInfo = game::getTowerInfo(towerType);
|
||||||
|
if (!towerInfo.isBigTower() || (towerInfo.isBigTower() && m_Client->CanPlaceBigTower(getClickWorldPos()))) {
|
||||||
|
if (ImGui::Button(game::getTowerInfo(towerType).getName().c_str())) {
|
||||||
|
m_Client->PlaceTower(towerType, getClickWorldPos());
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip(game::getTowerInfo(towerType).getDescription().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldRenderer::detectClick() {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
if (ImGui::IsMouseReleased(0) && !ImGui::IsAnyItemHovered() && !ImGui::IsAnyItemFocused()) {
|
||||||
|
glm::vec2 cursorPos = { io.MousePos.x, io.MousePos.y };
|
||||||
|
if (cursorPos == m_HoldCursorPos) {
|
||||||
|
click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 WorldRenderer::getCursorWorldPos() const {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
return m_Renderer->getCursorWorldPos({ io.MousePos.x, io.MousePos.y }, Display::getAspectRatio(), m_Zoom, Display::getWindowWidth(), Display::getWindowHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 WorldRenderer::getClickWorldPos() const{
|
||||||
|
return m_Renderer->getCursorWorldPos(m_HoldCursorPos, Display::getAspectRatio(), m_Zoom, Display::getWindowWidth(), Display::getWindowHeight());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -305,8 +305,8 @@ void tick(){
|
|||||||
|
|
||||||
void render(){
|
void render(){
|
||||||
tick();
|
tick();
|
||||||
client->render();
|
|
||||||
beginFrame();
|
beginFrame();
|
||||||
|
client->render();
|
||||||
if (client->isConnected())
|
if (client->isConnected())
|
||||||
renderGame();
|
renderGame();
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user