// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameplayTagAssetInterface.h" #include "GameFramework/Character.h" #include "MCharacter.generated.h" class AMGameplayActor; class UCameraComponent; class AMWeapon; class UMHealthComponent; class AMCharacter; DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnWeaponEquipped, AMCharacter*, Character, AMWeapon*, NewWeapon, AMWeapon*, PreviousWeapon); DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnCharacterEnterSafeZone, AMCharacter*, Character, AActor*, SafeZoneEnteredActor); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCharacterLeaveSafeZone, AMCharacter*, Character); UCLASS() class MECHDEFENCE_API AMCharacter : public ACharacter, public IGameplayTagAssetInterface { GENERATED_BODY() public: AMCharacter(); protected: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") UCameraComponent* CameraComponent; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") USkeletalMeshComponent* PlayerArms; UPROPERTY(EditDefaultsOnly, Category = "Player", meta=(Tooltip = "Maximum Distance to Trace for Interactable Objects", ClampMin = 50.f)) float MaxInteractableDistance; UPROPERTY(EditDefaultsOnly, Category = "Tags") FGameplayTagContainer ActorTags; UPROPERTY(EditDefaultsOnly, Category = "Player") TSubclassOf PrimaryWeaponClass; UPROPERTY(EditDefaultsOnly, Category = "Player") TSubclassOf ScannerClass; UPROPERTY(EditDefaultsOnly, Category = "Player") TSubclassOf BlowTorchClass; UPROPERTY(EditDefaultsOnly, Category = "Player") TSubclassOf TabletClass; UPROPERTY(EditDefaultsOnly, Category = "Player") UAnimSequence* FireAnimation; UPROPERTY(EditDefaultsOnly, Category = "Player") UAnimSequenceBase* ReloadAnimation; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Player") UMHealthComponent* HealthComponent; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") UAudioComponent* AudioComponent; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* HealingStartSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* HealingInProgressSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* HealingCompletedSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* SafeZoneEnterSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* SafeZoneLeaveSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* HitByBulletSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* WalkSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") USoundBase* CrouchWalkSound; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float DefaultFOV; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float ZoomInterpolateSpeed; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Tooltip = "The interval in seconds after which we check if player is in safe zone or not to determine whether to apply damage")) float OutOfSafeZoneDamageInterval; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float OutOfSafeZoneDamage; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Tooltip = "The interval in seconds after which healing is applied when the player is inside the safe zone is their health is low")) float SafeZoneHealInterval; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Tooltip = "The amount of healing applied when the player is inside safe zone")) float SafeZoneHealAmount; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Tooltip = "Time interval in seconds after which healing within safezone will begin")) float SafeZoneHealDelay; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Tooltip = "Minimum velocity threshold after which player movement sounds will be played")) float MinimumMovementVelocityThreshold; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float MaxStamina; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Player") float CurrentStamina; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float StaminaConsumeAmount; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Min = 0.f)) float StaminaConsumeInterval; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Min = 0.f, Tooltip = "The amount of time in seconds to wait before we start recovering stamina")) float StaminaRestoreDelay; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float StaminaRestoreAmount; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Min = 0.f)) float StaminaRestoreInterval; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player", meta = (Min = 1.f)) float SprintMultiplier; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float ArmRotateSpeed; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") float HiddenArmPitch; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") FVector HiddenArmLocation; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") TSubclassOf SafeZoneClass; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") TSubclassOf OutOfSafeZoneDamageClass; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player") FGameplayTagContainer SafeZoneTags; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Player") TArray Weapons; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Player") AMWeapon* CurrentWeapon; FTimerHandle TimerHandle_ApplyOutOfSafeZoneDamage; FTimerHandle TimerHandle_ApplySafeZoneHeal; FTimerHandle TimerHandle_RestoreStamina; FTimerHandle TimerHandle_ConsumeStamina; bool bWantsToZoom; bool bIsInSafeZone; bool bIsFirstTimeHeal; bool bIsMounted; bool bCanSprint; bool bIsSprinting; bool bWantsToHideEquippedItem; void MoveForward(float ScaleValue); void MoveRight(float ScaleValue); void StartCrouch(); void StopCrouch(); void StartFire(); void StopFire(); void Interact(); void Reload(); void StartZoom(); void StopZoom(); void StartSprint(); void StopSprint(); void ConsumeStamina(); void RestoreStamina(); void EnterSafeZone(AActor* SafeZoneActor); void LeaveSafeZone(); UFUNCTION() void ApplyOutOfSafeZoneDamage(); UFUNCTION() void ApplySafeZoneHealing(); UFUNCTION() void HandleCapsuleBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); UFUNCTION() void HandleCapsuleEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); virtual void BeginPlay() override; void HandleCVARChanged(); // The actor over which our cursor is currently hovering AActor* HoveredInteractableActor; // Used when sprinting to check whether the player has moved or not in order to determine if stamina should be consumed or not // We only check for the x and y positions to not count jumping as change in location FVector2D PreviousLocation; float DefaultArmPitch; FVector DefaultArmLocation; float TargetFOV; public: virtual void Tick(float DeltaTime) override; virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override; UFUNCTION(BlueprintCallable) void EquipWeapon(uint8 Weapon); UFUNCTION(BlueprintCallable) void CheckIfInSafeZone(); UFUNCTION() void HandleHealthChanged(UMHealthComponent* HealthComp, float Health, float HealthDelta, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser); UFUNCTION(BlueprintCallable) void SetMounted(bool Mounted) { bIsMounted = Mounted; } UPROPERTY(BlueprintAssignable, Category = "Player Events") FOnWeaponEquipped OnWeaponEquipped; UPROPERTY(BlueprintAssignable, Category = "Character Events") FOnCharacterEnterSafeZone OnCharacterEnterSafeZone; UPROPERTY(BlueprintAssignable, Category = "Character Events") FOnCharacterLeaveSafeZone OnCharacterLeaveSafeZone; UFUNCTION(BlueprintCallable) float GetStaminaRemappedInRange(float Min, float Max); UFUNCTION(BlueprintCallable) bool IsZoomedIn() const { return bWantsToZoom; } UFUNCTION(BlueprintCallable) bool IsInSafeZone() const { return bIsInSafeZone; } UFUNCTION(BlueprintCallable) bool IsMounted() const { return bIsMounted; } UFUNCTION(BlueprintCallable) void StartHidingEquippedItem(); UFUNCTION(BlueprintCallable) void StopHidingEquippedItem(); UFUNCTION(BlueprintCallable) void SetTargetFOV(float NewTargetFOV); UFUNCTION(BlueprintCallable) void ResetToDefaultFOV(); private: bool bDied; };