void CSelectedUnitsAI::GiveCommandNet(Command &c, int player) { const vector<int>& netSelected = selectedUnits.netSelected[player]; vector<int>::const_iterator ui; int nbrOfSelectedUnits = netSelected.size(); if (nbrOfSelectedUnits < 1) { // no units to command } else if ((c.id == CMD_ATTACK) && ((c.params.size() == 6) || ((c.params.size() == 4) && (c.params[3] > 0.001f)))) { SelectAttack(c, player); } else if (nbrOfSelectedUnits == 1) { // a single unit selected CUnit* unit = uh->units[*netSelected.begin()]; if(unit) { unit->commandAI->GiveCommand(c, false); if (MayRequireSetMaxSpeedCommand(c)) { AddUnitSetMaxSpeedCommand(unit, c.options); } if (c.id == CMD_WAIT) { if (player == gu->myPlayerNum) { waitCommandsAI.AcknowledgeCommand(c); } } } } // User Move Front Command: // // CTRL: Group Front/Speed command // // User Move Command: // // ALT: Group Front command // ALT+CTRL: Group Front/Speed command // CTRL: Group Locked/Speed command (maintain relative positions) // // User Patrol and Fight Commands: // // CTRL: Group Locked/Speed command (maintain relative positions) // ALT+CTRL: Group Locked command (maintain relative positions) // else if (((c.id == CMD_MOVE) || (c.id == CMD_FIGHT)) && (c.params.size() == 6)) { CalculateGroupData(player, !!(c.options & SHIFT_KEY)); MakeFrontMove(&c, player); const bool groupSpeed = !!(c.options & CONTROL_KEY); for(ui = netSelected.begin(); ui != netSelected.end(); ++ui) { CUnit* unit = uh->units[*ui]; if(unit) { if (groupSpeed) { AddGroupSetMaxSpeedCommand(unit, c.options); } else { AddUnitSetMaxSpeedCommand(unit, c.options); } } } } else if ((c.id == CMD_MOVE) && (c.options & ALT_KEY)) { CalculateGroupData(player, !!(c.options & SHIFT_KEY)); // use the vector from the middle of group to new pos as forward dir const float3 pos(c.params[0], c.params[1], c.params[2]); float3 frontdir = pos - centerCoor; frontdir.y = 0.0f; frontdir.ANormalize(); const float3 sideDir = frontdir.cross(UpVector); // calculate so that the units form in an aproximate square float length = 100.0f + (sqrt((float)nbrOfSelectedUnits) * 32.0f); // push back some extra params so it confer with a front move c.params.push_back(pos.x + (sideDir.x * length)); c.params.push_back(pos.y + (sideDir.y * length)); c.params.push_back(pos.z + (sideDir.z * length)); MakeFrontMove(&c, player); const bool groupSpeed = !!(c.options & CONTROL_KEY); for(ui = netSelected.begin(); ui != netSelected.end(); ++ui) { CUnit* unit = uh->units[*ui]; if(unit) { if (groupSpeed) { AddGroupSetMaxSpeedCommand(unit, c.options); } else { AddUnitSetMaxSpeedCommand(unit, c.options); } } } } else if ((c.options & CONTROL_KEY) && ((c.id == CMD_MOVE) || (c.id == CMD_PATROL) || (c.id == CMD_FIGHT))) { CalculateGroupData(player, !!(c.options & SHIFT_KEY)); const bool groupSpeed = !(c.options & ALT_KEY); for (ui = netSelected.begin(); ui != netSelected.end(); ++ui) { CUnit* unit = uh->units[*ui]; if (unit) { // Modifying the destination relative to the center of the group Command uc = c; float3 midPos; if (c.options & SHIFT_KEY) { midPos = LastQueuePosition(unit); } else { midPos = unit->midPos; } uc.params[CMDPARAM_MOVE_X] += midPos.x - centerCoor.x; uc.params[CMDPARAM_MOVE_Y] += midPos.y - centerCoor.y; uc.params[CMDPARAM_MOVE_Z] += midPos.z - centerCoor.z; unit->commandAI->GiveCommand(uc, false); if (groupSpeed) { AddGroupSetMaxSpeedCommand(unit, c.options); } else { AddUnitSetMaxSpeedCommand(unit, c.options); } } } } else { for (ui = netSelected.begin(); ui != netSelected.end(); ++ui) { CUnit* unit = uh->units[*ui]; if (unit) { // appending a CMD_SET_WANTED_MAX_SPEED command to // every command is a little bit wasteful, n'est pas? unit->commandAI->GiveCommand(c, false); if (MayRequireSetMaxSpeedCommand(c)) { AddUnitSetMaxSpeedCommand(unit, c.options); } } } if (c.id == CMD_WAIT) { if (player == gu->myPlayerNum) { waitCommandsAI.AcknowledgeCommand(c); } } } }
/* Group-AI. Processing commands given to selected group. */ void CSelectedUnitsAI::GiveCommandNet(Command &c,int player) { int nbrOfSelectedUnits = selectedUnits.netSelected[player].size(); if(nbrOfSelectedUnits < 1) //No units to command. return; if(nbrOfSelectedUnits == 1) { //Only one single unit selected. CUnit* unit=uh->units[*selectedUnits.netSelected[player].begin()]; if(unit) unit->commandAI->GiveCommand(c); return; } if(c.id==CMD_MOVE && c.params.size()==6){ MakeFrontMove(&c,player); } else if(c.id == CMD_MOVE && (c.options & ALT_KEY)) { CalculateGroupData(player); float3 pos(c.params[0],c.params[1],c.params[2]); float3 frontdir=pos-centerCoor; //use the vector from the middle of group to new pos as forward dir frontdir.y=0; frontdir.Normalize(); float3 sideDir=frontdir.cross(UpVector); float length=100+sqrtf(nbrOfSelectedUnits)*32; //calculate so that the units form in an aproximate square c.params.push_back(pos.x+sideDir.x*length); //push back some extra params so it confer with a front move c.params.push_back(pos.y+sideDir.y*length); c.params.push_back(pos.z+sideDir.z*length); MakeFrontMove(&c,player); } else if((c.id == CMD_MOVE || c.id == CMD_PATROL)&& (c.options & CONTROL_KEY)) { CalculateGroupData(player); for(vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit){ //Sets the wanted speed of this unit (and the group). Command uc; uc.id = CMD_SET_WANTED_MAX_SPEED; uc.options = c.options; if(c.options & ALT_KEY) //ALT overrides group-speed-setting. uc.params.push_back(unit->moveType->maxSpeed); else uc.params.push_back(minMaxSpeed); unit->commandAI->GiveCommand(uc); //Modifying the destination relative to the center of the group. uc = c; uc.params[CMDPARAM_MOVE_X] += unit->midPos.x - centerCoor.x; uc.params[CMDPARAM_MOVE_Y] += unit->midPos.y - centerCoor.y; uc.params[CMDPARAM_MOVE_Z] += unit->midPos.z - centerCoor.z; unit->commandAI->GiveCommand(uc); } } } else { 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); } } } }