Initial commit: Item Interaction Ecosystem plugin (UE5.7)
Server-authoritative, data-driven item/inventory/interaction/carry/equipment/ world-slot/placement/crafting framework. 8 modules, compiles against UE 5.7. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
178
Source/ItemInteraction/Public/ItemInteractionComponent.h
Normal file
178
Source/ItemInteraction/Public/ItemInteractionComponent.h
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright ExByte Studios. Item Interaction Ecosystem.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "InteractionTypes.h"
|
||||
#include "ItemInteractionComponent.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnInteractionResult, FGuid, RequestId, bool, bSuccess);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnOpenContainer, AActor*, ContainerActor);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnActionStarted, FGameplayTag, ActionTag, float, Duration);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnActionFinished, FGameplayTag, ActionTag, bool, bCompleted);
|
||||
|
||||
/** Replicated snapshot of a long/hold action in progress (section 19), for UI. */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FActiveInteractionState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Interaction")
|
||||
bool bActive = false;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Interaction")
|
||||
FGameplayTag ActionTag;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Interaction")
|
||||
float Duration = 0.f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Player-side hub that turns a chosen option into a server request and executes
|
||||
* the authorized result (sections 9, 25). Attach to the player pawn alongside
|
||||
* an InventoryComponent and (optionally) an InteractionTraceComponent.
|
||||
*
|
||||
* Flow: UI/input picks an FInteractionOption -> RequestInteraction() -> Server RPC
|
||||
* -> server re-resolves and re-validates -> executes the transaction -> state
|
||||
* replicates back. The client never changes item state itself.
|
||||
*/
|
||||
UCLASS(ClassGroup = (Interaction), meta = (BlueprintSpawnableComponent))
|
||||
class ITEMINTERACTION_API UItemInteractionComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UItemInteractionComponent();
|
||||
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
/** Client entry point: send the chosen option's request to the server. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Interaction")
|
||||
void RequestInteraction(const FInteractionOption& Option);
|
||||
|
||||
/** Client: signal that a hold action's button was released (cancels if mid-action). */
|
||||
UFUNCTION(BlueprintCallable, Category = "Interaction")
|
||||
void ReleaseHold();
|
||||
|
||||
/** Server: cancel any action in progress (bind to damage/stun for interruption). */
|
||||
UFUNCTION(BlueprintCallable, Category = "Interaction")
|
||||
void CancelActiveAction();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Interaction")
|
||||
const FActiveInteractionState& GetActiveAction() const { return ActiveAction; }
|
||||
|
||||
/** Lower-level entry: send a hand-built request. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Interaction")
|
||||
void SendRequest(const FInteractionRequest& Request);
|
||||
|
||||
// --- Inventory UI operations (section 23.3). Client calls, server validates. ---
|
||||
|
||||
/**
|
||||
* Move/transfer an item. StorageActor == null -> rearrange within the player's
|
||||
* own inventory. Otherwise transfer between the player and the storage actor's
|
||||
* inventory (loot). ToContainerId == invalid -> first accepting container.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Inventory")
|
||||
void RequestMoveItem(AActor* StorageActor, FGuid InstanceId, FGuid ToContainerId, int32 ToSlot);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Inventory")
|
||||
void RequestSplitStack(FGuid InstanceId, int32 Amount);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Inventory")
|
||||
void RequestMergeStack(FGuid SourceInstanceId, FGuid TargetInstanceId);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Inventory")
|
||||
void RequestDropFromInventory(FGuid InstanceId);
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Interaction")
|
||||
FOnInteractionResult OnInteractionResult;
|
||||
|
||||
/** Fired locally when the player chooses to open a container - UI opens the loot window. */
|
||||
UPROPERTY(BlueprintAssignable, Category = "Interaction")
|
||||
FOnOpenContainer OnOpenContainer;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Interaction")
|
||||
FOnActionStarted OnActionStarted;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Interaction")
|
||||
FOnActionFinished OnActionFinished;
|
||||
|
||||
/** Max slack (cm) added to the interactable's own distance when server-validating. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Interaction")
|
||||
float ServerDistanceTolerance = 75.f;
|
||||
|
||||
protected:
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_RequestInteraction(const FInteractionRequest& Request);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_MoveItem(AActor* StorageActor, FGuid InstanceId, FGuid ToContainerId, int32 ToSlot);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_SplitStack(FGuid InstanceId, int32 Amount);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_MergeStack(FGuid SourceInstanceId, FGuid TargetInstanceId);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_DropFromInventory(FGuid InstanceId);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_ReleaseHold();
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_InteractionResult(FGuid RequestId, bool bSuccess);
|
||||
|
||||
/** Server hook for dropping an item into the world. Overridden in ItemWorld. */
|
||||
virtual bool HandleDropFromInventory(FGuid InstanceId);
|
||||
|
||||
private:
|
||||
/** Server: full validation pipeline (section 9). Returns the authorized option. */
|
||||
bool AuthorizeRequest(const FInteractionRequest& Request, FInteractionContext& OutContext, FInteractionOption& OutOption) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Server: run a mode directly from an already-built context (used by the named
|
||||
* UInteractionAction_* classes so they share the one execution path). Builds a
|
||||
* minimal option/request and dispatches through ExecuteAuthorized (virtual, so
|
||||
* the ItemWorld subclass handles carry/equip/install/use).
|
||||
*/
|
||||
bool ServerExecuteMode(const FInteractionContext& Context, EItemInteractionMode Mode, FGameplayTag ActionTag);
|
||||
|
||||
protected:
|
||||
APawn* GetPawn() const;
|
||||
|
||||
/**
|
||||
* Server: run the authorized option's effect. Virtual so ItemWorld can add the
|
||||
* carry/drop/equip/install/use-on-target modes (which need ItemWorld types)
|
||||
* without ItemInteraction depending on ItemWorld. Base handles pickup + transfer.
|
||||
*/
|
||||
virtual bool ExecuteAuthorized(const FInteractionContext& Context, const FInteractionOption& Option, const FInteractionRequest& Request);
|
||||
|
||||
bool ExecutePickup(const FInteractionContext& Context);
|
||||
bool ExecuteTransfer(const FInteractionContext& Context, const FInteractionRequest& Request);
|
||||
bool ExecuteActionClass(const FInteractionContext& Context, const FInteractionOption& Option);
|
||||
|
||||
// --- Timed / hold action plumbing (section 19) ---
|
||||
void BeginTimedAction(const FInteractionContext& Context, const FInteractionOption& Option, const FInteractionRequest& Request);
|
||||
void CompleteTimedAction();
|
||||
void AbortTimedAction();
|
||||
void LockActionItem(bool bLock);
|
||||
|
||||
UPROPERTY(ReplicatedUsing = OnRep_ActiveAction)
|
||||
FActiveInteractionState ActiveAction;
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_ActiveAction();
|
||||
|
||||
// Server-side pending state.
|
||||
bool bHasPending = false;
|
||||
bool bPendingHold = false;
|
||||
float PendingEndTime = 0.f;
|
||||
float PendingMaxDistanceSq = 0.f;
|
||||
FInteractionContext PendingContext;
|
||||
FInteractionOption PendingOption;
|
||||
FInteractionRequest PendingRequest;
|
||||
};
|
||||
Reference in New Issue
Block a user