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; }
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; }
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); }
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)); }
// 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); }
// 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); } } }
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; }
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; }
// 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; } }
// 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; }
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); } }