250 lines
7.0 KiB
C++
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();
|
|
};
|