diff --git a/include/game/World.h b/include/game/World.h index ca3a65c..e2e710f 100644 --- a/include/game/World.h +++ b/include/game/World.h @@ -168,6 +168,7 @@ public: void spawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir); TowerPtr placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder); + TowerPtr removeTower(TowerID id); TilePtr getTile(std::int32_t x, std::int32_t y) const; diff --git a/include/game/client/Client.h b/include/game/client/Client.h index 68d0dcb..581d93f 100644 --- a/include/game/client/Client.h +++ b/include/game/client/Client.h @@ -44,6 +44,7 @@ public: void sendMobs(const std::vector& mobSends); void placeTower(game::TowerType type, const glm::vec2& position); void upgradeTower(game::TowerID tower, game::TowerLevel level); + void removeTower(game::TowerID tower); }; } // namespace client diff --git a/include/game/client/WorldClient.h b/include/game/client/WorldClient.h index 2880ccb..e16e6bd 100644 --- a/include/game/client/WorldClient.h +++ b/include/game/client/WorldClient.h @@ -19,6 +19,7 @@ public: virtual void HandlePacket(const protocol::SpawnMobPacket* packet); virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet); virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet); + virtual void HandlePacket(const protocol::RemoveTowerPacket* packet); }; diff --git a/include/game/server/ServerConnexion.h b/include/game/server/ServerConnexion.h index e4ff39e..7f90805 100644 --- a/include/game/server/ServerConnexion.h +++ b/include/game/server/ServerConnexion.h @@ -40,6 +40,7 @@ public: virtual void HandlePacket(const protocol::PlaceTowerPacket* packet); virtual void HandlePacket(const protocol::SendMobsPacket* packet); virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet); + virtual void HandlePacket(const protocol::RemoveTowerPacket* 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 a4870b9..835a0fd 100644 --- a/include/protocol/PacketHandler.h +++ b/include/protocol/PacketHandler.h @@ -35,7 +35,7 @@ public: 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 RemoveTowerPacket* packet) {} virtual void HandlePacket(const SendMobsPacket* packet) {} virtual void HandlePacket(const UpgradeTowerPacket* packet) {} }; diff --git a/include/protocol/Protocol.h b/include/protocol/Protocol.h index 20ac731..2ce34fb 100644 --- a/include/protocol/Protocol.h +++ b/include/protocol/Protocol.h @@ -33,12 +33,12 @@ enum class PacketType : std::uint8_t { UpdatePlayerTeam, ServerTps, WorldAddTower, - WorldRemoveTower, // client <--> server KeepAlive, Disconnect, UpgradeTower, + RemoveTower, }; struct WorldHeader { @@ -477,13 +477,13 @@ public: virtual PacketType getType() const { return PacketType::WorldAddTower; } }; -class WorldRemoveTowerPacket : public Packet { +class RemoveTowerPacket : public Packet { private: game::TowerID m_TowerID; public: - WorldRemoveTowerPacket() {} - WorldRemoveTowerPacket(game::TowerID id) : m_TowerID(id) {} - virtual ~WorldRemoveTowerPacket() {} + RemoveTowerPacket() {} + RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {} + virtual ~RemoveTowerPacket() {} virtual DataBuffer Serialize() const; virtual void Deserialize(DataBuffer& data); @@ -491,7 +491,7 @@ public: game::TowerID getTowerID() const { return m_TowerID; } - virtual PacketType getType() const { return PacketType::WorldRemoveTower; } + virtual PacketType getType() const { return PacketType::RemoveTower; } }; class UpgradeTowerPacket : public Packet { diff --git a/include/render/VertexCache.h b/include/render/VertexCache.h index 5cc5f84..37384d9 100644 --- a/include/render/VertexCache.h +++ b/include/render/VertexCache.h @@ -12,15 +12,19 @@ namespace render { class VertexCache { typedef std::vector Vector; - typedef std::pair ElementsIndex; - typedef std::pair DataIndex; + + struct DataIndex { + Vector position; + Vector color; + }; private: - Vector m_Positions; - Vector m_Colors; + std::size_t m_VertexCount; std::unordered_map m_Indexes; std::unique_ptr m_VertexArray; public: + VertexCache() : m_VertexCount(0) {} + void addData(std::uint64_t index, std::vector positions, std::vector colors); void removeData(std::uint64_t index); void clear(); diff --git a/include/render/WorldRenderer.h b/include/render/WorldRenderer.h index b14f22c..d8a5977 100644 --- a/include/render/WorldRenderer.h +++ b/include/render/WorldRenderer.h @@ -71,6 +71,7 @@ private: void renderMobTooltip() const; void detectClick(); void detectMobHovering() const; + void removeTower(); glm::vec2 getCursorWorldPos() const; glm::vec2 getClickWorldPos() const; diff --git a/src/game/World.cpp b/src/game/World.cpp index 7b53c1a..3e43104 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -122,6 +122,17 @@ TowerPtr World::placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::in return tower; } +TowerPtr World::removeTower(TowerID towerId) { + auto it = std::find_if(m_Towers.begin(), m_Towers.end(), [towerId](TowerPtr tower) { return tower->getID() == towerId;}); + if (it == m_Towers.end()) return nullptr; + + TowerPtr tower = *it; + + m_Towers.erase(it); + + return tower; +} + void World::tickMobs(std::uint64_t delta) { for (MobPtr mob : m_Mobs) { mob->tick(delta); diff --git a/src/game/client/Client.cpp b/src/game/client/Client.cpp index 8d7d88d..1241f0b 100644 --- a/src/game/client/Client.cpp +++ b/src/game/client/Client.cpp @@ -64,5 +64,10 @@ void Client::upgradeTower(game::TowerID tower, game::TowerLevel level) { m_Connexion.sendPacket(&packet); } +void Client::removeTower(game::TowerID tower) { + protocol::RemoveTowerPacket packet(tower); + m_Connexion.sendPacket(&packet); +} + } // namespace client } // namespace td diff --git a/src/game/client/WorldClient.cpp b/src/game/client/WorldClient.cpp index 32afb29..58d093d 100644 --- a/src/game/client/WorldClient.cpp +++ b/src/game/client/WorldClient.cpp @@ -12,6 +12,7 @@ WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::Packet GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this); GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this); GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this); + GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this); } void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) { @@ -39,5 +40,13 @@ void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) { notifyListeners(&WorldListener::OnTowerAdd, newTower); } +void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) { + game::TowerPtr tower = removeTower(packet->getTowerID()); + + if (tower != nullptr) { + notifyListeners(&WorldListener::OnTowerRemove, tower); + } +} + } // namespace client } // namespace td diff --git a/src/game/server/ServerConnexion.cpp b/src/game/server/ServerConnexion.cpp index 54812fb..2b8f11a 100644 --- a/src/game/server/ServerConnexion.cpp +++ b/src/game/server/ServerConnexion.cpp @@ -41,6 +41,7 @@ void ServerConnexion::registerHandlers() { GetDispatcher()->RegisterHandler(protocol::PacketType::PlaceTower, this); GetDispatcher()->RegisterHandler(protocol::PacketType::SendMobs, this); GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this); + GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this); } bool ServerConnexion::updateSocket() { @@ -181,6 +182,12 @@ void ServerConnexion::HandlePacket(const protocol::UpgradeTowerPacket* packet) { m_Server->broadcastPacket(packet); } +void ServerConnexion::HandlePacket(const protocol::RemoveTowerPacket* packet) { + //TODO: verify the packet + + m_Server->broadcastPacket(packet); +} + ServerConnexion::~ServerConnexion() { if (GetDispatcher() != nullptr) GetDispatcher()->UnregisterHandler(this); diff --git a/src/protocol/PacketFactory.cpp b/src/protocol/PacketFactory.cpp index fc40089..8a02c07 100644 --- a/src/protocol/PacketFactory.cpp +++ b/src/protocol/PacketFactory.cpp @@ -28,7 +28,7 @@ static std::map packets = { {PacketType::SpawnMob, []() -> PacketPtr {return std::make_unique(); } }, {PacketType::PlaceTower, []() -> PacketPtr {return std::make_unique(); } }, {PacketType::WorldAddTower, []() -> PacketPtr {return std::make_unique(); } }, - {PacketType::WorldRemoveTower, []() -> PacketPtr {return std::make_unique(); } }, + {PacketType::RemoveTower, []() -> PacketPtr {return std::make_unique(); } }, {PacketType::SendMobs, []() -> PacketPtr {return std::make_unique(); } }, {PacketType::UpgradeTower, []() -> PacketPtr {return std::make_unique(); } }, }; diff --git a/src/protocol/Protocol.cpp b/src/protocol/Protocol.cpp index 507dab4..4a26872 100644 --- a/src/protocol/Protocol.cpp +++ b/src/protocol/Protocol.cpp @@ -485,13 +485,13 @@ void WorldAddTowerPacket::Deserialize(DataBuffer& data) { data >> m_TowerID >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder; } -DataBuffer WorldRemoveTowerPacket::Serialize() const { +DataBuffer RemoveTowerPacket::Serialize() const { DataBuffer data; data << getID() << m_TowerID; return data; } -void WorldRemoveTowerPacket::Deserialize(DataBuffer& data) { +void RemoveTowerPacket::Deserialize(DataBuffer& data) { data >> m_TowerID; } @@ -543,7 +543,7 @@ REGISTER_DISPATCH_CLASS(ServerTpsPacket); REGISTER_DISPATCH_CLASS(SpawnMobPacket); REGISTER_DISPATCH_CLASS(PlaceTowerPacket); REGISTER_DISPATCH_CLASS(WorldAddTowerPacket); -REGISTER_DISPATCH_CLASS(WorldRemoveTowerPacket); +REGISTER_DISPATCH_CLASS(RemoveTowerPacket); REGISTER_DISPATCH_CLASS(SendMobsPacket); REGISTER_DISPATCH_CLASS(UpgradeTowerPacket); diff --git a/src/render/VertexCache.cpp b/src/render/VertexCache.cpp index 10dcab4..bdc3cc3 100644 --- a/src/render/VertexCache.cpp +++ b/src/render/VertexCache.cpp @@ -5,46 +5,43 @@ namespace td { namespace render { void VertexCache::addData(std::uint64_t index, std::vector positions, std::vector colors) { - ElementsIndex positionsIndexes; - positionsIndexes.first = m_Positions.end(); - m_Positions.insert(m_Positions.end(), positions.begin(), positions.end()); - positionsIndexes.second = m_Positions.end() - 1; - - ElementsIndex colorsIndexes; - colorsIndexes.first = m_Colors.end(); - m_Colors.insert(m_Colors.end(), colors.begin(), colors.end()); - colorsIndexes.second = m_Colors.end() - 1; - - m_Indexes.insert({ index, {positionsIndexes, colorsIndexes} }); + m_Indexes.insert({ index, {positions, colors} }); + m_VertexCount += colors.size(); // one color per vertex } void VertexCache::removeData(std::uint64_t index) { auto it = m_Indexes.find(index); if (it != m_Indexes.end()) { - DataIndex indexes = it->second; - ElementsIndex positionsIndexes = indexes.first; - ElementsIndex colorsIndexes = indexes.second; - - m_Positions.erase(positionsIndexes.first, positionsIndexes.second); - m_Colors.erase(colorsIndexes.first, colorsIndexes.second); - m_Indexes.erase(it); + m_VertexCount -= it->second.color.size(); // one color per vertex } } void VertexCache::clear() { - m_Positions.clear(); - m_Colors.clear(); m_Indexes.clear(); + m_VertexCount = 0; } void VertexCache::updateVertexArray() { - m_VertexArray = std::make_unique(m_Colors.size()); // one color per vertex + m_VertexArray = std::make_unique(m_VertexCount); // one color per vertex - GL::VertexBuffer positionsBuffer(m_Positions, 2); + Vector positions; + positions.reserve(m_VertexCount * 2); + + Vector colors; + colors.reserve(m_VertexCount); + + for (auto it = m_Indexes.begin(); it != m_Indexes.end(); it++) { + const DataIndex& data = it->second; + + positions.insert(positions.end(), data.position.begin(), data.position.end()); + colors.insert(colors.end(), data.color.begin(), data.color.end()); + } + + GL::VertexBuffer positionsBuffer(positions, 2); positionsBuffer.addVertexAttribPointer(0, 2, 0); - GL::VertexBuffer colorsBuffer(m_Colors, 1); + GL::VertexBuffer colorsBuffer(colors, 1); colorsBuffer.addVertexAttribPointer(1, 1, 0); m_VertexArray->bind(); diff --git a/src/render/WorldRenderer.cpp b/src/render/WorldRenderer.cpp index 4536492..3dbfff5 100644 --- a/src/render/WorldRenderer.cpp +++ b/src/render/WorldRenderer.cpp @@ -65,6 +65,18 @@ void WorldRenderer::update() { m_PopupOpened = false; } } + + if (ImGui::IsMouseDoubleClicked(1)) removeTower(); +} + +void WorldRenderer::removeTower() { + glm::vec2 cursorPos = getCursorWorldPos(); + + game::TowerPtr clickedTower = m_World->getTower(cursorPos); + + if (clickedTower != nullptr) { + m_Client->getClient()->removeTower(clickedTower->getID()); + } } void WorldRenderer::renderWorld() const {