void setMoveAction(int type) { switch (type) { case MOVE_SELECTION_TYPE_START: case MOVE_SELECTION_TYPE_STRAIGHT: printf("Straight Move\r\n"); StraightMove(); break; case MOVE_SELECTION_TYPE_STOP: printf("Stop Move\r\n"); StopMove(); break; case MOVE_SELECTION_TYPE_RIGHTSIFT_1: printf("Right Sift 1\r\n"); StraightMoveRightSift(); break; case MOVE_SELECTION_TYPE_LEFTSIFT_1: printf("Left Sift 1\r\n"); StraightMoveLeftSift(); break; case MOVE_SELECTION_TYPE_RIGHTSIFT_2: printf("Right Sift 2\r\n"); StraightMoveRightSift2(); break; case MOVE_SELECTION_TYPE_LEFTSIFT_2: printf("Left Sift 2\r\n"); StraightMoveLeftSift2(); break; case MOVE_SELECTION_TYPE_RIGHTTURN: printf("Right Turn\r\n"); //TurnMoveRight(); TurnLowMoveRight(); break; case MOVE_SELECTION_TYPE_LEFTTURN: printf("Left Turn\r\n"); //TurnMoveLeft(); TurnLowMoveLeft(); break; case MOVE_SELECTION_TYPE_RIGHTTURN_2: printf("Right Turn 2\r\n"); TurnMoveRight(); //TurnLowMoveRight(); break; case MOVE_SELECTION_TYPE_LEFTTURN_2: printf("Left Turn 2\r\n"); TurnMoveLeft(); //TurnLowMoveLeft(); break; case MOVE_SELECTION_TYPE_BACK: printf("Back Move\r\n"); StopMove(); _delay_ms(10); BackMove(); _delay_ms(1000); break; case MOVE_SELECTION_TYPE_S_MOVE_10: TestMode(); default: break; } }
void CBuilderCAI::ExecuteCapture(Command &c) { assert(owner->unitDef->canCapture); CBuilder* fac=(CBuilder*)owner; if(c.params.size()==1){ //capture unit CUnit* unit=uh->units[(int)c.params[0]]; if(unit && unit->team!=owner->team && UpdateTargetLostTimer((int)c.params[0])){ if(unit->pos.distance2D(fac->pos)<fac->buildDistance+unit->radius-8){ StopMove(); fac->SetCaptureTarget(unit); owner->moveType->KeepPointingTo(unit->pos, fac->buildDistance*0.9f+unit->radius, false); } else { if(goalPos.distance2D(unit->pos)>1) SetGoal(unit->pos,owner->pos, fac->buildDistance*0.9f+unit->radius); } } else { StopMove(); FinishCommand(); } } else { //capture area float3 pos(c.params[0],c.params[1],c.params[2]); float radius=c.params[3]; if(FindCaptureTargetAndCapture(pos,radius,c.options)){ inCommand=false; SlowUpdate(); return; } if(!(c.options & ALT_KEY)){ FinishCommand(); } } return; }
void CBuilderCAI::ExecuteResurrect(Command& c) { // not all builders are resurrect-capable by default if (!owner->unitDef->canResurrect) return; if (c.params.size() == 1) { unsigned int id = (unsigned int) c.params[0]; if (id >= unitHandler->MaxUnits()) { // resurrect feature CFeature* feature = featureHandler->GetFeature(id - unitHandler->MaxUnits()); if (feature && feature->udef != NULL) { if (((c.options & INTERNAL_ORDER) && !(c.options & CONTROL_KEY) && IsFeatureBeingReclaimed(feature->id, owner)) || !ResurrectObject(feature)) { StopMove(); RemoveUnitFromResurrecters(owner); FinishCommand(); } else { AddUnitToResurrecters(owner); } } else { RemoveUnitFromResurrecters(owner); if (ownerBuilder->lastResurrected && unitHandler->GetUnitUnsafe(ownerBuilder->lastResurrected) != NULL && owner->unitDef->canRepair) { // resurrection finished, start repair (by overwriting the current order) c = Command(CMD_REPAIR, c.options | INTERNAL_ORDER, ownerBuilder->lastResurrected); ownerBuilder->lastResurrected = 0; inCommand = false; SlowUpdate(); return; } StopMove(); FinishCommand(); } } else { // resurrect unit RemoveUnitFromResurrecters(owner); FinishCommand(); } } else if (c.params.size() == 4) { // area resurrect const float3 pos = c.GetPos(0); const float radius = c.params[3]; if (FindResurrectableFeatureAndResurrect(pos, radius, c.options, (c.options & META_KEY))) { inCommand = false; SlowUpdate(); return; } if (!(c.options & ALT_KEY)) { FinishCommand(); } } else { // wrong number of parameters RemoveUnitFromResurrecters(owner); FinishCommand(); } }
void CMobileCAI::RefuelIfNeeded() { if (!owner->moveType->reservedPad) { // we don't have a pad yet if (owner->currentFuel <= 0) { // we're out of fuel StopMove(); owner->userAttackGround = false; owner->userTarget = 0; inCommand = false; CAirBaseHandler::LandingPad* lp = airBaseHandler->FindAirBase(owner, owner->unitDef->minAirBasePower); if (lp) { // found a pad owner->moveType->ReservePad(lp); } else { // no pads available, search for a landing // spot near any that are currently occupied float3 landingPos = airBaseHandler->FindClosestAirBasePos(owner, owner->unitDef->minAirBasePower); if (landingPos != ZeroVector) { // NOTE: owner->userAttackGround is wrongly reset to // true in CUnit::AttackGround() via ExecuteAttack() SetGoal(landingPos, owner->pos); } else { owner->moveType->StopMoving(); } } } else if (owner->currentFuel < (owner->moveType->repairBelowHealth * owner->unitDef->maxFuel) && true /* (commandQue.empty() || commandQue.front().id == CMD_PATROL || commandQue.front().id == CMD_FIGHT) */) { // current fuel level is below our bingo threshold // note: force the refuel attempt (irrespective of // what our currently active command is) CAirBaseHandler::LandingPad* lp = airBaseHandler->FindAirBase(owner, owner->unitDef->minAirBasePower); if (lp) { StopMove(); owner->userAttackGround = false; owner->userTarget = 0; inCommand = false; owner->moveType->ReservePad(lp); } } else if (owner->health < owner->maxHealth * owner->moveType->repairBelowHealth) { // we're damaged, just seek a pad for repairs CAirBaseHandler::LandingPad* lp = airBaseHandler->FindAirBase(owner, owner->unitDef->minAirBasePower); if (lp) { owner->moveType->ReservePad(lp); } } } }
void CBuilderCAI::ExecuteResurrect(Command& c) { assert(owner->unitDef->canResurrect); CBuilder* fac=(CBuilder*)owner; if(c.params.size()==1){ int id=(int)c.params[0]; if(id>=MAX_UNITS){ //resurrect feature CFeatureSet::const_iterator it = featureHandler->GetActiveFeatures().find(id - MAX_UNITS); if (it != featureHandler->GetActiveFeatures().end() && (*it)->createdFromUnit != "") { CFeature* feature = *it; if (f3SqDist(feature->pos, fac->pos) < Square(fac->buildDistance*0.9f+feature->radius)) { StopMove(); owner->moveType->KeepPointingTo(feature->pos, fac->buildDistance*0.9f+feature->radius, false); fac->SetResurrectTarget(feature); } else { if (f3SqDist(goalPos, feature->pos) > 1) { SetGoal(feature->pos,owner->pos, fac->buildDistance*0.8f+feature->radius); } else { if(owner->moveType->progressState==AMoveType::Failed){ StopMove(); FinishCommand(); } } } } else { if(fac->lastResurrected && uh->units[fac->lastResurrected] && owner->unitDef->canRepair){ //resurrection finished, start repair c.id=CMD_REPAIR; //kind of hackery to overwrite the current order i suppose c.params.clear(); c.params.push_back(fac->lastResurrected); c.options|=INTERNAL_ORDER; fac->lastResurrected=0; inCommand=false; SlowUpdate(); return; } StopMove(); FinishCommand(); } } else { //resurrect unit FinishCommand(); } } else if(c.params.size()==4){//area resurect float3 pos(c.params[0],c.params[1],c.params[2]); float radius=c.params[3]; if(FindResurrectableFeatureAndResurrect(pos,radius,c.options)){ inCommand=false; SlowUpdate(); return; } if(!(c.options & ALT_KEY)){ FinishCommand(); } } else { //wrong number of parameters FinishCommand(); } return; }
void CBuilderCAI::ExecuteCapture(Command& c) { // not all builders are capture-capable by default if (!owner->unitDef->canCapture) return; CBuilder* builder = (CBuilder*) owner; if (c.params.size() == 1 || c.params.size() == 5) { // capture unit CUnit* unit = uh->GetUnit(c.params[0]); if (unit == NULL) { FinishCommand(); return; } if (c.params.size() == 5) { const float3 pos(c.params[1], c.params[2], c.params[3]); const float radius = c.params[4] + 100; // do not walk too far outside capture area if (((pos - unit->pos).SqLength2D() > (radius * radius) || (builder->curCapture == unit && unit->isMoving && !IsInBuildRange(unit)))) { StopMove(); FinishCommand(); return; } } if (unit->unitDef->capturable && unit->team != owner->team && UpdateTargetLostTimer(unit->id)) { if (MoveInBuildRange(unit)) { builder->SetCaptureTarget(unit); } } else { StopMove(); FinishCommand(); } } else if (c.params.size() == 4) { // area capture const float3 pos = c.GetPos(0); const float radius = c.params[3]; builder->StopBuild(); if (FindCaptureTargetAndCapture(pos, radius, c.options, (c.options & META_KEY))) { inCommand = false; SlowUpdate(); return; } if (!(c.options & ALT_KEY)) { FinishCommand(); } } else { FinishCommand(); } return; }
/// returns true if the unit has to land bool CMobileCAI::RefuelIfNeeded() { if (owner->unitDef->maxFuel <= 0.0f) return false; if (owner->moveType->GetReservedPad() != NULL) { // we already have a pad return false; } if (owner->currentFuel <= 0.0f) { // we're completely out of fuel owner->AttackUnit(NULL, false, false); inCommand = false; CAirBaseHandler::LandingPad* lp = airBaseHandler->FindAirBase(owner, owner->unitDef->minAirBasePower, true); if (lp != NULL) { // found a pad owner->moveType->ReservePad(lp); } else { // no pads available, search for a landing // spot near any that are currently occupied const float3& landingPos = airBaseHandler->FindClosestAirBasePos(owner, owner->unitDef->minAirBasePower); if (landingPos != ZeroVector) { SetGoal(landingPos, owner->pos); } else { StopMove(); } } return true; } else if (owner->moveType->WantsRefuel()) { // current fuel level is below our bingo threshold // note: force the refuel attempt (irrespective of // what our currently active command is) CAirBaseHandler::LandingPad* lp = airBaseHandler->FindAirBase(owner, owner->unitDef->minAirBasePower, true); if (lp != NULL) { StopMove(); owner->AttackUnit(NULL, false, false); owner->moveType->ReservePad(lp); inCommand = false; return true; } } return false; }
void CEntity::OnLoop() { //We’re not Moving if (MoveLeft == false && MoveRight == false) { StopMove(); } if (MoveLeft) { AccelX = -0.5; } else if (MoveRight) { AccelX = 0.5; } if (Flags & ENTITY_FLAG_GRAVITY) { AccelY = 0.75f; } SpeedX += AccelX * CFPS::FPSControl.GetSpeedFactor(); SpeedY += AccelY * CFPS::FPSControl.GetSpeedFactor(); if (SpeedX > MaxSpeedX) SpeedX = MaxSpeedX; if (SpeedX < -MaxSpeedX) SpeedX = -MaxSpeedX; if (SpeedY > MaxSpeedY) SpeedY = MaxSpeedY; if (SpeedY < -MaxSpeedY) SpeedY = -MaxSpeedY; OnAnimate(); OnMove(SpeedX, SpeedY); }
/* ================ rvMonsterStroggHover::State_Torso_BombAttack ================ */ stateResult_t rvMonsterStroggHover::State_Torso_BombAttack ( const stateParms_t& parms ) { enum { STAGE_INIT, STAGE_LOOP, STAGE_WAITLOOP, }; idVec3 vel = GetPhysics()->GetLinearVelocity(); if ( vel.z < 150.0f ) { vel.z += 20.0f; physicsObj.UseVelocityMove( true ); GetPhysics()->SetLinearVelocity( vel ); } switch ( parms.stage ) { case STAGE_INIT: move.fly_offset = 800;//go up! shots = gameLocal.random.RandomInt ( bombMaxShots-bombMinShots ) + bombMinShots; if ( GetEnemy() ) { //if I'm not above him, give me a quick boost first float zDiff = GetPhysics()->GetOrigin().z-GetEnemy()->GetPhysics()->GetOrigin().z; if ( zDiff < 150.0f ) { idVec3 vel = GetPhysics()->GetLinearVelocity(); vel.z += 200.0f; if ( zDiff < 0.0f ) { //even more if I'm below him! vel.z -= zDiff*2.0f; } physicsObj.UseVelocityMove( true ); GetPhysics()->SetLinearVelocity( vel ); } } if ( move.moveCommand == MOVE_TO_ATTACK ) { StopMove( MOVE_STATUS_DONE ); } if ( combat.tacticalCurrent == AITACTICAL_RANGED ) { ForceTacticalUpdate(); } if ( move.moveCommand == MOVE_NONE && !inPursuit && !circleStrafing ) { MoveToEnemy(); } return SRESULT_STAGE ( STAGE_LOOP ); case STAGE_LOOP: DoNamedAttack( "bomb", jointBomb ); nextBombFireTime = gameLocal.GetTime() + bombFireRate; return SRESULT_STAGE ( STAGE_WAITLOOP ); case STAGE_WAITLOOP: if ( nextBombFireTime <= gameLocal.GetTime() ) { if ( --shots <= 0 ) { move.fly_offset = spawnArgs.GetFloat("fly_offset","250"); ForceTacticalUpdate(); return SRESULT_DONE; } return SRESULT_STAGE ( STAGE_LOOP ); } return SRESULT_WAIT; } return SRESULT_ERROR; }
void CMobileCAI::ExecuteLoadUnits(Command &c) { CUnit* unit = unitHandler->GetUnit(c.params[0]); CTransportUnit* tran = dynamic_cast<CTransportUnit*>(unit); if (!tran) { FinishCommand(); return; } if (!inCommand) { inCommand = true; Command newCommand(CMD_LOAD_UNITS, INTERNAL_ORDER | SHIFT_KEY, owner->id); tran->commandAI->GiveCommandReal(newCommand); } if (owner->GetTransporter() != NULL) { if (!commandQue.empty()) FinishCommand(); return; } if (!unit) { return; } float3 pos = unit->pos; if ((pos - goalPos).SqLength2D() > cancelDistance) { SetGoal(pos, owner->pos); } if ((owner->pos - goalPos).SqLength2D() < cancelDistance) { StopMove(); } return; }
void CAIVehicle::Think( void ) { if( !( thinkFlags & TH_THINK ) ) { goto Quit; } if( m_Controller.GetEntity() ) { // Exit the combat state if we somehow got in it. // Later we can fight as directed by player, but right now it's too independent ClearEnemy(); // Update controls and movement dir UpdateSteering(); // Speed controls, for now just AI_MOVE bool bMovementReq = UpdateSpeed(); // Request move at direction if( bMovementReq ) { MoveAlongVector( m_CurAngle ); } else { StopMove( MOVE_STATUS_DONE ); // just turn if no forward/back movement is requested TurnToward( m_CurAngle ); } } idAI::Think(); Quit: return; }
void CMobileCAI::SlowUpdate() { if (gs->paused) // Commands issued may invoke SlowUpdate when paused return; if (dynamic_cast<AAirMoveType*>(owner->moveType)) { LandRepairIfNeeded() || RefuelIfNeeded(); } if (!commandQue.empty() && commandQue.front().timeOut < gs->frameNum) { StopMove(); FinishCommand(); return; } if (commandQue.empty()) { MobileAutoGenerateTarget(); //the attack order could terminate directly and thus cause a loop if (commandQue.empty() || commandQue.front().GetID() == CMD_ATTACK) { return; } } if (!slowGuard) { // when slow-guarding, regulate speed through {Start,Stop}SlowGuard SlowUpdateMaxSpeed(); } Execute(); }
/** * @breif executes the DGun command c */ void CMobileCAI::ExecuteDGun(Command &c){ if(uh->limitDgun && owner->unitDef->isCommander && owner->pos.distance(gs->Team(owner->team)->startPos)>uh->dgunRadius){ StopMove(); return FinishCommand(); } return ExecuteAttack(c); }
END_CLASS_STATES /* ================ rvMonsterConvoyGround::State_Fall ================ */ stateResult_t rvMonsterConvoyGround::State_Fall ( const stateParms_t& parms ) { enum { STAGE_INIT, // Initialize fall stage STAGE_WAITIMPACT, // Wait for the drop turret to hit the ground STAGE_IMPACT, // Handle drop turret impact, switch to combat state STAGE_WAITDONE, STAGE_DONE }; switch ( parms.stage ) { case STAGE_INIT: StopMove ( MOVE_STATUS_DONE ); StopAnimState ( ANIMCHANNEL_LEGS ); StopAnimState ( ANIMCHANNEL_TORSO ); StartSound ( "snd_falling", SND_CHANNEL_VOICE, 0, false, NULL ); PlayEffect ( "fx_droptrail", animator.GetJointHandle ( "origin" ), true ); DisableAnimState ( ANIMCHANNEL_LEGS ); PlayCycle ( ANIMCHANNEL_TORSO, "idle", 0 ); oldOrigin = physicsObj.GetOrigin ( ); return SRESULT_STAGE(STAGE_WAITIMPACT); case STAGE_WAITIMPACT: if ( physicsObj.HasGroundContacts ( ) ) { return SRESULT_STAGE(STAGE_IMPACT); } return SRESULT_WAIT; case STAGE_IMPACT: StopSound ( SND_CHANNEL_VOICE, false ); StopEffect ( "fx_droptrail" ); PlayEffect ( "fx_landing", GetPhysics()->GetOrigin(), (-GetPhysics()->GetGravityNormal()).ToMat3() ); if ( (physicsObj.GetOrigin ( ) - oldOrigin).LengthSqr() > Square(128.0f) ) { PlayAnim ( ANIMCHANNEL_TORSO, "land", 0 ); return SRESULT_STAGE ( STAGE_WAITDONE ); } return SRESULT_STAGE ( STAGE_DONE ); case STAGE_WAITDONE: if ( AnimDone ( ANIMCHANNEL_TORSO, 4 ) ) { return SRESULT_STAGE ( STAGE_DONE ); } return SRESULT_WAIT; case STAGE_DONE: onGround = true; SetAnimState ( ANIMCHANNEL_LEGS, "Legs_Idle" ); SetAnimState ( ANIMCHANNEL_TORSO, "Torso_Idle" ); return SRESULT_DONE; } return SRESULT_ERROR; }
void CBuilderCAI::ExecuteReclaim(Command &c) { assert(owner->unitDef->canReclaim); CBuilder* fac=(CBuilder*)owner; if(c.params.size()==1){ int id=(int) c.params[0]; if(id>=MAX_UNITS){ //reclaim feature CFeature* feature=featureHandler->features[id-MAX_UNITS]; if(feature){ if(!ReclaimObject(feature)){ StopMove(); FinishCommand(); } } else { StopMove(); FinishCommand(); } } else { //reclaim unit CUnit* unit=uh->units[id]; if(unit && unit!=owner && unit->unitDef->reclaimable && UpdateTargetLostTimer(id)){ if(!ReclaimObject(unit)){ StopMove(); FinishCommand(); } } else { FinishCommand(); } } } else if(c.params.size()==4){//area reclaim float3 pos(c.params[0],c.params[1],c.params[2]); float radius=c.params[3]; if(FindReclaimableFeatureAndReclaim(pos,radius,c.options,true)){ inCommand=false; SlowUpdate(); return; } if(!(c.options & ALT_KEY)){ FinishCommand(); } } else { //wrong number of parameters FinishCommand(); } return; }
void CBuilderCAI::ExecuteRepair(Command& c) { CBuilder* fac=(CBuilder*)owner; assert(owner->unitDef->canRepair || owner->unitDef->canAssist); if (c.params.size() == 1) { //repair unit CUnit* unit = uh->units[(int)c.params[0]]; if (tempOrder && owner->moveState == 1) { //limit how far away we go if (unit && LinePointDist(commandPos1, commandPos2, unit->pos) > 500) { StopMove(); FinishCommand(); return; } } if (unit && (unit->health < unit->maxHealth) && ((unit != owner) || owner->unitDef->canSelfRepair) && (!unit->soloBuilder || (unit->soloBuilder == owner)) && UpdateTargetLostTimer((int)c.params[0])) { if (f3SqDist(unit->pos, fac->pos) < Square(fac->buildDistance+unit->radius-8)) { StopMove(); fac->SetRepairTarget(unit); owner->moveType->KeepPointingTo(unit->pos, fac->buildDistance*0.9f+unit->radius, false); } else { if (f3SqDist(goalPos, unit->pos) > 1) { SetGoal(unit->pos,owner->pos, fac->buildDistance*0.9f+unit->radius); } } } else { StopMove(); FinishCommand(); } } else { // repair area float3 pos(c.params[0], c.params[1], c.params[2]); float radius=c.params[3]; if (FindRepairTargetAndRepair(pos, radius, c.options, false)) { inCommand=false; SlowUpdate(); return; } if (!(c.options & ALT_KEY)) { FinishCommand(); } } return; }
void hhCenturion::Event_MoveToTunnel() { if (!armchop_Target.IsValid()) { idThread::ReturnInt(0); return; } StopMove(MOVE_STATUS_DONE); MoveToPosition(armchop_Target->GetOrigin()); idThread::ReturnInt(1); }
void CTransportCAI::UnloadDrop(Command& c) { // fly over and drop unit if (inCommand) { if (!owner->script->IsBusy()) { FinishCommand(); } } else { auto transport = static_cast<CTransportUnit*>(owner); const auto& transportees = transport->GetTransportedUnits(); if (transportees.empty() || dropSpots.empty()) { FinishCommand(); return; } float3 pos = c.GetPos(0); // head towards goal // note that HoverAirMoveType must be modified to allow // non-stop movement through goals for this to work well if (goalPos.SqDistance2D(pos) > Square(20.0f)) { SetGoal(lastDropPos = pos, owner->pos); } CHoverAirMoveType* am = dynamic_cast<CHoverAirMoveType*>(owner->moveType); CUnit* transportee = (transportees.front()).unit; if (am != NULL) { pos.y = CGround::GetHeightAboveWater(pos.x, pos.z); am->maxDrift = 1.0f; // if near target or passed it accidentally, drop unit if (owner->pos.SqDistance2D(pos) < Square(40.0f) || (((pos - owner->pos).Normalize()).SqDistance(owner->frontdir) > 0.25 && owner->pos.SqDistance2D(pos)< (205*205))) { am->SetAllowLanding(false); owner->script->EndTransport(); transport->DetachUnitFromAir(transportee, pos); dropSpots.pop_back(); if (dropSpots.empty()) { // move the transport away after last drop SetGoal(owner->pos + owner->frontdir * 200, owner->pos); } FinishCommand(); } } else { inCommand = true; StopMove(); owner->script->TransportDrop(transportee, pos); } } }
// 压入一条指令 BOOL CObject_Bus::PushCommand(const SCommand_Object *pCmd) { switch(pCmd->m_wID) { case OC_BUS_MOVE: { FLOAT x = pCmd->m_afParam[0]; FLOAT y = pCmd->m_afParam[1]; FLOAT z = pCmd->m_afParam[2]; fVector3 fvGame(x, y, z); StartMove(&fvGame); } break; case OC_BUS_STOP_MOVE: { FLOAT x = pCmd->m_afParam[0]; FLOAT y = pCmd->m_afParam[1]; FLOAT z = pCmd->m_afParam[2]; fVector3 fvGame; CGameProcedure::s_pGfxSystem->Axis_Trans( tGfxSystem::AX_PLAN, fVector3(x, 0.0f, z), tGfxSystem::AX_GAME, fvGame); SetPosition(fvGame); StopMove(); } break; case OC_BUS_ADD_PASSENGER: { INT nIndex = pCmd->m_anParam[0]; INT nPassengerID = pCmd->m_anParam[1]; AddPassenger(nIndex, nPassengerID); } break; case OC_BUS_REMOVE_PASSENGER: { INT nPassengerID = pCmd->m_anParam[0]; RemovePassenger(nPassengerID); } break; case OC_BUS_REMOVE_ALL_PASSENGER: { RemoveAllPassengers(); } break; default: break; } return TRUE; }
void TestMode(void) { long move_time = 100000; long stop_time = 50000; StopMove(); _delay_ms(stop_time); StraightMove(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); StraightMoveLeftSift(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); StraightMoveRightSift(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); StraightMoveLeftSift2(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); StraightMoveRightSift2(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); TurnMoveRight(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); TurnMoveLeft(); _delay_ms(move_time); StopMove(); _delay_ms(stop_time); BackMove(); _delay_ms(move_time); }
void CTransportCAI::UnloadDrop(Command& c) { //fly over and drop unit if(inCommand){ if(!owner->cob->busy) //if(scriptReady) FinishCommand(); } else { if(((CTransportUnit*)owner)->transported.empty()){ FinishCommand(); return; } float3 pos(c.params[0],c.params[1],c.params[2]); //head towards goal //note that taairmovetype must be modified to allow non stop movement through goals for this to work well if(goalPos.distance2D(pos)>20){ SetGoal(pos,owner->pos); lastDropPos = pos; } if(CTAAirMoveType* am=dynamic_cast<CTAAirMoveType*>(owner->moveType)){ pos.y=ground->GetHeight(pos.x,pos.z); CUnit* unit=((CTransportUnit*)owner)->transported.front().unit; am->maxDrift=1; //if near target or have past it accidentally- drop unit if(owner->pos.distance2D(pos) < 40 || (((pos - owner->pos).Normalize()).distance(owner->frontdir.Normalize()) > 0.5 && owner->pos.distance2D(pos)< 205)) { am->dontLand=true; owner->cob->Call("EndTransport"); //test ((CTransportUnit*)owner)->DetachUnitFromAir(unit,pos); dropSpots.pop_back(); if (dropSpots.empty()) { float3 fix = owner->pos+owner->frontdir*200; SetGoal(fix,owner->pos);//move the transport away after last drop } FinishCommand(); } } else { inCommand=true; scriptReady=false; StopMove(); std::vector<int> args; args.push_back(((CTransportUnit*)owner)->transported.front().unit->id); args.push_back(PACKXZ(pos.x, pos.z)); owner->cob->Call("TransportDrop",args,ScriptCallback,this,0); } } }
void CBuilderCAI::ReclaimFeature(CFeature* f) { if (!owner->unitDef->canReclaim || !f->def->reclaimable) { // FIXME user shouldn't be able to queue buildings on top of features // in the first place (in this case). StopMove(); FinishCommand(); } else { Command c2(CMD_RECLAIM, 0, f->id + unitHandler->MaxUnits()); commandQue.push_front(c2); // this assumes that the reclaim command can never return directly // without having reclaimed the target SlowUpdate(); } }
bool CBuilderCAI::ReclaimObject(CSolidObject* object){ CBuilder* fac=(CBuilder*)owner; if (f3SqDist(object->pos, fac->pos) < Square(fac->buildDistance-1+object->radius)) { StopMove(); owner->moveType->KeepPointingTo(object->pos, fac->buildDistance*0.9f+object->radius, false); fac->SetReclaimTarget(object); } else { if (f3SqDist(goalPos, object->pos) > 1) { SetGoal(object->pos, owner->pos); } else { if (owner->moveType->progressState == AMoveType::Failed) { return false; } } } return true; }
/** * @brief Executes the guard command c */ void CMobileCAI::ExecuteGuard(Command &c) { assert(owner->unitDef->canGuard); assert(!c.params.empty()); CUnit* guarded = uh->GetUnit(c.params[0]); if (guarded != NULL && UpdateTargetLostTimer(guarded->id)) { if (owner->unitDef->canAttack && guarded->lastAttack + 40 < gs->frameNum && IsValidTarget(guarded->lastAttacker)) { StopSlowGuard(); Command nc; nc.id = CMD_ATTACK; nc.params.push_back(guarded->lastAttacker->id); nc.options = c.options; commandQue.push_front(nc); SlowUpdate(); return; } else { //float3 dif = guarded->speed * guarded->frontdir; float3 dif = guarded->pos - owner->pos; dif.Normalize(); float3 goal = guarded->pos - dif * (guarded->radius + owner->radius + 64); if((goalPos - goal).SqLength2D() > 1600 || (goalPos - owner->pos).SqLength2D() < (owner->maxSpeed*30 + 1 + SQUARE_SIZE*2) * (owner->maxSpeed*30 + 1 + SQUARE_SIZE*2)){ SetGoal(goal, owner->pos); } if((goal - owner->pos).SqLength2D() < 6400) { StartSlowGuard(guarded->maxSpeed); if((goal-owner->pos).SqLength2D() < 1800){ StopMove(); NonMoving(); } } else { StopSlowGuard(); } } } else { FinishCommand(); } return; }
/** * @brief Executes the guard command c */ void CMobileCAI::ExecuteGuard(Command &c) { assert(owner->unitDef->canGuard); assert(!c.params.empty()); const CUnit* guardee = unitHandler->GetUnit(c.params[0]); if (guardee == NULL) { FinishCommand(); return; } if (UpdateTargetLostTimer(guardee->id) == 0) { FinishCommand(); return; } if (guardee->outOfMapTime > (GAME_SPEED * 5)) { FinishCommand(); return; } const bool pushAttackCommand = owner->unitDef->canAttack && (guardee->lastAttackFrame + 40 < gs->frameNum) && IsValidTarget(guardee->lastAttacker); if (pushAttackCommand) { Command nc(CMD_ATTACK, c.options, guardee->lastAttacker->id); commandQue.push_front(nc); StopSlowGuard(); SlowUpdate(); } else { const float3 dif = (guardee->pos - owner->pos).SafeNormalize(); const float3 goal = guardee->pos - dif * (guardee->radius + owner->radius + 64.0f); const bool resetGoal = ((goalPos - goal).SqLength2D() > 1600.0f) || (goalPos - owner->pos).SqLength2D() < Square(owner->moveType->GetMaxSpeed() * GAME_SPEED + 1 + SQUARE_SIZE * 2); if (resetGoal) { SetGoal(goal, owner->pos); } if ((goal - owner->pos).SqLength2D() < 6400.0f) { StartSlowGuard(guardee->moveType->GetMaxSpeed()); if ((goal - owner->pos).SqLength2D() < 1800.0f) { StopMove(); NonMoving(); } } else { StopSlowGuard(); } } }
void CMobileCAI::SlowUpdate() { if(gs->paused) // Commands issued may invoke SlowUpdate when paused return; bool wantToLand = false; if (dynamic_cast<AAirMoveType*>(owner->moveType)) { wantToLand = LandRepairIfNeeded(); if (!wantToLand && owner->unitDef->maxFuel > 0) { wantToLand = RefuelIfNeeded(); } } if (!commandQue.empty() && commandQue.front().timeOut < gs->frameNum) { StopMove(); FinishCommand(); return; } if (commandQue.empty()) { IdleCheck(); //the attack order could terminate directly and thus cause a loop if(commandQue.empty() || commandQue.front().id == CMD_ATTACK) { return; } } // treat any following CMD_SET_WANTED_MAX_SPEED commands as options // to the current command (and ignore them when it's their turn) if (commandQue.size() >= 2 && !slowGuard) { CCommandQueue::iterator it = commandQue.begin(); it++; const Command& c = *it; if ((c.id == CMD_SET_WANTED_MAX_SPEED) && (c.params.size() >= 1)) { const float defMaxSpeed = owner->maxSpeed; const float newMaxSpeed = std::min(c.params[0], defMaxSpeed); if (newMaxSpeed > 0) owner->moveType->SetMaxSpeed(newMaxSpeed); } } Execute(); }
void CCommandAI::GiveWaitCommand(const Command& c) { if (commandQue.empty()) { commandQue.push_back(c); return; } else if (c.options & SHIFT_KEY) { if (commandQue.back().GetID() == CMD_WAIT) { waitCommandsAI.RemoveWaitCommand(owner, commandQue.back()); commandQue.pop_back(); } else { commandQue.push_back(c); return; } } else if (commandQue.front().GetID()== CMD_WAIT) { waitCommandsAI.RemoveWaitCommand(owner, commandQue.front()); commandQue.pop_front(); } else { // shutdown the current order owner->AttackUnit(0, true); StopMove(); inCommand = false; targetDied = false; unimportantMove = false; commandQue.push_front(c); return; } if (commandQue.empty()) { if (!owner->group) { eoh->UnitIdle(*owner); } eventHandler.UnitIdle(owner); } else { SlowUpdate(); } return; }
void rvMonsterStroggHover::Pursue ( void ) { if ( marker.GetEntity() && GetEnemy() ) { marker.GetEntity()->GetPhysics()->SetOrigin( GetEnemy()->GetPhysics()->GetOrigin()+attackPosOffset ); if ( DebugFilter(ai_debugMove) ) { gameRenderWorld->DebugAxis( marker.GetEntity()->GetPhysics()->GetOrigin(), marker.GetEntity()->GetPhysics()->GetAxis() ); } if ( MarkerPosValid() ) { bool breakOff = false; if ( move.fl.done ) {//even once get there, hold that position for a while... if ( holdPosTime && holdPosTime > gameLocal.GetTime() ) {//held this position long enough breakOff = true; } else { if ( !holdPosTime ) {//just got there, hold position for a bit holdPosTime = gameLocal.random.RandomInt(2000)+3000 + gameLocal.GetTime(); } if ( !MoveToEntity( marker ) ) { breakOff = true; } } } if ( !breakOff ) { return; } } } if ( !move.fl.done ) { StopMove( MOVE_STATUS_DONE ); } inPursuit = false; }
bool CAirCAI::AirAutoGenerateTarget(AAirMoveType* myPlane) { assert(commandQue.empty()); assert(myPlane->owner == owner); const UnitDef* ownerDef = owner->unitDef; const bool autoLand = !ownerDef->DontLand() && myPlane->autoLand; const bool autoAttack = ((owner->fireState >= FIRESTATE_FIREATWILL) && (owner->moveState != MOVESTATE_HOLDPOS)); if (myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING && autoLand) { StopMove(); } if (ownerDef->canAttack && autoAttack && owner->maxRange > 0) { if (ownerDef->IsFighterAirUnit()) { const float3 P = owner->pos + (owner->speed * 10.0); const float R = 1000.0f * owner->moveState; const CUnit* enemy = CGameHelper::GetClosestEnemyAircraft(NULL, P, R, owner->allyteam); if (IsValidTarget(enemy)) { Command nc(CMD_ATTACK, INTERNAL_ORDER, enemy->id); commandQue.push_front(nc); inCommand = false; return true; } } else { const float3 P = owner->pos + (owner->speed * 20.0f); const float R = 500.0f * owner->moveState; const CUnit* enemy = CGameHelper::GetClosestValidTarget(P, R, owner->allyteam, this); if (enemy != NULL) { Command nc(CMD_ATTACK, INTERNAL_ORDER, enemy->id); commandQue.push_front(nc); inCommand = false; return true; } } } return false; }
void CBuilderCAI::ExecuteRestore(Command &c) { assert(owner->unitDef->canRestore); CBuilder* fac=(CBuilder*)owner; if(inCommand){ if(!fac->terraforming){ FinishCommand(); } } else if(owner->unitDef->canRestore){ float3 pos(c.params[0],c.params[1],c.params[2]); float radius(c.params[3]); if(fac->pos.distance2D(pos)<fac->buildDistance-1){ StopMove(); fac->StartRestore(pos,radius); owner->moveType->KeepPointingTo(pos, fac->buildDistance*0.9f, false); inCommand=true; } else { SetGoal(pos,owner->pos, fac->buildDistance*0.9f); } } return; }