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) {
				PUSH_CODE_MODE
				ENTER_MIXED
				if (player == gu->myPlayerNum) {
					waitCommandsAI.AcknowledgeCommand(c);
				}
				POP_CODE_MODE
			}
		}
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);
            }
        }
    }
}