feat: add castle tooltip
This commit is contained in:
@@ -19,7 +19,7 @@ typedef std::map<std::uint8_t, Player> PlayerList;
|
||||
class Game {
|
||||
protected:
|
||||
World* m_World;
|
||||
std::array<Team, 2> 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
|
||||
|
||||
@@ -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<Team, 2> TeamList;
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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<gui::TowerPlacePopup> m_TowerPlacePopup;
|
||||
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
|
||||
std::unique_ptr<gui::CastleTooltip> 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;
|
||||
|
||||
27
include/render/gui/CastleTooltip.h
Normal file
27
include/render/gui/CastleTooltip.h
Normal file
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<utils::shape::Rectangle>(redCastle);
|
||||
data << blueSpawn << static_cast<utils::shape::Rectangle>(blueCastle);
|
||||
|
||||
// tile palette
|
||||
data << m_Header.m_TilePalette.size();
|
||||
data << static_cast<std::uint64_t>(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<utils::shape::Rectangle>(redCastle);
|
||||
data << blueSpawn << static_cast<utils::shape::Rectangle>(blueCastle);
|
||||
|
||||
// tile palette
|
||||
data << m_Header.m_World->getTilePalette().size();
|
||||
data << static_cast<std::uint64_t>(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;
|
||||
|
||||
@@ -37,6 +37,7 @@ WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m
|
||||
m_Renderer->setCamMovement({});
|
||||
m_TowerPlacePopup = std::make_unique<gui::TowerPlacePopup>(m_Client->getClient());
|
||||
m_MobTooltip = std::make_unique<gui::MobTooltip>(m_Client->getClient());
|
||||
m_CastleTooltip = std::make_unique<gui::CastleTooltip>(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);
|
||||
|
||||
27
src/render/gui/CastleTooltip.cpp
Normal file
27
src/render/gui/CastleTooltip.cpp
Normal file
@@ -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<int>(m_Castle->getLife()), game::TeamCastle::CastleMaxLife);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
} // namespace gui
|
||||
} // namespace td
|
||||
Reference in New Issue
Block a user