Skip to content
Snippets Groups Projects
GameCommander.cpp 3.17 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "GameCommander.h"
    #include "IDABot.h"
    #include "Util.h"
    
    GameCommander::GameCommander(IDABot & bot)
        : m_bot                 (bot)
        , m_productionManager   (bot)
        , m_scoutManager        (bot)
        , m_combatCommander     (bot)
        , m_initialScoutSet     (false)
    {
    
    }
    
    void GameCommander::onStart()
    {
        m_productionManager.onStart();
        m_scoutManager.onStart();
        m_combatCommander.onStart();
    }
    
    void GameCommander::onFrame()
    {
        m_timer.start();
    
        handleUnitAssignments();
    
        m_productionManager.onFrame();
        m_scoutManager.onFrame();
        m_combatCommander.onFrame(m_combatUnits);
    }
    
    // assigns units to various managers
    void GameCommander::handleUnitAssignments()
    {
        m_validUnits.clear();
        m_combatUnits.clear();
    
        // filter our units for those which are valid and usable
        setValidUnits();
    
        // set each type of unit
        setScoutUnits();
        setCombatUnits();
    }
    
    bool GameCommander::isAssigned(const Unit & unit) const
    {
        return     (std::find(m_combatUnits.begin(), m_combatUnits.end(), unit) != m_combatUnits.end())
            || (std::find(m_scoutUnits.begin(), m_scoutUnits.end(), unit) != m_scoutUnits.end());
    }
    
    // Validates units as usable for distribution to various managers.
    // A unit is defined as invalid if it cannot be controlled by the player.
    void GameCommander::setValidUnits()
    {
        // Make sure the unit is completed and alive and usable.
        for (auto & unit : m_bot.UnitInfo().getUnits(Players::Self))
        {
            m_validUnits.push_back(unit);
        }
    }
    
    void GameCommander::setScoutUnits()
    {
        // if we haven't set a scout unit, do it
        if (m_scoutUnits.empty() && !m_initialScoutSet)
        {
            // if it exists
            if (shouldSendInitialScout())
            {
                // grab the closest worker to the supply provider to send to scout
                Unit workerScout = m_bot.Workers().getClosestMineralWorkerTo(m_bot.GetStartLocation());
    
                // if we find a worker (which we should) add it to the scout units
                if (workerScout.isValid())
                {
                    m_scoutManager.setWorkerScout(workerScout);
                    assignUnit(workerScout, m_scoutUnits);
                    m_initialScoutSet = true;
                }
            }
        }
    }
    
    bool GameCommander::shouldSendInitialScout()
    {
    
        return true; // m_bot.Strategy().scoutConditionIsMet();
    
    }
    
    // Sets combat units to be passed to CombatCommander.
    void GameCommander::setCombatUnits()
    {
        for (auto & unit : m_validUnits)
        {
            BOT_ASSERT(unit.isValid(), "Have a null unit in our valid units\n");
    
            if (!isAssigned(unit) && unit.getType().isCombatUnit())
            {
                assignUnit(unit, m_combatUnits);
            }
        }
    }
    
    void GameCommander::assignUnit(const Unit & unit, std::vector<Unit> & units)
    {
        if (std::find(m_scoutUnits.begin(), m_scoutUnits.end(), unit) != m_scoutUnits.end())
        {
            m_scoutUnits.erase(std::remove(m_scoutUnits.begin(), m_scoutUnits.end(), unit), m_scoutUnits.end());
        }
        else if (std::find(m_combatUnits.begin(), m_combatUnits.end(), unit) != m_combatUnits.end())
        {
            m_combatUnits.erase(std::remove(m_combatUnits.begin(), m_combatUnits.end(), unit), m_combatUnits.end());
        }
    
        units.push_back(unit);
    }