📄 groupai.cpp
字号:
// GroupAI.cpp: implementation of the CGroupAI class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "GroupAI.h"
#include <stdarg.h>
#include "ExternalAI/IGroupAiCallback.h"
#include "ExternalAI/IAICallback.h"
#include "Sim/Units/UnitDef.h"
#include "Sim/Units/CommandAI/CommandQueue.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
namespace std{
void _xlen(){};
}
CGroupAI::CGroupAI()
{
CommandDescription cd;
unitsChanged=false;
nextBuildingId=1;
}
CGroupAI::~CGroupAI()
{
for(map<int,UnitInfo*>::iterator ui=myUnits.begin();ui!=myUnits.end();++ui)
delete ui->second;
myUnits.clear();
for(map<int,QuedBuilding*>::iterator qbi=quedBuildngs.begin();qbi!=quedBuildngs.end();++qbi)
delete qbi->second;
quedBuildngs.clear();
for(map<int,BuildOption*>::iterator boi=buildOptions.begin();boi!=buildOptions.end();++boi)
delete boi->second;
buildOptions.clear();
}
void CGroupAI::InitAi(IGroupAICallback* callback)
{
this->callback=callback;
aicb = callback->GetAICallback ();
UpdateAvailableCommands();
};
bool CGroupAI::AddUnit(int unit)
{
const UnitDef* ud=aicb->GetUnitDef(unit);
UnitInfo* info=new UnitInfo;
info->lastGivenOrder=0;
info->buildSpeed=ud->buildSpeed;
info->totalGuardSpeed=0;
info->moveSpeed=aicb->GetUnitSpeed(unit);
const vector<CommandDescription>* cd=aicb->GetUnitCommands(unit);
for(vector<CommandDescription>::const_iterator cdi=cd->begin();cdi!=cd->end();++cdi){ //check if this unit brings some new build options
if(cdi->id<0){ //id<0 = build option
info->possibleBuildOrders.insert(cdi->id);
info->orderedBuildOrders.push_back(cdi->id);
if(buildOptions.find(cdi->id)==buildOptions.end()){ //if we havent seen it before then add it
BuildOption* bo=new BuildOption;
bo->type=cdi->type;
bo->name=cdi->name;
bo->numQued=0;
const UnitDef* ud=aicb->GetUnitDef(bo->name.c_str());
bo->buildTime=ud->buildTime;
if(bo->buildTime==0){
char c[6000];
sprintf(c,"Zero build time unit? %f %s %s",ud->buildTime,ud->name.c_str(),bo->name.c_str());
aicb->SendTextMsg(c,0);
bo->buildTime=1;
}
buildOptions[cdi->id]=bo;
}
}
}
myUnits[unit]=info;
unitsChanged=true;
return true;
}
void CGroupAI::RemoveUnit(int unit)
{
UnitInfo* info=myUnits[unit];
if(info->lastGivenOrder){
if(info->lastGivenOrder>0){ //set to build something
QuedBuilding* qb=quedBuildngs[info->lastGivenOrder];
qb->unitsOnThis.erase(unit);
qb->totalBuildSpeed-=info->buildSpeed+info->totalGuardSpeed;
} else { //set to guard something
UnitInfo* guardInfo=myUnits[-info->lastGivenOrder];
guardInfo->unitsGuardingMe.erase(unit);
guardInfo->totalGuardSpeed-=info->buildSpeed;
}
}
for(std::set<int>::iterator gi=info->unitsGuardingMe.begin();gi!=info->unitsGuardingMe.end();++gi){
UnitInfo* guardInfo=myUnits[*gi];
guardInfo->lastGivenOrder=0;
}
info->unitsGuardingMe.clear();
delete myUnits[unit];
myUnits.erase(unit);
unitsChanged=true;
}
void CGroupAI::GiveCommand(Command* c)
{
if(c->id==CMD_STOP)
return;
for(std::vector<CommandDescription>::iterator cdi=commands.begin();cdi!=commands.end();++cdi){
if(cdi->id==c->id){
if(cdi->type==CMDTYPE_ICON){ //factory build unit
int prevNum=buildOptions[c->id]->numQued;
int numItems=1;
if(c->options& SHIFT_KEY)
numItems*=5;
if(c->options & CONTROL_KEY)
numItems*=20;
if(c->options & RIGHT_MOUSE_KEY){
buildOptions[c->id]->numQued=max(0,buildOptions[c->id]->numQued-numItems);
} else {
buildOptions[c->id]->numQued+=numItems;
}
UpdateFactoryIcon(&*cdi,buildOptions[c->id]->numQued);
callback->UpdateIcons();
} else { //built on map
float3 pos(c->params[0],c->params[1],c->params[2]);
int close=FindCloseQuedBuilding(pos,15);
if(close>=0){
QuedBuilding* qb=quedBuildngs[close];
if(!qb->unitsOnThis.empty()){
FinishBuilderTask(*qb->unitsOnThis.begin(),false);
}
delete qb;
quedBuildngs.erase(close);
return;
}
QuedBuilding* qb=new QuedBuilding;
qb->type=c->id;
qb->pos=pos;
qb->buildTimeLeft=buildOptions[c->id]->buildTime;
qb->totalBuildSpeed=0;
qb->failedTries=0;
qb->startFrame=frameNum;
quedBuildngs[nextBuildingId++]=qb;
}
}
}
}
void CGroupAI::CommandFinished(int unit,int type)
{
UnitInfo* info=myUnits[unit];
bool isFactory=info->moveSpeed==0;
if(isFactory){
for(std::set<int>::iterator gi=info->unitsGuardingMe.begin();gi!=info->unitsGuardingMe.end();++gi){
UnitInfo* guardInfo=myUnits[*gi];
guardInfo->lastGivenOrder=0;
}
info->unitsGuardingMe.clear();
info->totalGuardSpeed=0;
info->lastGivenOrder=0;
FindNewJob(unit);
} else {
if(info->lastGivenOrder>0 && type==quedBuildngs[info->lastGivenOrder]->type){
// aicb->SendTextMsg("Command finsihed for builder",0);
QuedBuilding* qb=quedBuildngs[info->lastGivenOrder];
qb->unitsOnThis.erase(unit);
qb->totalBuildSpeed-=info->buildSpeed+info->totalGuardSpeed;
bool found=false;
int foundUnits[1000];
int num=aicb->GetFriendlyUnits(foundUnits,qb->pos,10);
for(int a=0;a<num;++a){
const UnitDef* ud=aicb->GetUnitDef(foundUnits[a]);
if(ud->id==-qb->type){ //ok found the right unit
// aicb->SendTextMsg("Building finished ok",0);
delete qb;
quedBuildngs.erase(info->lastGivenOrder);
found=true;
break;
}
}
if(!found){
qb->failedTries++;
if(qb->failedTries>3){
aicb->SendTextMsg("Building failed",0);
delete qb;
quedBuildngs.erase(info->lastGivenOrder);
}
}
for(std::set<int>::iterator gi=info->unitsGuardingMe.begin();gi!=info->unitsGuardingMe.end();++gi){
UnitInfo* guardInfo=myUnits[*gi];
guardInfo->lastGivenOrder=0;
}
info->unitsGuardingMe.clear();
info->totalGuardSpeed=0;
info->lastGivenOrder=0;
FindNewJob(unit);
}
}
}
int CGroupAI::GetDefaultCmd(int unitid)
{
return CMD_STOP;
}
void CGroupAI::Update()
{
frameNum=aicb->GetCurrentFrame();
if(unitsChanged){
UpdateAvailableCommands();
updateUnit=myUnits.begin();
unitsChanged=false;
}
if(!myUnits.empty()){
FindNewJob(updateUnit->first);
++updateUnit;
if(updateUnit==myUnits.end())
updateUnit=myUnits.begin();
}
if(!(frameNum & 3) && callback->IsSelected()){
int team=aicb->GetMyTeam();
for(map<int,QuedBuilding*>::iterator qbi=quedBuildngs.begin();qbi!=quedBuildngs.end();++qbi){
aicb->DrawUnit(buildOptions[qbi->second->type]->name.c_str(),qbi->second->pos,0,4,team,true,true);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -