diff --git a/include/game/Towers.h b/include/game/Towers.h index a5e1483..886e5a6 100644 --- a/include/game/Towers.h +++ b/include/game/Towers.h @@ -125,6 +125,7 @@ typedef std::shared_ptr TowerPtr; namespace TowerFactory { TowerPtr createTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder); +std::string getTowerName(TowerType type); } // namespace TowerFactory diff --git a/include/game/World.h b/include/game/World.h index 11489b0..908f0a2 100644 --- a/include/game/World.h +++ b/include/game/World.h @@ -163,7 +163,7 @@ public: bool CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID player) const; bool CanPlaceBigTower(const glm::vec2& worldPos, PlayerID player) const; - TowerPtr GetTower(const glm::vec2& position); // returns null if no tower is here + TowerPtr getTower(const glm::vec2& position) const; // returns null if no tower is here const std::unordered_map& getChunks() const { return m_Chunks; } diff --git a/include/render/WorldRenderer.h b/include/render/WorldRenderer.h index d498b17..1bdd48e 100644 --- a/include/render/WorldRenderer.h +++ b/include/render/WorldRenderer.h @@ -28,7 +28,7 @@ private: glm::vec2 m_HoldCursorPos; float m_Zoom; float m_CamSensibility = 1; - bool m_TowerPlacePopupOpened = false; + bool m_PopupOpened = false; VertexCache m_TowersCache; public: WorldRenderer(game::World* world, client::ClientGame* client); @@ -53,6 +53,8 @@ private: void renderMobs() const; void renderTileSelect() const; void renderPopups() const; + void renderTowerPlacePopup() const; + void renderTowerUpgradePopup() const; void renderMobTooltip() const; void detectClick(); glm::vec2 getCursorWorldPos() const; diff --git a/src/game/Towers.cpp b/src/game/Towers.cpp index c393c78..c0aef2b 100644 --- a/src/game/Towers.cpp +++ b/src/game/Towers.cpp @@ -160,6 +160,35 @@ TowerPtr createTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, return towerFactory.at(type)(id, x, y, builder); } +std::string getTowerName(TowerType type) { + switch (type) { + + case TowerType::Archer: + return "Archer"; + case TowerType::Artillery: + return "Artillery"; + case TowerType::Ice: + return "Ice"; + case TowerType::Mage: + return "Mage"; + case TowerType::Poison: + return "Poison"; + case TowerType::Quake: + return "Quake"; + case TowerType::Sorcerer: + return "Sorcerer"; + case TowerType::Zeus: + return "Zeus"; + case TowerType::Leach: + return "Leach"; + case TowerType::Necromancer: + return "Necromancer"; + case TowerType::Turret: + return "Turret"; + + } +} + } // namespace TowerFactory @@ -207,7 +236,7 @@ void MageTower::tick(std::uint64_t delta, World* world) { bool wasTowerActive = false; for (MobPtr mob : world->getMobList()) { if (isMobInRange(mob)) { - mob->addEffect(EffectType::Fire, getLevel().getLevel() * 5, this); + mob->addEffect(EffectType::Fire, getLevel().getLevel() * 5, this); wasTowerActive = true; } } diff --git a/src/game/World.cpp b/src/game/World.cpp index 4967c77..b740038 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -202,7 +202,7 @@ bool World::CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID playerID) co for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { game::TilePtr adjacentTile = getTile(worldPos.x + x, worldPos.y + y); - if (adjacentTile == nullptr || adjacentTile->getType() != game::TileType::Tower) { + if (adjacentTile == nullptr || adjacentTile->getType() != game::TileType::Tower || getTower({worldPos.x + x, worldPos.y + y}) != nullptr) { return false; } } @@ -214,6 +214,8 @@ bool World::CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID playerID) co } bool World::CanPlaceBigTower(const glm::vec2& worldPos, PlayerID playerID) const { + if(!CanPlaceLittleTower(worldPos, playerID)) return false; + TilePtr tile = getTile(worldPos.x, worldPos.y); const Player& player = m_Game->getPlayers()[playerID]; @@ -228,7 +230,7 @@ bool World::CanPlaceBigTower(const glm::vec2& worldPos, PlayerID playerID) const for (int x = -2; x < 3; x++) { for (int y = -2; y < 3; y++) { game::TilePtr adjacentTile = getTile(worldPos.x + x, worldPos.y + y); - if (adjacentTile == nullptr || adjacentTile->getType() != game::TileType::Tower) { + if (adjacentTile == nullptr || adjacentTile->getType() != game::TileType::Tower || getTower({worldPos.x + x, worldPos.y + y}) != nullptr) { return false; } } @@ -257,7 +259,7 @@ void World::cleanDeadMobs() { } } -TowerPtr World::GetTower(const glm::vec2& position) { +TowerPtr World::getTower(const glm::vec2& position) const{ for (TowerPtr tower : m_Towers) { if (tower->getSize() == TowerSize::Big) { if (tower->getX() - 2 <= position.x && tower->getX() + 3 >= position.x && diff --git a/src/render/WorldRenderer.cpp b/src/render/WorldRenderer.cpp index c5c2bda..50b2e0b 100644 --- a/src/render/WorldRenderer.cpp +++ b/src/render/WorldRenderer.cpp @@ -54,10 +54,10 @@ void WorldRenderer::update() { } updateCursorPos(); if (ImGui::IsMouseClicked(0)) { - if (!m_TowerPlacePopupOpened) { + if (!m_PopupOpened) { m_HoldCursorPos = { io.MousePos.x, io.MousePos.y }; } else { - m_TowerPlacePopupOpened = false; + m_PopupOpened = false; } } } @@ -88,6 +88,11 @@ void WorldRenderer::renderTileSelect() const { m_Renderer->renderModel(tileSelectModel); } +void WorldRenderer::renderPopups() const { + renderTowerPlacePopup(); + renderTowerUpgradePopup(); +} + void WorldRenderer::render() { if (m_WorldVao == nullptr) return; @@ -126,9 +131,13 @@ void WorldRenderer::changeZoom(float zoomStep) { } void WorldRenderer::click() { - if (m_Client->getWorld().CanPlaceLittleTower(getClickWorldPos(), m_Client->getPlayer()->getID())) { + const game::TowerPtr tower = m_Client->getWorld().getTower(getClickWorldPos()); + if(tower != nullptr){ // there is a tower here + ImGui::OpenPopup("TowerUpgrade"); + m_PopupOpened = true; + }else if (m_Client->getWorld().CanPlaceLittleTower(getClickWorldPos(), m_Client->getPlayer()->getID())) { ImGui::OpenPopup("TowerPlace"); - m_TowerPlacePopupOpened = true; + m_PopupOpened = true; } } @@ -137,7 +146,7 @@ void WorldRenderer::setCamPos(float camX, float camY) { m_Renderer->setCamPos(m_CamPos); } -void WorldRenderer::renderPopups() const { +void WorldRenderer::renderTowerPlacePopup() const { if (ImGui::BeginPopup("TowerPlace")) { for (int i = 0; i < (int)game::TowerType::TowerCount; i++) { game::TowerType towerType = game::TowerType(i); @@ -157,6 +166,18 @@ void WorldRenderer::renderPopups() const { } } +void WorldRenderer::renderTowerUpgradePopup() const { + if (ImGui::BeginPopup("TowerUpgrade")) { + game::TowerPtr tower = m_Client->getWorld().getTower(getClickWorldPos()); + if(tower == nullptr){ + ImGui::EndPopup(); + return; + } + ImGui::Text("Tower : %s", game::TowerFactory::getTowerName(tower->getType()).c_str()); + ImGui::EndPopup(); + } +} + void WorldRenderer::detectClick() { ImGuiIO& io = ImGui::GetIO(); if (ImGui::IsMouseReleased(0) && !ImGui::IsAnyItemHovered() && !ImGui::IsAnyItemFocused()) { @@ -173,30 +194,30 @@ void WorldRenderer::renderMobTooltip() const { // mob size is currently 1x1 for all mobs float mobCenterX = mob->getX(); float mobCenterY = mob->getY(); - if (cursorWorldPos.x > mobCenterX - 0.5f && cursorWorldPos.x < mobCenterX + 0.5f + if (cursorWorldPos.x > mobCenterX - 0.5f && cursorWorldPos.x < mobCenterX + 0.5f && cursorWorldPos.y > mobCenterY - 0.5f && cursorWorldPos.y < mobCenterY + 0.5f) { - const game::Player& sender = m_Client->getPlayerById(mob->getSender()); + const game::Player& sender = m_Client->getPlayerById(mob->getSender()); - ImGui::BeginTooltip(); - ImGui::Text("Sender :"); - ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, getImGuiTeamColor(sender.getTeamColor())); - ImGui::Text("%s", sender.getName().c_str()); - ImGui::PopStyleColor(); - ImGui::Text("Mob HP : %.1f/%i", mob->getHealth(), mob->getStats()->getMaxLife()); - ImGui::Text("Mob Type : %s", game::MobFactory::getMobName(mob->getType()).c_str()); - ImGui::Text("Mob Level : %i", mob->getLevel()); - ImGui::NewLine(); - ImGui::Text("Mob Stats :"); - ImGui::Text("\tMax health : %i", mob->getStats()->getMaxLife()); - ImGui::Text("\tSpeed : %.1f", mob->getStats()->getMovementSpeed()); - ImGui::Text("\tDamage : %.1f", mob->getStats()->getDamage()); - ImGui::Text("\tMoney cost : %i", mob->getStats()->getMoneyCost()); - ImGui::Text("\tEXP cost : %i", mob->getStats()->getExpCost()); - ImGui::Text("\tEXP reward : %i", mob->getStats()->getExpReward()); - ImGui::EndTooltip(); - break; + ImGui::BeginTooltip(); + ImGui::Text("Sender :"); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, getImGuiTeamColor(sender.getTeamColor())); + ImGui::Text("%s", sender.getName().c_str()); + ImGui::PopStyleColor(); + ImGui::Text("Mob HP : %.1f/%i", mob->getHealth(), mob->getStats()->getMaxLife()); + ImGui::Text("Mob Type : %s", game::MobFactory::getMobName(mob->getType()).c_str()); + ImGui::Text("Mob Level : %i", mob->getLevel()); + ImGui::NewLine(); + ImGui::Text("Mob Stats :"); + ImGui::Text("\tMax health : %i", mob->getStats()->getMaxLife()); + ImGui::Text("\tSpeed : %.1f", mob->getStats()->getMovementSpeed()); + ImGui::Text("\tDamage : %.1f", mob->getStats()->getDamage()); + ImGui::Text("\tMoney cost : %i", mob->getStats()->getMoneyCost()); + ImGui::Text("\tEXP cost : %i", mob->getStats()->getExpCost()); + ImGui::Text("\tEXP reward : %i", mob->getStats()->getExpReward()); + ImGui::EndTooltip(); + break; } } }