Select Git revision

Max Götz Hans-Georg Körschen authored
UnitInfoMenu.cpp 7.08 KiB
/**
* @authors Max Körschen
*/
#include "UnitInfoMenu.hpp"
#include <SDL_ttf.h>
#include <iostream>
namespace advanced_wars
{
// UnitInfoMenu::UnitInfoMenu() : m_currentUnit(nullptr), m_isVisible(false) {}
UnitInfoMenu::UnitInfoMenu() : m_currentUnit(nullptr) {}
std::string UnitInfoMenu::getMovementTypeString(MovementType type)
{
switch (type)
{
case MovementType::FOOT:
return "Foot";
case MovementType::WHEELED:
return "Wheeled";
case MovementType::TREAD:
return "Tracked";
case MovementType::AIR:
return "Aircraft";
case MovementType::SEA:
return "Ship";
case MovementType::LANDER:
return "Lander";
default:
return "Unknown";
}
}
std::unordered_map<UnitTypeId, std::string> unitDescriptions = {
{ UnitTypeId::INFANTERY,"Infanterie Kostenguenstig und vielseitig einsetzbar" },
{ UnitTypeId::MECHANIZED_INFANTERY,
"Mech-Infanterie Stark gegen Panzer langsam aber effizient" },
{ UnitTypeId::RECON, "Aufklaerung Schnell und ideal für frühe Aufklaerung"},
{ UnitTypeId::MEDIUM_TANK, "Mittlerer Panzer Guter Allrounder stark und ausgewogen"},
{ UnitTypeId::HEAVY_TANK,
"Schwerer Panzer Langsam aber sehr stark und beschützend" },
{ UnitTypeId::NEO_TANK, "Neo Tank Einer der besten Panzer stark und vielseitig"},
{ UnitTypeId::APC, "Transporter Traeger fuer Infanterie keine Offensivkraefte"},
{ UnitTypeId::ANTI_AIR_TANK, "FlugabwehrPanzer Ideal zur Luftverteidigung"},
{ UnitTypeId::ARTILLERY, "Artillerie Kann aus Distanz zufuegen aber verletzbar im Nahkampf"},
{ UnitTypeId::ROCKET_ARTILLERY,
"Raketenartillerie Grosse Reichweite ideal fuer defensive Taktiken" },
{UnitTypeId::ANTI_AIR_MISSILE_LAUNCHER,
"Raketenwerfer Kann Flugeinheiten auf grosse Distanz angreifen" },
{ UnitTypeId::FIGHTER, "Jaeger Ideal fuer Luftueberlegenheit"},
{ UnitTypeId::BOMBER,
"Bomber Stark gegen Boden- und Seeziele aber verletzbar gegen Luft-und Flak" },
{ UnitTypeId::BATTLE_HELICOPTER,
"Kampfhubschrauber Stark gegen Bodenfahrzeuge und Infanterie" },
{ UnitTypeId::TRANSPORT_HELICOPTER,
"Transporthubschrauber Kann Einheiten schnell transportieren" },
{ UnitTypeId::BATTLESHIP, "Schlachtschiff Langreichweitenangriff auf See und Land"},
{ UnitTypeId::CRUISER, "Kreuzer Verteidigung gegen Luft und U-Boot-Einheiten"},
{ UnitTypeId::LANDER, "Landungsschiff Transport und Versorgung"},
{ UnitTypeId::SUBMARINE, "U-Boot Versteckt sich und kann Ueberwasserziele angreifen"}
};
void UnitInfoMenu::handleEvent(Engine& /*engine*/, SDL_Event& /*event*/) {}
void UnitInfoMenu::setUnit(Unit& unit)
{
m_currentUnit = &unit;
m_isVisible = true;
}
void UnitInfoMenu::render(Engine& engine)
{
if ((m_currentUnit == nullptr) || !m_isVisible)
{
return;
}
// TTF Initialisierung
if (TTF_Init() == -1)
{
std::cerr << "TTF konnte nicht initialisiert werden: " << TTF_GetError() << "\n";
return;
}
std::string basePath = SDL_GetBasePath();
std::string fullPath = basePath + "res/ARCADECLASSIC.TTF";
TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 16);
if (font == nullptr)
{
std::cerr << "Failed to load font: " << TTF_GetError() << "\n";
return;
}
SDL_Color yellow = {255, 255, 0, 255}; // Gelb für den Text
int spacing = 10; // Abstand zwischen den Textzeilen
UnitTypeId unitId = m_currentUnit->getUnitTypeId();
// Textzeilen, einschließlich der Beschreibung
std::vector<std::string> infoLines = {
"HP " + std::to_string(m_currentUnit->getHealth()),
"Movement " + std::to_string(m_currentUnit->getMovementPoints()),
"Ammo " + std::to_string(m_currentUnit->getAmmo()),
"Movement Type " + getMovementTypeString(m_currentUnit->getMovementType()),
"Cost " + std::to_string(m_currentUnit->getCost()),
unitDescriptions[unitId] // Beschreibung einfügen
};
int maxTextWidth = 0;
int totalHeight = 0;
std::vector<SDL_Texture*> textures;
for (const auto& line : infoLines)
{
SDL_Surface* textSurface = TTF_RenderText_Solid(font, line.c_str(), yellow);
if (textSurface == nullptr)
{
continue;
}
maxTextWidth = std::max(maxTextWidth, textSurface->w);
totalHeight += textSurface->h + spacing;
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine.renderer(), textSurface);
textures.push_back(textTexture);
SDL_FreeSurface(textSurface);
}
int width = std::max(maxTextWidth + (20 * RENDERING_SCALE), (16 * RENDERING_SCALE) + 20);
int height = totalHeight +
(30 * RENDERING_SCALE); // Die Höhe anpassen, um alle Textzeilen zu integrieren
SDL_Rect box = {m_x, m_y, width, height};
SDL_SetRenderDrawColor(engine.renderer(), 75, 87, 219, 255); // Schwarzes Hintergrundrechteck
SDL_RenderFillRect(engine.renderer(), &box);
SDL_SetRenderDrawColor(engine.renderer(), 255, 255, 255, 255); // Weißer Rahmen
SDL_RenderDrawRect(engine.renderer(), &box);
// Render unit sprite
Spritesheet* spritesheet = engine.getSpritesheet();
SDL_Texture* unitTexture = spritesheet->getUnitTextures()
.at(static_cast<int>(m_currentUnit->getFaction()))
.at(static_cast<int>(unitId))
.at(static_cast<int>(UnitState::IDLE))
.first;
SDL_Rect spriteRect = {m_x + 10, m_y + 10, 16 * RENDERING_SCALE, 16 * RENDERING_SCALE};
SDL_Rect sourceRect = {0, 0, 16, 16};
SDL_RenderCopy(engine.renderer(), unitTexture, &sourceRect, &spriteRect);
// Text zeichnen
int textY = m_y + (20 * RENDERING_SCALE); // Starte etwas unterhalb des Sprites
for (auto* texture : textures)
{
int w;
int h;
SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
SDL_Rect textRect = {m_x + 10, textY, w, h};
SDL_RenderCopy(engine.renderer(), texture, nullptr, &textRect);
SDL_DestroyTexture(texture);
textY += (h + spacing);
}
TTF_CloseFont(font);
TTF_Quit();
}
void UnitInfoMenu::update(int x, int y)
{
m_x = x;
m_y = y;
}
} // namespace advanced_wars