Files
BallisticsDocs/Source/EasyBallistics/Public/EBGun.h
T
2025-07-04 03:26:03 -07:00

250 lines
7.0 KiB
C++

// Copyright 2016 Mookie. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/StaticMeshComponent.h"
#include "EBBarrel.h"
#include "EBMagazine.h"
#include "EBWeaponConfiguration.h"
#include "EBBulletProperties.h"
#include "EBGun.generated.h"
UENUM(BlueprintType)
enum class EGunState : uint8
{
GS_Ready UMETA(DisplayName = "Ready"),
GS_Firing UMETA(DisplayName = "Firing"),
GS_Reloading UMETA(DisplayName = "Reloading"),
GS_Jammed UMETA(DisplayName = "Jammed"),
GS_Empty UMETA(DisplayName = "Empty"),
GS_SafetyOn UMETA(DisplayName = "Safety On"),
GS_Malfunction UMETA(DisplayName = "Malfunction")
};
UCLASS(Blueprintable, BlueprintType)
class EASYBALLISTICS_API AEBGun : public AActor
{
GENERATED_BODY()
public:
AEBGun();
// Core Components
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
USkeletalMeshComponent* GunMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UEBBarrel* Barrel;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UEBMagazine* Magazine;
// Weapon Configuration
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Configuration")
UEBWeaponConfiguration* WeaponConfig;
// Gun State
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_GunState, Category = "Gun State")
EGunState CurrentGunState = EGunState::GS_Ready;
UPROPERTY(BlueprintReadOnly, Replicated, Category = "Gun State")
bool bSafetyOn = false;
UPROPERTY(BlueprintReadOnly, Replicated, Category = "Gun State")
bool bChamberedRound = false;
UPROPERTY(BlueprintReadOnly, Replicated, Category = "Gun State")
bool bHammerCocked = false;
// Firing Interface
UFUNCTION(BlueprintCallable, Category = "Gun|Firing")
void PullTrigger();
UFUNCTION(BlueprintCallable, Category = "Gun|Firing")
void ReleaseTrigger();
UFUNCTION(BlueprintCallable, Category = "Gun|Controls")
void SetSafety(bool bNewSafetyState);
UFUNCTION(BlueprintCallable, Category = "Gun|Controls")
void CockHammer();
UFUNCTION(BlueprintCallable, Category = "Gun|Controls")
void ReleaseHammer();
// Ammunition Management
UFUNCTION(BlueprintCallable, Category = "Gun|Ammunition")
void LoadMagazine(TArray<UEBBulletPropertiesAsset*> BulletTypes);
UFUNCTION(BlueprintCallable, Category = "Gun|Ammunition")
void EjectMagazine();
UFUNCTION(BlueprintCallable, Category = "Gun|Ammunition")
void InsertMagazine(UEBMagazine* NewMagazine);
UFUNCTION(BlueprintCallable, Category = "Gun|Ammunition")
void ChargingHandle();
UFUNCTION(BlueprintCallable, Category = "Gun|Ammunition")
void EjectChamberedRound();
// State Queries
UFUNCTION(BlueprintPure, Category = "Gun|State")
bool CanFire() const;
UFUNCTION(BlueprintPure, Category = "Gun|State")
bool IsLoaded() const;
UFUNCTION(BlueprintPure, Category = "Gun|State")
int32 GetRoundsInMagazine() const;
UFUNCTION(BlueprintPure, Category = "Gun|State")
int32 GetTotalRounds() const;
UFUNCTION(BlueprintPure, Category = "Gun|State")
UEBBulletPropertiesAsset* GetChamberedBulletType() const;
// Configuration
UFUNCTION(BlueprintCallable, Category = "Gun|Configuration")
void ApplyWeaponConfiguration(UEBWeaponConfiguration* NewConfig);
UFUNCTION(BlueprintCallable, Category = "Gun|Configuration")
void SetFireMode(EFireMode NewFireMode);
UFUNCTION(BlueprintPure, Category = "Gun|Configuration")
EFireMode GetFireMode() const;
// Barrel Integration
UFUNCTION(BlueprintPure, Category = "Gun|Barrel")
float GetBarrelLength() const;
UFUNCTION(BlueprintPure, Category = "Gun|Barrel")
float GetEffectiveMuzzleVelocity() const;
UFUNCTION(BlueprintPure, Category = "Gun|Barrel")
float GetBarrelAccuracy() const;
UFUNCTION(BlueprintCallable, Category = "Gun|Barrel")
FVector CalculateRecoilImpulse() const;
UFUNCTION(BlueprintPure, Category = "Gun|Barrel")
bool IsBarrelConnected() const;
// Events
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGunStateChanged, EGunState, NewState);
UPROPERTY(BlueprintAssignable, Category = "Gun Events")
FOnGunStateChanged OnGunStateChanged;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGunFired, UEBBulletPropertiesAsset*, BulletType);
UPROPERTY(BlueprintAssignable, Category = "Gun Events")
FOnGunFired OnGunFired;
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnMagazineEmpty);
UPROPERTY(BlueprintAssignable, Category = "Gun Events")
FOnMagazineEmpty OnMagazineEmpty;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMagazineChanged, UEBMagazine*, NewMagazine);
UPROPERTY(BlueprintAssignable, Category = "Gun Events")
FOnMagazineChanged OnMagazineChanged;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSafetyChanged, bool, bNewSafetyState);
UPROPERTY(BlueprintAssignable, Category = "Gun Events")
FOnSafetyChanged OnSafetyChanged;
// Networking
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
// Replication
UFUNCTION()
void OnRep_GunState();
// Internal Functions
UFUNCTION(BlueprintImplementableEvent, Category = "Gun|Internal")
void OnGunStateChangedInternal(EGunState OldState, EGunState NewState);
UFUNCTION(BlueprintImplementableEvent, Category = "Gun|Internal")
void OnFireAnimationStart();
UFUNCTION(BlueprintImplementableEvent, Category = "Gun|Internal")
void OnReloadAnimationStart();
UFUNCTION(BlueprintImplementableEvent, Category = "Gun|Internal")
void OnJamAnimation();
void SetGunState(EGunState NewState);
void ProcessFiring();
void ProcessReloading();
void CycleAction();
bool FeedNextRound();
// Timers
FTimerHandle FireRateTimer;
FTimerHandle ReloadTimer;
FTimerHandle CycleTimer;
// Firing Control
bool bTriggerPressed = false;
bool bCanProcessNextShot = true;
int32 BurstShotsFired = 0;
// Chambered Round
UPROPERTY(Replicated)
UEBBulletPropertiesAsset* ChamberedBulletType;
private:
EGunState PreviousGunState;
// Server Functions
UFUNCTION(Server, Reliable)
void ServerPullTrigger();
UFUNCTION(Server, Reliable)
void ServerReleaseTrigger();
UFUNCTION(Server, Reliable)
void ServerSetSafety(bool bNewSafetyState);
UFUNCTION(Server, Reliable)
void ServerEjectMagazine();
UFUNCTION(Server, Reliable)
void ServerInsertMagazine(UEBMagazine* NewMagazine);
UFUNCTION(Server, Reliable)
void ServerChargingHandle();
UFUNCTION(Server, Reliable)
void ServerSetFireMode(EFireMode NewFireMode);
// Multicast Functions
UFUNCTION(NetMulticast, Reliable)
void MulticastOnGunFired(UEBBulletPropertiesAsset* BulletType);
UFUNCTION(NetMulticast, Reliable)
void MulticastOnMagazineChanged(UEBMagazine* NewMagazine);
UFUNCTION(NetMulticast, Reliable)
void MulticastOnSafetyChanged(bool bNewSafetyState);
// Event Handlers
UFUNCTION()
void OnMagazineEmptyHandler(UEBMagazine* EmptyMagazine);
UFUNCTION()
void OnBulletFedHandler(UEBMagazine* SourceMagazine, UEBBulletPropertiesAsset* BulletType);
UFUNCTION()
void OnBarrelShotFiredHandler();
// Internal firing function
void FireShot();
};