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:
169
Source/ItemDatabase/Public/ItemDatabaseSubsystem.h
Normal file
169
Source/ItemDatabase/Public/ItemDatabaseSubsystem.h
Normal file
@ -0,0 +1,169 @@
|
||||
// Copyright ExByte Studios. Item Interaction Ecosystem.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Subsystems/GameInstanceSubsystem.h"
|
||||
#include "ItemDefinitionRow.h"
|
||||
#include "ItemAuxiliaryRows.h"
|
||||
#include "ItemContentRows.h"
|
||||
#include "ItemInstanceData.h"
|
||||
#include "ItemDatabaseSubsystem.generated.h"
|
||||
|
||||
/** One problem found by ValidateData (section 28). */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FItemValidationIssue
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Validation")
|
||||
FName ItemId;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Validation")
|
||||
FString Message;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Validation")
|
||||
bool bIsError = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authoritative, read-only access point for all static item data (section 35 stage 1).
|
||||
*
|
||||
* Loads the configured data tables once, flattens them into fast lookup maps and
|
||||
* exposes definition/property/feature/interaction queries plus redirect resolution
|
||||
* and a data validator. Lives on the GameInstance so it is available on both
|
||||
* server and clients; the tables themselves are never replicated (section 32).
|
||||
*/
|
||||
UCLASS()
|
||||
class ITEMDATABASE_API UItemDatabaseSubsystem : public UGameInstanceSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
//~ USubsystem
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
|
||||
/** Convenience accessor from any world context. */
|
||||
static UItemDatabaseSubsystem* Get(const UObject* WorldContext);
|
||||
|
||||
/** (Re)load every configured table and rebuild the lookup caches. */
|
||||
void RebuildCache();
|
||||
|
||||
// --- Definition lookup ---
|
||||
|
||||
/** Returns the definition for an item (after redirects), or null if unknown. C++ fast path. */
|
||||
const FItemDefinitionRow* GetItemDefinition(FName ItemId) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Item|Database")
|
||||
bool FindItemDefinition(FName ItemId, FItemDefinitionRow& OutDefinition) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
bool HasItem(FName ItemId) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
void GetAllItemIds(TArray<FName>& OutItemIds) const;
|
||||
|
||||
/** Applies the redirect chain; returns the input unchanged if no redirect exists. */
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
FName ResolveRedirect(FName ItemId) const;
|
||||
|
||||
// --- Instances ---
|
||||
|
||||
/**
|
||||
* Builds a fresh instance of ItemId with a new GUID and its default runtime
|
||||
* properties applied. The single correct way to mint an item (server-side).
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Item|Database")
|
||||
FItemInstanceData MakeItemInstance(FName ItemId, int32 Quantity = 1) const;
|
||||
|
||||
/** Writes the item's default runtime properties into Out (does not clear first). */
|
||||
void ApplyDefaultProperties(FName ItemId, FItemRuntimeProperties& Out) const;
|
||||
|
||||
/** Adds only default properties that are missing (save migration, section 26.2). */
|
||||
void ApplyMissingDefaultProperties(FName ItemId, FItemRuntimeProperties& Out) const;
|
||||
|
||||
/** Current schema version stamped onto fresh/migrated instances. */
|
||||
static constexpr int32 CurrentItemDataVersion = 1;
|
||||
|
||||
/** Applies redirects + version migration to a loaded instance (section 26). */
|
||||
UFUNCTION(BlueprintCallable, Category = "Item|Database")
|
||||
void MigrateLoadedItem(UPARAM(ref) FItemInstanceData& Item) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
int32 GetMaxStack(FName ItemId) const;
|
||||
|
||||
// --- Auxiliary data ---
|
||||
|
||||
void GetPropertyRows(FName ItemId, TArray<FItemPropertyRow>& Out) const;
|
||||
void GetFeatureRows(FName ItemId, TArray<FItemFeatureRow>& Out) const;
|
||||
|
||||
/** Feature rows for one specific feature tag (e.g. all Rotting params of raw_meat). */
|
||||
void GetFeatureRows(FName ItemId, const FGameplayTag& Feature, TArray<FItemFeatureRow>& Out) const;
|
||||
|
||||
void GetInteractionRows(FName ItemId, TArray<FItemInteractionRow>& Out) const;
|
||||
|
||||
/** Per-property replication policy default (section 22), or None if unspecified. */
|
||||
EItemPropertyReplicationPolicy GetPropertyPolicy(FName ItemId, const FGameplayTag& PropertyTag) const;
|
||||
|
||||
/** Property tags on an item that are flagged ServerOnly (never sent to clients). */
|
||||
void GetServerOnlyProperties(FName ItemId, TArray<FGameplayTag>& Out) const;
|
||||
|
||||
// --- Containers / world slots / loot / recipes (section 6) ---
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
bool FindContainerDef(FGameplayTag ContainerTag, FContainerDefRow& OutDef) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
bool FindWorldSlotDef(FGameplayTag SlotTag, FWorldSlotDefRow& OutDef) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
bool FindRecipe(FName RecipeId, FCraftingRecipeRow& OutRecipe) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Item|Database")
|
||||
void GetAllRecipes(TArray<FCraftingRecipeRow>& OutRecipes) const;
|
||||
|
||||
void GetLootEntries(FName TableId, TArray<FLootEntryRow>& Out) const;
|
||||
|
||||
/** Rolls a loot table into a list of fresh item instances (server). */
|
||||
UFUNCTION(BlueprintCallable, Category = "Item|Database")
|
||||
void RollLoot(FName TableId, int32 RollCount, TArray<FItemInstanceData>& OutItems) const;
|
||||
|
||||
// --- Validation (section 28) ---
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Item|Database")
|
||||
void ValidateData(TArray<FItemValidationIssue>& OutIssues) const;
|
||||
|
||||
private:
|
||||
void LoadDefinitions(UDataTable* Table);
|
||||
void LoadProperties(UDataTable* Table);
|
||||
void LoadFeatures(UDataTable* Table);
|
||||
void LoadInteractions(UDataTable* Table);
|
||||
void LoadRedirects(UDataTable* Table);
|
||||
void LoadContainers(UDataTable* Table);
|
||||
void LoadWorldSlots(UDataTable* Table);
|
||||
void LoadLoot(UDataTable* Table);
|
||||
void LoadRecipes(UDataTable* Table);
|
||||
|
||||
/** ItemId -> definition. */
|
||||
TMap<FName, FItemDefinitionRow> Definitions;
|
||||
|
||||
/** ItemId -> default property rows. */
|
||||
TMap<FName, TArray<FItemPropertyRow>> PropertiesByItem;
|
||||
|
||||
/** ItemId -> feature parameter rows. */
|
||||
TMap<FName, TArray<FItemFeatureRow>> FeaturesByItem;
|
||||
|
||||
/** ItemId -> interaction rows. */
|
||||
TMap<FName, TArray<FItemInteractionRow>> InteractionsByItem;
|
||||
|
||||
/** Old -> new id. */
|
||||
TMap<FName, FName> Redirects;
|
||||
|
||||
TMap<FGameplayTag, FContainerDefRow> ContainerDefs;
|
||||
TMap<FGameplayTag, FWorldSlotDefRow> WorldSlotDefs;
|
||||
TMap<FName, TArray<FLootEntryRow>> LootByTable;
|
||||
TMap<FName, FCraftingRecipeRow> RecipesById;
|
||||
|
||||
bool bCacheBuilt = false;
|
||||
};
|
||||
Reference in New Issue
Block a user