#pragma once

#include "CoreMinimal.h"
#include "TapOrChargeChargeableInteraction.h"
#include "UObject/NoExportTypes.h"
#include "DreamProjectionInteractionDefinition.generated.h"

class UTargetableComponent;
class AGenerator;
class AActor;
class ADBDPlayer;
class ASurvivor;

UCLASS(Blueprintable, Abstract, EditInlineNew, meta=(BlueprintSpawnableComponent))
class THENIGHTMARE_API UDreamProjectionInteractionDefinition : public UTapOrChargeChargeableInteraction
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float OnBloodSpurtsAINoiseEventRange;

private:
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, ReplicatedUsing=OnRep_TeleportTarget, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UTargetableComponent* _teleportTarget;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Replicated, Transient, meta=(AllowPrivateAccess=true))
	FTransform _selectedTeleportLocation;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	bool _isInteractionOngoing;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Replicated, Transient, meta=(AllowPrivateAccess=true))
	bool _teleportFailed;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _bloodSpurtInterval;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _collisionCheckCapsuleHalfHeight;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _collisionCheckCapsuleRadius;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	FVector _collisionCheckLocationOffset;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _capsuleTraceAngleIncrement;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _downRaycastLength;

private:
	UFUNCTION(BlueprintCallable, Server, Reliable)
	void Server_SetTeleportTarget(UTargetableComponent* target);

	UFUNCTION(BlueprintCallable)
	void OnRep_TeleportTarget();

protected:
	UFUNCTION(BlueprintCallable)
	void OnBloodSpurts(const AGenerator* targetGenerator);

	UFUNCTION(BlueprintCallable, NetMulticast, Reliable)
	void Multicast_TeleportPlayer(FVector location, FRotator rotation);

	UFUNCTION(BlueprintCallable, NetMulticast, Reliable)
	void Multicast_OnTeleportLocationChosen(const FTransform& location, const AActor* targetActor);

private:
	UFUNCTION(BlueprintPure)
	bool HasTeleportFailed() const;

protected:
	UFUNCTION(BlueprintPure)
	ADBDPlayer* GetOwningPlayer() const;

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_ShowBloodSpurts(const AGenerator* targetGenerator);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnTeleportLocationChosen(FTransform location, const ASurvivor* targetSurvivor);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnTeleported(FTransform transformBeforeTeleport, FVector teleportLocation);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnTeleportChargeStarted(ADBDPlayer* player);

public:
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

public:
	UDreamProjectionInteractionDefinition();
};

FORCEINLINE uint32 GetTypeHash(const UDreamProjectionInteractionDefinition) { return 0; }
