std::string CSelectedUnits::GetTooltip(void)
{
	std::string s;
	if(selectedGroup!=-1 && grouphandler->groups[selectedGroup]->ai){
		s="Group selected";
	} else if(!selectedUnits.empty()){
		// show the player name instead of unit name if it has FBI tag showPlayerName
		if((*selectedUnits.begin())->unitDef->showPlayerName)
		{
			s=gs->players[gs->Team((*selectedUnits.begin())->team)->leader]->playerName.c_str();
		} else {
			s=(*selectedUnits.begin())->tooltip;
		}
	}
	if(selectedUnits.empty()){
		return s;
	}
	char tmp[500];
	float maxHealth=0,curHealth=0,cost=0,exp=0,range=0,metalMake=0,metalUse=0,energyMake=0,energyUse=0,maxfuel=0,curfuel=0,numfuel=0;
	for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
		maxHealth+=(*ui)->maxHealth;
		curHealth+=(*ui)->health;
		exp+=(*ui)->experience;
		cost+=(*ui)->metalCost+(*ui)->energyCost/60;
		range+=(*ui)->maxRange;
		metalMake+=(*ui)->metalMake;
		metalUse+=(*ui)->metalUse;
		energyMake+=(*ui)->energyMake;
		energyUse+=(*ui)->energyUse;
		maxfuel+=(*ui)->unitDef->maxFuel;
		curfuel+=(*ui)->currentFuel;
		if((*ui)->unitDef->maxFuel > 0)
			numfuel++;
	}
	float num=selectedUnits.size();
	sprintf(tmp,"\nHealth %.0f/%.0f",curHealth,maxHealth);
	s+=tmp;

	if(maxfuel>0){
		sprintf(tmp," Fuel %.0f/%.0f",curfuel/numfuel,maxfuel/numfuel);
		s+=tmp;
	}

	sprintf(tmp,"\nExperience %.2f Cost %.0f Range %.0f \n\xff\xd3\xdb\xffMetal: \xff\x50\xff\x50%.1f\xff\x90\x90\x90/\xff\xff\x50\x01-%.1f\xff\xd3\xdb\xff Energy: \xff\x50\xff\x50%.1f\xff\x90\x90\x90/\xff\xff\x50\x01-%.1f",
	        exp/num,cost,range/num, metalMake, metalUse, energyMake, energyUse);
	s += tmp;
	
  if (gs->cheatEnabled && (selectedUnits.size() == 1)) {
  	CUnit* unit = *selectedUnits.begin();
    SNPRINTF(tmp, sizeof(tmp), "\xff\xc0\xc0\xff  [TechLevel %i]",
             unit->unitDef->techLevel);
    s += tmp;
	}

	return s;
}
void CSelectedUnits::Draw()
{
	glDisable(GL_DEPTH_TEST );
	//glEnable(GL_BLEND);
	//glColor4f(0,0.8f,0,0.4f);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glColor3f(0,1.0f,0);
	set<CUnit*>::iterator ui;
	glBegin(GL_QUADS);
	if(selectedGroup!=-1){
		for(ui=grouphandler->groups[selectedGroup]->units.begin();ui!=grouphandler->groups[selectedGroup]->units.end();++ui){
			float3 pos((*ui)->pos+(*ui)->speed*gu->timeOffset);
			glVertexf3(pos+float3((*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,-(*ui)->ysize*4));
			glVertexf3(pos+float3((*ui)->xsize*4,0,-(*ui)->ysize*4));
		}
	} else {
		for(ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			float3 pos((*ui)->pos+(*ui)->speed*gu->timeOffset);
			glVertexf3(pos+float3((*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,-(*ui)->ysize*4));
			glVertexf3(pos+float3((*ui)->xsize*4,0,-(*ui)->ysize*4));
		}
	}
	glEnd();
	glEnable(GL_DEPTH_TEST );
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	//glDisable(GL_BLEND);
}
void CSelectedUnits::DrawCommands(void)
{
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);

	lineDrawer.Configure(cmdColors.UseColorRestarts(),
	                     cmdColors.UseRestartColor(),
	                     cmdColors.restart,
	                     cmdColors.RestartAlpha());
	                     
	glBlendFunc((GLenum)cmdColors.QueuedBlendSrc(),
	            (GLenum)cmdColors.QueuedBlendDst());
	            
	glEnable(GL_BLEND);
	
	glLineWidth(cmdColors.QueuedLineWidth());

	set<CUnit*>::iterator ui;
	if(selectedGroup!=-1){
		for(ui=grouphandler->groups[selectedGroup]->units.begin();ui!=grouphandler->groups[selectedGroup]->units.end();++ui){
			(*ui)->commandAI->DrawCommands();
		}
	} else {
		for(ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			(*ui)->commandAI->DrawCommands();
		}
	}

	glLineWidth(1.0f);

	glEnable(GL_DEPTH_TEST);
}
void CSelectedUnits::SetCommandPage(int page)
{
	if(selectedGroup!=-1 && grouphandler->groups[selectedGroup]->ai){
		grouphandler->groups[selectedGroup]->lastCommandPage=page;
	}
	if(!selectedUnits.empty())
		(*selectedUnits.begin())->commandAI->lastSelectedCommandPage=page;
}
Example #5
0
void CSelectedUnits::SetCommandPage(int page)
{
	GML_RECMUTEX_LOCK(sel); // SetCommandPage - called from CGame::Draw --> RunLayoutCommand --> LayoutIcons --> RevertToCmdDesc

	CUnitSet::iterator ui;
	for (ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		(*ui)->commandAI->lastSelectedCommandPage = page;
	}
}
void CSelectedUnits::SendSelection(void)
{
	// first, convert CUnit* to unit IDs.
	std::vector<short> selectedUnitIDs(selectedUnits.size());
	std::vector<short>::iterator i = selectedUnitIDs.begin();
	CUnitSet::const_iterator ui = selectedUnits.begin();
	for(; ui != selectedUnits.end(); ++i, ++ui) *i = (*ui)->id;
	net->Send(CBaseNetProtocol::Get().SendSelect(gu->myPlayerNum, selectedUnitIDs));
	selectionChanged=false;
}
void CSelectedUnits::SendSelection(void)
{
	// first, convert CUnit* to unit IDs.
	std::vector<short> selectedUnitIDs(selectedUnits.size());
	std::vector<short>::iterator i = selectedUnitIDs.begin();
	std::set<CUnit*>::const_iterator ui = selectedUnits.begin();
	for(; ui != selectedUnits.end(); ++i, ++ui) *i = (*ui)->id;
	net->SendSTLData<unsigned char, std::vector<short> >(NETMSG_SELECT, gu->myPlayerNum, selectedUnitIDs);
	selectionChanged=false;
}
void CSelectedUnits::SetCommandPage(int page)
{
	if(selectedGroup!=-1 && grouphandlers[gu->myTeam]->groups[selectedGroup]->ai){
		grouphandlers[gu->myTeam]->groups[selectedGroup]->lastCommandPage=page;
	}

	CUnitSet::iterator ui;
	for (ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		(*ui)->commandAI->lastSelectedCommandPage = page;
	}
}
void CSelectedUnits::ClearSelected()
{
	set<CUnit*>::iterator ui;
	ENTER_MIXED;
	for(ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
		(*ui)->commandAI->selected=false;
		DeleteDeathDependence(*ui);
	}
	ENTER_UNSYNCED;

	selectedUnits.clear();
	selectionChanged=true;
	possibleCommandsChanged=true;
	selectedGroup=-1;
}
Example #10
0
void CSelectedUnits::ClearSelected()
{
	GML_RECMUTEX_LOCK(sel); // ClearSelected

	CUnitSet::iterator ui;
	for(ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
		(*ui)->commandAI->selected=false;
		DeleteDeathDependence(*ui);
	}

	selectedUnits.clear();
	selectionChanged=true;
	possibleCommandsChanged=true;
	selectedGroup=-1;
}
void CSelectedUnits::DrawCommands(void)
{
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);
	set<CUnit*>::iterator ui;
	if(selectedGroup!=-1){
		for(ui=grouphandler->groups[selectedGroup]->units.begin();ui!=grouphandler->groups[selectedGroup]->units.end();++ui){
			(*ui)->commandAI->DrawCommands();
		}
	} else {
		for(ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			(*ui)->commandAI->DrawCommands();
		}
	}
	glEnable(GL_DEPTH_TEST);
}
Example #12
0
void CSelectedUnits::SendCommand(const Command& c)
{
	if (selectionChanged) {
		// send new selection
		GML_RECMUTEX_LOCK(sel); // SendSelection

		// first, convert CUnit* to unit IDs.
		std::vector<short> selectedUnitIDs(selectedUnits.size());
		std::vector<short>::iterator i = selectedUnitIDs.begin();
		CUnitSet::const_iterator ui = selectedUnits.begin();
		for(; ui != selectedUnits.end(); ++i, ++ui) {
			*i = (*ui)->id;
		}
		net->Send(CBaseNetProtocol::Get().SendSelect(gu->myPlayerNum, selectedUnitIDs));
		selectionChanged = false;
	}

	net->Send(CBaseNetProtocol::Get().SendCommand(gu->myPlayerNum, c.GetID(), c.options, c.params));
}
int CSelectedUnits::GetDefaultCmd(CUnit* unit, CFeature* feature)
{
	// NOTE: the unitDef->aihint value is being ignored
	int luaCmd;
	if (eventHandler.DefaultCommand(unit, feature, luaCmd)) {
		return luaCmd;
	}

	if ((selectedGroup != -1) && grouphandlers[gu->myTeam]->groups[selectedGroup]->ai) {
		return grouphandlers[gu->myTeam]->groups[selectedGroup]->GetDefaultCmd(unit, feature);
	}

	// return the default if there are no units selected
	CUnitSet::const_iterator ui = selectedUnits.begin();
	if (ui == selectedUnits.end()) {
		return CMD_STOP;
	}

	// setup the locals for IsBetterLeader()
	targetUnit = unit;
	targetFeature = feature;
	if (targetUnit) {
		targetIsEnemy = !gs->Ally(gu->myAllyTeam, targetUnit->allyteam);
	}

	// find the best leader to pick the command
	const CUnit* leaderUnit = *ui;
	const UnitDef* leaderDef = leaderUnit->unitDef;
	for (++ui; ui != selectedUnits.end(); ++ui) {
		const CUnit* testUnit = *ui;
		const UnitDef* testDef = testUnit->unitDef;
		if (testDef != leaderDef) {
			if (IsBetterLeader(testDef, leaderDef)) {
				leaderDef = testDef;
				leaderUnit = testUnit;
			}
		}
	}

	return (leaderUnit->commandAI->GetDefaultCmd(unit, feature));
}
Example #14
0
// CALLINFO:
// CGame::Draw --> DrawCommands
// CMiniMap::DrawForReal --> DrawCommands
void CSelectedUnits::DrawCommands()
{
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);

	lineDrawer.Configure(cmdColors.UseColorRestarts(),
	                     cmdColors.UseRestartColor(),
	                     cmdColors.restart,
	                     cmdColors.RestartAlpha());
	lineDrawer.SetupLineStipple();

	glEnable(GL_BLEND);
	glBlendFunc((GLenum)cmdColors.QueuedBlendSrc(),
	            (GLenum)cmdColors.QueuedBlendDst());

	glLineWidth(cmdColors.QueuedLineWidth());

	GML_RECMUTEX_LOCK(sel); // DrawCommands
	GML_RECMUTEX_LOCK(group); // DrawCommands
	GML_STDMUTEX_LOCK(cai); // DrawCommands

	CUnitSet::iterator ui;
	if (selectedGroup != -1) {
		CUnitSet& groupUnits = grouphandlers[gu->myTeam]->groups[selectedGroup]->units;
		for(ui = groupUnits.begin(); ui != groupUnits.end(); ++ui) {
			(*ui)->commandAI->DrawCommands();
		}
	} else {
		for(ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
			(*ui)->commandAI->DrawCommands();
		}
	}

	// draw the commands from AIs
	grouphandlers[gu->myTeam]->DrawCommands();
	waitCommandsAI.DrawCommands();

	glLineWidth(1.0f);

	glEnable(GL_DEPTH_TEST);
}
int CSelectedUnits::GetDefaultCmd(CUnit *unit,CFeature* feature)
{
	if(selectedGroup!=-1 && grouphandler->groups[selectedGroup]->ai){
		return grouphandler->groups[selectedGroup]->GetDefaultCmd(unit,feature);
	}
	int cmd=CMD_STOP;
	int lowestHint=10000;//find better way to decide
	CUnit* selected=0;
	int i = 0;
	for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
		if((!(*ui)->immobile || (i==selectedUnits.size() - 1 && lowestHint == 10000)) && (*ui)->aihint<lowestHint)
		{
			selected=*ui;
			lowestHint=(*ui)->aihint;
		}
		i++;
	} 	
	if(selected)
		cmd=selected->commandAI->GetDefaultCmd(unit,feature);
	return cmd;
}
void CSelectedUnits::Draw()
{
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND); // for line smoothing
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glLineWidth(cmdColors.UnitBoxLineWidth());

	glColor4fv(cmdColors.unitBox);

	glBegin(GL_QUADS);
	set<CUnit*>::iterator ui;
	if(selectedGroup!=-1){
		for(ui=grouphandler->groups[selectedGroup]->units.begin();ui!=grouphandler->groups[selectedGroup]->units.end();++ui){
			if((*ui)->isIcon)
				continue;
			float3 pos((*ui)->pos+(*ui)->speed*gu->timeOffset);
			glVertexf3(pos+float3((*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,-(*ui)->ysize*4));
			glVertexf3(pos+float3((*ui)->xsize*4,0,-(*ui)->ysize*4));
		}
	} else {
		for(ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->isIcon)
				continue;
			float3 pos((*ui)->pos+(*ui)->speed*gu->timeOffset);
			glVertexf3(pos+float3((*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,(*ui)->ysize*4));
			glVertexf3(pos+float3(-(*ui)->xsize*4,0,-(*ui)->ysize*4));
			glVertexf3(pos+float3((*ui)->xsize*4,0,-(*ui)->ysize*4));
		}
	}
	glEnd();
	
	glLineWidth(1.0f);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
}
Example #17
0
// CALLINFO:
// DrawMapStuff --> CGuiHandler::GetDefaultCommand --> GetDefaultCmd
// CMouseHandler::DrawCursor --> DrawCentroidCursor --> CGuiHandler::GetDefaultCommand --> GetDefaultCmd
// LuaUnsyncedRead::GetDefaultCommand --> CGuiHandler::GetDefaultCommand --> GetDefaultCmd
int CSelectedUnits::GetDefaultCmd(const CUnit* unit, const CFeature* feature)
{
	int luaCmd;
	if (eventHandler.DefaultCommand(unit, feature, luaCmd)) {
		return luaCmd;
	}

	GML_RECMUTEX_LOCK(sel); // GetDefaultCmd

	// return the default if there are no units selected
	CUnitSet::const_iterator ui = selectedUnits.begin();
	if (ui == selectedUnits.end()) {
		return CMD_STOP;
	}

	// setup the locals for IsBetterLeader()
	targetUnit = unit;
	targetFeature = feature;
	if (targetUnit) {
		targetIsEnemy = !teamHandler->Ally(gu->myAllyTeam, targetUnit->allyteam);
	}

	// find the best leader to pick the command
	const CUnit* leaderUnit = *ui;
	const UnitDef* leaderDef = leaderUnit->unitDef;
	for (++ui; ui != selectedUnits.end(); ++ui) {
		const CUnit* testUnit = *ui;
		const UnitDef* testDef = testUnit->unitDef;
		if (testDef != leaderDef) {
			if (IsBetterLeader(testDef, leaderDef)) {
				leaderDef = testDef;
				leaderUnit = testUnit;
			}
		}
	}

	return (leaderUnit->commandAI->GetDefaultCmd(unit, feature));
}
void CSelectedUnits::GiveCommand(Command c, bool fromUser)
{
//	logOutput.Print("Command given %i",c.id);
	if ((gu->spectating && !gs->godMode) || selectedUnits.empty()) {
		return;
	}

	if (fromUser) {		//add some statistics
		gs->players[gu->myPlayerNum]->currentStats->numCommands++;
		if (selectedGroup!=-1) {
			gs->players[gu->myPlayerNum]->currentStats->unitCommands+=grouphandlers[gu->myTeam]->groups[selectedGroup]->units.size();
		} else {
			gs->players[gu->myPlayerNum]->currentStats->unitCommands+=selectedUnits.size();
		}
	}

	if (c.id == CMD_GROUPCLEAR) {
		for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->group){
				(*ui)->SetGroup(0);
				possibleCommandsChanged=true;
			}
		}
		return;
	}
	else if (c.id == CMD_GROUPSELECT) {
		SelectGroup((*selectedUnits.begin())->group->id);
		return;
	}
	else if (c.id == CMD_GROUPADD) {
		CGroup* group=0;
		for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->group){
				group=(*ui)->group;
				possibleCommandsChanged=true;
				break;
			}
		}
		if(group){
			for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
				if(!(*ui)->group)
					(*ui)->SetGroup(group);
			}
			SelectGroup(group->id);
		}
		return;
	}
	else if (c.id == CMD_AISELECT) {
		if (gs->noHelperAIs) {
			logOutput.Print("GroupAI and LuaUI control is disabled");
			return;
		}
		if(c.params[0]!=0){
			map<AIKey,string>::iterator aai;
			int a=0;
			for(aai=grouphandlers[gu->myTeam]->lastSuitedAis.begin();aai!=grouphandlers[gu->myTeam]->lastSuitedAis.end() && a<c.params[0]-1;++aai){
				a++;
			}
			CGroup* group=grouphandlers[gu->myTeam]->CreateNewGroup(aai->first);

			for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
				(*ui)->SetGroup(group);
			}
			SelectGroup(group->id);
		}
		return;
	}
	else if (c.id == CMD_TIMEWAIT) {
		waitCommandsAI.AddTimeWait(c);
		return;
	}
	else if (c.id == CMD_DEATHWAIT) {
		if (gs->activeAllyTeams <= 2) {
			waitCommandsAI.AddDeathWait(c);
		} else {
			logOutput.Print("DeathWait can only be used when there are 2 Ally Teams");
		}
		return;
	}
	else if (c.id == CMD_SQUADWAIT) {
		waitCommandsAI.AddSquadWait(c);
		return;
	}
	else if (c.id == CMD_GATHERWAIT) {
		waitCommandsAI.AddGatherWait(c);
		return;
	}

//	FIXME:  selectedUnitsAI.GiveCommand(c);

	if ((selectedGroup != -1) && grouphandlers[gu->myTeam]->groups[selectedGroup]->ai) {
		grouphandlers[gu->myTeam]->groups[selectedGroup]->GiveCommand(c);
		return;
	}

	SendCommand(c);

	if (!selectedUnits.empty()) {
		CUnitSet::iterator ui = selectedUnits.begin();

		int soundIdx = (*ui)->unitDef->sounds.ok.getRandomIdx();
		if (soundIdx >= 0) {
			sound->PlayUnitReply(
				(*ui)->unitDef->sounds.ok.getID(soundIdx), (*ui),
				(*ui)->unitDef->sounds.ok.getVolume(soundIdx), true);
		}
	}
}
Example #19
0
void CSelectedUnits::GiveCommand(Command c, bool fromUser)
{
	GML_RECMUTEX_LOCK(sel); // GiveCommand
	GML_RECMUTEX_LOCK(group); // GiveCommand

//	logOutput.Print("Command given %i",c.id);
	if ((gu->spectating && !gs->godMode) || selectedUnits.empty()) {
		return;
	}

	if (fromUser) {		//add some statistics
		playerHandler->Player(gu->myPlayerNum)->currentStats.numCommands++;
		if (selectedGroup!=-1) {
			playerHandler->Player(gu->myPlayerNum)->currentStats.unitCommands+=grouphandlers[gu->myTeam]->groups[selectedGroup]->units.size();
		} else {
			playerHandler->Player(gu->myPlayerNum)->currentStats.unitCommands+=selectedUnits.size();
		}
	}

	if (c.id == CMD_GROUPCLEAR) {
		for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->group){
				(*ui)->SetGroup(0);
				possibleCommandsChanged=true;
			}
		}
		return;
	}
	else if (c.id == CMD_GROUPSELECT) {
		SelectGroup((*selectedUnits.begin())->group->id);
		return;
	}
	else if (c.id == CMD_GROUPADD) {
		CGroup* group=0;
		for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->group){
				group=(*ui)->group;
				possibleCommandsChanged=true;
				break;
			}
		}
		if(group){
			for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
				if(!(*ui)->group)
					(*ui)->SetGroup(group);
			}
			SelectGroup(group->id);
		}
		return;
	}
	else if (c.id == CMD_AISELECT) {
		if (gs->noHelperAIs) {
			logOutput.Print("LuaUI control is disabled");
			return;
		}
		if(c.params[0]!=0){
			CGroup* group=grouphandlers[gu->myTeam]->CreateNewGroup();

			for(CUnitSet::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
				(*ui)->SetGroup(group);
			}
			SelectGroup(group->id);
		}
		return;
	}
	else if (c.id == CMD_TIMEWAIT) {
		waitCommandsAI.AddTimeWait(c);
		return;
	}
	else if (c.id == CMD_DEATHWAIT) {
		if (teamHandler->ActiveAllyTeams() <= 2) {
			waitCommandsAI.AddDeathWait(c);
		} else {
			logOutput.Print("DeathWait can only be used when there are 2 Ally Teams");
		}
		return;
	}
	else if (c.id == CMD_SQUADWAIT) {
		waitCommandsAI.AddSquadWait(c);
		return;
	}
	else if (c.id == CMD_GATHERWAIT) {
		waitCommandsAI.AddGatherWait(c);
		return;
	}

	SendCommand(c);

	if (!selectedUnits.empty()) {
		CUnitSet::iterator ui = selectedUnits.begin();

		int soundIdx = (*ui)->unitDef->sounds.ok.getRandomIdx();
		if (soundIdx >= 0) {
			Channels::UnitReply.PlaySample(
				(*ui)->unitDef->sounds.ok.getID(soundIdx), (*ui),
				(*ui)->unitDef->sounds.ok.getVolume(soundIdx));
		}
	}
}
CSelectedUnits::AvailableCommandsStruct CSelectedUnits::GetAvailableCommands()
{
	possibleCommandsChanged = false;

	if (selectedGroup != -1 && grouphandlers[gu->myTeam]->groups[selectedGroup]->ai) {
		AvailableCommandsStruct ac;
		ac.commandPage = grouphandlers[gu->myTeam]->groups[selectedGroup]->lastCommandPage;
		ac.commands = grouphandlers[gu->myTeam]->groups[selectedGroup]->GetPossibleCommands();

		CommandDescription c;			//make sure we can clear the group even when selected
		c.id      = CMD_GROUPCLEAR;
		c.action  = "groupclear";
		c.type    = CMDTYPE_ICON;
		c.name    = "Clear group";
		c.tooltip = "Removes the units from any group they belong to";
		ac.commands.push_back(c);

		return ac;
	}

	int commandPage = 1000;
	int foundGroup = -2;
	int foundGroup2 = -2;
	map<int, int> states;

	for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		vector<CommandDescription>* c = &(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for (ci = c->begin(); ci != c->end(); ++ci) {
			states[ci->id] = ci->disabled ? 2 : 1;
		}
		if ((*ui)->commandAI->lastSelectedCommandPage < commandPage) {
			commandPage = (*ui)->commandAI->lastSelectedCommandPage;
		}

		if (foundGroup == -2 && (*ui)->group) {
			foundGroup = (*ui)->group->id;
		}
		if (!(*ui)->group || foundGroup!=(*ui)->group->id) {
			foundGroup = -1;
		}

		if (foundGroup2 == -2 && (*ui)->group) {
			foundGroup2 = (*ui)->group->id;
		}
		if (foundGroup2 >= 0 && (*ui)->group && (*ui)->group->id != foundGroup2) {
			foundGroup2 = -1;
		}
	}

	vector<CommandDescription> groupCommands;
	if (!gs->noHelperAIs) {
		//create a new group
		if (foundGroup != -2) {
			map<AIKey, string>::iterator aai;
			map<AIKey, string> suitedAis = grouphandlers[gu->myTeam]->GetSuitedAis(selectedUnits);
			if (suitedAis.size() >= 2) { // default doesn't count
				CommandDescription c;
				c.id      = CMD_AISELECT;
				c.action  = "aiselect";
				c.type    = CMDTYPE_COMBO_BOX;
				c.name    = "Select AI";
				c.tooltip = "Create a new group using the selected units and with the ai selected";

				c.params.push_back("0");
				c.params.push_back("None");
				for (aai = suitedAis.begin(); aai != suitedAis.end(); ++aai) {
					c.params.push_back((aai->second).c_str());
				}
				groupCommands.push_back(c);
			}
		}

		// add the selected units to a previous group (that at least one unit is also selected from)
		if ((foundGroup < 0) && (foundGroup2 >= 0)) {
			CommandDescription c;
			c.id      = CMD_GROUPADD;
			c.action  = "groupadd";
			c.type    = CMDTYPE_ICON;
			c.name    = "Add to group";
			c.tooltip = "Adds the selected to an existing group (of which one or more units is already selected)";
			groupCommands.push_back(c);
		}

		// select the group to which the units belong
		if (foundGroup >= 0) {
			CommandDescription c;

			c.id      = CMD_GROUPSELECT;
			c.action  = "groupselect";
			c.type    = CMDTYPE_ICON;
			c.name    = "Select group";
			c.tooltip = "Select the group that these units belong to";
			groupCommands.push_back(c);
		}

		// remove all selected units from any groups they belong to
		if (foundGroup2 != -2) {
			CommandDescription c;

			c.id      = CMD_GROUPCLEAR;
			c.action  = "groupclear";
			c.type    = CMDTYPE_ICON;
			c.name    = "Clear group";
			c.tooltip = "Removes the units from any group they belong to";
			groupCommands.push_back(c);
		}
	} // end if (!gs->noHelperAIs)

	vector<CommandDescription> commands ;
	// load the first set  (separating build and non-build commands)
	for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		vector<CommandDescription>* c = &(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for (ci = c->begin(); ci != c->end(); ++ci) {
			if (buildIconsFirst) {
				if (ci->id >= 0) { continue; }
			} else {
				if (ci->id < 0)  { continue; }
			}
			if (ci->showUnique && selectedUnits.size() > 1) {
				continue;
			}
			if (states[ci->id] > 0) {
				commands.push_back(*ci);
				states[ci->id] = 0;
			}
		}
	}

	if (!buildIconsFirst && !gs->noHelperAIs) {
		vector<CommandDescription>::iterator ci;
		for(ci = groupCommands.begin(); ci != groupCommands.end(); ++ci) {
			commands.push_back(*ci);
		}
	}

	// load the second set  (all those that have not already been included)
	for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		vector<CommandDescription>* c = &(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for (ci = c->begin(); ci != c->end(); ++ci) {
			if (buildIconsFirst) {
				if (ci->id < 0)  { continue; }
			} else {
				if (ci->id >= 0) { continue; }
			}
			if (ci->showUnique && selectedUnits.size() > 1) {
				continue;
			}
			if (states[ci->id] > 0) {
				commands.push_back(*ci);
				states[ci->id] = 0;
			}
		}
	}
	if (buildIconsFirst && !gs->noHelperAIs) {
		vector<CommandDescription>::iterator ci;
		for (ci = groupCommands.begin(); ci != groupCommands.end(); ++ci) {
			commands.push_back(*ci);
		}
	}

	AvailableCommandsStruct ac;
	ac.commandPage = commandPage;
	ac.commands = commands;
	return ac;
}
Example #21
0
void CSelectedUnits::GiveCommand(Command c, bool fromUser)
{
	GML_RECMUTEX_LOCK(grpsel); // GiveCommand

//	LOG_L(L_DEBUG, "Command given %i", c.id);
	if ((gu->spectating && !gs->godMode) || selectedUnits.empty()) {
		return;
	}

	const int& cmd_id = c.GetID();

	if (fromUser) { // add some statistics
		playerHandler->Player(gu->myPlayerNum)->currentStats.numCommands++;
		if (selectedGroup != -1) {
			playerHandler->Player(gu->myPlayerNum)->currentStats.unitCommands += grouphandlers[gu->myTeam]->groups[selectedGroup]->units.size();
		} else {
			playerHandler->Player(gu->myPlayerNum)->currentStats.unitCommands += selectedUnits.size();
		}
	}

	if (cmd_id == CMD_GROUPCLEAR) {
		for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
			if ((*ui)->group) {
				(*ui)->SetGroup(0);
				possibleCommandsChanged = true;
			}
		}
		return;
	}
	else if (cmd_id == CMD_GROUPSELECT) {
		SelectGroup((*selectedUnits.begin())->group->id);
		return;
	}
	else if (cmd_id == CMD_GROUPADD) {
		CGroup* group = NULL;
		for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
			if ((*ui)->group) {
				group = (*ui)->group;
				possibleCommandsChanged = true;
				break;
			}
		}
		if (group) {
			for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
				if (!(*ui)->group) {
					(*ui)->SetGroup(group);
				}
			}
			SelectGroup(group->id);
		}
		return;
	}
	else if (cmd_id == CMD_TIMEWAIT) {
		waitCommandsAI.AddTimeWait(c);
		return;
	}
	else if (cmd_id == CMD_DEATHWAIT) {
		waitCommandsAI.AddDeathWait(c);
		return;
	}
	else if (cmd_id == CMD_SQUADWAIT) {
		waitCommandsAI.AddSquadWait(c);
		return;
	}
	else if (cmd_id == CMD_GATHERWAIT) {
		waitCommandsAI.AddGatherWait(c);
		return;
	}

	SendCommand(c);

	#if (PLAY_SOUNDS == 1)
	if (!selectedUnits.empty()) {
		CUnitSet::const_iterator ui = selectedUnits.begin();

		const int soundIdx = (*ui)->unitDef->sounds.ok.getRandomIdx();
		if (soundIdx >= 0) {
			Channels::UnitReply.PlaySample(
				(*ui)->unitDef->sounds.ok.getID(soundIdx), (*ui),
				(*ui)->unitDef->sounds.ok.getVolume(soundIdx));
		}
	}
	#endif
}
CSelectedUnits::AvailableCommandsStruct CSelectedUnits::GetAvailableCommands()
{
	possibleCommandsChanged=false;

	if(selectedGroup!=-1 && grouphandler->groups[selectedGroup]->ai){
		AvailableCommandsStruct ac;
		ac.commandPage=grouphandler->groups[selectedGroup]->lastCommandPage;
		ac.commands=grouphandler->groups[selectedGroup]->GetPossibleCommands();

		CommandDescription c;			//make sure we can clear the group even when selected
		c.id=CMD_GROUPCLEAR;
		c.action="groupclear";
		c.type=CMDTYPE_ICON;
		c.name="Clear group";
		c.tooltip="Removes the units from any group they belong to";
		c.hotkey="Shift+q";
		ac.commands.push_back(c);

		return ac;
	}

	int commandPage=1000;
	int foundGroup=-2;
	int foundGroup2=-2;
	map<int,int> count;

	for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
		vector<CommandDescription>* c=&(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for(ci=c->begin();ci!=c->end();++ci)
			count[ci->id]=1;
		if((*ui)->commandAI->lastSelectedCommandPage<commandPage)
			commandPage=(*ui)->commandAI->lastSelectedCommandPage;

		if(foundGroup==-2 && (*ui)->group)
			foundGroup=(*ui)->group->id;
		if(!(*ui)->group || foundGroup!=(*ui)->group->id)
			foundGroup=-1;

		if(foundGroup2==-2 && (*ui)->group)
			foundGroup2=(*ui)->group->id;
		if(foundGroup2>=0 && (*ui)->group && (*ui)->group->id!=foundGroup2)
			foundGroup2=-1;
	}

	vector<CommandDescription> commands ;
	for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
		vector<CommandDescription>* c=&(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for(ci=c->begin();ci!=c->end();++ci){
			if(ci->showUnique && selectedUnits.size()>1)
				continue;
			if(count[ci->id]>0){
				commands.push_back(*ci);
				count[ci->id]=0;
			}
		}
	}

	if(foundGroup!=-2){			//create a new group
		CommandDescription c;
		c.id=CMD_AISELECT;
		c.action="aiselect";
		c.type=CMDTYPE_COMBO_BOX;
		c.name="Select AI";
		c.tooltip="Create a new group using the selected units and with the ai selected";
		c.hotkey="Ctrl+q";

		c.params.push_back("0");
		c.params.push_back("None");
		map<string,string>::iterator aai;
		for(aai=grouphandler->availableAI.begin();aai!=grouphandler->availableAI.end();++aai){
			c.params.push_back(aai->second.c_str());
		}
		commands.push_back(c);
	}

	if(foundGroup<0 && foundGroup2>=0){			//add the selected units to a previous group (that at least one unit is also selected from)
		CommandDescription c;
		c.id=CMD_GROUPADD;
		c.action="groupadd";
		c.type=CMDTYPE_ICON;
		c.name="Add to group";
		c.tooltip="Adds the selected to an existing group (of which one or more units is already selected)";
		c.hotkey="q";
		commands.push_back(c);
	}

	if(foundGroup>=0){				//select the group to which the units belong
		CommandDescription c;

		c.id=CMD_GROUPSELECT;
		c.action="groupselect";
		c.type=CMDTYPE_ICON;
		c.name="Select group";
		c.tooltip="Select the group that these units belong to";
		c.hotkey="q";
		commands.push_back(c);
	}

	if(foundGroup2!=-2){				//remove all selected units from any groups they belong to
		CommandDescription c;

		c.id=CMD_GROUPCLEAR;
		c.action="groupclear";
		c.type=CMDTYPE_ICON;
		c.name="Clear group";
		c.tooltip="Removes the units from any group they belong to";
		c.hotkey="Shift+q";
		commands.push_back(c);
	}

	AvailableCommandsStruct ac;
	ac.commandPage=commandPage;
	ac.commands=commands;
	return ac;
}
Example #23
0
// CALLINFO:
// CTooltipConsole::Draw --> CMouseHandler::GetCurrentTooltip
// LuaUnsyncedRead::GetCurrentTooltip --> CMouseHandler::GetCurrentTooltip
// CMouseHandler::GetCurrentTooltip --> CMiniMap::GetToolTip --> GetTooltip
// CMouseHandler::GetCurrentTooltip --> GetTooltip
std::string CSelectedUnits::GetTooltip()
{
	std::string s = "";
	{
		GML_RECMUTEX_LOCK(sel); // GetTooltip - called from TooltipConsole::Draw --> MouseHandler::GetCurrentTooltip --> GetTooltip

		if (!selectedUnits.empty()) {
			const CUnit* unit = (*selectedUnits.begin());
			const CTeam* team = NULL;

			// show the player name instead of unit name if it has FBI tag showPlayerName
			if (unit->unitDef->showPlayerName) {
				team = teamHandler->Team(unit->team);
				s = team->GetControllerName();
			} else {
				s = (*selectedUnits.begin())->tooltip;
			}

		}

		if (selectedUnits.empty()) {
			return s;
		}
	}

	const string custom = eventHandler.WorldTooltip(NULL, NULL, NULL);
	if (!custom.empty()) {
		return custom;
	}

	{
		GML_RECMUTEX_LOCK(sel); // GetTooltip

		char tmp[500];
		int numFuel = 0;
		float maxHealth = 0.0f, curHealth = 0.0f;
		float maxFuel = 0.0f, curFuel = 0.0f;
		float exp = 0.0f, cost = 0.0f, range = 0.0f;
		float metalMake = 0.0f, metalUse = 0.0f, energyMake = 0.0f, energyUse = 0.0f;

#define NO_TEAM -32
#define MULTI_TEAM -64
		int ctrlTeam = NO_TEAM;

		CUnitSet::const_iterator ui;
		for (ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
			const CUnit* unit = *ui;
			maxHealth  += unit->maxHealth;
			curHealth  += unit->health;
			exp        += unit->experience;
			cost       += unit->metalCost + (unit->energyCost / 60.0f);
			range      += unit->maxRange;
			metalMake  += unit->metalMake;
			metalUse   += unit->metalUse;
			energyMake += unit->energyMake;
			energyUse  += unit->energyUse;
			maxFuel    += unit->unitDef->maxFuel;
			curFuel    += unit->currentFuel;
			if (unit->unitDef->maxFuel > 0) {
				numFuel++;
			}
			if (ctrlTeam == NO_TEAM) {
				ctrlTeam = unit->team;
			} else if (ctrlTeam != unit->team) {
				ctrlTeam = MULTI_TEAM;
			}
		}
		if ((numFuel > 0) && (maxFuel > 0.0f)) {
			curFuel = curFuel / numFuel;
			maxFuel = maxFuel / numFuel;
		}
		const float num = selectedUnits.size();

		s += CTooltipConsole::MakeUnitStatsString(
			curHealth, maxHealth,
			curFuel,   maxFuel,
			(exp / num), cost, (range / num),
			metalMake,  metalUse,
			energyMake, energyUse);

		if (gs->cheatEnabled && (num == 1)) {
			const CUnit* unit = *selectedUnits.begin();
			SNPRINTF(tmp, sizeof(tmp), "\xff\xc0\xc0\xff  [TechLevel %i]",
				unit->unitDef->techLevel);
			s += tmp;
		}

		std::string ctrlName = "";
		if (ctrlTeam == MULTI_TEAM) {
			ctrlName = "(Multiple teams)";
		} else if (ctrlTeam != NO_TEAM) {
			ctrlName = teamHandler->Team(ctrlTeam)->GetControllerName();
		}
		s += "\n\xff\xff\xff\xff" + ctrlName;

		return s;
	}
}
Example #24
0
// CALLINFO:
// CTooltipConsole::Draw --> CMouseHandler::GetCurrentTooltip
// LuaUnsyncedRead::GetCurrentTooltip --> CMouseHandler::GetCurrentTooltip
// CMouseHandler::GetCurrentTooltip --> CMiniMap::GetToolTip --> GetTooltip
// CMouseHandler::GetCurrentTooltip --> GetTooltip
std::string CSelectedUnits::GetTooltip(void)
{
	GML_RECMUTEX_LOCK(sel); // GetTooltip - called from TooltipConsole::Draw --> MouseHandler::GetCurrentTooltip --> GetTooltip
	GML_RECMUTEX_LOCK(group); // GetTooltip

	std::string s = "";
	if (!selectedUnits.empty()) {
		// show the player name instead of unit name if it has FBI tag showPlayerName
		if ((*selectedUnits.begin())->unitDef->showPlayerName) {
			if (teamHandler->Team((*selectedUnits.begin())->team)->leader >= 0)
				s = playerHandler->Player(teamHandler->Team((*selectedUnits.begin())->team)->leader)->name.c_str();
			else
				s = "Uncontrolled";
		} else {
			s = (*selectedUnits.begin())->tooltip;
		}
	}

	if (selectedUnits.empty()) {
		return s;
	}

	const string custom = eventHandler.WorldTooltip(NULL, NULL, NULL);
	if (!custom.empty()) {
		return custom;
	}

	char tmp[500];
	int numFuel = 0;
	float maxHealth = 0.0f, curHealth = 0.0f;
	float maxFuel = 0.0f, curFuel = 0.0f;
	float exp = 0.0f, cost = 0.0f, range = 0.0f;
	float metalMake = 0.0f, metalUse = 0.0f, energyMake = 0.0f, energyUse = 0.0f;

	CUnitSet::iterator ui;
	for (ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		const CUnit* unit = *ui;
		maxHealth  += unit->maxHealth;
		curHealth  += unit->health;
		exp        += unit->experience;
		cost       += unit->metalCost + (unit->energyCost / 60.0f);
		range      += unit->maxRange;
		metalMake  += unit->metalMake;
		metalUse   += unit->metalUse;
		energyMake += unit->energyMake;
		energyUse  += unit->energyUse;
		maxFuel    += unit->unitDef->maxFuel;
		curFuel    += unit->currentFuel;
		if (unit->unitDef->maxFuel > 0) {
			numFuel++;
		}
	}
	if ((numFuel > 0) && (maxFuel > 0.0f)) {
		curFuel = curFuel / numFuel;
		maxFuel = maxFuel / numFuel;
	}
	const float num = selectedUnits.size();

	s += CTooltipConsole::MakeUnitStatsString(
	       curHealth, maxHealth,
	       curFuel,   maxFuel,
	       (exp / num), cost, (range / num),
	       metalMake,  metalUse,
	       energyMake, energyUse);

  if (gs->cheatEnabled && (selectedUnits.size() == 1)) {
  	CUnit* unit = *selectedUnits.begin();
    SNPRINTF(tmp, sizeof(tmp), "\xff\xc0\xc0\xff  [TechLevel %i]",
             unit->unitDef->techLevel);
    s += tmp;
	}

	return s;
}
Example #25
0
CSelectedUnits::AvailableCommandsStruct CSelectedUnits::GetAvailableCommands()
{
	GML_RECMUTEX_LOCK(sel); // GetAvailableCommands
	GML_RECMUTEX_LOCK(group); // GetAvailableCommands

	possibleCommandsChanged = false;

	int commandPage = 1000;
	int foundGroup = -2;
	int foundGroup2 = -2;
	map<int, int> states;

	for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		vector<CommandDescription>* c = &(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for (ci = c->begin(); ci != c->end(); ++ci) {
			states[ci->id] = ci->disabled ? 2 : 1;
		}
		if ((*ui)->commandAI->lastSelectedCommandPage < commandPage) {
			commandPage = (*ui)->commandAI->lastSelectedCommandPage;
		}

		if (foundGroup == -2 && (*ui)->group) {
			foundGroup = (*ui)->group->id;
		}
		if (!(*ui)->group || foundGroup!=(*ui)->group->id) {
			foundGroup = -1;
		}

		if (foundGroup2 == -2 && (*ui)->group) {
			foundGroup2 = (*ui)->group->id;
		}
		if (foundGroup2 >= 0 && (*ui)->group && (*ui)->group->id != foundGroup2) {
			foundGroup2 = -1;
		}
	}

	vector<CommandDescription> groupCommands;

	vector<CommandDescription> commands ;
	// load the first set  (separating build and non-build commands)
	for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		vector<CommandDescription>* c = &(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for (ci = c->begin(); ci != c->end(); ++ci) {
			if (buildIconsFirst) {
				if (ci->id >= 0) { continue; }
			} else {
				if (ci->id < 0)  { continue; }
			}
			if (ci->showUnique && selectedUnits.size() > 1) {
				continue;
			}
			if (states[ci->id] > 0) {
				commands.push_back(*ci);
				states[ci->id] = 0;
			}
		}
	}

	if (!buildIconsFirst && !gs->noHelperAIs) {
		vector<CommandDescription>::iterator ci;
		for(ci = groupCommands.begin(); ci != groupCommands.end(); ++ci) {
			commands.push_back(*ci);
		}
	}

	// load the second set  (all those that have not already been included)
	for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
		vector<CommandDescription>* c = &(*ui)->commandAI->GetPossibleCommands();
		vector<CommandDescription>::iterator ci;
		for (ci = c->begin(); ci != c->end(); ++ci) {
			if (buildIconsFirst) {
				if (ci->id < 0)  { continue; }
			} else {
				if (ci->id >= 0) { continue; }
			}
			if (ci->showUnique && selectedUnits.size() > 1) {
				continue;
			}
			if (states[ci->id] > 0) {
				commands.push_back(*ci);
				states[ci->id] = 0;
			}
		}
	}
	if (buildIconsFirst && !gs->noHelperAIs) {
		vector<CommandDescription>::iterator ci;
		for (ci = groupCommands.begin(); ci != groupCommands.end(); ++ci) {
			commands.push_back(*ci);
		}
	}

	AvailableCommandsStruct ac;
	ac.commandPage = commandPage;
	ac.commands = commands;
	return ac;
}
void CSelectedUnits::GiveCommand(Command c,bool fromUser)
{
//	info->AddLine("Command given %i",c.id);
	if(gu->spectating || selectedUnits.empty())
		return;

	if(fromUser){		//add some statistics
		gs->players[gu->myPlayerNum]->currentStats->numCommands++;
		if(selectedGroup!=-1){
			gs->players[gu->myPlayerNum]->currentStats->unitCommands+=grouphandler->groups[selectedGroup]->units.size();
		} else {
			gs->players[gu->myPlayerNum]->currentStats->unitCommands+=selectedUnits.size();
		}
	}

	if(c.id==CMD_GROUPCLEAR){
		for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->group)
				(*ui)->SetGroup(0);
		}
		return;
	}

	if(selectedGroup!=-1 && (grouphandler->groups[selectedGroup]->ai || c.id==CMD_AISELECT)){
		grouphandler->groups[selectedGroup]->GiveCommand(c);
		return;
	}

	if(c.id==CMD_GROUPSELECT){
		SelectGroup((*selectedUnits.begin())->group->id);
		return;
	}

	if(c.id==CMD_GROUPADD){
		CGroup* group=0;
		for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
			if((*ui)->group){
				group=(*ui)->group;
				break;
			}
		}
		if(group){
			for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
				if(!(*ui)->group)
					(*ui)->SetGroup(group);
			}	
			SelectGroup(group->id);
		}
		return;
	}

	if(c.id==CMD_AISELECT){
		if(c.params[0]!=0){
			map<string,string>::iterator aai;
			int a=0;
			for(aai=grouphandler->availableAI.begin();aai!=grouphandler->availableAI.end() && a<c.params[0]-1;++aai){
				a++;
			}
			CGroup* group=grouphandler->CreateNewGroup(aai->first);

			for(set<CUnit*>::iterator ui=selectedUnits.begin();ui!=selectedUnits.end();++ui){
				(*ui)->SetGroup(group);
			}
			SelectGroup(group->id);
		}
		return;
	}
//	selectedUnitsAI.GiveCommand(c);

	SendCommand(c);

	if(!selectedUnits.empty()){
		set<CUnit*>::iterator ui = selectedUnits.begin();
		if((*ui)->unitDef->sounds.ok.id)
			sound->PlayUnitReply((*ui)->unitDef->sounds.ok.id, (*ui), (*ui)->unitDef->sounds.ok.volume, true);
	}
}