Skip to content
Snippets Groups Projects
Select Git revision
  • ecd2a07ab35490fd1db05de563bc91ddcee81dbf
  • main default protected
  • leveleditor
  • david-author
  • clang-tidy-cleanup
  • architecture-refactoring
  • cleanUpMenus
  • doxygen-cleanup
  • project-structure-refactoring
  • interpolation
  • buildingFeatures
  • win_end_screen
  • helpMenu
  • leveleditor-placement
  • text-rendering
  • updated_unit_contextmenu
  • level-from-commandline
  • unit_contextmenu
  • player
  • engine-scaling
  • clang-tidy
21 results

UnitInfoMenu.cpp

Blame
  • 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