void CSelectedUnitsAI::MakeFrontMove(Command* c,int player) { float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(c->params[3],c->params[4],c->params[5]); if(centerPos.distance(rightPos)<selectedUnits.netSelected[player].size()+33){ //treat this as a standard move if the front isnt long enough for(vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit){ unit->commandAI->GiveCommand(*c); } } return; } float frontLength=centerPos.distance(rightPos)*2; sideDir=centerPos-rightPos; sideDir.y=0; sideDir.Normalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; int positionsUsed=0; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ MoveToPos(oi->second,centerPos,positionsUsed++,c->options); } }
void CGroupAI::MakeFormationMove(Command* c) { float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(centerPos); if(c->params.size()==6) rightPos=float3(c->params[3],c->params[4],c->params[5]); float frontLength=centerPos.distance(rightPos)*2; if(frontLength>80){ sideDir=centerPos-rightPos; sideDir.y=0; sideDir.Normalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); } int positionsUsed=0; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ MoveToPos(oi->second,centerPos,positionsUsed++,c->options); } }
void CSelectedUnitsAI::MakeFrontMove(Command* c,int player) { centerPos.x=c->params[0]; centerPos.y=c->params[1]; centerPos.z=c->params[2]; rightPos.x=c->params[3]; rightPos.y=c->params[4]; rightPos.z=c->params[5]; float3 nextPos(0.0f, 0.0f, 0.0f);//it's in "front" coordinates (rotated to real, moved by rightPos) if(centerPos.distance(rightPos)<selectedUnits.netSelected[player].size()+33) { //Strange line! treat this as a standard move if the front isnt long enough for(vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit) { unit->commandAI->GiveCommand(*c, false); } } return; } frontLength=centerPos.distance(rightPos)*2; addSpace = 0; if (frontLength > sumLength*2*8) { addSpace = (frontLength - sumLength*2*8)/(selectedUnits.netSelected[player].size() - 1); } sideDir=centerPos-rightPos; sideDir.y=0; float3 sd = sideDir; sd.y=frontLength/2; sideDir.ANormalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); for (std::multimap<float,int>::iterator oi=orderedUnits.begin(); oi!=orderedUnits.end(); ++oi) { nextPos = MoveToPos(oi->second, nextPos, sd, c); } }
void CGroupAI::Update() { if(callback->IsSelected()){ const Command* c=callback->GetOrderPreview(); if(c->id==CMD_MOVE && c->params.size()==6){ //draw a preview of how the units will be ordered float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(c->params[3],c->params[4],c->params[5]); float frontLength=centerPos.distance(rightPos)*2; if(frontLength>80){ float3 tempSideDir=centerPos-rightPos; tempSideDir.y=0; tempSideDir.Normalize(); float3 tempFrontDir=tempSideDir.cross(float3(0,1,0)); int tempNumColumns=(int)(frontLength/columnDist); int posNum=0; float rot=GetRotationFromVector(tempFrontDir); std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ int lineNum=posNum/tempNumColumns; int colNum=posNum-lineNum*tempNumColumns; float side=(0.25f+colNum*0.5f)*columnDist*(colNum&1 ? -1:1); float3 pos=centerPos-tempFrontDir*(float)lineNum*lineDist+tempSideDir*side; pos.y=aicb->GetElevation(pos.x,pos.z); const UnitDef* ud=aicb->GetUnitDef(oi->second); aicb->DrawUnit(ud->name.c_str(),pos,rot,1,aicb->GetMyTeam(),true,false); ++posNum; } } } } }
void CSelectedUnitsHandlerAI::MakeFrontMove(Command* c,int player) { centerPos.x=c->params[0]; centerPos.y=c->params[1]; centerPos.z=c->params[2]; rightPos.x=c->params[3]; rightPos.y=c->params[4]; rightPos.z=c->params[5]; // in "front" coordinates (rotated to real, moved by rightPos) float3 nextPos; if (centerPos.distance(rightPos)<selectedUnitsHandler.netSelected[player].size()+33) { // Strange line! treat this as a standard move if the front isnt long enough for (auto ui = selectedUnitsHandler.netSelected[player].begin(); ui != selectedUnitsHandler.netSelected[player].end(); ++ui) { CUnit* unit = unitHandler->GetUnit(*ui); if (unit != nullptr) unit->commandAI->GiveCommand(*c, false); } return; } frontLength=centerPos.distance(rightPos)*2; addSpace = 0; if (frontLength > sumLength*2*8) { addSpace = (frontLength - sumLength*2*8)/(selectedUnitsHandler.netSelected[player].size() - 1); } sideDir=centerPos-rightPos; sideDir.y=0; float3 sd = sideDir; sd.y=frontLength/2; sideDir.ANormalize(); frontDir=sideDir.cross(UpVector); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); std::multimap<float, std::vector<int> > sortUnits; std::vector<std::pair<int,Command> > frontcmds; for (std::multimap<float,int>::iterator oi = orderedUnits.begin(); oi != orderedUnits.end();){ bool newline; nextPos = MoveToPos(oi->second, nextPos, sd, c, &frontcmds, &newline); // mix units in each row to avoid weak flanks consisting solely of e.g. artillery units std::multimap<float, std::vector<int> >::iterator si = sortUnits.find(oi->first); if(si == sortUnits.end()) si = sortUnits.insert(std::pair<float, std::vector<int> >(oi->first, std::vector<int>())); si->second.push_back(oi->second); ++oi; if(oi != orderedUnits.end()) MoveToPos(oi->second, nextPos, sd, c, NULL, &newline); if(oi == orderedUnits.end() || newline) { std::vector<std::vector<int>*> sortUnitsVector; for (std::multimap<float, std::vector<int> >::iterator ui = sortUnits.begin(); ui!=sortUnits.end(); ++ui) { sortUnitsVector.push_back(&(*ui).second); } std::vector<int> randunits; int sz = sortUnitsVector.size(); std::vector<int> sortPos(sz, 0); for (std::vector<std::pair<int,Command> >::iterator fi = frontcmds.begin(); fi != frontcmds.end(); ++fi) { int bestpos = 0; float bestval = 1.0f; for (int i = 0; i < sz; ++i) { const int n = sortUnitsVector[i]->size(); const int k = sortPos[i]; if (k < n) { const float val = (0.5f + k) / (float)n; if (val < bestval) { bestval = val; bestpos = i; } } } int pos = sortPos[bestpos]; randunits.push_back((*sortUnitsVector[bestpos])[pos]); sortPos[bestpos] = pos + 1; } sortUnits.clear(); int i = 0; for (auto fi = frontcmds.begin(); fi != frontcmds.end(); ++fi) { unitHandler->GetUnit(randunits[i++])->commandAI->GiveCommand(fi->second, false); } frontcmds.clear(); } } }