void ATurret::TargetOutofRange() { if (!IsValid(this)) return; TArray<FHitResult> hits; FVector start = GetActorLocation(); FVector end = start; end.Z += 5.f; TArray<AGameCharacter*> possibleTargets; GetWorld()->SweepMultiByChannel(hits, start, end, GetActorRotation().Quaternion(), ECC_Visibility, FCollisionShape::MakeSphere(GetCurrentValueForStat(EStat::ES_AARange))); for (FHitResult hit : hits) { AGameCharacter* gc = Cast<AGameCharacter>(hit.GetActor()); if (IsValid(gc) && gc->IsAlive() && GetTeamIndex() != gc->GetTeamIndex()) possibleTargets.AddUnique(gc); } //first aggro any minions first for (AGameCharacter* gc : possibleTargets) { if (gc->IsA(AMinionCharacter::StaticClass())) { SetCurrentTarget(gc); StartAutoAttack(); return; } } //then aggro an objective if we can for (AGameCharacter* gc : possibleTargets) { if (gc->IsA(ARealmObjective::StaticClass())) { SetCurrentTarget(gc); StartAutoAttack(); return; } } //lastly aggro any mythos for (AGameCharacter* gc : possibleTargets) { if (gc->IsA(APlayerCharacter::StaticClass())) { SetCurrentTarget(gc); StartAutoAttack(); return; } } StopAutoAttack(); }
void ATurret::OnFinishAATimer() { bAutoAttackOnCooldown = false; bAutoAttackLaunching = false; if (IsValid(GetCurrentTarget()) && GetCurrentTarget()->IsAlive() && !GetCurrentTarget()->bHidden) StartAutoAttack(); else TargetOutofRange(); }
void ATurret::OnSeePawn(APawn* OtherActor) { AGameCharacter* gc = Cast<AGameCharacter>(OtherActor); if (gc && (!gc->IsAlive() || gc->GetTeamIndex() == GetTeamIndex())) return; if (!currentTarget && IsValid(gc)) { SetCurrentTarget(gc); StartAutoAttack(); } }
void ATurret::TargetOutofRange() { float leastDistance = -1.f; int32 leastInd = -1; if (!IsValid(this)) return; inRangeTargets.Empty(); for (TActorIterator<AGameCharacter> chritr(GetWorld()); chritr; ++chritr) { AGameCharacter* gc = *chritr; if (IsValid(gc) && gc->IsAlive() && gc != this && gc->GetTeamIndex() != GetTeamIndex()) { float dist = (gc->GetActorLocation() - GetActorLocation()).Size(); if (dist <= GetCurrentValueForStat(EStat::ES_AARange)) inRangeTargets.AddUnique(gc); } } //if we should priortize Mythos AGameCharacter* otherTarget = nullptr; for (int32 i = 0; i < inRangeTargets.Num(); i++) { if (inRangeTargets[i]->IsA(AMinionCharacter::StaticClass())) continue; float distanceSq = (inRangeTargets[i]->GetActorLocation() - GetActorLocation()).SizeSquared2D(); if (!inRangeTargets[i]->IsAlive() || distanceSq > FMath::Square(710.f)) { inRangeTargets.RemoveAt(i); continue; } if (leastDistance == -1.f) { leastDistance = distanceSq; leastInd = i; continue; } if (distanceSq < leastDistance) { leastDistance = distanceSq; leastInd = i; } } if (bPrioritizeMythos) { if (leastInd >= 0) { currentTarget = inRangeTargets[leastInd]; StartAutoAttack(); return; } } else { if (leastInd >= 0) otherTarget = inRangeTargets[leastInd]; } leastDistance = -1.f; leastInd = -1; for (int32 i = 0; i < inRangeTargets.Num(); i++) { if (!inRangeTargets[i]->IsA(AMinionCharacter::StaticClass())) continue; float distanceSq = (inRangeTargets[i]->GetActorLocation() - GetActorLocation()).SizeSquared2D(); if (!inRangeTargets[i]->IsAlive() || distanceSq > FMath::Square(710.f)) { inRangeTargets.RemoveAt(i); continue; } if (leastDistance == -1.f) { leastDistance = distanceSq; leastInd = i; continue; } if (distanceSq < leastDistance) { leastDistance = distanceSq; leastInd = i; } } if (leastInd >= 0) { currentTarget = inRangeTargets[leastInd]; StartAutoAttack(); return; } if (otherTarget) { currentTarget = otherTarget; StartAutoAttack(); } else { currentTarget = nullptr; StopAutoAttack(); } }