diff --git a/include/game/Towers.h b/include/game/Towers.h index 14113a5..7e9f9a6 100644 --- a/include/game/Towers.h +++ b/include/game/Towers.h @@ -18,7 +18,9 @@ enum class TowerType : std::uint8_t{ Leach, Turret, - Necromancer + Necromancer, + + TowerCount }; enum class TowerSize : bool{ @@ -64,8 +66,8 @@ public: // operator to sort maps friend bool operator<(const TowerLevel& level, const TowerLevel& other){ - return level.getLevel() * (std::uint8_t)level.getPath() < - other.getLevel() * (std::uint8_t)other.getPath(); + return level.getLevel() * static_cast(level.getPath()) < + other.getLevel() * static_cast(other.getPath()); } }; diff --git a/include/game/client/Client.h b/include/game/client/Client.h index 1ce5dd2..d456df2 100644 --- a/include/game/client/Client.h +++ b/include/game/client/Client.h @@ -18,10 +18,14 @@ private: ClientGame m_Game; bool m_Connected; 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 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); diff --git a/include/game/client/ClientGame.h b/include/game/client/ClientGame.h index aabfb87..3cab147 100644 --- a/include/game/client/ClientGame.h +++ b/include/game/client/ClientGame.h @@ -12,8 +12,11 @@ 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; @@ -21,7 +24,7 @@ private: client::WorldClient m_WorldClient; render::WorldRenderer m_WorldRenderer; public: - ClientGame(protocol::PacketDispatcher* dispatcher, render::Renderer* renderer); + ClientGame(Client* client); virtual ~ClientGame(); virtual void tick(std::uint64_t delta); @@ -31,6 +34,13 @@ public: std::uint32_t getLobbyTime() const{return m_LobbyTime;} 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::PlayerJoinPacket* packet); virtual void HandlePacket(protocol::PlayerLeavePacket* packet); diff --git a/include/game/client/TowersInfo.h b/include/game/client/TowersInfo.h new file mode 100644 index 0000000..eaf0ea3 --- /dev/null +++ b/include/game/client/TowersInfo.h @@ -0,0 +1,26 @@ +#pragma once + +#include "game/Towers.h" +#include + +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 diff --git a/include/game/client/WorldClient.h b/include/game/client/WorldClient.h index 153b8f6..fef9edc 100644 --- a/include/game/client/WorldClient.h +++ b/include/game/client/WorldClient.h @@ -16,6 +16,7 @@ public: virtual void HandlePacket(protocol::WorldBeginDataPacket* packet); virtual void HandlePacket(protocol::WorldDataPacket* packet); + virtual void HandlePacket(protocol::WorldAddTowerPacket* packet); virtual void HandlePacket(protocol::SpawnMobPacket* packet); }; diff --git a/include/game/server/ServerConnexion.h b/include/game/server/ServerConnexion.h index 191c41c..72de88f 100644 --- a/include/game/server/ServerConnexion.h +++ b/include/game/server/ServerConnexion.h @@ -37,6 +37,7 @@ public: virtual void HandlePacket(protocol::KeepAlivePacket* packet); virtual void HandlePacket(protocol::SelectTeamPacket* packet); virtual void HandlePacket(protocol::DisconnectPacket* packet); + virtual void HandlePacket(protocol::PlaceTowerPacket* packet); std::uint8_t getID() const{return m_ID;} const game::Player* getPlayer() const{return m_Player;} diff --git a/include/protocol/PacketHandler.h b/include/protocol/PacketHandler.h index ac867df..b890f1e 100644 --- a/include/protocol/PacketHandler.h +++ b/include/protocol/PacketHandler.h @@ -33,6 +33,8 @@ public: virtual void HandlePacket(DisconnectPacket* packet){} virtual void HandlePacket(ServerTpsPacket* packet){} virtual void HandlePacket(SpawnMobPacket* packet){} + virtual void HandlePacket(PlaceTowerPacket* packet){} + virtual void HandlePacket(WorldAddTowerPacket* packet){} }; } // namespace protocol diff --git a/include/protocol/Protocol.h b/include/protocol/Protocol.h index 77bee9f..b6bab4b 100644 --- a/include/protocol/Protocol.h +++ b/include/protocol/Protocol.h @@ -28,6 +28,8 @@ enum class PacketType : std::uint8_t{ UpdatePlayerTeam, ServerTps, SpawnMob, + PlaceTower, + WorldAddTower }; class Packet{ @@ -380,5 +382,49 @@ public: 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; } +}; + } } \ No newline at end of file diff --git a/include/render/WorldRenderer.h b/include/render/WorldRenderer.h index 0e71229..1d2e325 100644 --- a/include/render/WorldRenderer.h +++ b/include/render/WorldRenderer.h @@ -7,36 +7,51 @@ #include 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 m_WorldVao, m_MobVao, m_SelectTileVao; + std::unique_ptr m_WorldVao, m_MobVao, m_SelectTileVao; glm::vec2 m_CamPos; glm::vec2 m_CursorPos; + glm::vec2 m_HoldCursorPos; float m_Zoom = 1; float m_CamSensibility = 1; + bool m_TowerPlacePopupOpened = false; public: - WorldRenderer(game::World* world, Renderer* renderer); + WorldRenderer(game::World* world, client::ClientGame* client); ~WorldRenderer(); void loadModels(); void update(); - void render() const; + void render(); void setCamPos(float camX, float camY); void moveCam(float relativeX, float relativeY, float aspectRatio); void changeZoom(float zoom); - void click(int mouseX, int mouseY); private: + void click(); void renderWorld() const; void renderTowers() const; void renderMobs() const; void renderTileSelect() const; + void renderPopups() const; + void detectClick(); + glm::vec2 getCursorWorldPos() const; + glm::vec2 getClickWorldPos() const; void updateCursorPos(); }; diff --git a/src/game/client/ClientGame.cpp b/src/game/client/ClientGame.cpp index bb16a7b..993df5f 100644 --- a/src/game/client/ClientGame.cpp +++ b/src/game/client/ClientGame.cpp @@ -1,14 +1,16 @@ #include "game/client/ClientGame.h" #include "protocol/PacketDispatcher.h" //#include "game/Team.h" +#include "game/client/Client.h" #include namespace td { namespace client { -ClientGame::ClientGame(protocol::PacketDispatcher* dispatcher, render::Renderer* renderer): protocol::PacketHandler(dispatcher), - game::Game(&m_WorldClient), m_Renderer(renderer), m_WorldClient(this), m_WorldRenderer(&m_WorldClient, m_Renderer){ +ClientGame::ClientGame(Client* client): protocol::PacketHandler(client->getConnexion().GetDispatcher()), + 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::PlayerJoin, 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 td diff --git a/src/game/client/TowersInfo.cpp b/src/game/client/TowersInfo.cpp new file mode 100644 index 0000000..b3178a1 --- /dev/null +++ b/src/game/client/TowersInfo.cpp @@ -0,0 +1,27 @@ +#include "game/client/TowersInfo.h" + +#include + +namespace td { +namespace game { + +static const std::map 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 diff --git a/src/game/client/WorldClient.cpp b/src/game/client/WorldClient.cpp index 3707c67..3dd3426 100644 --- a/src/game/client/WorldClient.cpp +++ b/src/game/client/WorldClient.cpp @@ -9,6 +9,7 @@ namespace client{ WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::PacketHandler(game->GetDispatcher()), m_Game(game){ GetDispatcher()->RegisterHandler(protocol::PacketType::WorldBeginData, this); GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this); + GetDispatcher()->RegisterHandler(protocol::PacketType::WorldAddTower, this); GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this); } @@ -20,6 +21,10 @@ void WorldClient::HandlePacket(protocol::WorldDataPacket* packet){ loadMap(packet); } +void WorldClient::HandlePacket(protocol::WorldAddTowerPacket* packet){ + +} + void WorldClient::HandlePacket(protocol::SpawnMobPacket* packet){ spawnMobAt(packet->getMobID(), packet->getMobType(), packet->getMobLevel(), packet->getSender(), packet->getMobX(), packet->getMobY(), packet->getMobDirection()); diff --git a/src/game/server/ServerConnexion.cpp b/src/game/server/ServerConnexion.cpp index 8a5bc90..2aed84e 100644 --- a/src/game/server/ServerConnexion.cpp +++ b/src/game/server/ServerConnexion.cpp @@ -38,6 +38,7 @@ void ServerConnexion::registerHandlers(){ GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this); GetDispatcher()->RegisterHandler(protocol::PacketType::SelectTeam, this); GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this); + GetDispatcher()->RegisterHandler(protocol::PacketType::PlaceTower, this); } 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(){ if (GetDispatcher() != nullptr) diff --git a/src/protocol/PacketFactory.cpp b/src/protocol/PacketFactory.cpp index 425dc11..6410ae4 100644 --- a/src/protocol/PacketFactory.cpp +++ b/src/protocol/PacketFactory.cpp @@ -26,6 +26,8 @@ static std::map packets = { {PacketType::Disconnect, []() -> Packet* {return new DisconnectPacket(); } }, {PacketType::ServerTps, []() -> Packet* {return new ServerTpsPacket(); } }, {PacketType::SpawnMob, []() -> Packet* {return new SpawnMobPacket(); } }, + {PacketType::PlaceTower, []() -> Packet* {return new PlaceTowerPacket(); } }, + {PacketType::WorldAddTower, []() -> Packet* {return new WorldAddTowerPacket(); } }, }; Packet* createPacket(PacketType type, DataBuffer& buffer){ diff --git a/src/protocol/Protocol.cpp b/src/protocol/Protocol.cpp index cda09cc..08972a0 100644 --- a/src/protocol/Protocol.cpp +++ b/src/protocol/Protocol.cpp @@ -391,6 +391,26 @@ void SpawnMobPacket::Deserialize(DataBuffer& data){ >> 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(WorldBeginDataPacket); REGISTER_DISPATCH_CLASS(WorldDataPacket); @@ -408,6 +428,8 @@ REGISTER_DISPATCH_CLASS(UpdatePlayerTeamPacket); REGISTER_DISPATCH_CLASS(DisconnectPacket); REGISTER_DISPATCH_CLASS(ServerTpsPacket); REGISTER_DISPATCH_CLASS(SpawnMobPacket); +REGISTER_DISPATCH_CLASS(PlaceTowerPacket); +REGISTER_DISPATCH_CLASS(WorldAddTowerPacket); } // namespace protocol } // namespace td \ No newline at end of file diff --git a/src/render/WorldRenderer.cpp b/src/render/WorldRenderer.cpp index 4242edd..e016fe9 100644 --- a/src/render/WorldRenderer.cpp +++ b/src/render/WorldRenderer.cpp @@ -3,13 +3,15 @@ #include "render/Renderer.h" #include "../render/gui/imgui/imgui.h" #include "window/Display.h" +#include "game/client/TowersInfo.h" +#include "game/client/ClientGame.h" #include namespace td { namespace render { -void WorldRenderer::loadModels(){ +void WorldRenderer::loadModels() { std::cout << "World Created !\n"; m_WorldVao = std::make_unique(std::move(WorldLoader::loadWorldModel(m_World))); m_MobVao = std::make_unique(std::move(WorldLoader::loadMobModel())); @@ -17,103 +19,147 @@ void WorldRenderer::loadModels(){ 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(){ - ImGuiIO& io = ImGui::GetIO(); - - 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::updateCursorPos() { + m_CursorPos = getCursorWorldPos(); } -void WorldRenderer::update(){ - if(m_WorldVao == nullptr) +void WorldRenderer::update() { + if (m_WorldVao == nullptr) return; ImGuiIO& io = ImGui::GetIO(); - if(io.MouseDown[0] && !ImGui::IsAnyItemActive()){ + if (io.MouseDown[0] && !ImGui::IsAnyItemActive()) { ImVec2 mouseDelta = ImGui::GetIO().MouseDelta; - const float relativeX = mouseDelta.x / (float) Display::getWindowWidth() * 2; - const float relativeY = mouseDelta.y / (float) Display::getWindowHeight() * 2; + const float relativeX = mouseDelta.x / (float)Display::getWindowWidth() * 2; + const float relativeY = mouseDelta.y / (float)Display::getWindowHeight() * 2; moveCam(relativeX, relativeY, Display::getAspectRatio()); } - if(io.MouseWheel != 0){ + if (io.MouseWheel != 0) { changeZoom(io.MouseWheel); } 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); } -void WorldRenderer::renderMobs() const{ - for(game::MobPtr mob : m_World->getMobList()){ +void WorldRenderer::renderMobs() const { + for (game::MobPtr mob : m_World->getMobList()) { Renderer::Model model; model.vao = m_MobVao.get(); - model.positon = {mob->getX(), mob->getY()}; + model.positon = { mob->getX(), mob->getY() }; m_Renderer->renderModel(model); } } -void WorldRenderer::renderTowers() const{ +void WorldRenderer::renderTowers() const { Renderer::Model tileSelectModel; 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); } -void WorldRenderer::renderTileSelect() const{ +void WorldRenderer::renderTileSelect() const { } -void WorldRenderer::render() const{ - if(m_WorldVao == nullptr) +void WorldRenderer::render() { + if (m_WorldVao == nullptr) return; renderWorld(); renderMobs(); renderTowers(); renderTileSelect(); + detectClick(); + renderPopups(); } -WorldRenderer::~WorldRenderer(){ - +WorldRenderer::~WorldRenderer() { + } -void WorldRenderer::moveCam(float relativeX, float relativeY, float aspectRatio){ - if(m_WorldVao == nullptr) +void WorldRenderer::moveCam(float relativeX, float relativeY, float aspectRatio) { + if (m_WorldVao == nullptr) return; float movementX = -relativeX / m_Zoom * aspectRatio; float movementY = relativeY / m_Zoom; - m_Renderer->setCamMovement({movementX, movementY}); + m_Renderer->setCamMovement({ movementX, movementY }); } -void WorldRenderer::changeZoom(float zoomStep){ - if(m_WorldVao == nullptr) +void WorldRenderer::changeZoom(float zoomStep) { + if (m_WorldVao == nullptr) return; static float sensibility = 1.5f; - if (zoomStep < 0){ + if (zoomStep < 0) { m_Zoom /= -zoomStep * sensibility; - } - else{ + } else { m_Zoom *= zoomStep * sensibility; } m_Renderer->setZoom(m_Zoom); m_Renderer->setCamMovement({}); } -void WorldRenderer::click(int mouseX, int mouseY){ - if(m_WorldVao == nullptr) - return; +void WorldRenderer::click() { + if (m_Client->CanPlaceLittleTower(getClickWorldPos())) { + ImGui::OpenPopup("TowerPlace"); + m_TowerPlacePopupOpened = true; + } } -void WorldRenderer::setCamPos(float camX, float camY){ - m_CamPos = {camX, camY}; +void WorldRenderer::setCamPos(float camX, float camY) { + m_CamPos = { camX, camY }; 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 td diff --git a/src/render/gui/TowerGui.cpp b/src/render/gui/TowerGui.cpp index f8be9cf..2654838 100644 --- a/src/render/gui/TowerGui.cpp +++ b/src/render/gui/TowerGui.cpp @@ -305,8 +305,8 @@ void tick(){ void render(){ tick(); - client->render(); beginFrame(); + client->render(); if (client->isConnected()) renderGame(); else