virtual void GetClosestApproachTarget() { float dist = FLT_MAX; const AUVec3f& refPos = m_pOwner->GetEntity()->GetPosition(); GetClosestTarget( m_pBBIndividual->visible_infected, refPos, dist, &m_pApproachTarget ); GetClosestTarget( m_pBBIndividual->visible_viruses, refPos, dist, &m_pApproachTarget ); }
void GetClosestAvoidTarget() { float dist = FLT_MAX; const AUVec3f& refPos = m_pOwner->GetEntity()->GetPosition(); GetClosestTarget( m_pBBIndividual->visible_wbc, refPos, dist, &m_pAvoidTarget ); if ( m_pAvoidTarget && m_pAvoidTarget->GetThreatRating() < m_pOwner->GetThreatRating() ) { m_pAvoidTarget = 0; } }
// Called every frame void UAd_CharacterAIComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) { Super::TickComponent( DeltaTime, TickType, ThisTickFunction ); //if (!isAI) return;// OwningPawn == PlayersPawn) return; if (!Cast<AAdder_DodgeBallCharacter>(OwningPawn)->isAI) return; // ... AITimer = AITimer - DeltaTime; if (AITimer < 0) { if (!Cast<AAdder_DodgeBallCharacter>(OwningPawn)->isAlive && Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall) { Cast<AAdder_DodgeBallCharacter>(OwningPawn)->ThrowBall(); Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall = false; return; } targetPoint += FVector(rand() % 511 - 255, rand() % 511 - 255, 0); //UE_LOG(LogTemp, Warning, TEXT("Iterating")); bool gettingPowerUp = false; if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)->currentPowerup == PowerUp::PowerUpType::none) { for (TActorIterator<APowerUpPickUp> Tai(GetWorld()); Tai; ++Tai) { if (IsClosestToTarget(*Tai)) { FVector PUpPoint = Tai->GetActorLocation(); if (PUpPoint.X < boundsPoint.X + boundsVector.X && PUpPoint.X > boundsPoint.X - boundsVector.X &&PUpPoint.Y < boundsPoint.Y + boundsVector.Y && PUpPoint.Y > boundsPoint.Y - boundsVector.Y) { targetPoint = PUpPoint; gettingPowerUp = true; } } } } targetActor = nullptr; if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall || !gettingPowerUp) { FVector UserPoint = OwningPawn->GetTransform().GetLocation(); for (TActorIterator<AMyBallClass> Tai(GetWorld()); Tai; ++Tai) { if (Tai->ActorHasTag("Ball")) { if (Tai->GetAttachParentActor() == GetOwner()) {// || Tai->OwningActor == GetOwner()) { //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("BallOwner"))); targetActor = GetClosestTarget(); if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)) { //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("hasBall"))); Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall = true; Cast<AAdder_DodgeBallCharacter>(OwningPawn)->ballRef = *Tai; if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)->throwPower > 0.75f) { Cast<AAdder_DodgeBallCharacter>(OwningPawn)->ThrowBall(); Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall = false; } } if (targetActor != nullptr) { targetPoint = targetActor->GetActorLocation(); } else GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("nullTarget"))); } else { //targetActor = nullptr; if (IsClosestToTarget(*Tai)) { //chase the ball if it's on AI side of the court FVector BallPoint = Tai->GetActorLocation(); if (BallPoint.X < boundsPoint.X + boundsVector.X && BallPoint.X > boundsPoint.X - boundsVector.X &&BallPoint.Y < boundsPoint.Y + boundsVector.Y && BallPoint.Y > boundsPoint.Y - boundsVector.Y) { //targetPoint = BallPoint; targetPoint = BallPoint + Tai->GetVelocity()* FVector::Dist(BallPoint, UserPoint) * 0.003f; } //run from the ball if it's flying FVector BallVelocity = Tai->GetVelocity(); bool IsDeadly = Cast<AMyBallClass>(*Tai)->GetIsDeadly(); //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("BallVector: %f"), BallVelocity.Size())); if (BallVelocity.Size() > 120.0f && IsDeadly) { FVector MovePoint = (OwningPawn->GetTransform().GetLocation() - BallPoint); MovePoint.Normalize(); targetPoint = UserPoint + (MovePoint * 180); } } } } } } if (targetPoint.X > boundsPoint.X + boundsVector.X) targetPoint.X -= 255;// = boundsPoint.X + boundsVector.X; if (targetPoint.X < boundsPoint.X - boundsVector.X) targetPoint.X += 255;// = boundsPoint.X - boundsVector.X; if (targetPoint.Y > boundsPoint.Y + boundsVector.Y) targetPoint.Y -= 255;// = boundsPoint.Y + boundsVector.Y; if (targetPoint.Y < boundsPoint.Y - boundsVector.Y) targetPoint.Y += 255;// = boundsPoint.Y - boundsVector.Y; if(Cast<AAdder_DodgeBallCharacter>(OwningPawn)) if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall == true && targetActor != nullptr) { targetPoint = targetActor->GetActorLocation(); } targetPoint.Z = OwningPawn->GetTransform().GetLocation().Z; AITimer = AITimer + AITimeStep + (rand() % 100) / 250.0f; } if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)) { if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall) { if (targetActor == nullptr) { targetActor = GetClosestTarget(); if (targetActor != nullptr) targetPoint = targetActor->GetActorLocation(); } // if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)) { Cast<AAdder_DodgeBallCharacter>(OwningPawn)->WindUp(); // if (Cast<AAdder_DodgeBallCharacter>(OwningPawn)->throwPower > 0.95f) { // Cast<AAdder_DodgeBallCharacter>(OwningPawn)->ThrowBall(); // Cast<AAdder_DodgeBallCharacter>(OwningPawn)->hasBall = false; // } // } }// else if (targetActor != nullptr) { } } if (FMath::Abs(FVector::Dist(targetPoint, OwningPawn->GetTransform().GetLocation())) > 32) { //OwningPawn->AddMovementInput(targetPoint - OwningPawn->GetTransform().GetLocation(), 1, false); OwningPawn->GetMovementComponent()->AddInputVector(targetPoint - OwningPawn->GetTransform().GetLocation(), false); } }
//------------------------------------------------------------------------ void CGunTurret::ServerUpdate(SEntityUpdateContext &ctx, int update) { //update parameters. SNH: cache these in MP since they never change. if(!gEnv->bMultiplayer) { UpdateEntityProperties(); } IEntity *pCurrentTarget = gEnv->pEntitySystem->GetEntity(m_targetId); IActor *pCurrentActor = GetActor(m_targetId); bool mg=false; bool rocket=false; if(IsOperational()) { bool renew_target = false; //do this before, cause it's more important if(m_turretparams.TAC_check_time != 0.f) { if(m_checkTACTimer>m_turretparams.TAC_check_time) { m_checkTACTimer = 0.0f; IEntity *pClosest = GetClosestTACShell(); if(pClosest) { ChangeTargetTo(pClosest); pCurrentTarget = pClosest; } } else m_checkTACTimer += ctx.fFrameTime; } //actually if(...), break at end while(pCurrentTarget) { if(InternalIsFiring(false)) m_burstTimer += ctx.fFrameTime; else m_burstTimer = 0.f; ETargetClass t_class = GetTargetClass(pCurrentTarget); bool validClass = (t_class!=eTC_NotATarget); Vec3 tpos = PredictTargetPos(pCurrentTarget,false); bool inrange = IsInRange(tpos, t_class); if(m_rayTimer <= 0.f) { m_canShoot = IsTargetShootable(pCurrentTarget); m_rayTimer = (m_canShoot) ? 0.5f : 0.2f; } else m_rayTimer -= ctx.fFrameTime; if(!(validClass && inrange && m_canShoot)) { m_abandonTargetTimer += ctx.fFrameTime; } else m_abandonTargetTimer = 0.0f; if(m_abandonTargetTimer > m_turretparams.abandon_target_time + m_randoms[eRV_AbandonTarget].val) { renew_target = true; m_randoms[eRV_AbandonTarget].New(); break; } bool aim = inrange&&m_canShoot&&IsAiming(tpos, m_turretparams.aim_tolerance); mg = aim && !m_turretparams.search_only && IsTargetMGable(tpos); bool burst = (m_turretparams.burst_time == 0.f || UpdateBurst(ctx.fFrameTime)); mg &= burst; // a bit less tolerant for rockets aim=aim&&IsAiming(tpos, m_turretparams.aim_tolerance*0.5f); rocket = aim && !m_turretparams.search_only && m_fm2 && t_class == eTC_Vehicle && IsTargetRocketable(tpos); if(g_pGameCVars->i_debug_turrets) { IRenderer *pRenderer = gEnv->pRenderer; static float white[4] = {1,1,1,1}; float x = 5.f, y = 50.f, step1 = 15.f, /*step2 = 20.f, */size=1.3f; pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Target: %s", pCurrentTarget->GetName()); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "InRange: %i", inrange); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "CanShoot: %i", m_canShoot); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "IsAiming: %i", aim); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Burst: %i", burst); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "MG: %i", mg); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "BurstTimer: %.2f", m_burstTimer); //pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Rocket: %i", rocket); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "TargetPos: %.1f %.1f %.1f", tpos.x, tpos.y, tpos.z); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Abandon: %.2f", m_abandonTargetTimer); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Update: %.2f", m_updateTargetTimer); pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "GoalYaw: %.2f, GoalPitch: %.2f", m_goalYaw, m_goalPitch); } break; } m_updateTargetTimer += ctx.fFrameTime; if(renew_target || m_updateTargetTimer > m_turretparams.update_target_time+m_randoms[eRV_UpdateTarget].Val()) { IEntity *pClosestTAC = GetClosestTACShell(); IEntity *pClosest = (pClosestTAC) ? pClosestTAC : GetClosestTarget(); // change target if tac shell, or other target closer than current // otherwise, only change after abandoning time is exceeded if(pClosestTAC || (pClosest && pClosest->GetId()!=m_targetId) || (!pClosest && !(m_abandonTargetTimer>0.f && m_abandonTargetTimer<=m_turretparams.abandon_target_time))) { ChangeTargetTo(pClosest); pCurrentTarget = pClosest; } m_updateTargetTimer = 0.f; m_randoms[eRV_UpdateTarget].New(); } if(pCurrentTarget) { if(m_turretparams.surveillance || IsTargetShootable(pCurrentTarget)) UpdateGoal(pCurrentTarget, ctx.fFrameTime); } else { if(m_turretparams.searching) { UpdateSearchingGoal(ctx.fFrameTime); } } } if(m_fm && mg != InternalIsFiring(false)) { if(mg) InternalStartFire(false); else InternalStopFire(false); } if(m_fm2 && rocket != InternalIsFiring(true)) { if(rocket) InternalStartFire(true); else InternalStopFire(true); } }