BWAPI
Public Member Functions | Private Member Functions | Private Attributes
BuildManager Class Reference

#include <BuildManager.h>

Inheritance diagram for BuildManager:
Inheritance graph
[legend]
Collaboration diagram for BuildManager:
Collaboration graph
[legend]

List of all members.

Public Member Functions

void update ()
void draw ()
void build (BWAPI::UnitType type, bool immediate=false)
void build (BWAPI::UnitType type, BWAPI::TilePosition goalPosition, bool immediate=false)
virtual const std::string & getName () const

Private Member Functions

void drawDebugText ()

Private Attributes

queue< BuildReqbuildQueue
stack< BuildReqbuildStack

Detailed Description

Definition at line 31 of file BuildManager.h.


Member Function Documentation

void BuildManager::build ( BWAPI::UnitType  type,
bool  immediate = false 
)

Referenced by SupplyManager::update().

Here is the caller graph for this function:

void BuildManager::build ( BWAPI::UnitType  type,
BWAPI::TilePosition  goalPosition,
bool  immediate = false 
)
void BuildManager::draw ( ) [virtual]

Reimplemented from Manager.

Definition at line 258 of file BuildManager.cpp.

References BWAPI::Broodwar, and Manager::draw().

{
        Broodwar->drawTextScreen(2, 40, "\x07 BM : (SCV=%d) (CC=%d)", 
        numAgents(UnitTypes::Terran_SCV),
        numAgents(UnitTypes::Terran_Command_Center));

    drawDebugText();

        Manager::draw();
}

Here is the call graph for this function:

void BuildManager::drawDebugText ( ) [private]

Definition at line 214 of file BuildManager.cpp.

References BWAPI::Broodwar, BuildReq::type, and UnitTypeStrings.

{
    const int starty  = 60;
    int x = 2; 
    int y = starty;

    Broodwar->drawTextScreen(x, y, "BuildMgr - queue (%d)", (int)buildQueue.size());

    deque<BuildReq> tempq;
    while(!buildQueue.empty())
    {
        BuildReq req = buildQueue.front();
        buildQueue.pop();
        Broodwar->drawTextScreen(x, y += 10, "-%s", UnitTypeStrings[req.type.getID()]);
        tempq.push_back(req);
    }
    while(!tempq.empty())
    {
        BuildReq req = tempq.front();
        tempq.pop_front();
        buildQueue.push(req);
    }

    tempq.clear();

    x = 150;
    y = starty;

    Broodwar->drawTextScreen(x, y, "BuildMgr - stack (%d)", (int)buildStack.size());
    while(!buildStack.empty())
    {
        BuildReq req = buildStack.top();
        buildStack.pop();
        Broodwar->drawTextScreen(x, y += 10, "-%s", UnitTypeStrings[req.type.getID()]);
                tempq.push_front(req);
    }
    while(!tempq.empty())
    {
        BuildReq req = tempq.front();
        tempq.pop_front();
        buildStack.push(req);
    }
}
virtual const std::string& BuildManager::getName ( ) const [inline, virtual]

Reimplemented from Manager.

Definition at line 46 of file BuildManager.h.

    {
        static const std::string name("BuildMgr");
        return name; 
    }
void BuildManager::update ( ) [virtual]

Reimplemented from Manager.

Definition at line 25 of file BuildManager.cpp.

References BWAPI::Broodwar, BuildReq::builder, BuildState, COMPLETE, Agent::getState(), IdleState, ISSUED, ResourceManager::makeAgentGatherMinerals(), NEW, STARTED, BuildReq::state, TrainState, BuildReq::type, and Manager::update().

{
        // Update Agents
        Manager::update();

        // Done with the current request?
        if (buildStack.empty())
        {
                // Try to start a new request
                if (!buildQueue.empty())
                {
                        buildStack.push(buildQueue.front());
                        buildQueue.pop();
                }
        }

        // Process requests if there are any
        if (buildStack.empty())
                return;

        BuildReq &req = buildStack.top();
        UnitType type = req.type;

        switch (req.state)
        {
        case NEW: 
        {
                //Broodwar->sendText("Trying to build: %s", type.c_str());

                // Check reqs
                int mineralsNeeded = type.mineralPrice();
                int gasNeeded = type.gasPrice();
                int mineralsOwned = Broodwar->self()->minerals();
                int gasOwned = Broodwar->self()->gas();

                // Required supply?
                int supplyOwned = Broodwar->self()->supplyTotal() - Broodwar->self()->supplyUsed();
                if (supplyOwned < type.supplyRequired())
                {
                        break;
                }

                // Required units?
                map<UnitType, int> requiredUnits = type.requiredUnits();
                for (map<UnitType, int>::iterator i = requiredUnits.begin(); i != requiredUnits.end(); i++)
                {
                        UnitType rt = (*i).first;
                        int rc = (*i).second;
                        if (Broodwar->self()->visibleUnitCount(rt) < rc)
                        {
                                build(rt, true);
                                Broodwar->sendText("%s pushed: prereq to build %s", rt.c_str(), type.c_str());
                                break;
                        }
                }
                
                // Required builder?
                UnitType builderType = type.whatBuilds().first;
                if (Broodwar->self()->visibleUnitCount(builderType) < 1)
                {
                        build(builderType, true);
            // TODO: I've had several crashes here...
            // they seem to stem from the calls to c_str(), they must be returning a bad pointer...
            // commenting it out has stopped the crashes here for me so far.
//                      Broodwar->sendText("%s pushed:  Need a %s to build %s", builderType.c_str(), type.c_str());
                        break;
                }

                // Required resources?
                if (mineralsOwned < mineralsNeeded ||
                        gasOwned < gasNeeded) 
                {
                        break;
                }

                // OK - requirements met, let's build it!
                // Find an idle builder
                for (AgentSetIter i = agents.begin(); i != agents.end(); i++)
                {
                        if ((*i)->getUnit().getType().getID() == builderType.getID()
                                && (*i)->getState() != BuildState 
                                && (*i)->getState() != TrainState)  
                        {
                                // Found one, build it (this works for addons too)
                                if (type.isBuilding())
                                        (*i)->setState(BuildState);
                                else
                                        (*i)->setState(TrainState);
                                (*i)->setUnitTypeTarget(type);
                                // Remember we issued the command
                                req.builder = &(*i)->getUnit();
                                req.state = ISSUED;
                                Broodwar->sendText("BM: Worker found, building %s", type.c_str());
                                break;
                        }
                }
                // Wait if we didn't find a builder
                if (req.builder == NULL)
                {
                        break;
                }
        }
        break;

        case ISSUED:
        {
                /* We need to determine if the order has been started (i.e. resources spent) */
                Unit* builder = req.builder;

                if (builder->getType().isBuilding())
                {
                        if (builder->isTraining())
                        {
                                req.state = STARTED;
                        }
                }
                else if (builder->getType().isWorker())
                {
                        /*
                         * We can't check if a builder is *really* building using ->isConstructing(),
                         * but we can see if a structure is being built by our builder
                         */
                        UnitSet ownedUnits = Broodwar->self()->getUnits();
                        for (UnitSetConstIter i = ownedUnits.begin(); i != ownedUnits.end(); i++)
                        {
                                if ((*i)->getBuildUnit() == builder &&
                                        (*i)->isVisible())
                                {
                                        req.state = STARTED;
                                }
                        }
                }
                break;
        }

        case STARTED:
                /*
                 * TODO:  Monitor the orders we have started, and verify them to completion.
                 *        In the case of a killed SCV doing a build, we may want to restart the
                 *        order.
                 */
                buildStack.pop();
                break;

        case COMPLETE:
                break;
        }

    // Keep our workers busy when they aren't building
    AgentSet workers(getAgentsOfType(UnitTypes::Terran_SCV));
    for(AgentSetIter worker = workers.begin(); worker != workers.end(); ++worker)
    {
        Agent& agent = **worker;
        if( agent.getState() == IdleState ) 
        {
            ResourceManager::makeAgentGatherMinerals(agent);
        }
    }
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 34 of file BuildManager.h.

Definition at line 35 of file BuildManager.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines