// do an action, action must be legal for this not to break std::vector<ActionType> GameState::doAction(const ActionType & action) { BOSS_ASSERT(action.getRace() == _race, "Race of action does not match race of the state"); _actionsPerformed.push_back(ActionPerformed()); _actionsPerformed[_actionsPerformed.size()-1].actionType = action; BOSS_ASSERT(isLegal(action), "Trying to perform an illegal action: %s %s", action.getName().c_str(), getActionsPerformedString().c_str()); // set the actionPerformed _actionPerformed = action; _actionPerformedK = 1; FrameCountType workerReadyTime = whenWorkerReady(action); FrameCountType ffTime = whenCanPerform(action); BOSS_ASSERT(ffTime >= 0 && ffTime < 1000000, "FFTime is very strange: %d", ffTime); auto actionsFinished=fastForward(ffTime); _actionsPerformed[_actionsPerformed.size()-1].actionQueuedFrame = _currentFrame; _actionsPerformed[_actionsPerformed.size()-1].gasWhenQueued = _gas; _actionsPerformed[_actionsPerformed.size()-1].mineralsWhenQueued = _minerals; // how much time has elapsed since the last action was queued? FrameCountType elapsed(_currentFrame - _lastActionFrame); _lastActionFrame = _currentFrame; BOSS_ASSERT(canAffordMinerals(action), "Minerals less than price: %ld < %d, ffTime=%d %s", _minerals, action.mineralPrice(), (int)elapsed, action.getName().c_str()); BOSS_ASSERT(canAffordGas(action), "Gas less than price: %ld < %d, ffTime=%d %s", _gas, action.gasPrice(), (int)elapsed, action.getName().c_str()); // modify our resources _minerals -= action.mineralPrice(); _gas -= action.gasPrice(); // do race specific things here if (getRace() == Races::Protoss) { _units.addActionInProgress(action, _currentFrame + action.buildTime()); } else if (getRace() == Races::Terran) { if (action.isBuilding() && !action.isAddon()) { if (getNumMineralWorkers() == 0) { std::cout << toString() << std::endl; } BOSS_ASSERT(getNumMineralWorkers() > 0, "Don't have any mineral workers to assign"); _units.setBuildingWorker(); } _units.addActionInProgress(action, _currentFrame + action.buildTime()); } else if (getRace() == Races::Zerg) { // zerg must subtract a larva if the action was unit creation if (action.isUnit() && !action.isBuilding()) { if (action.isMorphed()) { _units.morphUnit(action.whatBuildsActionType(), action, _currentFrame + action.buildTime()); } else { BOSS_ASSERT(getHatcheryData().numLarva() > 0, "We should have a larva to use"); _units.getHatcheryData().useLarva(); _units.addActionInProgress(action, _currentFrame + action.buildTime()); } } else if (action.isBuilding()) { _units.morphUnit(action.whatBuildsActionType(), action, _currentFrame + action.buildTime()); } else { // if it's not a unit or a building it's a tech so we queue it normally _units.addActionInProgress(action, _currentFrame + action.buildTime()); } } return actionsFinished; }
void BuildingStatus::queueActionType(const ActionType & action) { _timeRemaining = action.buildTime(); _isConstructing = action; }