feat: remove tower
This commit is contained in:
@@ -168,6 +168,7 @@ public:
|
|||||||
void spawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
void spawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
||||||
|
|
||||||
TowerPtr placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
|
TowerPtr placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
|
||||||
|
TowerPtr removeTower(TowerID id);
|
||||||
|
|
||||||
TilePtr getTile(std::int32_t x, std::int32_t y) const;
|
TilePtr getTile(std::int32_t x, std::int32_t y) const;
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
void sendMobs(const std::vector<protocol::MobSend>& mobSends);
|
void sendMobs(const std::vector<protocol::MobSend>& mobSends);
|
||||||
void placeTower(game::TowerType type, const glm::vec2& position);
|
void placeTower(game::TowerType type, const glm::vec2& position);
|
||||||
void upgradeTower(game::TowerID tower, game::TowerLevel level);
|
void upgradeTower(game::TowerID tower, game::TowerLevel level);
|
||||||
|
void removeTower(game::TowerID tower);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
virtual void HandlePacket(const protocol::SpawnMobPacket* packet);
|
virtual void HandlePacket(const protocol::SpawnMobPacket* packet);
|
||||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
|
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
|
||||||
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet);
|
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet);
|
||||||
|
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public:
|
|||||||
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet);
|
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet);
|
||||||
virtual void HandlePacket(const protocol::SendMobsPacket* packet);
|
virtual void HandlePacket(const protocol::SendMobsPacket* packet);
|
||||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
|
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
|
||||||
|
virtual void HandlePacket(const protocol::RemoveTowerPacket* 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; }
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
virtual void HandlePacket(const SpawnMobPacket* packet) {}
|
virtual void HandlePacket(const SpawnMobPacket* packet) {}
|
||||||
virtual void HandlePacket(const PlaceTowerPacket* packet) {}
|
virtual void HandlePacket(const PlaceTowerPacket* packet) {}
|
||||||
virtual void HandlePacket(const WorldAddTowerPacket* 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 SendMobsPacket* packet) {}
|
||||||
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
|
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,12 +33,12 @@ enum class PacketType : std::uint8_t {
|
|||||||
UpdatePlayerTeam,
|
UpdatePlayerTeam,
|
||||||
ServerTps,
|
ServerTps,
|
||||||
WorldAddTower,
|
WorldAddTower,
|
||||||
WorldRemoveTower,
|
|
||||||
|
|
||||||
// client <--> server
|
// client <--> server
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
Disconnect,
|
Disconnect,
|
||||||
UpgradeTower,
|
UpgradeTower,
|
||||||
|
RemoveTower,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WorldHeader {
|
struct WorldHeader {
|
||||||
@@ -477,13 +477,13 @@ public:
|
|||||||
virtual PacketType getType() const { return PacketType::WorldAddTower; }
|
virtual PacketType getType() const { return PacketType::WorldAddTower; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorldRemoveTowerPacket : public Packet {
|
class RemoveTowerPacket : public Packet {
|
||||||
private:
|
private:
|
||||||
game::TowerID m_TowerID;
|
game::TowerID m_TowerID;
|
||||||
public:
|
public:
|
||||||
WorldRemoveTowerPacket() {}
|
RemoveTowerPacket() {}
|
||||||
WorldRemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
|
RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
|
||||||
virtual ~WorldRemoveTowerPacket() {}
|
virtual ~RemoveTowerPacket() {}
|
||||||
|
|
||||||
virtual DataBuffer Serialize() const;
|
virtual DataBuffer Serialize() const;
|
||||||
virtual void Deserialize(DataBuffer& data);
|
virtual void Deserialize(DataBuffer& data);
|
||||||
@@ -491,7 +491,7 @@ public:
|
|||||||
|
|
||||||
game::TowerID getTowerID() const { return m_TowerID; }
|
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 {
|
class UpgradeTowerPacket : public Packet {
|
||||||
|
|||||||
@@ -12,15 +12,19 @@ namespace render {
|
|||||||
class VertexCache {
|
class VertexCache {
|
||||||
|
|
||||||
typedef std::vector<float> Vector;
|
typedef std::vector<float> Vector;
|
||||||
typedef std::pair<Vector::iterator, Vector::iterator> ElementsIndex;
|
|
||||||
typedef std::pair<ElementsIndex, ElementsIndex> DataIndex;
|
struct DataIndex {
|
||||||
|
Vector position;
|
||||||
|
Vector color;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector m_Positions;
|
std::size_t m_VertexCount;
|
||||||
Vector m_Colors;
|
|
||||||
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
|
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
|
||||||
std::unique_ptr<GL::VertexArray> m_VertexArray;
|
std::unique_ptr<GL::VertexArray> m_VertexArray;
|
||||||
public:
|
public:
|
||||||
|
VertexCache() : m_VertexCount(0) {}
|
||||||
|
|
||||||
void addData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
|
void addData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
|
||||||
void removeData(std::uint64_t index);
|
void removeData(std::uint64_t index);
|
||||||
void clear();
|
void clear();
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ private:
|
|||||||
void renderMobTooltip() const;
|
void renderMobTooltip() const;
|
||||||
void detectClick();
|
void detectClick();
|
||||||
void detectMobHovering() const;
|
void detectMobHovering() const;
|
||||||
|
void removeTower();
|
||||||
glm::vec2 getCursorWorldPos() const;
|
glm::vec2 getCursorWorldPos() const;
|
||||||
glm::vec2 getClickWorldPos() const;
|
glm::vec2 getClickWorldPos() const;
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,17 @@ TowerPtr World::placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::in
|
|||||||
return tower;
|
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) {
|
void World::tickMobs(std::uint64_t delta) {
|
||||||
for (MobPtr mob : m_Mobs) {
|
for (MobPtr mob : m_Mobs) {
|
||||||
mob->tick(delta);
|
mob->tick(delta);
|
||||||
|
|||||||
@@ -64,5 +64,10 @@ void Client::upgradeTower(game::TowerID tower, game::TowerLevel level) {
|
|||||||
m_Connexion.sendPacket(&packet);
|
m_Connexion.sendPacket(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::removeTower(game::TowerID tower) {
|
||||||
|
protocol::RemoveTowerPacket packet(tower);
|
||||||
|
m_Connexion.sendPacket(&packet);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::Packet
|
|||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
||||||
|
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) {
|
void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) {
|
||||||
@@ -39,5 +40,13 @@ void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) {
|
|||||||
notifyListeners(&WorldListener::OnTowerAdd, newTower);
|
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 client
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ void ServerConnexion::registerHandlers() {
|
|||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlaceTower, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlaceTower, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::SendMobs, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::SendMobs, this);
|
||||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
||||||
|
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerConnexion::updateSocket() {
|
bool ServerConnexion::updateSocket() {
|
||||||
@@ -181,6 +182,12 @@ void ServerConnexion::HandlePacket(const protocol::UpgradeTowerPacket* packet) {
|
|||||||
m_Server->broadcastPacket(packet);
|
m_Server->broadcastPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerConnexion::HandlePacket(const protocol::RemoveTowerPacket* packet) {
|
||||||
|
//TODO: verify the packet
|
||||||
|
|
||||||
|
m_Server->broadcastPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
ServerConnexion::~ServerConnexion() {
|
ServerConnexion::~ServerConnexion() {
|
||||||
if (GetDispatcher() != nullptr)
|
if (GetDispatcher() != nullptr)
|
||||||
GetDispatcher()->UnregisterHandler(this);
|
GetDispatcher()->UnregisterHandler(this);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ static std::map<PacketType, PacketCreator> packets = {
|
|||||||
{PacketType::SpawnMob, []() -> PacketPtr {return std::make_unique<SpawnMobPacket>(); } },
|
{PacketType::SpawnMob, []() -> PacketPtr {return std::make_unique<SpawnMobPacket>(); } },
|
||||||
{PacketType::PlaceTower, []() -> PacketPtr {return std::make_unique<PlaceTowerPacket>(); } },
|
{PacketType::PlaceTower, []() -> PacketPtr {return std::make_unique<PlaceTowerPacket>(); } },
|
||||||
{PacketType::WorldAddTower, []() -> PacketPtr {return std::make_unique<WorldAddTowerPacket>(); } },
|
{PacketType::WorldAddTower, []() -> PacketPtr {return std::make_unique<WorldAddTowerPacket>(); } },
|
||||||
{PacketType::WorldRemoveTower, []() -> PacketPtr {return std::make_unique<WorldRemoveTowerPacket>(); } },
|
{PacketType::RemoveTower, []() -> PacketPtr {return std::make_unique<RemoveTowerPacket>(); } },
|
||||||
{PacketType::SendMobs, []() -> PacketPtr {return std::make_unique<SendMobsPacket>(); } },
|
{PacketType::SendMobs, []() -> PacketPtr {return std::make_unique<SendMobsPacket>(); } },
|
||||||
{PacketType::UpgradeTower, []() -> PacketPtr {return std::make_unique<UpgradeTowerPacket>(); } },
|
{PacketType::UpgradeTower, []() -> PacketPtr {return std::make_unique<UpgradeTowerPacket>(); } },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -485,13 +485,13 @@ void WorldAddTowerPacket::Deserialize(DataBuffer& data) {
|
|||||||
data >> m_TowerID >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder;
|
data >> m_TowerID >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer WorldRemoveTowerPacket::Serialize() const {
|
DataBuffer RemoveTowerPacket::Serialize() const {
|
||||||
DataBuffer data;
|
DataBuffer data;
|
||||||
data << getID() << m_TowerID;
|
data << getID() << m_TowerID;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRemoveTowerPacket::Deserialize(DataBuffer& data) {
|
void RemoveTowerPacket::Deserialize(DataBuffer& data) {
|
||||||
data >> m_TowerID;
|
data >> m_TowerID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +543,7 @@ REGISTER_DISPATCH_CLASS(ServerTpsPacket);
|
|||||||
REGISTER_DISPATCH_CLASS(SpawnMobPacket);
|
REGISTER_DISPATCH_CLASS(SpawnMobPacket);
|
||||||
REGISTER_DISPATCH_CLASS(PlaceTowerPacket);
|
REGISTER_DISPATCH_CLASS(PlaceTowerPacket);
|
||||||
REGISTER_DISPATCH_CLASS(WorldAddTowerPacket);
|
REGISTER_DISPATCH_CLASS(WorldAddTowerPacket);
|
||||||
REGISTER_DISPATCH_CLASS(WorldRemoveTowerPacket);
|
REGISTER_DISPATCH_CLASS(RemoveTowerPacket);
|
||||||
REGISTER_DISPATCH_CLASS(SendMobsPacket);
|
REGISTER_DISPATCH_CLASS(SendMobsPacket);
|
||||||
REGISTER_DISPATCH_CLASS(UpgradeTowerPacket);
|
REGISTER_DISPATCH_CLASS(UpgradeTowerPacket);
|
||||||
|
|
||||||
|
|||||||
@@ -5,46 +5,43 @@ namespace td {
|
|||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
void VertexCache::addData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors) {
|
void VertexCache::addData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors) {
|
||||||
ElementsIndex positionsIndexes;
|
m_Indexes.insert({ index, {positions, colors} });
|
||||||
positionsIndexes.first = m_Positions.end();
|
m_VertexCount += colors.size(); // one color per vertex
|
||||||
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} });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexCache::removeData(std::uint64_t index) {
|
void VertexCache::removeData(std::uint64_t index) {
|
||||||
auto it = m_Indexes.find(index);
|
auto it = m_Indexes.find(index);
|
||||||
if (it != m_Indexes.end()) {
|
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_Indexes.erase(it);
|
||||||
|
m_VertexCount -= it->second.color.size(); // one color per vertex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexCache::clear() {
|
void VertexCache::clear() {
|
||||||
m_Positions.clear();
|
|
||||||
m_Colors.clear();
|
|
||||||
m_Indexes.clear();
|
m_Indexes.clear();
|
||||||
|
m_VertexCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexCache::updateVertexArray() {
|
void VertexCache::updateVertexArray() {
|
||||||
m_VertexArray = std::make_unique<GL::VertexArray>(m_Colors.size()); // one color per vertex
|
m_VertexArray = std::make_unique<GL::VertexArray>(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);
|
positionsBuffer.addVertexAttribPointer(0, 2, 0);
|
||||||
|
|
||||||
GL::VertexBuffer colorsBuffer(m_Colors, 1);
|
GL::VertexBuffer colorsBuffer(colors, 1);
|
||||||
colorsBuffer.addVertexAttribPointer(1, 1, 0);
|
colorsBuffer.addVertexAttribPointer(1, 1, 0);
|
||||||
|
|
||||||
m_VertexArray->bind();
|
m_VertexArray->bind();
|
||||||
|
|||||||
@@ -65,6 +65,18 @@ void WorldRenderer::update() {
|
|||||||
m_PopupOpened = false;
|
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 {
|
void WorldRenderer::renderWorld() const {
|
||||||
|
|||||||
Reference in New Issue
Block a user