void CCommandAI::ExecuteInsert(const Command& c, bool fromSynced) { if (c.params.size() < 3) { return; } // make the command Command newCmd; newCmd.id = (int)c.params[1]; newCmd.options = (unsigned char)c.params[2]; for (int p = 3; p < (int)c.params.size(); p++) { newCmd.params.push_back(c.params[p]); } // validate the command if (!AllowedCommand(newCmd, fromSynced)) { return; } CCommandQueue* queue = &commandQue; bool facBuildQueue = false; CFactoryCAI* facCAI = dynamic_cast<CFactoryCAI*>(this); if (facCAI) { if (c.options & CONTROL_KEY) { // check the build order const map<int, CFactoryCAI::BuildOption>& bOpts = facCAI->buildOptions; if ((newCmd.id != CMD_STOP) && (newCmd.id != CMD_WAIT) && ((newCmd.id >= 0) || (bOpts.find(newCmd.id) == bOpts.end()))) { return; } facBuildQueue = true; } else { // use the new commands queue = &facCAI->newUnitCommands; } } // FIXME: handle CMD_LOOPBACKATTACK, etc... CCommandQueue::iterator insertIt = queue->begin(); if (c.options & ALT_KEY) { // treat param0 as a position int pos = (int)c.params[0]; const unsigned int qsize = queue->size(); if (pos < 0) { pos = qsize + pos + 1; // convert the negative index if (pos < 0) { pos = 0; } } if (pos > qsize) { pos = qsize; } std::advance(insertIt, pos); } else { // treat param0 as a command tag const unsigned int tag = (unsigned int)c.params[0]; CCommandQueue::iterator ci; bool found = false; for (ci = queue->begin(); ci != queue->end(); ++ci) { const Command& qc = *ci; if (qc.tag == tag) { insertIt = ci; found = true; break; } } if (!found) { return; } if ((c.options & RIGHT_MOUSE_KEY) && (insertIt != queue->end())) { insertIt++; // insert after the tagged command } } if (facBuildQueue) { facCAI->InsertBuildCommand(insertIt, newCmd); if (!owner->stunned) { SlowUpdate(); } return; } // shutdown the current order if the insertion is at the beginning if (!queue->empty() && (insertIt == queue->begin())) { inCommand = false; targetDied = false; unimportantMove = false; orderTarget = NULL; const Command& cmd = commandQue.front(); eoh->CommandFinished(*owner, cmd); eventHandler.UnitCmdDone(owner, cmd.id, cmd.tag); } queue->insert(insertIt, newCmd); if (!owner->stunned) { SlowUpdate(); } return; }