167 lines
8.8 KiB
C++
167 lines
8.8 KiB
C++
// Copyright 2020 Mookie. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Components/PrimitiveComponent.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
#include "EBBullet.h"
|
|
#include "EBWeaponConfiguration.h"
|
|
|
|
#include "EBBarrel.generated.h"
|
|
|
|
UCLASS(Blueprintable, ClassGroup = (Custom), hidecategories = (Object, LOD, Physics, Lighting, TextureStreaming, Collision, HLOD, Mobile, VirtualTexture, ComponentReplication), editinlinenew, meta = (BlueprintSpawnableComponent))
|
|
class EASYBALLISTICS_API UEBBarrel : public UPrimitiveComponent
|
|
{
|
|
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// Sets default values for this component's properties
|
|
UEBBarrel();
|
|
|
|
// Gun Integration
|
|
UPROPERTY(BlueprintReadOnly, Category = "Gun Integration")
|
|
class AEBGun* ParentGun;
|
|
|
|
// Barrel Physical Properties (from weapon config)
|
|
UPROPERTY(BlueprintReadOnly, Category = "Barrel Properties")
|
|
float BarrelLength = 16.0f; // inches
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "Barrel Properties")
|
|
float RiflingTwist = 7.0f; // 1:X twist rate
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "Barrel Properties")
|
|
float BoreRadius = 0.112f; // inches
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "Barrel Properties")
|
|
float MuzzleVelocityMin = 91440.0f; // cm/s
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "Barrel Properties")
|
|
float MuzzleVelocityMax = 91440.0f; // cm/s
|
|
|
|
// Called every frame
|
|
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
|
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Debug") float DebugArrowSize = 100.0f;
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Debug") bool DebugImpactInfo = false;
|
|
|
|
// Enhanced Debug Controls
|
|
UFUNCTION(BlueprintCallable, Category = "EBBarrel|Debug")
|
|
void SetBulletDebugCategory(const FString& CategoryName, bool bEnabled);
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "EBBarrel|Debug")
|
|
void SetAllBulletDebugCategories(bool bEnabled);
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "EBBarrel|Debug")
|
|
void ClearAllBulletDebugDisplay();
|
|
|
|
UFUNCTION(BlueprintPure, Category = "EBBarrel|Debug")
|
|
FString GetBulletDebugInfo() const;
|
|
|
|
// Gun Integration Functions
|
|
UFUNCTION(BlueprintCallable, Category = "Gun Integration")
|
|
void SetParentGun(class AEBGun* Gun);
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
class AEBGun* GetParentGun() const { return ParentGun; }
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Gun Integration")
|
|
void ApplyBarrelConfiguration(const struct FBarrelConfiguration& BarrelConfig);
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
bool IsConnectedToGun() const { return ParentGun != nullptr; }
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
class UEBMagazine* GetConnectedMagazine() const;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
class UEBBulletPropertiesAsset* GetChamberedBulletType() const;
|
|
|
|
// Enhanced Barrel Functions
|
|
UFUNCTION(BlueprintPure, Category = "Barrel Properties")
|
|
float CalculateEffectiveMuzzleVelocity(class UEBBulletPropertiesAsset* BulletType) const;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Barrel Properties")
|
|
float CalculateBarrelAccuracy() const;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Barrel Properties")
|
|
FVector CalculateRecoilImpulse(class UEBBulletPropertiesAsset* BulletType) const;
|
|
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Velocity", meta = (ToolTip = "Bullet inherits barrel velocity, only works with physics enabled or with additional velocity set")) float InheritVelocity = 1.0f;
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Velocity", meta = (ToolTip = "Amount of recoil applied to the barrel, only works with physics enabled")) float RecoilMultiplier = 1.0f;
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Velocity", meta = (ToolTip = "Additional velocity, for use with InheritVelocity")) FVector AdditionalVelocity = FVector(0,0,0);
|
|
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Weapon", meta = (ToolTip = "Additional maximum spread, in radians, applied on top of bullet spread", ClampMin = "0")) float Spread=0.0f;
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Weapon", meta = (ToolTip = "Additional Spread bias, higher is more accurate on average", ClampMin = "0")) float SpreadBias = 0.0f;
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Weapon", meta = (ToolTip = "Minimum of random multiplier applied to bullet muzzle velocity")) float MuzzleVelocityMultiplierMin = 1.0f;
|
|
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Weapon", meta = (ToolTip = "Maximum of random multiplier applied to bullet muzzle velocity")) float MuzzleVelocityMultiplierMax = 1.0f;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Replication") bool ReplicateVariables=true;
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Replication") bool ReplicateShotFiredEvents = true;
|
|
|
|
FRandomStream RandomStream;
|
|
|
|
// New simplified single-shot firing interface. Spawns exactly one bullet of the given class using
|
|
// the barrel's current transform. This bypasses the legacy internal shooting state machine so that
|
|
// higher-level gun/weapon controllers can directly fire a round without manipulating Barrel internals.
|
|
UFUNCTION(BlueprintCallable, Category = "Shooting")
|
|
void FireBullet(TSubclassOf<class AEBBullet> BulletClass);
|
|
|
|
// New Gun-Integrated Ammo Functions
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
int GetMagazineRoundCount() const;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
bool HasChamberedRound() const;
|
|
|
|
UFUNCTION(BlueprintPure, Category = "Gun Integration")
|
|
bool CanFireFromGun() const;
|
|
|
|
UFUNCTION(BlueprintCallable, meta = (AutoCreateRefTerm = "IgnoredActors"), Category = "Prediction") void PredictHit(bool& Hit, FHitResult& TraceResult, FVector& HitLocation, float& HitTime, AActor*& HitActor, TArray<FVector>& Trajectory, TSubclassOf<class AEBBullet> BulletClass, TArray<AActor*>IgnoredActors, float MaxTime = 10.0f, float Step = 0.1f) const;
|
|
UFUNCTION(BlueprintCallable, meta = (AutoCreateRefTerm = "IgnoredActors"), Category = "Prediction") void PredictHitFromLocation(bool &Hit, FHitResult& TraceResult, FVector& HitLocation, float& HitTime, AActor*& HitActor, TArray<FVector>& Trajectory, TSubclassOf<class AEBBullet> BulletClass, FVector StartLocation, FVector AimDirection, TArray<AActor*>IgnoredActors, float MaxTime = 10.0f, float Step = 0.1f) const;
|
|
UFUNCTION(BlueprintCallable, Category = "Prediction") void CalculateAimDirection(TSubclassOf<class AEBBullet> BulletClass, FVector TargetLocation, FVector TargetVelocity, FVector& AimDirection, FVector& PredictedTargetLocation, FVector& PredictedIntersectionLocation, float& PredictedFlightTime, float& Error, float MaxTime = 10.0f, float Step = 0.1f, int NumIterations = 4) const;
|
|
UFUNCTION(BlueprintCallable, Category = "Prediction") void CalculateAimDirectionFromLocation(TSubclassOf<class AEBBullet> BulletClass, FVector StartLocation, FVector TargetLocation, FVector TargetVelocity, FVector& AimDirection, FVector& PredictedTargetLocation, FVector& PredictedIntersectionLocation, float& PredictedFlightTime, float& Error, float MaxTime = 10.0f, float Step=0.1f, int NumIterations = 4) const;
|
|
|
|
UFUNCTION(BlueprintNativeEvent, Category = "Events") void InitialBulletTransform(FVector InLocation, FVector InDirection, FVector& OutLocation, FVector& OutDirection);
|
|
UFUNCTION(BlueprintNativeEvent, Category = "Events") void ApplyRecoil(UPrimitiveComponent* Component, FVector InLocation, FVector Impulse);
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBeforeShotFired);
|
|
UPROPERTY(BlueprintAssignable, Category = "Events")
|
|
FBeforeShotFired BeforeShotFired;
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FShotFired);
|
|
UPROPERTY(BlueprintAssignable, Category = "Events")
|
|
FShotFired ShotFired;
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAmmoDepleted);
|
|
UPROPERTY(BlueprintAssignable, Category = "Events")
|
|
FAmmoDepleted AmmoDepleted;
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FReadyToShoot);
|
|
UPROPERTY(BlueprintAssignable, Category = "Events")
|
|
FReadyToShoot ReadyToShoot;
|
|
|
|
#if WITH_EDITOR
|
|
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
|
|
virtual bool IsZeroExtent() const override { return false; };
|
|
virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override;
|
|
#endif
|
|
|
|
private:
|
|
void SpawnBullet(AActor* Owner, FVector LocalLocation, FVector LocalAim);
|
|
|
|
UFUNCTION(Server, Unreliable, WithValidation) void ClientAim(FVector_NetQuantize NewLocation, FVector_NetQuantizeNormal NewAim);
|
|
UFUNCTION(Server, Reliable, WithValidation) void ShootRep(bool Trigger);
|
|
UFUNCTION(Server, Reliable, WithValidation) void ShootRepCSA(bool Trigger, FVector_NetQuantize NewLocation, FVector_NetQuantizeNormal NewAim);
|
|
|
|
UFUNCTION(NetMulticast, Reliable)
|
|
void ShotFiredMulticast();
|
|
|
|
FVector Aim;
|
|
FVector Location;
|
|
bool RemoteAimReceived;
|
|
float TimeSinceAimUpdate;
|
|
bool PredictTrace(UWorld* World, AEBBullet* Bullet, FVector Start, FVector End, FHitResult &HitResult, TArray<AActor*> IgnoredActors) const;
|
|
}; |