<commit_before>
#include "FlarePilotHelper.h"
#include "../Flare.h"
#include "../Game/FlareCompany.h"
#include "../Game/FlareSector.h"
#include "../Game/FlareGame.h"
#include "../Game/FlareCollider.h"
#include "FlareRCS.h"
#include "FlareOrbitalEngine.h"
#include "FlareWeapon.h"
#include "FlareShipPilot.h"
#include "../Quests/FlareMeteorite.h"


DECLARE_CYCLE_STAT(TEXT("PilotHelper CheckFriendlyFire"), STAT_PilotHelper_CheckFriendlyFire, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper Anticollision"), STAT_PilotHelper_AnticollisionCorrection, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper Anticollision Avoidance"), STAT_PilotHelper_AnticollisionCorrection_Avoidance, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper GetBestTarget"), STAT_PilotHelper_GetBestTarget, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper GetBestTargetComponent"), STAT_PilotHelper_GetBestTargetComponent, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper CheckRelativeDangerosity"), STAT_PilotHelper_CheckRelativeDangerosity, STATGROUP_Flare);


bool PilotHelper::CheckFriendlyFire(UFlareSector* Sector, UFlareCompany* MyCompany, FVector FireBaseLocation, FVector FireBaseVelocity , float AmmoVelocity, FVector FireAxis, float MaxDelay, float AimRadius)
{
	SCOPE_CYCLE_COUNTER(STAT_PilotHelper_CheckFriendlyFire);

	//FLOG("CheckFriendlyFire");
	for (int32 SpacecraftIndex = 0; SpacecraftIndex < Sector->GetSpacecrafts().Num(); SpacecraftIndex++)
	{
		AFlareSpacecraft* SpacecraftCandidate = Sector->GetSpacecrafts()[SpacecraftIndex];

		if (SpacecraftCandidate)
		{
			if (MyCompany->GetWarState(SpacecraftCandidate->GetParent()->GetCompany()) == EFlareHostility::Hostile)
			{
				//FLOG("  hostile, skip");
				continue;
			}

			// Compute target Axis for each gun
			FVector AmmoIntersectionLocation;
			float AmmoIntersectionTime = SpacecraftHelper::GetIntersectionPosition(SpacecraftCandidate->GetActorLocation(), SpacecraftCandidate->Airframe->GetPhysicsLinearVelocity(), FireBaseLocation, FireBaseVelocity , AmmoVelocity, 0, &AmmoIntersectionLocation);
			if (AmmoIntersectionTime < 0 || AmmoIntersectionTime > MaxDelay)
			{
				// No ammo intersection, or too far, don't alert
				//FLOGV("  Too far (%f > %f)", AmmoIntersectionTime , MaxDelay);
				continue;
			}

			float TargetSize = SpacecraftCandidate->GetMeshScale() / 100.f + AimRadius * 2; // Radius in meters
			FVector DeltaLocation = (SpacecraftCandidate->GetActorLocation()-FireBaseLocation) / 100.f;
			float Distance = DeltaLocation.Size();

			FVector FireTargetAxis = (AmmoIntersectionLocation - FireBaseLocation - AmmoIntersectionTime * FireBaseVelocity).GetUnsafeNormal();

			float AngularPrecisionDot = FVector::DotProduct(FireTargetAxis, FireAxis);
			float AngularPrecision = FMath::Acos(AngularPrecisionDot);
			float AngularSize = FMath::Atan(TargetSize / Distance);



			/*FLOGV("  TargetSize %f", TargetSize);
			FLOGV("  Distance %f", Distance);
			FLOGV("  AngularPrecision %f", AngularPrecision);
			FLOGV("  AngularSize %f", AngularSize);*/
			if (AngularPrecision < AngularSize)
			{
				//FLOG("  Dangerous");
				// Dangerous !
				return true;
			}
		}
	}
	return false;

}

bool PilotHelper::FindMostDangerousCollision(AActor*& MostDangerousCandidateActor,
											 FVector& MostDangerousLocation,
											 float& MostDangerousTimeToHit,
											 float& MostDangerousInterceptDepth,
											 AFlareSpacecraft* Ship, AnticollisionConfig IgnoreConfig, float SpeedLimit)
{
	SCOPE_CYCLE_COUNTER(STAT_PilotHelper_AnticollisionCorrection);

	typedef TPair<AActor*, FVector> TFlareCollisionCandidate;

	UFlareSector* ActiveSector = Ship->GetGame()->GetActiveSector();
	TArray<TFlareCollisionCandidate> Candidates;
	TFlareCollisionCandidate Candidate;

	// Select dangerous ships
	for (auto SpacecraftCandidate : ActiveSector->GetSpacecrafts())
	{
		if (SpacecraftCandidate != Ship
		 && SpacecraftCandidate != IgnoreConfig.SpacecraftToIgnore
		 && !(IgnoreConfig.IgnoreAllStations && SpacecraftCandidate->IsStation())
		 && !Ship->GetDockingSystem()->IsGrantedShip(SpacecraftCandidate)
		 && !Ship->GetDockingSystem()->IsDockedShip(SpacecraftCandidate)
		 && !(Ship->GetSize() == EFlarePartSize::L
			  && SpacecraftCandidate->GetSize() == EFlarePartSize::S
			  && IsShipDangerous(SpacecraftCandidate)
			  && Ship->GetWarState(SpacecraftCandidate->GetCompany()) == EFlareHostility::Hostile))
		{
			Candidate.Key = SpacecraftCandidate;
			Candidate.Value = SpacecraftCandidate->Airframe->GetPhysicsLinearVelocity();
			Candidates.Add(Candidate);
		}
	}

	// Select dangerous asteroids
	for (auto AsteroidCandidate : ActiveSector->GetAsteroids())
	{
		Candidate.Key = AsteroidCandidate;
		Candidate.Value = AsteroidCandidate->GetAsteroidComponent()->GetPhysicsLinearVelocity();
		Candidates.Add(Candidate);
	}<commit_msg>#1105 Fix docking on complex with large ships<commit_after>
#include "FlarePilotHelper.h"
#include "../Flare.h"
#include "../Game/FlareCompany.h"
#include "../Game/FlareSector.h"
#include "../Game/FlareGame.h"
#include "../Game/FlareCollider.h"
#include "FlareRCS.h"
#include "FlareOrbitalEngine.h"
#include "FlareWeapon.h"
#include "FlareShipPilot.h"
#include "../Quests/FlareMeteorite.h"


DECLARE_CYCLE_STAT(TEXT("PilotHelper CheckFriendlyFire"), STAT_PilotHelper_CheckFriendlyFire, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper Anticollision"), STAT_PilotHelper_AnticollisionCorrection, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper Anticollision Avoidance"), STAT_PilotHelper_AnticollisionCorrection_Avoidance, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper GetBestTarget"), STAT_PilotHelper_GetBestTarget, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper GetBestTargetComponent"), STAT_PilotHelper_GetBestTargetComponent, STATGROUP_Flare);
DECLARE_CYCLE_STAT(TEXT("PilotHelper CheckRelativeDangerosity"), STAT_PilotHelper_CheckRelativeDangerosity, STATGROUP_Flare);


bool PilotHelper::CheckFriendlyFire(UFlareSector* Sector, UFlareCompany* MyCompany, FVector FireBaseLocation, FVector FireBaseVelocity , float AmmoVelocity, FVector FireAxis, float MaxDelay, float AimRadius)
{
	SCOPE_CYCLE_COUNTER(STAT_PilotHelper_CheckFriendlyFire);

	//FLOG("CheckFriendlyFire");
	for (int32 SpacecraftIndex = 0; SpacecraftIndex < Sector->GetSpacecrafts().Num(); SpacecraftIndex++)
	{
		AFlareSpacecraft* SpacecraftCandidate = Sector->GetSpacecrafts()[SpacecraftIndex];

		if (SpacecraftCandidate)
		{
			if (MyCompany->GetWarState(SpacecraftCandidate->GetParent()->GetCompany()) == EFlareHostility::Hostile)
			{
				//FLOG("  hostile, skip");
				continue;
			}

			// Compute target Axis for each gun
			FVector AmmoIntersectionLocation;
			float AmmoIntersectionTime = SpacecraftHelper::GetIntersectionPosition(SpacecraftCandidate->GetActorLocation(), SpacecraftCandidate->Airframe->GetPhysicsLinearVelocity(), FireBaseLocation, FireBaseVelocity , AmmoVelocity, 0, &AmmoIntersectionLocation);
			if (AmmoIntersectionTime < 0 || AmmoIntersectionTime > MaxDelay)
			{
				// No ammo intersection, or too far, don't alert
				//FLOGV("  Too far (%f > %f)", AmmoIntersectionTime , MaxDelay);
				continue;
			}

			float TargetSize = SpacecraftCandidate->GetMeshScale() / 100.f + AimRadius * 2; // Radius in meters
			FVector DeltaLocation = (SpacecraftCandidate->GetActorLocation()-FireBaseLocation) / 100.f;
			float Distance = DeltaLocation.Size();

			FVector FireTargetAxis = (AmmoIntersectionLocation - FireBaseLocation - AmmoIntersectionTime * FireBaseVelocity).GetUnsafeNormal();

			float AngularPrecisionDot = FVector::DotProduct(FireTargetAxis, FireAxis);
			float AngularPrecision = FMath::Acos(AngularPrecisionDot);
			float AngularSize = FMath::Atan(TargetSize / Distance);



			/*FLOGV("  TargetSize %f", TargetSize);
			FLOGV("  Distance %f", Distance);
			FLOGV("  AngularPrecision %f", AngularPrecision);
			FLOGV("  AngularSize %f", AngularSize);*/
			if (AngularPrecision < AngularSize)
			{
				//FLOG("  Dangerous");
				// Dangerous !
				return true;
			}
		}
	}
	return false;

}

bool PilotHelper::FindMostDangerousCollision(AActor*& MostDangerousCandidateActor,
											 FVector& MostDangerousLocation,
											 float& MostDangerousTimeToHit,
											 float& MostDangerousInterceptDepth,
											 AFlareSpacecraft* Ship, AnticollisionConfig IgnoreConfig, float SpeedLimit)
{
	SCOPE_CYCLE_COUNTER(STAT_PilotHelper_AnticollisionCorrection);

	typedef TPair<AActor*, FVector> TFlareCollisionCandidate;

	UFlareSector* ActiveSector = Ship->GetGame()->GetActiveSector();
	TArray<TFlareCollisionCandidate> Candidates;
	TFlareCollisionCandidate Candidate;

	// Select dangerous ships
	for (auto SpacecraftCandidate : ActiveSector->GetSpacecrafts())
	{
		if (SpacecraftCandidate != Ship
		 && SpacecraftCandidate != IgnoreConfig.SpacecraftToIgnore
		 && !(IgnoreConfig.IgnoreAllStations && SpacecraftCandidate->IsStation())
		 && !Ship->GetDockingSystem()->IsGrantedShip(SpacecraftCandidate)
		 && !Ship->GetDockingSystem()->IsDockedShip(SpacecraftCandidate)
		 && !(Ship->GetSize() == EFlarePartSize::L
			  && SpacecraftCandidate->GetSize() == EFlarePartSize::S
			  && IsShipDangerous(SpacecraftCandidate)
			  && Ship->GetWarState(SpacecraftCandidate->GetCompany()) == EFlareHostility::Hostile)
		&& !(IgnoreConfig.SpacecraftToIgnore && IgnoreConfig.SpacecraftToIgnore->IsStation() && IgnoreConfig.SpacecraftToIgnore->GetParent()->IsComplexElement() && SpacecraftCandidate->GetParent() == IgnoreConfig.SpacecraftToIgnore->GetParent()->GetComplexMaster())
		&& !(IgnoreConfig.SpacecraftToIgnore && IgnoreConfig.SpacecraftToIgnore->IsStation() && IgnoreConfig.SpacecraftToIgnore->GetParent()->IsComplex() && SpacecraftCandidate->GetParent()->GetComplexMaster() == IgnoreConfig.SpacecraftToIgnore->GetParent())
		)
		{
			Candidate.Key = SpacecraftCandidate;
			Candidate.Value = SpacecraftCandidate->Airframe->GetPhysicsLinearVelocity();
			Candidates.Add(Candidate);
		}
	}

	// Select dangerous asteroids
	for (auto AsteroidCandidate : ActiveSector->GetAsteroids())
	{
		Candidate.Key = AsteroidCandidate;
		Candidate.Value = AsteroidCandidate->GetAsteroidComponent()->GetPhysicsLinearVelocity();
		Candidates.Add(Candidate);
	}
{'fraction_non_alphanumeric': 0.1158357771260997, 'fraction_numerical': 0.002737047898338221, 'mean_word_length': 6.240622788393489, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3101421', 'n_tokens_mistral': 3646, 'n_tokens_neox': 3216, 'n_words': 517}