Skip to content
Snippets Groups Projects
Select Git revision
  • de2f7cf3a9b422bb1c5e2fc0fea8a1a08132ec9b
  • main default protected
  • ravaflow3g
  • docs
  • v0.1.2
  • v0.1.1
  • v0.1.0
7 results

conf.py

Blame
  • unit.cpp 9.78 KiB
    #include "unit.hpp"
    #include <tinyxml2.h>
    #include <iostream>
    #include "config.hpp"
    
    namespace advanced_wars
    {
    
        MatchupTabel_secondaryweapon secWeapon;
        MatchupTabel_secondaryweapon primWeapon;
    
        Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
            : x(x), y(y), faction(faction), id(id), state(state)
        {
            health = max_health;
        };
    
        void Unit::render(Engine &engine, int scale)
        {
            Spritesheet *spritesheet = engine.get_spritesheet();
    
            int step = engine.get_stage() % spritesheet->get_unit_textures()
                                                .at(static_cast<int>(faction))
                                                .at(static_cast<int>(id))
                                                .at(static_cast<int>(state))
                                                .second;
    
            if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE)
            {
    
                SDL_Rect src;
                src.x = step * spritesheet->get_unit_width();
                src.y = 0;
                src.w = spritesheet->get_unit_width();
                src.h = spritesheet->get_unit_height();
    
                SDL_Rect dst;
                dst.x = x * spritesheet->get_unit_width() * scale;
                dst.y = y * spritesheet->get_unit_height() * scale;
                dst.w = spritesheet->get_unit_width() * scale;
                dst.h = spritesheet->get_unit_height() * scale;
    
                SDL_RenderCopyEx(engine.renderer(),
                                 spritesheet->get_unit_textures()
                                     .at(static_cast<int>(faction))
                                     .at(static_cast<int>(id))
                                     .at(static_cast<int>(state))
                                     .first,
                                 &src, &dst, 0, NULL, SDL_FLIP_NONE);
            }
            else
            {
                // The moving states have a resolution of 24x24 instead of 16x16 and need to
                // be handled separately
                SDL_Rect src;
                src.x = step * spritesheet->get_unit_moving_width();
                src.y = 0;
                src.w = spritesheet->get_unit_moving_width();
                src.h = spritesheet->get_unit_moving_height();
    
                SDL_Rect dst;
                dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
                dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
                dst.w = spritesheet->get_unit_moving_width() * scale;
                dst.h = spritesheet->get_unit_moving_height() * scale;
    
                SDL_RenderCopyEx(engine.renderer(),
                                 spritesheet->get_unit_textures()
                                     .at(static_cast<int>(faction))
                                     .at(static_cast<int>(id))
                                     .at(static_cast<int>(state))
                                     .first,
                                 &src, &dst, 0, NULL, SDL_FLIP_NONE);
            }
        }
    
        MatchupTabel damageMatrix;
        std::vector<Unit *> units;
    
        void Unit::attack(Unit *ally, Unit *enemy)
        {
    
            if (ally->has_attacked)
            {
                // display the unit as not able to attack (maybe greyscale?)
            }
    
            // Start Attack: choose the appropriate weapon:
            int offDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((ally->health) / (ally->max_health));
            int defDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((enemy->health) / (enemy->max_health));
    
            enemy->health = enemy->health - offDamage;
            if (enemy->health > 0)
            {
                ally->health = ally->health - defDamage;
                if (ally->health <= 0)
                {
                    ally->~Unit();
                }
            }
            else
            {
                enemy->~Unit();
            }
        }
    
        void Unit::update_position(int posX, int posY)
        {
            this->x = posX;
            this->y = posY;
        }
    
        void Unit::onClick(SDL_Event event)
        {
    
            Unit *defender = nullptr;
            Unit *attacker = nullptr;
    
            switch (event.button.button)
            {
            case SDL_BUTTON_LEFT:
    
                // we have to re-initialize the unit.state (probably to idle)
                this->is_selected = true;
    
                for (Unit *unit : units)
                {
                    if (inRange(unit))
                    {
                        unit->state = advanced_wars::UnitState::UNAVAILABLE;
                    };
                }
                break;
            case SDL_BUTTON_RIGHT:
    
                this->is_targeted = true;
    
                for (Unit *unit : units)
                {
                    if (unit->state == advanced_wars::UnitState::UNAVAILABLE)
                    {
                        continue;
                    }
    
                    if (unit->is_selected)
                    {
                        attacker = unit;
                    }
    
                    if (unit->is_targeted)
                    {
                        defender = unit;
                    }
                }
    
                if (attacker && defender)
                {
                    attack(attacker, defender);
                    break;
                }
                else
                {
                    std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
                    break;
                }
            }
        }
    
        bool Unit::inRange(Unit *enemy)
        {
            if (this->x == enemy->x)
            {
                return abs(this->y - enemy->y) <= this->range;
            }
            else if (this->y == enemy->y)
            {
                return abs(this->x - enemy->x) <= this->range;
            }
            return false;
        }
    
        // Config test start
    
        void Unit::readXML()
        {
    
            Config config(secWeapon, primWeapon);
            // Lade Konfigurationsdaten von XML
            try
            {
                config.loadFromXML("../xml/config.xml");
            }
            catch (const std::exception &e)
            {
                std::cerr << "Error loading XML: " << e.what() << std::endl;
            }
    
            // Liste der zu testenden UnitIds
            std::vector<UnitId> testUnits = {UnitId::INFANTERY, UnitId::MECHANIZED_INFANTERY};
    
            for (auto id : testUnits)
            {
                try
                {
                    int cost = config.get_unit_cost(id);
                    int movement = config.get_unit_movementPoints(id);
                    int ammo = config.get_unit_ammo(id);
                    int minRange = config.get_unit_minRange(id);
                    int maxRange = config.get_unit_maxRange(id);
    
                    std::string primaryWeapon = "None";
                    std::string secondaryWeapon = "None";
    
                    if (id == UnitId::INFANTERY || id == UnitId::MECHANIZED_INFANTERY)
                    { // Bsp.-Fall, hier müssten je nach Wunschbedingungen ID's ergänzt werden
                        try
                        {
                            primaryWeapon = config.get_unit_primaryweapon(id);
                        }
                        catch (...)
                        {
                            // Es passiert nichts, wenn die Primärwaffe fehlt
                        }
                        try
                        {
                            secondaryWeapon = config.get_unit_secondaryweapon(id);
                        }
                        catch (...)
                        {
                            // Es passiert nichts, wenn die Sekundärwaffe fehlt
                        }
                    }
    
                    std::cout << "Unit ID: " << static_cast<int>(id) << std::endl;
                    std::cout << "  Cost: " << cost << std::endl;
                    std::cout << "  Movement Points: " << movement << std::endl;
                    std::cout << "  Ammo: " << ammo << std::endl;
                    std::cout << "  Primary Weapon: " << primaryWeapon << "; Range: " << minRange << "-" << maxRange << std::endl;
                    std::cout << "  Secondary Weapon: " << secondaryWeapon << std::endl;
                }
                catch (const std::exception &e)
                {
                    std::cerr << "Error retrieving unit data for ID " << static_cast<int>(id) << ": " << e.what() << std::endl;
                }
            }
            std::cout << "Debug secWeapon Inhalt:" << std::endl;
            for (const auto &outer : secWeapon)
            {
                std::cout << "Einheit ID: " << static_cast<int>(outer.first) << std::endl;
                for (const auto &inner : outer.second)
                {
                    std::cout << "  Ziel ID: " << static_cast<int>(inner.first)
                              << " Schaden: " << inner.second << std::endl;
                }
            }
        }
    
        // Config test end
    
        /*
        void Unit::loadXML(const char *filename)
        {
    
            tinyxml2::XMLDocument doc;
            if (doc.LoadFile(filename) != tinyxml2::XML_SUCCESS)
            {
                std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
                return;
            }
    
            MatchupTabel damageMatrix;
            tinyxml2::XMLElement *unitElement = doc.FirstChildElement("Units")->FirstChildElement("Unit");
    
            // get all Units
            while (unitElement)
            {
    
                const u_int8_t UnitId = unitElement->Attribute("id");
    
                std::unordered_map<u_int8_t, int> attackValues;
                tinyxml2::XMLElement *attackElement = unitElement->FirstChildElement("Attack");
    
                // get all attack-values
                while (attackElement)
                {
    
                    tinyxml2::XMLElement *attackTypeElement = attackElement->FirstChildElement();
    
                    while (attackTypeElement)
                    {
                        UnitId Unit_Id = static_cast<UnitId> attackTypeElement->Name(); // wenn das geht kauf ich maggus sein kochbuch
    
                        int attackValue = attackTypeElement->IntText();
    
                        attackValues[Unit_Id] = attackValue;
    
                        attackTypeElement = attackTypeElement->NextSiblingElement();
                    }
                }
    
                damageMatrix[unitElement][attackValues];
                unitElement = unitElement->NextSiblingElement("Unit");
            }
        }
        */
    } // namespace advanced_wars