예제 #1
0
void cCombatManager::UnitDamaged(const int& unitID, UnitInfo* U, const int& attackerID, EnemyInfo* A, float3& dir)
{
	ValidateEnemy(unitID,U,false);
	if( attackerID >= 0 && attackerID != U->enemyID )
	{
		float3 Pos = cb->GetUnitPos(unitID);
		float3 APos = GetEnemyPosition(attackerID,A);
		if( U->enemyID == -1 || Pos.distance(APos) < Pos.distance(GetEnemyPosition(U->enemyID,U->E)) )
			if( CanAttack(U, A, APos) != 0 && (U->group == 0 || U->group->Enemies.find(attackerID) != U->group->Enemies.end()) )
			{
				U->enemyID=attackerID;
				U->E = A;
				U->enemyEff = CanAttack(U, A, APos);
			}
	}
	if( U->inCombat )
	{
		if( U->ud->isCommander )
		{
			if( int(cb->GetCurrentUnitCommands(unitID)->size()) == 0 )
				UnitIdle(unitID,U);
			else if( cb->GetCurrentUnitCommands(unitID)->front().id != CMD_MOVE )
			{
				if( cb->GetUnitHealth(unitID)/U->ud->health <= 0.66 ||
					(cb->GetUnitHealth(unitID)/U->ud->health <= 0.9 && cb->GetCurrentUnitCommands(unitID)->front().id == CMD_CAPTURE) )
					UnitIdle(unitID,U);
			}
		}
		return;
	}
	if( U->BuildQ != 0 && U->BuildQ->RS != 0 )
		U->BuildQ->tryCount = 4; // If the project is destroyed too many times, give up on it
	U->inCombat=true;
	if( U->enemyID == -1 )
	{
		if( attackerID >= 0 )
		{
			float3 APos = GetEnemyPosition(attackerID,A);
			CommandRun(unitID,U,APos);
		}
		else
		{
			float3 EPos = cb->GetUnitPos(unitID);
			EPos.x += dir.x*700;
			EPos.z += dir.z*700;
			EPos.y = cb->GetElevation(EPos.x,EPos.z);
			CommandRun(unitID,U,EPos);
		}
	}
	else
		UnitIdle(unitID,U);
}
예제 #2
0
void cRAI::UnitFinished(int unit)
{
	if( RAIDEBUGGING ) *l<<"\nUnitFinished("<<unit<<")";
	if( Units.find(unit) == Units.end() ) // Occurs if a player canceled a build order with more than one quaried and something still finished
		UnitCreated(unit);

	UnitInfo* U = &Units.find(unit)->second;
	U->unitBeingBuilt = false;
	if( U->AIDisabled )
	{
		if( RAIDEBUGGING ) *l<<"#";
		return;
	}

	B->UnitFinished(unit,U);
	if( U->AIDisabled )
	{
		if( RAIDEBUGGING ) *l<<"#";
		return;
	}
	B->PM->UnitFinished(unit,U);
	SWM->UnitFinished(unit,U->udr);
	UM->UnitFinished(unit,U);
	if( U->ud->highTrajectoryType == 2 && rand()%4 == 0 )
	{	// Nothing too meanful, just a degree of randomness
		Command c;
		c.id = CMD_TRAJECTORY;
		c.params.push_back(1);
		cb->GiveOrder(unit,&c);
	}
	if( U->ud->speed == 0 )
		UnitIdle(unit);
		
	if( RAIDEBUGGING ) *l<<"#";
}
예제 #3
0
void CEngineOutHandler::UnitIdle(const CUnit& unit) {
	AI_EVT_MTH();

	const int teamId = unit.team;
	const int unitId = unit.id;

	DO_FOR_TEAM_SKIRMISH_AIS(UnitIdle(unitId), teamId);
}
예제 #4
0
void XAICUnitHandler::OnEvent(const XAIIEvent* e) {
	switch (e->type) {
		case XAI_EVENT_UNIT_CREATED: {
			UnitCreated(dynamic_cast<const XAIUnitCreatedEvent*>(e));
		} break;

		case XAI_EVENT_UNIT_FINISHED: {
			UnitFinished(dynamic_cast<const XAIUnitFinishedEvent*>(e));
		} break;

		case XAI_EVENT_UNIT_DESTROYED: {
			UnitDestroyed(dynamic_cast<const XAIUnitDestroyedEvent*>(e));
		} break;

		case XAI_EVENT_UNIT_DAMAGED: {
			UnitDamaged(dynamic_cast<const XAIUnitDamagedEvent*>(e));
		} break;

		case XAI_EVENT_UNIT_IDLE: {
			UnitIdle(dynamic_cast<const XAIUnitIdleEvent*>(e));
		} break;


		case XAI_EVENT_UNIT_GIVEN: {
			UnitGiven(dynamic_cast<const XAIUnitGivenEvent*>(e));
		} break;

		case XAI_EVENT_UNIT_CAPTURED: {
			UnitCaptured(dynamic_cast<const XAIUnitCapturedEvent*>(e));
		} break;


		case XAI_EVENT_INIT: {
			unitsByID.resize(MAX_UNITS, NULL);

			for (int i = 0; i < MAX_UNITS; i++) {
				unitsByID[i] = new XAICUnit(i, xaih);
			}
		} break;

		case XAI_EVENT_UPDATE: {
			Update();
		} break;

		case XAI_EVENT_RELEASE: {
			for (int i = 0; i < MAX_UNITS; i++) {
				delete unitsByID[i]; unitsByID[i] = NULL;
			}

			unitsByID.clear();
		} break;

		default: {
		} break;
	}
}
예제 #5
0
파일: XAIGroup.cpp 프로젝트: rrti/ai-libs
void XAIGroup::AddUnitMember(XAICUnit* u) {
	if (!HasUnitMember(u)) {
		unitsByID[u->GetID()] = u;
		u->SetGroupPtr(this);

		UnitIdle(u->GetID());
		Update(false);
	} else {
		assert(u->GetGroupPtr() == this);
	}
}
예제 #6
0
파일: AAI.cpp 프로젝트: Mocahteam/SpringPP
int AAI::HandleEvent(int msg, const void* data)
{
	switch (msg)
	{
		case AI_EVENT_UNITGIVEN: // 1
		case AI_EVENT_UNITCAPTURED: // 2
			{
				const IGlobalAI::ChangeTeamEvent* cte = (const IGlobalAI::ChangeTeamEvent*) data;

				const int myAllyTeamId = cb->GetMyAllyTeam();
				const bool oldEnemy = !cb->IsAllied(myAllyTeamId, cb->GetTeamAllyTeam(cte->oldteam));
				const bool newEnemy = !cb->IsAllied(myAllyTeamId, cb->GetTeamAllyTeam(cte->newteam));

				if (oldEnemy && !newEnemy) {
					// unit changed from an enemy to an allied team
					// we got a new friend! :)
					EnemyDestroyed(cte->unit, -1);
				} else if (!oldEnemy && newEnemy) {
					// unit changed from an ally to an enemy team
					// we lost a friend! :(
					EnemyCreated(cte->unit);
					if (!cb->UnitBeingBuilt(cte->unit)) {
						EnemyFinished(cte->unit);
					}
				}

				if (cte->oldteam == cb->GetMyTeam()) {
					// we lost a unit
					UnitDestroyed(cte->unit, -1);
				} else if (cte->newteam == cb->GetMyTeam()) {
					// we have a new unit
					UnitCreated(cte->unit, -1);
					if (!cb->UnitBeingBuilt(cte->unit)) {
						UnitFinished(cte->unit);
						UnitIdle(cte->unit);
					}
				}
				break;
			}
	}
	return 0;
}
예제 #7
0
void cUnitManager::UnitIdle(int unit,UnitInfo *U)
{
//	*l<<" (t="<<U->pBOL->task<<")";
	switch( U->pBOL->task )
	{
	case TASK_CONSTRUCT:
		G->Build->UBuilderIdle(unit,U);
		break;
	case TASK_ASSAULT:
		{
			if( int(U->Group->Enemies.size()) > 0 )
			{
				U->bInCombat = true;
				U->commandTimeOut = 0;
				return;
			}
			if( G->UDH->BLMobileRadar->UDefActive == 0 && G->Enemies.size() < 15 && int(G->Enemies.size()) <= int(UAssault.size())/2 )
			{
				int num=0;
				for( map<int,UnitInfo*>::iterator iU = U->Group->Units.begin(); iU != U->Group->Units.end(); iU++ )
				{
					if( cb->GetUnitPos(iU->first).distance2D(U->Group->ScoutPoint) < 350.0f )
						num++;
				}
				if( num >= 1+int(U->Group->Units.size())/2 )
				{
					U->Group->ScoutPoint = G->GetRandomPosition(U->mapBody);
					for( map<int,UnitInfo*>::iterator iU = U->Group->Units.begin(); iU != U->Group->Units.end(); iU++ )
						iU->second->commandTimeOut = 0;
				}

				Command c;
				if( cb->GetUnitPos(unit).distance2D(U->Group->ScoutPoint) < 350.0f )
				{
					c.id = CMD_WAIT;
					U->commandTimeOut = cb->GetCurrentFrame() + 300;
					//c.timeOut = cb->GetCurrentFrame() + 300;

				}
				else
				{
					c.id = CMD_MOVE;
					c.params.push_back(U->Group->ScoutPoint.x);
					c.params.push_back(U->Group->ScoutPoint.y);
					c.params.push_back(U->Group->ScoutPoint.z);
				}
				cb->GiveOrder(unit, &c);
			}
			else
			{
				Command c;
				if( cb->GetUnitPos(unit).distance2D(U->Group->RallyPoint) < 400 )
				{
					c.id = CMD_WAIT;
					U->commandTimeOut = cb->GetCurrentFrame() + 900;
					//c.timeOut = cb->GetCurrentFrame() + 300;

				}
				else
				{
					c.id = CMD_MOVE;
					c.params.push_back(U->Group->RallyPoint.x);
					c.params.push_back(U->Group->RallyPoint.y);
					c.params.push_back(U->Group->RallyPoint.z);
				}
				cb->GiveOrder(unit, &c);
			}
		}
		break;
	case TASK_SCOUT:
		{
			sScoutUnitInfo *S = &UScout.find(unit)->second;
			if( S->ScoutLocAssigned )
			{
				float3 Pos=cb->GetUnitPos(unit);
				const UnitDef* ud = cb->GetUnitDef(unit);

				if( Pos.x - S->SL->location.x > 100 || Pos.x - S->SL->location.x < -100 || Pos.z - S->SL->location.z > 100 || Pos.z - S->SL->location.z < -100 )
				{
					Command c;
					c.id = CMD_MOVE;
					c.params.push_back(S->SL->location.x);
					c.params.push_back(S->SL->location.y);
					c.params.push_back(S->SL->location.z);
					cb->GiveOrder(unit, &c);
				}
				return;
			}
			if( SLSize>0 )
			{
				S->SL= SL[0];
				SL[0]=SL[--SLSize];
				UnitIdle(unit,U);
				return;
			}
			Command c;
			c.id = CMD_MOVE;
			float3 movePos=G->GetRandomPosition(U->mapBody);
			c.params.push_back(movePos.x);
			c.params.push_back(movePos.y);
			c.params.push_back(movePos.z);
			cb->GiveOrder(unit, &c);
		}
		break;
	case TASK_SUICIDE:
		{
			Command c;
			if( int(G->Enemies.size()) > 0 && G->CombatM->GetClosestEnemy(cb->GetUnitPos(unit), U) >= 0 )
			{
				int iRan=rand()%int(G->Enemies.size());
				map<int,EnemyInfo>::iterator iE=G->Enemies.begin();
				for( int i=0; i<iRan; i++,iE++ ) {}

				U->bInCombat=true;
				U->enemyID=iE->first;
				U->E = &iE->second;
				U->enemyEff = G->CombatM->CanAttack(U,U->E,G->CombatM->GetEnemyPosition(U->enemyID,U->E));

				c.id = CMD_ATTACK;
				c.params.push_back(iE->first);
				cb->GiveOrder(unit,&c);
				return;
			}

			c.id = CMD_MOVE;
			float3 movePos=G->GetRandomPosition(U->mapBody);
			c.params.push_back(movePos.x);
			c.params.push_back(movePos.y);
			c.params.push_back(movePos.z);
			cb->GiveOrder(unit, &c);
		}
		break;
	case TASK_SUPPORT:
		{
			Command c;
			c.id = CMD_WAIT;
			cb->GiveOrder(unit, &c);
		}
		break;
	case TASK_TRANSPORT:
		{
			sTransportUnitInfo *T = &UTrans.find(unit)->second;
			if( T->AssistID == -1 )
			{
				Command c;
				c.id = CMD_WAIT;
				cb->GiveOrder(unit, &c);

				U->commandTimeOut=cb->GetCurrentFrame()+450;
			}
			else
			{

			}
		}
		break;
	}
}
예제 #8
0
void cRAI::Update()
{
	frame=cb->GetCurrentFrame();
	if(frame%FUPDATE_MINIMAL)
		return;

	if( RAIDEBUGGING ) *l<<"\nUpdate("<<frame<<")";

	if(!(frame%FUPDATE_POWER))
	{	// Old Code, ensures a unit won't just go permanently idle, hopefully unnecessary in the future
		ValidateAllUnits();
		for(map<int,UnitInfo>::iterator iU=Units.begin(); iU!=Units.end(); iU++)
			if( !cb->UnitBeingBuilt(iU->first) && !iU->second.AIDisabled && iU->second.udrBL->task > 1 &&
				frame > iU->second.lastUnitIdleFrame+FUPDATE_UNITS && iU->second.UE == 0 && cb->GetCurrentUnitCommands(iU->first)->size() == 0 )
			{
//				*l<<"\nWARNING: Unit was Idle  Name="<<iU->second.ud->humanName<<"("<<iU->first<<")";
				UnitIdle(iU->first);
			}
	}

	while( eventSize > 0 && eventList[0]->frame <= frame )
	{
		switch( eventList[0]->type )
		{
		case 1: // Checks for idleness
//			*l<<"\n(u1)";
			if( ValidateUnit(eventList[0]->unitID) ) // if false, the event will be removed elsewhere
			{
				if( !IsHumanControled(eventList[0]->unitID,eventList[0]->unitI) )
				{
//					*l<<" Stopping "<<eventList[0]->unitI->ud->humanName<<"("<<eventList[0]->unitID<<")";
					eventList[0]->unitI->lastUnitIdleFrame = -1;
					if( eventList[0]->unitI->ud->speed == 0 )
					{
						int unit = eventList[0]->unitID;
						UpdateEventRemove(eventList[0]);
						UnitIdle(unit);
					}
					else
					{	// doesn't seem to work for factories  Spring-Version(v0.76b1)
						Command c;
						c.id=CMD_STOP;
						cb->GiveOrder(eventList[0]->unitID, &c);
						UpdateEventRemove(eventList[0]);
					}
				}
				else
				{
					eventList[0]->frame = frame;
					UpdateEventReorderFirst();
				}
			}
			break;
		case 2: // Few Unit Monitoring
//			*l<<"\n(u2)";
			if( ValidateUnit(eventList[0]->unitID) ) // if false, the event will be removed elsewhere
			{
				if( !eventList[0]->unitI->inCombat &&
					!IsHumanControled(eventList[0]->unitID,eventList[0]->unitI) &&
					eventList[0]->unitI->BuildQ != 0 &&
					cb->GetCurrentUnitCommands(eventList[0]->unitID)->front().id < 0 )
				{
					if( eventList[0]->lastPosition == 0 )
						eventList[0]->lastPosition = new float3;
					float3 position = cb->GetUnitPos(eventList[0]->unitID);
					if( eventList[0]->unitI->BuildQ->creationID.size() > 0 )
					{
						eventList[0]->lastPosition->x = -1.0;
						float3 conPosition = cb->GetUnitPos(eventList[0]->unitI->BuildQ->creationID.front());
						if( abs(int(position.x-conPosition.x)) + 4.0 < 8.0*eventList[0]->unitI->ud->xsize/2.0 + 8.0*eventList[0]->unitI->BuildQ->creationUD->ud->xsize/2.0 &&
							abs(int(position.z-conPosition.z)) + 4.0 < 8.0*eventList[0]->unitI->ud->ysize/2.0 + 8.0*eventList[0]->unitI->BuildQ->creationUD->ud->ysize/2.0 )
						{	// most likely, the commander built something on top of himself
							Command c;
							c.id = CMD_RECLAIM;
							c.params.push_back(eventList[0]->unitI->BuildQ->creationID.front());
							cb->GiveOrder(eventList[0]->unitID,&c);
							if( B->BP->NeedResourceSite(eventList[0]->unitI->BuildQ->creationUD->ud) )
							{
								c.params.clear();
								c.id = CMD_MOVE;
								c.options = SHIFT_KEY;
								if( position.x < conPosition.x )
									c.params.push_back(position.x - ((position.x-conPosition.x)/position.distance2D(conPosition))*(8.0*eventList[0]->unitI->ud->xsize/2.0 +8.0*eventList[0]->unitI->BuildQ->creationUD->ud->xsize/2.0) );
								else
									c.params.push_back(position.x + ((position.x-conPosition.x)/position.distance2D(conPosition))*(8.0*eventList[0]->unitI->ud->xsize/2.0 +8.0*eventList[0]->unitI->BuildQ->creationUD->ud->xsize/2.0) );
								c.params.push_back(position.y);
								if( position.z < conPosition.z )
									c.params.push_back(position.z - ((position.z-conPosition.z)/position.distance2D(conPosition))*(8.0*eventList[0]->unitI->ud->ysize/2.0 +8.0*eventList[0]->unitI->BuildQ->creationUD->ud->ysize/2.0) );
								else
									c.params.push_back(position.z + ((position.z-conPosition.z)/position.distance2D(conPosition))*(8.0*eventList[0]->unitI->ud->ysize/2.0 +8.0*eventList[0]->unitI->BuildQ->creationUD->ud->ysize/2.0) );
								cb->GiveOrder(eventList[0]->unitID,&c);
							}
						}
					}
					else if( position == *eventList[0]->lastPosition )
					{	// most likely, the commander is stuck at the starting point
//						if( eventList[0]->unitI->area == 0 && TM->udMobileType.find(eventList[0]->unitI->ud->id)->second != 0 )
//						{} // trapped forever
						eventList[0]->unitI->lastUnitIdleFrame = -1;
						Command c;
						c.id = CMD_MOVE;
						float f = (40.0+(rand()%401)/10.0);
						if( rand()%2 == 0 )
							c.params.push_back(position.x + f );
						else
							c.params.push_back(position.x - f );
						c.params.push_back(position.y);
						f = (40.0+(rand()%401)/10.0);
						if( rand()%2 == 0 )
							c.params.push_back(position.z + f );
						else
							c.params.push_back(position.z - f );
						cb->GiveOrder(eventList[0]->unitID,&c);
						*eventList[0]->lastPosition = position;
					}
					else
						*eventList[0]->lastPosition = position;
				}
				if( Units.size() >= 10 )
				{
					if( eventList[0]->lastPosition != 0 )
						delete eventList[0]->lastPosition;
					UpdateEventRemove(eventList[0]);
				}
				else
					UpdateEventReorderFirst();
			}
			break;
		case 3: // Initiatization
//			*l<<"\n(u3)";
			if( frame >= 210 || ( cb->GetMetalIncome()>0 && cb->GetMetalIncome()<0.9*cb->GetMetalStorage() ) || ( cb->GetEnergyIncome()>0 && cb->GetEnergyIncome()<0.9*cb->GetEnergyStorage() ) )
			{
				*l<<"\nInitiated=true  Frame="<<frame<<" Metal-Income="<<cb->GetMetalIncome()<<" Energy-Income="<<cb->GetEnergyIncome()<<"\n";
				UpdateEventRemove(eventList[0]);
				B->UpdateUDRCost();
				for(map<int,UnitInfo>::iterator i=Units.begin(); i!=Units.end(); i++ )
					if( !i->second.AIDisabled  )
					{
						if( Units.size() < 10 && i->second.ud->movedata != 0 )
							UpdateEventAdd(2,frame+FUPDATE_MINIMAL,i->first,&i->second);
						if( cb->GetCurrentUnitCommands(i->first)->size() == 0 )
							UnitIdle(i->first);
					}
				B->bInitiated=true;
			}
			else
				UpdateEventReorderFirst();
			break;
		default:
			*l<<"(ERROR)";
			UpdateEventRemove(eventList[0]);
			break;
		}
	}

	if(!(frame%FUPDATE_POWER))
	{
		B->PM->Update();
		SWM->Update();
		if(!(frame%FUPDATE_BUILDLIST))
			B->UpdateUDRCost();
	}
	if( RAIDEBUGGING ) *l<<"#";
}
예제 #9
0
int cRAI::HandleEvent(int msg,const void* data)
{
	if( RAIDEBUGGING ) *l<<"\nHandleEvent("<<msg<<","<<"~"<<")";
	switch (msg)
	{
	case AI_EVENT_UNITGIVEN:
		{
			const IGlobalAI::ChangeTeamEvent* cte = (const IGlobalAI::ChangeTeamEvent*) data;
			if( cte->newteam != cb->GetMyTeam() )
			{
				cb->SendTextMsg("cRAI::HandleEvent(AI_EVENT_UNITGIVEN): This AI is out of date, check for a more recent one.",0);
				*l<<"\nERROR: cRAI::HandleEvent(AI_EVENT_UNITGIVEN): This AI is out of date, check for a more recent one.\n";
			}

			if( Enemies.find(cte->unit) != Enemies.end() )
				EnemyDestroyed(cte->unit,-1);

			if( cb->GetUnitHealth(cte->unit) <= 0 ) // ! Work Around:  Spring-Version(v0.74b1-0.75b2)
			{
				*l<<"\nERROR: HandleEvent(AI_EVENT_UNITGIVEN): given unit is dead or does not exist";
				return 0;
			}

			UnitCreated(cte->unit);
			Units.find(cte->unit)->second.AIDisabled=false;
			if( !cb->UnitBeingBuilt(cte->unit) )
			{
				UnitFinished(cte->unit);
				UnitIdle(cte->unit);
			}
		}
		break;
	case AI_EVENT_UNITCAPTURED:
		{
			const IGlobalAI::ChangeTeamEvent* cte = (const IGlobalAI::ChangeTeamEvent*) data;
			if( cte->oldteam != cb->GetMyTeam() )
			{
				cb->SendTextMsg("cRAI::HandleEvent(AI_EVENT_UNITCAPTURED): This AI is out of date, check for a more recent one.",0);
				*l<<"\nERROR: cRAI::HandleEvent(AI_EVENT_UNITCAPTURED): This AI is out of date, check for a more recent one.\n";
			}

			UnitDestroyed(cte->unit,-1);
		}
		break;
	case AI_EVENT_PLAYER_COMMAND:
		{
			const IGlobalAI::PlayerCommandEvent* pce = (const IGlobalAI::PlayerCommandEvent*) data;
			bool ImportantCommand=false;
			if( pce->command.id < 0 )
				ImportantCommand = true;
			switch( pce->command.id )
			{
			case CMD_MOVE:
			case CMD_PATROL:
			case CMD_FIGHT:
			case CMD_ATTACK:
			case CMD_AREA_ATTACK:
			case CMD_GUARD:
			case CMD_REPAIR:
			case CMD_LOAD_UNITS:
			case CMD_UNLOAD_UNITS:
			case CMD_UNLOAD_UNIT:
			case CMD_RECLAIM:
			case CMD_DGUN:
			case CMD_RESTORE:
			case CMD_RESURRECT:
			case CMD_CAPTURE:
				ImportantCommand = true;
			}

			for( int i=0; i<int(pce->units.size()); i++ )
			{
				if( Units.find(pce->units.at(i)) == Units.end() ) // ! Work Around:  Spring-Version(v0.75b2)
				{
					*l<<"\nERROR: HandleEvent(AI_EVENT_PLAYER_COMMAND): unknown unit id="<<pce->units.at(i);
//					pce->units.erase(pce->units.begin()+i);
//					i--;
				}
				else if( ImportantCommand )
					Units.find(pce->units.at(i))->second.humanCommand = true;
			}
			if( ImportantCommand )
			{
				B->HandleEvent(pce);
			}
			else if( pce->command.id == CMD_SELFD )
			{
				for( vector<int>::const_iterator i=pce->units.begin(); i!=pce->units.end(); i++ )
					UnitDestroyed(*i,-1);
			}
		}
		break;
	}
	if( RAIDEBUGGING ) *l<<"#";
	return 0;
}
예제 #10
0
void Scouter::UnitMoveFailed(int unit){
	NLOG("Scouter::UnitMoveFailed");
	UnitIdle(unit);
}
예제 #11
0
void cUnitManager::UnitIdle(int unit,UnitInfo *U)
{
//	*l<<" (t="<<U->udrBL->task<<")";
	switch( U->udrBL->task )
	{
	case TASK_CONSTRUCT:
		G->B->UBuilderIdle(unit,U);
		break;
	case TASK_ASSAULT:
		{
			if( int(U->group->Enemies.size()) > 0 )
			{
				U->inCombat = true;
				G->UpdateEventAdd(1,cb->GetCurrentFrame()+90,unit,U);
			}
			if( G->Enemies.size() == 0 && (UAssault.size() > 50 || (G->UDH->BLMobileRadar->UDefActiveTemp == 0)) )
			{
				int num=0;
				for( map<int,UnitInfo*>::iterator iU = U->group->Units.begin(); iU != U->group->Units.end(); ++iU )
				{
					if( cb->GetUnitPos(iU->first).distance2D(U->group->M->ScoutPoint) < 350.0f )
						num++;
				}
				if( num >= 1+int(U->group->Units.size())/2 )
				{
					U->group->M->ScoutPoint = G->GetRandomPosition(U->area);
					for( map<int,UnitInfo*>::iterator iU = U->group->Units.begin(); iU != U->group->Units.end(); ++iU )
						G->UpdateEventAdd(1,0,iU->first,iU->second);
				}

				Command c;
				if( cb->GetUnitPos(unit).distance2D(U->group->M->ScoutPoint) < 400.0f )
				{
					c.id = CMD_WAIT;
					c.timeOut = cb->GetCurrentFrame()+900;
//					G->UpdateEventAdd(1,cb->GetCurrentFrame()+300,unit,U);
				}
				else
				{
					c.id = CMD_MOVE;
					c.params.push_back(U->group->M->ScoutPoint.x);
					c.params.push_back(U->group->M->ScoutPoint.y);
					c.params.push_back(U->group->M->ScoutPoint.z);
				}
				cb->GiveOrder(unit, &c);
			}
			else
			{
				Command c;
				if( cb->GetUnitPos(unit).distance2D(U->group->M->RallyPoint) < 400.0f )
				{
					c.id = CMD_WAIT;
					c.timeOut = cb->GetCurrentFrame()+900;
//					G->UpdateEventAdd(1,cb->GetCurrentFrame()+900,unit,U);
				}
				else
				{
					c.id = CMD_MOVE;
					c.params.push_back(U->group->M->RallyPoint.x);
					c.params.push_back(U->group->M->RallyPoint.y);
					c.params.push_back(U->group->M->RallyPoint.z);
				}
				cb->GiveOrder(unit, &c);
			}
		}
		break;
	case TASK_SCOUT:
		{
			sScoutUnitInfo *S = &UScout.find(unit)->second;
			if( S->ScoutLocAssigned )
			{
				float3 Pos=cb->GetUnitPos(unit);
				//const UnitDef* ud = cb->GetUnitDef(unit);

				if( Pos.x - S->SL->position.x > 100 || Pos.x - S->SL->position.x < -100 || Pos.z - S->SL->position.z > 100 || Pos.z - S->SL->position.z < -100 )
				{
					Command c;
					c.id = CMD_MOVE;
					c.params.push_back(S->SL->position.x);
					c.params.push_back(S->SL->position.y);
					c.params.push_back(S->SL->position.z);
					cb->GiveOrder(unit, &c);
				}
				return;
			}
			if( SLSize>0 )
			{
				S->SL= SL[0];
				SL[0]=SL[--SLSize];
				UnitIdle(unit,U);
				return;
			}
			Command c;
			c.id = CMD_MOVE;
			float3 movePos=G->GetRandomPosition(U->area);
			c.params.push_back(movePos.x);
			c.params.push_back(movePos.y);
			c.params.push_back(movePos.z);
			cb->GiveOrder(unit, &c);
		}
		break;
	case TASK_SUICIDE:
		{
			Command c;
			if( int(G->Enemies.size()) > 0 && G->CM->GetClosestEnemy(cb->GetUnitPos(unit), U) >= 0 )
			{
				set<int> Targets;
				for( map<int,EnemyInfo>::iterator iE=G->Enemies.begin(); iE!=G->Enemies.end(); ++iE )
					if( G->TM->CanMoveToPos(U->area,G->CM->GetEnemyPosition(iE->first,&iE->second)) )
						Targets.insert(iE->first);

				int iT=rand()%int(Targets.size());
				set<int>::iterator enemyID = Targets.begin();
				for( int i=0; i<iT; i++,enemyID++ ) {}

				U->inCombat=true;
				U->enemyID = *enemyID;
				U->E = &G->Enemies.find(U->enemyID)->second;
				U->enemyEff = G->CM->CanAttack(U,U->E,G->CM->GetEnemyPosition(U->enemyID,U->E));

				c.id = CMD_ATTACK;
				c.params.push_back(U->enemyID);
				cb->GiveOrder(unit,&c);
				return;
			}

			c.id = CMD_MOVE;
			float3 movePos=G->GetRandomPosition(U->area);
			c.params.push_back(movePos.x);
			c.params.push_back(movePos.y);
			c.params.push_back(movePos.z);
			cb->GiveOrder(unit, &c);
		}
		break;
	case TASK_SUPPORT:
		{
			Command c;
			c.id = CMD_WAIT;
			cb->GiveOrder(unit, &c);
		}
		break;
	case TASK_TRANSPORT:
		{
			sTransportUnitInfo *T = &UTrans.find(unit)->second;
			if( T->AssistID == -1 )
			{
				Command c;
				c.id = CMD_WAIT;
				cb->GiveOrder(unit, &c);

				G->UpdateEventAdd(1,cb->GetCurrentFrame()+450,unit,U);
			}
		}
		break;
	}
}
예제 #12
0
int cRAI::HandleEvent(int msg,const void* data)
{
	if( RAIDEBUGGING ) *l<<"\nHandleEvent("<<msg<<","<<"~"<<")";
	switch (msg)
	{
	case AI_EVENT_UNITGIVEN:
	case AI_EVENT_UNITCAPTURED:
		{
			const IGlobalAI::ChangeTeamEvent* cte = (const IGlobalAI::ChangeTeamEvent*) data;

			const int myAllyTeamId = cb->GetMyAllyTeam();
			const bool oldEnemy = !cb->IsAllied(myAllyTeamId, cb->GetTeamAllyTeam(cte->oldteam));
			const bool newEnemy = !cb->IsAllied(myAllyTeamId, cb->GetTeamAllyTeam(cte->newteam));

			if ( oldEnemy && !newEnemy ) {
			{
				if( Enemies.find(cte->unit) != Enemies.end() )
					EnemyDestroyed(cte->unit,-1);
				}
			}
			else if( !oldEnemy && newEnemy )
			{
				// unit changed from an ally to an enemy team
				// we lost a friend! :(
				EnemyCreated(cte->unit);
				if (!cb->UnitBeingBuilt(cte->unit)) {
					EnemyFinished(cte->unit);
				}
			}

			if( cte->oldteam == cb->GetMyTeam() )
			{
				UnitDestroyed(cte->unit,-1);
			}
			else if( cte->newteam == cb->GetMyTeam() )
			{
				if( cb->GetUnitHealth(cte->unit) <= 0 ) // ! Work Around:  Spring-Version(v0.74b1-0.75b2)
				{
					*l<<"\nERROR: HandleEvent(AI_EVENT_(UNITGIVEN|UNITCAPTURED)): given unit is dead or does not exist";
					return 0;
				}
				UnitCreated(cte->unit, -1);
				Units.find(cte->unit)->second.AIDisabled=false;
				if( !cb->UnitBeingBuilt(cte->unit) )
				{
					UnitFinished(cte->unit);
					UnitIdle(cte->unit);
				}
			}
		}
		break;
	case AI_EVENT_PLAYER_COMMAND:
		{
			const IGlobalAI::PlayerCommandEvent* pce = (const IGlobalAI::PlayerCommandEvent*) data;
			bool ImportantCommand=false;
			if( pce->command.id < 0 )
				ImportantCommand = true;
			switch( pce->command.id )
			{
			case CMD_MOVE:
			case CMD_PATROL:
			case CMD_FIGHT:
			case CMD_ATTACK:
			case CMD_AREA_ATTACK:
			case CMD_GUARD:
			case CMD_REPAIR:
			case CMD_LOAD_UNITS:
			case CMD_UNLOAD_UNITS:
			case CMD_UNLOAD_UNIT:
			case CMD_RECLAIM:
			case CMD_DGUN:
			case CMD_RESTORE:
			case CMD_RESURRECT:
			case CMD_CAPTURE:
				ImportantCommand = true;
			}

			for( int i=0; i<int(pce->units.size()); i++ )
			{
				if( Units.find(pce->units.at(i)) == Units.end() ) // ! Work Around:  Spring-Version(v0.75b2)
				{
					*l<<"\nERROR: HandleEvent(AI_EVENT_PLAYER_COMMAND): unknown unit id="<<pce->units.at(i);
//					pce->units.erase(pce->units.begin()+i);
//					i--;
				}
				else if( ImportantCommand )
					Units.find(pce->units.at(i))->second.humanCommand = true;
			}
			if( ImportantCommand )
			{
				B->HandleEvent(pce);
			}
			else if( pce->command.id == CMD_SELFD )
			{
				for( vector<int>::const_iterator i=pce->units.begin(); i!=pce->units.end(); ++i )
					UnitDestroyed(*i,-1);
			}
		}
		break;
	}
	if( RAIDEBUGGING ) *l<<"#";
	return 0;
}
예제 #13
0
void cSWeaponManager::Update()
{
	for( map<int,sRAIUnitDef*>::iterator iU = mWeapon.begin(); iU!=mWeapon.end(); ++iU )
		if( !G->IsHumanControled(iU->first,&G->Units.find(iU->first)->second) )
			UnitIdle(iU->first,iU->second);
}