From 24617c539fda38a10184bea451a24017dcfcfdec Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sun, 12 Dec 2021 13:32:39 +0100 Subject: [PATCH] feat: add castle tooltip --- include/game/BaseGame.h | 4 +++- include/game/Team.h | 23 ++++++++++++++++++++--- include/game/World.h | 2 ++ include/misc/Shapes.h | 3 +++ include/render/WorldRenderer.h | 5 +++++ include/render/gui/CastleTooltip.h | 27 +++++++++++++++++++++++++++ src/game/Team.cpp | 2 +- src/game/World.cpp | 7 +++++++ src/protocol/Protocol.cpp | 21 +++++++++++++-------- src/render/WorldRenderer.cpp | 26 +++++++++++++++++++++++++- src/render/gui/CastleTooltip.cpp | 27 +++++++++++++++++++++++++++ 11 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 include/render/gui/CastleTooltip.h create mode 100644 src/render/gui/CastleTooltip.cpp diff --git a/include/game/BaseGame.h b/include/game/BaseGame.h index 963e4e5..a16d616 100644 --- a/include/game/BaseGame.h +++ b/include/game/BaseGame.h @@ -19,7 +19,7 @@ typedef std::map PlayerList; class Game { protected: World* m_World; - std::array m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} }; + TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} }; GameState m_GameState = GameState::Lobby; PlayerList m_Players; public: @@ -49,6 +49,8 @@ public: const Player* getPlayerById(PlayerID id) const; Player* getPlayerById(PlayerID id); + const TeamList& getTeams() const { return m_Teams; } + }; } // namespace game diff --git a/include/game/Team.h b/include/game/Team.h index 4c804a2..a3dc82d 100644 --- a/include/game/Team.h +++ b/include/game/Team.h @@ -23,7 +23,7 @@ class Spawn : public utils::shape::Rectangle { private: Direction m_Direction; public: - Spawn(){ + Spawn() { setWidth(5); setHeight(5); } @@ -33,19 +33,34 @@ public: void setDirection(Direction direction) { m_Direction = direction; } }; -struct TeamCastle : public utils::shape::Rectangle{ +class Team; + +class TeamCastle : public utils::shape::Rectangle { private: + const Team* m_Team; float m_Life; public: - TeamCastle() : m_Life(1000) { + 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 { @@ -71,5 +86,7 @@ public: std::uint8_t getPlayerCount() const; }; +typedef std::array TeamList; + } // namespace game } // namespace td diff --git a/include/game/World.h b/include/game/World.h index 9c60aa4..61c78ec 100644 --- a/include/game/World.h +++ b/include/game/World.h @@ -205,6 +205,8 @@ public: Team& getTeam(TeamColor team); const Team& getTeam(TeamColor team) const; + const TeamList& getTeams() const; + const TowerList& getTowers() const { return m_Towers; }; TowerPtr getTowerById(TowerID tower); diff --git a/include/misc/Shapes.h b/include/misc/Shapes.h index 1483b46..e626f93 100644 --- a/include/misc/Shapes.h +++ b/include/misc/Shapes.h @@ -47,6 +47,9 @@ public: void setCenterY(float y) { m_Center.setY(y); } void setSize(float width, float height) { setWidth(width); setHeight(height); } + void setSize(Point size) { setSize(size.getX(), size.getY()); } + Point getSize() { return { m_Width, m_Height }; } + void setWidth(float width) { m_Width = width; } void setHeight(float height) { m_Height = height; } diff --git a/include/render/WorldRenderer.h b/include/render/WorldRenderer.h index d8a5977..295f3f5 100644 --- a/include/render/WorldRenderer.h +++ b/include/render/WorldRenderer.h @@ -7,6 +7,7 @@ #include "render/gui/TowerPlacePopup.h" #include "render/gui/MobTooltip.h" +#include "render/gui/CastleTooltip.h" #include "render/gui/imgui/imgui.h" @@ -40,6 +41,7 @@ private: std::unique_ptr m_TowerPlacePopup; std::unique_ptr m_MobTooltip; + std::unique_ptr m_CastleTooltip; public: WorldRenderer(game::World* world, client::ClientGame* client); ~WorldRenderer(); @@ -69,8 +71,11 @@ private: void renderPopups(); void renderTowerUpgradePopup(); void renderMobTooltip() const; + void renderCastleTooltip() const; void detectClick(); void detectMobHovering() const; + void detectCastleHovering() const; + void renderTooltips() const; void removeTower(); glm::vec2 getCursorWorldPos() const; glm::vec2 getClickWorldPos() const; diff --git a/include/render/gui/CastleTooltip.h b/include/render/gui/CastleTooltip.h new file mode 100644 index 0000000..6de2572 --- /dev/null +++ b/include/render/gui/CastleTooltip.h @@ -0,0 +1,27 @@ +#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; } +}; + +} // namespace gui +} // namespace td diff --git a/src/game/Team.cpp b/src/game/Team.cpp index bdf5e58..8df1fb8 100644 --- a/src/game/Team.cpp +++ b/src/game/Team.cpp @@ -5,7 +5,7 @@ namespace td { namespace game { -Team::Team(TeamColor color) : m_Color(color) {} +Team::Team(TeamColor color) : m_Color(color), m_TeamCastle(this) {} void Team::addPlayer(Player* newPlayer) { m_Players.push_back(newPlayer); diff --git a/src/game/World.cpp b/src/game/World.cpp index 46b5155..fa8a995 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -44,7 +44,10 @@ bool World::loadMap(const protocol::WorldBeginDataPacket* worldHeader) { m_SpawnColorPalette = worldHeader->getSpawnPalette(); getRedTeam().getCastle() = worldHeader->getRedCastle(); + getRedTeam().getCastle().setTeam(&getRedTeam()); + getBlueTeam().getCastle() = worldHeader->getBlueCastle(); + getBlueTeam().getCastle().setTeam(&getBlueTeam()); m_TilePalette = worldHeader->getTilePalette(); @@ -328,5 +331,9 @@ const Player* World::getPlayerById(PlayerID id) const { return m_Game->getPlayerById(id); } +const TeamList& World::getTeams() const { + return m_Game->getTeams(); +} + } // namespace game } // namespace td diff --git a/src/protocol/Protocol.cpp b/src/protocol/Protocol.cpp index 4a26872..c779a99 100644 --- a/src/protocol/Protocol.cpp +++ b/src/protocol/Protocol.cpp @@ -94,11 +94,11 @@ DataBuffer WorldBeginDataPacket::SerializeCustom() const { const game::Spawn& redSpawn = m_Header.m_RedSpawn, blueSpawn = m_Header.m_BlueSpawn; const game::TeamCastle& redCastle = m_Header.m_RedCastle, blueCastle = m_Header.m_BlueCastle; - data << redSpawn << redCastle; - data << blueSpawn << blueCastle; + data << redSpawn << static_cast(redCastle); + data << blueSpawn << static_cast(blueCastle); // tile palette - data << m_Header.m_TilePalette.size(); + data << static_cast(m_Header.m_TilePalette.size()); for (game::TilePtr tile : m_Header.m_TilePalette) { data << tile; @@ -126,11 +126,11 @@ DataBuffer WorldBeginDataPacket::Serialize() const { const game::Spawn& redSpawn = m_Header.m_World->getRedTeam().getSpawn(), blueSpawn = m_Header.m_World->getBlueTeam().getSpawn(); const game::TeamCastle& redCastle = m_Header.m_World->getRedTeam().getCastle(), blueCastle = m_Header.m_World->getBlueTeam().getCastle(); - data << redSpawn << redCastle; - data << blueSpawn << blueCastle; + data << redSpawn << static_cast(redCastle); + data << blueSpawn << static_cast(blueCastle); // tile palette - data << m_Header.m_World->getTilePalette().size(); + data << static_cast(m_Header.m_World->getTilePalette().size()); for (game::TilePtr tile : m_Header.m_World->getTilePalette()) { data << tile; @@ -155,8 +155,13 @@ void WorldBeginDataPacket::Deserialize(DataBuffer& data) { data.SetReadOffset(data.GetReadOffset() + decoPalletteSizeByte); - data >> m_Header.m_RedSpawn >> m_Header.m_RedCastle; - data >> m_Header.m_BlueSpawn >> m_Header.m_BlueCastle; + utils::shape::Rectangle redCastle, blueCastle; + + data >> m_Header.m_RedSpawn >> redCastle; + data >> m_Header.m_BlueSpawn >> blueCastle; + + m_Header.m_RedCastle.setShape(redCastle); + m_Header.m_BlueCastle.setShape(blueCastle); std::uint64_t tilePaletteSize; data >> tilePaletteSize; diff --git a/src/render/WorldRenderer.cpp b/src/render/WorldRenderer.cpp index 0b5aa1b..125f9ac 100644 --- a/src/render/WorldRenderer.cpp +++ b/src/render/WorldRenderer.cpp @@ -37,6 +37,7 @@ WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m m_Renderer->setCamMovement({}); m_TowerPlacePopup = std::make_unique(m_Client->getClient()); m_MobTooltip = std::make_unique(m_Client->getClient()); + m_CastleTooltip = std::make_unique(m_Client->getClient()); m_Client->getWorld().getWorldNotifier().bindListener(this); } @@ -119,7 +120,7 @@ void WorldRenderer::render() { renderMobs(); renderTowers(); renderTileSelect(); - renderMobTooltip(); + renderTooltips(); renderPopups(); detectClick(); } @@ -128,6 +129,11 @@ WorldRenderer::~WorldRenderer() { } +void WorldRenderer::renderTooltips() const { + renderMobTooltip(); + renderCastleTooltip(); +} + void WorldRenderer::moveCam(float relativeX, float relativeY, float aspectRatio) { if (m_WorldVao == nullptr) return; @@ -245,6 +251,13 @@ void WorldRenderer::renderMobTooltip() const { m_MobTooltip->render(); } +void WorldRenderer::renderCastleTooltip() const { + if (ImGui::IsAnyItemHovered()) return; + + detectCastleHovering(); + m_CastleTooltip->render(); +} + void WorldRenderer::detectMobHovering() const { glm::vec2 cursorWorldPos = getCursorWorldPos(); for (game::MobPtr mob : m_World->getMobList()) { @@ -256,6 +269,17 @@ void WorldRenderer::detectMobHovering() const { m_MobTooltip->setMob(nullptr); } +void WorldRenderer::detectCastleHovering() const { + glm::vec2 cursorWorldPos = getCursorWorldPos(); + for (const game::Team& team : m_World->getTeams()) { + if (team.getCastle().collidesWith({ cursorWorldPos.x, cursorWorldPos.y })) { + m_CastleTooltip->setCastle(&team.getCastle()); + return; + } + } + m_CastleTooltip->setCastle(nullptr); +} + void WorldRenderer::OnTowerAdd(game::TowerPtr tower) { WorldLoader::RenderData renderData = WorldLoader::loadTowerModel(tower); m_TowersCache.addData(tower->getID(), renderData.positions, renderData.colors); diff --git a/src/render/gui/CastleTooltip.cpp b/src/render/gui/CastleTooltip.cpp new file mode 100644 index 0000000..2d5ba2a --- /dev/null +++ b/src/render/gui/CastleTooltip.cpp @@ -0,0 +1,27 @@ +#include "render/gui/CastleTooltip.h" +#include "render/gui/imgui/imgui.h" + +#include "render/WorldRenderer.h" + +#include "game/client/Client.h" + +namespace td { +namespace gui { + +CastleTooltip::CastleTooltip(client::Client* client) : GuiWidget(client) { + +} + +void CastleTooltip::render() { + if (m_Castle == nullptr) return; + + ImGui::BeginTooltip(); + ImGui::PushStyleColor(ImGuiCol_Text, render::WorldRenderer::getImGuiTeamColor(m_Castle->getTeam()->getColor())); + ImGui::Text("Castle : "); + ImGui::PopStyleColor(); + ImGui::Text("\tCastle HP : %i/%i", static_cast(m_Castle->getLife()), game::TeamCastle::CastleMaxLife); + ImGui::EndTooltip(); +} + +} // namespace gui +} // namespace td