#include "EnterAurora.h" #include "AuroraBaseWeapon.h" // Sets default values AAuroraBaseWeapon::AAuroraBaseWeapon(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // Create Weapon Mesh weaponMesh = ObjectInitializer.CreateDefaultSubobject(this, TEXT("Weapon Mesh")); RootComponent = weaponMesh; // Create Audio Component audioSource = ObjectInitializer.CreateDefaultSubobject(this, TEXT("Audio Source")); audioSource->AttachTo(RootComponent); audioSource->bAutoActivate = false; bCanFire = true; } // Called when the game starts or when spawned void AAuroraBaseWeapon::BeginPlay() { Super::BeginPlay(); } // Called every frame void AAuroraBaseWeapon::Tick(float DeltaTime) { Super::Tick(DeltaTime); //GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Cyan, TEXT("Cryo: " + FString::SanitizeFloat(currentCryoLevel))); } void AAuroraBaseWeapon::OnWeaponFireStart() { if (bCanFire) { Instant_Fire(); audioSource->Activate(true); audioSource->Play(0.0f); bCanFire = false; GetWorld()->GetTimerManager().SetTimer(fireHandler, this, &AAuroraBaseWeapon::OnWeaponFireStop, fireRate, false); } } void AAuroraBaseWeapon::OnWeaponFireStop() { bCanFire = true; } void AAuroraBaseWeapon::Instant_Fire() { const int32 RandomSeed = FMath::Rand(); FRandomStream weaponRandomStream(RandomSeed); const float currentSpread = weaponSpread; const float spreadCone = FMath::DegreesToRadians(weaponSpread * 0.5f); const FVector aimDir = weaponMesh->GetSocketRotation(muzzleSocket).Vector(); const FVector startTrace = weaponMesh->GetSocketLocation(muzzleSocket); const FVector shootDir = weaponRandomStream.VRandCone(aimDir, spreadCone, spreadCone); const FVector endTrace = startTrace + shootDir * weaponRange; const FHitResult impact = WeaponTrace(startTrace, endTrace); ProcessInstantHit(impact, startTrace, shootDir, RandomSeed, currentSpread); } FHitResult AAuroraBaseWeapon::WeaponTrace(const FVector & TraceFrom, const FVector & TraceTo) const { static FName weaponFireTag = FName(TEXT("WeaponTrace")); FCollisionQueryParams traceParams(weaponFireTag, true, Instigator); traceParams.bTraceAsyncScene = true; traceParams.bReturnPhysicalMaterial = true; traceParams.AddIgnoredActor(this); FHitResult hit(ForceInit); GetWorld()->LineTraceSingleByChannel(hit, TraceFrom, TraceTo, Trace_Weapon, traceParams); return hit; } void AAuroraBaseWeapon::ProcessInstantHit(const FHitResult & Impact, const FVector & Origin, const FVector & ShootDir, int32 RandomSeed, float ReticleSpread) { const FVector endTrace = Origin + ShootDir * weaponRange; const FVector endPoint = Impact.GetActor() ? Impact.ImpactPoint : endTrace; DrawDebugLine(this->GetWorld(), Origin, Impact.TraceEnd, FColor::Red, true, 1000.0f, 10.0f); FDamageEvent damageEvent; }