Files
inventory-system-plugin/Source/ItemPlacement/Public/PlacementPreviewComponent.h
Bonchellon 7f7e043a88 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>
2026-06-22 20:49:56 +03:00

83 lines
2.7 KiB
C++

// Copyright ExByte Studios. Item Interaction Ecosystem.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "ItemPlacementRules.h"
#include "PlacementPreviewComponent.generated.h"
class UStaticMeshComponent;
struct FItemDefinitionRow;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlacementStateChanged, bool, bIsValid);
/**
* Drives the local ghost-mesh preview and the server-validated confirm for
* placeable items (section 13). The client shows a green/red ghost; the server
* re-runs every rule before committing (collision, slope, distance, surface).
*/
UCLASS(ClassGroup = (Placement), meta = (BlueprintSpawnableComponent))
class ITEMPLACEMENT_API UPlacementPreviewComponent : public UActorComponent
{
GENERATED_BODY()
public:
UPlacementPreviewComponent();
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UPROPERTY(BlueprintReadOnly, Category = "Placement")
bool bIsPlacing = false;
UPROPERTY(BlueprintReadOnly, Category = "Placement")
FName ItemId;
UPROPERTY(BlueprintReadOnly, Category = "Placement")
FGuid ItemInstanceId;
UPROPERTY(BlueprintReadOnly, Category = "Placement")
FTransform PreviewTransform = FTransform::Identity;
UPROPERTY(BlueprintReadOnly, Category = "Placement")
bool bCurrentValid = false;
UPROPERTY(BlueprintAssignable, Category = "Placement")
FOnPlacementStateChanged OnPlacementStateChanged;
/** Client: begin placing an inventory item. */
UFUNCTION(BlueprintCallable, Category = "Placement")
void StartPlacement(FGuid InstanceId);
/** Client: confirm at the current preview transform (sends a server request). */
UFUNCTION(BlueprintCallable, Category = "Placement")
void ConfirmPlacement();
/** Client: abort placement. */
UFUNCTION(BlueprintCallable, Category = "Placement")
void CancelPlacement();
UFUNCTION(BlueprintCallable, Category = "Placement")
void RotatePreview(float DeltaYawDegrees);
/** Pure rule check used by both the client preview and the server (section 13.3). */
static bool ValidatePlacement(const UObject* WorldContext, const FItemDefinitionRow& Def,
const FTransform& Transform, AActor* Instigator, FString& OutReason);
protected:
UFUNCTION(Server, Reliable)
void Server_ConfirmPlacement(FGuid InstanceId, FTransform Transform);
private:
UPROPERTY(Transient)
TObjectPtr<UStaticMeshComponent> Ghost = nullptr;
float PreviewYaw = 0.f;
bool ComputePreviewTransform(FTransform& OutTransform) const;
void DestroyGhost();
void SetValidity(bool bNewValid);
bool GetViewPoint(FVector& OutLoc, FRotator& OutRot) const;
};