int CCommandAI::CancelCommands(const Command &c, CCommandQueue& q, bool& first) { first = false; int cancelCount = 0; while (true) { CCommandQueue::iterator ci = GetCancelQueued(c, q); if (ci == q.end()) { return cancelCount; } first = first || (ci == q.begin()); cancelCount++; CCommandQueue::iterator firstErase = ci; CCommandQueue::iterator lastErase = ci; ci++; if ((ci != q.end()) && (ci->id == CMD_SET_WANTED_MAX_SPEED)) { lastErase = ci; cancelCount++; ci++; } if ((ci != q.end()) && (ci->id == CMD_WAIT)) { waitCommandsAI.RemoveWaitCommand(owner, *ci); lastErase = ci; cancelCount++; ci++; } lastErase++; // STL: erase the range [first, last) q.erase(firstErase, lastErase); if (c.id >= 0) { return cancelCount; // only delete one non-build order } } return cancelCount; }
void CCommandAI::ExecuteRemove(const Command& c) { // disable repeating during the removals const bool prevRepeat = repeatOrders; repeatOrders = false; CCommandQueue* queue = &commandQue; bool facBuildQueue = false; CFactoryCAI* facCAI = dynamic_cast<CFactoryCAI*>(this); if (facCAI) { if (c.options & CONTROL_KEY) { // check the build order facBuildQueue = true; } else { // use the new commands queue = &facCAI->newUnitCommands; } } if ((c.params.size() <= 0) || (queue->size() <= 0)) { return; } // erase commands by a list of command types bool active = false; for (unsigned int p = 0; p < c.params.size(); p++) { const int removeValue = (int)c.params[p]; // tag or id if (facBuildQueue && (removeValue == 0) && !(c.options & ALT_KEY)) { continue; // don't remove tag=0 commands from build queues, they // are used the same way that CMD_STOP is, to void orders } CCommandQueue::iterator ci; do { for (ci = queue->begin(); ci != queue->end(); ++ci) { const Command& qc = *ci; if (c.options & ALT_KEY) { if (qc.id != removeValue) { continue; } } else { if (qc.tag != removeValue) { continue; } } if (qc.id == CMD_WAIT) { waitCommandsAI.RemoveWaitCommand(owner, qc); } if (facBuildQueue) { facCAI->RemoveBuildCommand(ci); ci = queue->begin(); break; // the removal may have corrupted the iterator } if (!facCAI && (ci == queue->begin())) { if (!active) { active = true; FinishCommand(); ci = queue->begin(); break; } active = true; } queue->erase(ci); ci = queue->begin(); break; // the removal may have corrupted the iterator } } while (ci != queue->end()); } repeatOrders = prevRepeat; return; }
void CCommandAI::ExecuteRemove(const Command& c) { CCommandQueue* queue = &commandQue; CFactoryCAI* facCAI = dynamic_cast<CFactoryCAI*>(this); // if false, remove commands by tag const bool removeByID = (c.options & ALT_KEY); // disable repeating during the removals const bool prevRepeat = repeatOrders; // erase commands by a list of command types bool active = false; bool facBuildQueue = false; if (facCAI) { if (c.options & CONTROL_KEY) { // keep using the build-order queue facBuildQueue = true; } else { // use the command-queue for new units queue = &facCAI->newUnitCommands; } } if ((c.params.size() <= 0) || (queue->size() <= 0)) { return; } repeatOrders = false; for (unsigned int p = 0; p < c.params.size(); p++) { const int removeValue = c.params[p]; // tag or id if (facBuildQueue && !removeByID && (removeValue == 0)) { // don't remove commands with tag 0 from build queues, they // are used the same way that CMD_STOP is (to void orders) continue; } CCommandQueue::iterator ci; do { for (ci = queue->begin(); ci != queue->end(); ++ci) { const Command& qc = *ci; if (removeByID) { if (qc.GetID() != removeValue) { continue; } } else { if (qc.tag != removeValue) { continue; } } if (qc.GetID() == CMD_WAIT) { waitCommandsAI.RemoveWaitCommand(owner, qc); } if (facBuildQueue) { // if ci == queue->begin() and !queue->empty(), this pop_front()'s // via CFAI::ExecuteStop; otherwise only modifies *ci (not <queue>) if (facCAI->RemoveBuildCommand(ci)) { ci = queue->begin(); break; } } if (!facCAI && (ci == queue->begin())) { if (!active) { active = true; FinishCommand(); ci = queue->begin(); break; } active = true; } queue->erase(ci); ci = queue->begin(); // the removal may have corrupted the iterator break; } } while (ci != queue->end()); } repeatOrders = prevRepeat; }