// Copyright ExByte Studios. Item Interaction Ecosystem. #pragma once #include "CoreMinimal.h" #include "GameplayTagContainer.h" #include "ItemInstanceData.h" #include "ItemTransaction.generated.h" class UInventoryComponent; /** Kind of mutation a transaction step performs (section 10). */ UENUM(BlueprintType) enum class EItemTransactionStepType : uint8 { AddItem, RemoveItem, UpdateItem, MoveItem }; /** One atomic step. Carries enough to apply AND to roll back. */ USTRUCT(BlueprintType) struct ITEMINVENTORY_API FItemTransactionStep { GENERATED_BODY() UPROPERTY() EItemTransactionStepType Type = EItemTransactionStepType::AddItem; UPROPERTY() TWeakObjectPtr Inventory; /** Item payload for AddItem / UpdateItem. */ UPROPERTY() FItemInstanceData Item; UPROPERTY() FGuid InstanceId; UPROPERTY() FGuid ToContainer; UPROPERTY() int32 ToSlot = INDEX_NONE; // --- runtime (rollback bookkeeping) --- UPROPERTY() bool bApplied = false; UPROPERTY() FItemInstanceData UndoSnapshot; UPROPERTY() FGuid UndoFromContainer; UPROPERTY() int32 UndoFromSlot = INDEX_NONE; }; /** * Atomic multi-step item operation (section 10). Build steps, then Apply(): * if any step fails, every applied step is rolled back so the inventories are * left untouched. The single correct way to do multi-inventory moves. * * Server-only. Operates through UInventoryComponent's authoritative methods. */ USTRUCT(BlueprintType) struct ITEMINVENTORY_API FItemTransaction { GENERATED_BODY() UPROPERTY() FGuid TransactionId; UPROPERTY() FGameplayTag TransactionType; UPROPERTY() TWeakObjectPtr Instigator; UPROPERTY() TArray Steps; FItemTransaction() { TransactionId = FGuid::NewGuid(); } // --- Builders --- FItemTransaction& Add(UInventoryComponent* Inventory, const FItemInstanceData& Item); FItemTransaction& Remove(UInventoryComponent* Inventory, const FGuid& InstanceId); FItemTransaction& Update(UInventoryComponent* Inventory, const FItemInstanceData& Item); FItemTransaction& Move(UInventoryComponent* Inventory, const FGuid& InstanceId, const FGuid& ToContainerId, int32 ToSlotIndex); /** Non-mutating feasibility check of every step. */ bool Validate() const; /** Applies all steps; on any failure rolls back and returns false. */ bool Apply(); /** Undoes every applied step in reverse order. */ void Rollback(); };