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); }
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<<"#"; }
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); }
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; } }
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); } }
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; }
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; } }
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<<"#"; }
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; }
void Scouter::UnitMoveFailed(int unit){ NLOG("Scouter::UnitMoveFailed"); UnitIdle(unit); }
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; } }
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; }
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); }