⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 groupai.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -