← back to drstreit__Unreal-01-VaultInventory

Function bodies 468 total

All specs Real LLM only Function bodies
Server_RequestOpenContainer_Implementation method · cpp · L696-L739 (44 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::Server_RequestOpenContainer_Implementation(AActor* Container)
{
	UInventoryValidationSubsystem* Validation = CachedValidation.Get();
	if (!Validation)
	{
		UE_LOG(LogVaultValidation, Warning, TEXT("OpenContainer: Validation subsystem unavailable"));
		return;
	}

	// Distance check
	FGameplayTag DistResult = Validation->CheckDistance(GetOwner(), Container);
	if (DistResult != VaultTags::Validation_Success)
	{
		UE_LOG(LogVaultValidation, Warning, TEXT("OpenContainer: Too far from container"));
		return;
	}

	// Access policy: check read permission on the container's inventory (if present)
	UInventoryManagerComponent* ContainerInv = Container->FindComponentByClass<UInventoryManagerComponent>();
	if (ContainerInv)
	{
		FGameplayTag AccessResult = Validation->CheckAccessPolicy(
			GetOwner(), ContainerInv, nullptr, EAccessOperation::Read);
		if (AccessResult != VaultTags::Validation_Success)
		{
			UE_LOG(LogVaultValidation, Warning, TEXT("OpenContainer: 
Server_RequestTransformItems_Validate method · cpp · L742-L746 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::Server_RequestTransformItems_Validate(UItemTransformationRule* Rule)
{
	return ValidateRPCPreconditions() && IsValid(Rule);
}
Server_RequestTransformItems_Implementation method · cpp · L747-L755 (9 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::Server_RequestTransformItems_Implementation(UItemTransformationRule* Rule)
{
	const FGameplayTag Result = Authority_TransformItems(Rule);
	if (Result != VaultTags::Validation_Success)
	{
		UE_LOG(LogVaultValidation, Warning, TEXT("TransformItems: Failed — %s"), *Result.ToString());
	}
}
Server_RequestBulkMove_Validate method · cpp · L756-L760 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::Server_RequestBulkMove_Validate(const TArray<FItemMoveIntent>& MoveIntents)
{
	return ValidateRPCPreconditions() && MoveIntents.Num() > 0;
}
Server_RequestBulkMove_Implementation method · cpp · L761-L796 (36 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::Server_RequestBulkMove_Implementation(const TArray<FItemMoveIntent>& MoveIntents)
{
	UInventoryValidationSubsystem* Validation = CachedValidation.Get();
	if (!Validation)
	{
		UE_LOG(LogVaultValidation, Warning, TEXT("BulkMove: Validation subsystem unavailable"));
		return;
	}

	APawn* OwnerPawn = Cast<APawn>(GetOwner());
	APlayerController* PC = OwnerPawn ? Cast<APlayerController>(OwnerPawn->GetController()) : nullptr;

	// All-or-nothing: validate every intent before executing any
	for (const FItemMoveIntent& Intent : MoveIntents)
	{
		const FGameplayTag Result = Validation->ValidateMoveIntent(PC, this, this, Intent.SourceIndex, Intent.TargetIndex);
		if (Result != VaultTags::Validation_Success)
		{
			UE_LOG(LogVaultValidation, Warning,
				TEXT("BulkMove: Validation failed — %s (Source=%d, Target=%d). Rejecting entire batch."),
				*Result.ToString(), Intent.SourceIndex, Intent.TargetIndex);
			return;
		}
	}

	// Execute all swaps
	for (const FIte
Authority_TransformItems method · cpp · L799-L967 (169 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
FGameplayTag UInventoryManagerComponent::Authority_TransformItems(UItemTransformationRule* Rule)
{
	if (!ensureMsgf(GetOwnerRole() == ROLE_Authority,
		TEXT("Authority_TransformItems called on non-authority")))
	{
		return VaultTags::Validation_Error_ServerNotReady;
	}

	if (!IsValid(Rule) || !IsValid(Rule->OutputDef) || Rule->Inputs.Num() == 0)
	{
		return VaultTags::Validation_Error_ItemNotFound;
	}

	UInventoryValidationSubsystem* Validation = CachedValidation.Get();

	// Access policy check: actor must have modify permission to transform items.
	// Transformation consumes inputs and creates outputs — requires full modify rights.
	if (Validation)
	{
		APawn* OwnerPawn = Cast<APawn>(GetOwner());
		AActor* RequestingActor = OwnerPawn ? Cast<AActor>(OwnerPawn->GetController()) : GetOwner();
		FGameplayTag AccessResult = Validation->CheckAccessPolicy(RequestingActor, this, nullptr, EAccessOperation::Modify);
		if (AccessResult != VaultTags::Validation_Success)
		{
			UE_LOG(LogVaultVal
FindEntryByID method · cpp · L970-L974 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
const FInventoryEntry* UInventoryManagerComponent::FindEntryByID(const FGuid& InstanceID) const
{
	return InventoryArray.FindByInstanceID(InstanceID);
}
Repobility · MCP-ready · https://repobility.com
BP_FindEntryByID method · cpp · L975-L980 (6 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
FInventoryEntry UInventoryManagerComponent::BP_FindEntryByID(FGuid InstanceID) const
{
	const FInventoryEntry* Found = FindEntryByID(InstanceID);
	return Found ? *Found : FInventoryEntry();
}
GetCurrencyBalance method · cpp · L981-L985 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
int32 UInventoryManagerComponent::GetCurrencyBalance(FGameplayTag CurrencyType) const
{
	return Wallet.GetBalance(CurrencyType);
}
HasCurrencyBalance method · cpp · L986-L990 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::HasCurrencyBalance(FGameplayTag CurrencyType, int32 Amount) const
{
	return Wallet.HasBalance(CurrencyType, Amount);
}
IsItemBound method · cpp · L991-L996 (6 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::IsItemBound(FGuid InstanceID) const
{
	const FInventoryEntry* Entry = FindEntryByID(InstanceID);
	return Entry && Entry->IsBound();
}
IsItemExpired method · cpp · L997-L1002 (6 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::IsItemExpired(FGuid InstanceID) const
{
	const FInventoryEntry* Entry = FindEntryByID(InstanceID);
	return Entry && Entry->IsExpired();
}
CreateSnapshot method · cpp · L1003-L1022 (20 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
FInventorySnapshot UInventoryManagerComponent::CreateSnapshot() const
{
	FInventorySnapshot Snap;
	Snap.Entries = InventoryArray.Entries;
	Snap.Wallet = Wallet;
	Snap.LockVersion = LockVersion;
	Snap.TimestampUTC = FDateTime::UtcNow();

	// Compute hash if validation subsystem is available (requires a world)
	if (const UWorld* World = GetWorld())
	{
		if (const UInventoryValidationSubsystem* Validation = World->GetSubsystem<UInventoryValidationSubsystem>())
		{
			Snap.InventoryHash = Validation->ComputeInventoryHash(this);
		}
	}

	return Snap;
}
NotifyItemAdded method · cpp · L1026-L1030 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::NotifyItemAdded(const FInventoryEntry& Entry)
{
	OnInventoryItemAdded.Broadcast(Entry);
}
NotifyItemRemoved method · cpp · L1031-L1035 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::NotifyItemRemoved(const FGuid& InstanceID)
{
	OnInventoryItemRemoved.Broadcast(InstanceID);
}
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
NotifyItemChanged method · cpp · L1036-L1040 (5 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::NotifyItemChanged(const FInventoryEntry& Entry)
{
	OnInventoryItemChanged.Broadcast(Entry);
}
TriggerAsyncSave method · cpp · L1043-L1089 (47 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::TriggerAsyncSave()
{
	if (PersistenceMode == EVaultPersistenceMode::SessionOnly)
	{
		// Session-only inventory — never persist to storage
		return;
	}

	// Snapshot inventory state on the game thread — providers handle async I/O internally
	UWorld* World_Local = GetWorld();
	UGameInstance* GI = World_Local ? World_Local->GetGameInstance() : nullptr;
	UVaultStorageManager* StorageManager = GI ? GI->GetSubsystem<UVaultStorageManager>() : nullptr;
	if (StorageManager == nullptr)
	{
		UE_LOG(LogVaultStorage, Warning, TEXT("TriggerAsyncSave: No VaultStorageManager available for %s"),
			*GetOwner()->GetName());
		return;
	}

	TScriptInterface<IInventoryStorageProvider> Provider = StorageManager->GetActiveProvider();
	if (!Provider.GetObject())
	{
		UE_LOG(LogVaultStorage, Warning, TEXT("TriggerAsyncSave: No active storage provider for %s"),
			*GetOwner()->GetName());
		return;
	}

	// Build payload on game thread — plain struct snapshot is safe to hand of
OnAsyncSaveComplete method · cpp · L1090-L1117 (28 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
void UInventoryManagerComponent::OnAsyncSaveComplete(bool bSuccess, const FString& ErrorMessage)
{
	if (bSuccess)
	{
		LockVersion++;
		UE_LOG(LogVaultStorage, Verbose, TEXT("AsyncSave complete: ProfileID=%s, LockVersion=%d"),
			*ProfileID, LockVersion);
	}
	else
	{
		UE_LOG(LogVaultStorage, Warning, TEXT("AsyncSave failed: ProfileID=%s — %s"), *ProfileID, *ErrorMessage);
		OnSessionConflictDetected.Broadcast();
	}

	// Record metrics for observability
	UWorld* World_Local = GetWorld();
	UGameInstance* GI = World_Local ? World_Local->GetGameInstance() : nullptr;
	UVaultStorageManager* SM = GI ? GI->GetSubsystem<UVaultStorageManager>() : nullptr;
	if (SM != nullptr)
	{
		TScriptInterface<IInventoryStorageProvider> Provider = SM->GetActiveProvider();
		SM->RecordOperationMetrics(
			Provider.GetInterface()
				? Provider->GetLastOperationMetrics()
				: FStorageOperationMetrics());
	}
}
ValidateRPCPreconditions method · cpp · L1118-L1151 (34 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::ValidateRPCPreconditions()
{
	// Economy config gate — reject RPCs until config is loaded in cloud mode.
	// We allow the RPC through (return true) but log a warning so the _Implementation
	// can handle the rejection gracefully. Returning false here would disconnect the client
	// in shipping builds, which is too aggressive for a transient startup condition.
	if (!bEconomyConfigReady)
	{
		UE_LOG(LogVaultValidation, Verbose, TEXT("RPC rejected: economy config not ready"));
	}

	// Rate limit check — sustained abuse results in _Validate returning false,
	// which triggers a client disconnect in shipping builds (intentional for cheaters)
	UInventoryValidationSubsystem* Validation = CachedValidation.Get();

	if (Validation)
	{
		const APawn* OwnerPawn = Cast<APawn>(GetOwner());
		APlayerController* PC = OwnerPawn
			? Cast<APlayerController>(OwnerPawn->GetController())
			: nullptr;

		const FGameplayTag RateLimitResult = Validation->CheckRateLimit(PC);
HasItemByDef method · cpp · L1154-L1166 (13 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
bool UInventoryManagerComponent::HasItemByDef(const UItemDefinition* ItemDef) const
{
	if (!IsValid(ItemDef)) return false;
	for (const FInventoryEntry& Entry : InventoryArray.Entries)
	{
		if (Entry.ItemDef.Get() == ItemDef)
		{
			return true;
		}
	}
	return false;
}
CountItemsByDef method · cpp · L1167-L1180 (14 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
int32 UInventoryManagerComponent::CountItemsByDef(const UItemDefinition* ItemDef) const
{
	if (!IsValid(ItemDef)) return 0;
	int32 Total = 0;
	for (const FInventoryEntry& Entry : InventoryArray.Entries)
	{
		if (Entry.ItemDef.Get() == ItemDef)
		{
			Total += Entry.StackCount;
		}
	}
	return Total;
}
GetTotalWeight method · cpp · L1181-L1194 (14 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
float UInventoryManagerComponent::GetTotalWeight() const
{
	float TotalWeight = 0.0f;
	for (const FInventoryEntry& Entry : InventoryArray.Entries)
	{
		if (!IsValid(Entry.ItemDef.Get())) continue;
		if (const UItemFragment_Weight* WeightFrag = Entry.ItemDef->FindFragmentByClass<UItemFragment_Weight>())
		{
			TotalWeight += WeightFrag->PerItemWeight * Entry.StackCount;
		}
	}
	return TotalWeight;
}
FindItemsByTag method · cpp · L1195-L1214 (20 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
TArray<FInventoryEntry> UInventoryManagerComponent::FindItemsByTag(FGameplayTagContainer FilterTags, bool bRequireAll) const
{
	TArray<FInventoryEntry> Results;
	if (FilterTags.IsEmpty()) return Results;

	for (const FInventoryEntry& Entry : InventoryArray.Entries)
	{
		if (!IsValid(Entry.ItemDef.Get())) continue;
		const FGameplayTagContainer& ItemTags = Entry.ItemDef->ItemTags;
		const bool bMatch = bRequireAll
			? ItemTags.HasAll(FilterTags)
			: ItemTags.HasAny(FilterTags);
		if (bMatch)
		{
			Results.Add(Entry);
		}
	}
	return Results;
}
Powered by Repobility — scan your code at https://repobility.com
PreviewTransformation method · cpp · L1215-L1251 (37 LOC)
Source/VaultCore/Private/Component/InventoryManagerComponent.cpp
FGameplayTag UInventoryManagerComponent::PreviewTransformation(
	UItemTransformationRule* Rule,
	TArray<UItemDefinition*>& OutOutputDefs,
	TArray<int32>& OutOutputQuantities) const
{
	OutOutputDefs.Reset();
	OutOutputQuantities.Reset();

	if (!IsValid(Rule))
	{
		return VaultTags::Validation_Error_ItemNotFound;
	}

	// Read-only: verify all inputs are available without mutating state
	for (const FTransformInput& Input : Rule->Inputs)
	{
		if (!IsValid(Input.RequiredItemDef.Get()))
		{
			return VaultTags::Validation_Error_ItemNotFound;
		}
		const int32 Available = CountItemsByDef(Input.RequiredItemDef);
		if (Available < Input.MinQuantity)
		{
			return VaultTags::Validation_Error_InsufficientQuantity;
		}
	}

	// Report predicted outputs
	if (IsValid(Rule->OutputDef.Get()))
	{
		OutOutputDefs.Add(Rule->OutputDef);
		OutOutputQuantities.Add(Rule->OutputQuantity);
	}

	return VaultTags::Validation_Success;
}
DepositMaterial method · cpp · L23-L76 (54 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
FGameplayTag UCraftingStationComponent::DepositMaterial(
	APlayerController* Player, FGuid ItemInstanceID, int32 Quantity)
{
	if (!IsValid(Player) || !ItemInstanceID.IsValid() || Quantity <= 0)
	{
		return VaultTags::Validation_Error_OutOfBounds;
	}

	UInventoryManagerComponent* Comp = Player->GetPawn()
		? Player->GetPawn()->FindComponentByClass<UInventoryManagerComponent>()
		: nullptr;
	if (!Comp) return VaultTags::Validation_Error_NotOwner;

	const FInventoryEntry* Entry = Comp->FindEntryByID(ItemInstanceID);
	if (!Entry) return VaultTags::Validation_Error_ItemNotFound;

	// Lock the item to prevent concurrent operations
	UInventoryValidationSubsystem* Validation = GetWorld()->GetSubsystem<UInventoryValidationSubsystem>();
	if (Validation)
	{
		if (Validation->IsInstanceLocked(ItemInstanceID))
		{
			return VaultTags::Validation_Error_Locked;
		}
		Validation->LockInstance(ItemInstanceID);
	}

	// Guard against missing definition — corrupt or unloaded entries should not reach craf
WithdrawMaterial method · cpp · L77-L97 (21 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
FGameplayTag UCraftingStationComponent::WithdrawMaterial(
	APlayerController* Player, int32 SlotIndex)
{
	if (!InputSlots.IsValidIndex(SlotIndex))
	{
		return VaultTags::Validation_Error_OutOfBounds;
	}

	const FCraftingSlot& Slot = InputSlots[SlotIndex];

	// Unlock the item
	UInventoryValidationSubsystem* Validation = GetWorld()->GetSubsystem<UInventoryValidationSubsystem>();
	if (Validation)
	{
		Validation->UnlockInstance(Slot.ItemInstanceID);
	}

	InputSlots.RemoveAt(SlotIndex);
	return VaultTags::Validation_Success;
}
ExecuteCraft method · cpp · L98-L368 (271 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
FGameplayTag UCraftingStationComponent::ExecuteCraft(
	APlayerController* Player, FGameplayTag RecipeTag)
{
	if (!IsValid(Player) || !RecipeTag.IsValid())
	{
		return VaultTags::Validation_Error_OutOfBounds;
	}

	// Get the economy config via VaultStorageManager — the single source of truth for economy data
	UWorld* World_Local = GetWorld();
	UGameInstance* GI = World_Local ? World_Local->GetGameInstance() : nullptr;
	UVaultStorageManager* StorageManager = GI ? GI->GetSubsystem<UVaultStorageManager>() : nullptr;
	if (!StorageManager)
	{
		UE_LOG(LogVault, Warning, TEXT("ExecuteCraft: VaultStorageManager unavailable."));
		return VaultTags::Validation_Error_ServerNotReady;
	}

	// Gate on economy config readiness — server must have loaded config before accepting crafts
	if (!StorageManager->IsEconomyConfigReady())
	{
		UE_LOG(LogVault, Warning,
			TEXT("ExecuteCraft: Economy config not ready. Recipe=%s"), *RecipeTag.ToString());
		return VaultTags::Validation_Error_ServerNotReady;
	}

CollectOutput method · cpp · L369-L434 (66 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
FGameplayTag UCraftingStationComponent::CollectOutput(
	APlayerController* Player, int32 OutputSlotIndex)
{
	if (!OutputSlots.IsValidIndex(OutputSlotIndex))
	{
		return VaultTags::Validation_Error_OutOfBounds;
	}

	const FCraftingSlot& Slot = OutputSlots[OutputSlotIndex];

	UInventoryManagerComponent* Comp = Player->GetPawn()
		? Player->GetPawn()->FindComponentByClass<UInventoryManagerComponent>()
		: nullptr;
	if (!Comp) return VaultTags::Validation_Error_NotOwner;

	if (IsValid(Slot.ItemDef.Get()))
	{
		// Check slot capacity before adding — if full, overflow to mail
		UInventoryValidationSubsystem* Validation = GetWorld()
			? GetWorld()->GetSubsystem<UInventoryValidationSubsystem>()
			: nullptr;

		const bool bInventoryFull = Validation
			&& Validation->CheckSlotCapacity(Comp) != VaultTags::Validation_Success;

		if (bInventoryFull)
		{
			// Overflow: route crafted item to mail for async pickup
			UMailSubsystem* MailSub = GetWorld()
				? GetWorld()->GetSubsystem<UMailSubsyst
ReturnAllMaterials method · cpp · L435-L456 (22 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
void UCraftingStationComponent::ReturnAllMaterials()
{
	// Disconnect safety: unlock all deposited items
	UInventoryValidationSubsystem* Validation = GetWorld()
		? GetWorld()->GetSubsystem<UInventoryValidationSubsystem>()
		: nullptr;

	for (const FCraftingSlot& Slot : InputSlots)
	{
		if (Validation)
		{
			Validation->UnlockInstance(Slot.ItemInstanceID);
		}
		// Items are still in the player's inventory (they were locked, not removed)
		// Unlocking returns them to usable state
	}

	InputSlots.Reset();

	UE_LOG(LogVault, Log, TEXT("Crafting: All materials returned to owners (disconnect safety)."));
}
EnsureCraftingTimer method · cpp · L459-L468 (10 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
void UCraftingStationComponent::EnsureCraftingTimer()
{
	if (!CraftingTickTimerHandle.IsValid() && GetWorld())
	{
		GetWorld()->GetTimerManager().SetTimer(
			CraftingTickTimerHandle, this, &UCraftingStationComponent::TickCraftingJobs,
			1.0f, true);
	}
}
TickCraftingJobs method · cpp · L469-L513 (45 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
void UCraftingStationComponent::TickCraftingJobs()
{
	const FDateTime Now = FDateTime::UtcNow();
	bool bAnyCompleted = false;

	for (FCraftingJob& Job : ActiveJobs)
	{
		if (Job.bComplete) continue;

		const double ElapsedSeconds = (Now - Job.StartedAtUTC).GetTotalSeconds();
		if (ElapsedSeconds >= Job.DurationSeconds)
		{
			Job.bComplete = true;
			bAnyCompleted = true;

			// Move pending outputs to OutputSlots
			for (const FCraftingSlot& PendingSlot : Job.PendingOutputs)
			{
				OutputSlots.Add(PendingSlot);
			}

			UE_LOG(LogVault, Log, TEXT("Crafting job completed: %s (Recipe=%s)"),
				*Job.JobID.ToString(), *Job.RecipeTag.ToString());

			// Broadcast for each output
			for (const FCraftingSlot& PendingSlot : Job.PendingOutputs)
			{
				OnCraftingComplete.Broadcast(PendingSlot.ItemDef, PendingSlot.Quantity);
			}
		}
	}

	// Remove completed jobs
	if (bAnyCompleted)
	{
		ActiveJobs.RemoveAll([](const FCraftingJob& Job) { return Job.bComplete; });
	}

	// Stop timer if no m
Source: Repobility analyzer · https://repobility.com
CancelCraftingJob method · cpp · L514-L533 (20 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
FGameplayTag UCraftingStationComponent::CancelCraftingJob(FGuid JobID, APlayerController* Player)
{
	const int32 Index = ActiveJobs.IndexOfByPredicate([&JobID](const FCraftingJob& Job)
	{
		return Job.JobID == JobID;
	});

	if (Index == INDEX_NONE)
	{
		return VaultTags::Validation_Error_ItemNotFound;
	}

	// Remove the job — inputs were already consumed so they cannot be returned.
	// This is intentional: canceling a timed craft forfeits the materials.
	ActiveJobs.RemoveAt(Index);

	UE_LOG(LogVault, Log, TEXT("Crafting job cancelled: %s"), *JobID.ToString());
	return VaultTags::Validation_Success;
}
SalvageItem method · cpp · L536-L609 (74 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
FGameplayTag UCraftingStationComponent::SalvageItem(APlayerController* Player, FGuid ItemInstanceID)
{
	if (!IsValid(Player) || !ItemInstanceID.IsValid())
	{
		return VaultTags::Validation_Error_OutOfBounds;
	}

	UInventoryManagerComponent* Comp = Player->GetPawn()
		? Player->GetPawn()->FindComponentByClass<UInventoryManagerComponent>()
		: nullptr;
	if (!Comp) return VaultTags::Validation_Error_NotOwner;

	const FInventoryEntry* Entry = Comp->FindEntryByID(ItemInstanceID);
	if (!Entry || !IsValid(Entry->ItemDef.Get())) return VaultTags::Validation_Error_ItemNotFound;

	// Look up salvage recipe from economy config
	UWorld* World_Local = GetWorld();
	UGameInstance* GI = World_Local ? World_Local->GetGameInstance() : nullptr;
	UVaultStorageManager* StorageManager = GI ? GI->GetSubsystem<UVaultStorageManager>() : nullptr;
	if (!StorageManager || !StorageManager->IsEconomyConfigReady())
	{
		return VaultTags::Validation_Error_ServerNotReady;
	}

	const FVaultEconomyConfig& EconConfig = 
CanCraft method · cpp · L612-L659 (48 LOC)
Source/VaultCore/Private/Crafting/CraftingStationComponent.cpp
bool UCraftingStationComponent::CanCraft(FGameplayTag RecipeTag, TArray<FGameplayTag>& OutMissingInputs) const
{
	OutMissingInputs.Reset();

	// Look up recipe from economy config
	UWorld* World_Local = GetWorld();
	if (!World_Local) return false;

	UGameInstance* GI = World_Local->GetGameInstance();
	UVaultStorageManager* SM = GI ? GI->GetSubsystem<UVaultStorageManager>() : nullptr;
	if (!SM || !SM->IsEconomyConfigReady()) return false;

	const FVaultEconomyConfig& Config = SM->GetEconomyConfig();
	const FCraftingRecipe* Recipe = Config.CraftingRecipes.Find(RecipeTag);

	if (!Recipe)
	{
		OutMissingInputs.Add(RecipeTag);
		return false;
	}

	// Check each ingredient against deposited materials
	bool bAllPresent = true;
	for (const FCraftingIngredient& Ingredient : Recipe->Ingredients)
	{
		int32 AvailableQty = 0;
		for (const FCraftingSlot& Slot : InputSlots)
		{
			if (Slot.ItemDef.Get() == Ingredient.ItemDef.Get())
			{
				AvailableQty += Slot.Quantity;
			}
		}

		if (AvailableQt
GetPreloadDependencies method · cpp · L4-L17 (14 LOC)
Source/VaultCore/Private/Data/Fragments/ItemFragment_Visuals.cpp
void UItemFragment_Visuals::GetPreloadDependencies(TArray<UObject*>& OutDeps)
{
	Super::GetPreloadDependencies(OutDeps);

	// Register soft references so Asset Manager knows to load them
	if (!InventoryIcon.IsNull())
	{
		if (UObject* IconObj = InventoryIcon.Get())
		{
			OutDeps.Add(IconObj);
		}
	}
}
GetFragmentDescription method · cpp · L20-L23 (4 LOC)
Source/VaultCore/Private/Data/Fragments/ItemFragment_Visuals.cpp
FText UItemFragment_Visuals::GetFragmentDescription() const
{
	return DisplayName.IsEmpty() ? FText::FromString(TEXT("Visuals")) : DisplayName;
}
IsValid method · cpp · L14-L19 (6 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
bool FInventoryEntry::IsValid() const
{
	// Valid if we have a tag (replicated/serialized path) OR a resolved definition (legacy/server path)
	return (ItemDefTag.IsValid() || ::IsValid(ItemDef)) && InstanceID.IsValid();
}
IsBound method · cpp · L20-L24 (5 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
bool FInventoryEntry::IsBound() const
{
	return !BoundToOwnerID.IsEmpty();
}
IsExpired method · cpp · L25-L29 (5 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
bool FInventoryEntry::IsExpired() const
{
	return HasExpiry() && FDateTime::UtcNow() > ExpiresAtUTC;
}
Repobility · MCP-ready · https://repobility.com
HasExpiry method · cpp · L30-L35 (6 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
bool FInventoryEntry::HasExpiry() const
{
	// FDateTime(0) == no expiry
	return ExpiresAtUTC.GetTicks() > 0;
}
GetBalance method · cpp · L38-L43 (6 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
int32 FWalletContainer::GetBalance(FGameplayTag CurrencyTag) const
{
	const int32* Found = Balances.Find(CurrencyTag);
	return Found ? *Found : 0;
}
HasBalance method · cpp · L44-L48 (5 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
bool FWalletContainer::HasBalance(FGameplayTag CurrencyTag, int32 Amount) const
{
	return GetBalance(CurrencyTag) >= Amount;
}
AddCurrency method · cpp · L49-L58 (10 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
void FWalletContainer::AddCurrency(FGameplayTag CurrencyTag, int32 Amount)
{
	if (!ensureMsgf(Amount >= 0, TEXT("AddCurrency: negative amount %d rejected"), Amount))
	{
		return; // Graceful rejection — never crash the server on player-controlled data
	}
	int32& Balance = Balances.FindOrAdd(CurrencyTag, 0);
	Balance += Amount;
}
DeductCurrency method · cpp · L59-L73 (15 LOC)
Source/VaultCore/Private/Data/InventoryEntry.cpp
bool FWalletContainer::DeductCurrency(FGameplayTag CurrencyTag, int32 Amount)
{
	if (!ensureMsgf(Amount >= 0, TEXT("DeductCurrency: negative amount %d rejected"), Amount))
	{
		return false; // Graceful rejection
	}
	int32* Balance = Balances.Find(CurrencyTag);
	if (!Balance || *Balance < Amount)
	{
		return false;
	}
	*Balance -= Amount;
	return true;
}
GetPrimaryAssetId method · cpp · L4-L8 (5 LOC)
Source/VaultCore/Private/Data/ItemDefinition.cpp
FPrimaryAssetId UItemDefinition::GetPrimaryAssetId() const
{
	return FPrimaryAssetId(TEXT("ItemDefinition"), GetFName());
}
BP_FindFragmentByClass method · cpp · L9-L26 (18 LOC)
Source/VaultCore/Private/Data/ItemDefinition.cpp
const UItemFragment* UItemDefinition::BP_FindFragmentByClass(TSubclassOf<UItemFragment> FragmentClass) const
{
	if (!FragmentClass)
	{
		return nullptr;
	}

	for (const TObjectPtr<UItemFragment>& Fragment : Fragments)
	{
		if (IsValid(Fragment) && Fragment->IsA(FragmentClass))
		{
			return Fragment;
		}
	}

	return nullptr;
}
Initialize method · cpp · L18-L46 (29 LOC)
Source/VaultCore/Private/Data/ItemDefinitionRegistry.cpp
void UItemDefinitionRegistry::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);

	UE_LOG(LogVaultRegistry, Display, TEXT("ItemDefinitionRegistry initializing..."));

	// 1. Register hand-crafted .uasset definitions via Asset Manager
	PopulateFromAssetManager();

	// 2. Register DataTable-driven definitions from settings
	const UVaultSettings* Settings = UVaultSettings::Get();
	if (Settings && !Settings->ItemDefinitionsDataTable.IsNull())
	{
		UDataTable* DataTable = Settings->ItemDefinitionsDataTable.LoadSynchronous();
		if (DataTable)
		{
			PopulateFromDataTable(DataTable);
		}
		else
		{
			UE_LOG(LogVaultRegistry, Warning,
				TEXT("ItemDefinitionsDataTable configured but failed to load."));
		}
	}

	// 3. Lock the registry
	FinalizeRegistry();
}
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
Deinitialize method · cpp · L47-L54 (8 LOC)
Source/VaultCore/Private/Data/ItemDefinitionRegistry.cpp
void UItemDefinitionRegistry::Deinitialize()
{
	UE_LOG(LogVaultRegistry, Display, TEXT("ItemDefinitionRegistry shutting down. %d definitions registered."),
		DefinitionMap.Num());

	Super::Deinitialize();
}
ResolveDefinition method · cpp · L57-L68 (12 LOC)
Source/VaultCore/Private/Data/ItemDefinitionRegistry.cpp
const UItemDefinition* UItemDefinitionRegistry::ResolveDefinition(FGameplayTag ItemDefTag) const
{
	if (!ItemDefTag.IsValid())
	{
		return nullptr;
	}

	FReadScopeLock ReadLock(RegistryLock);
	const TObjectPtr<UItemDefinition>* Found = DefinitionMap.Find(ItemDefTag);
	return Found ? Found->Get() : nullptr;
}
GetAllDefinitions method · cpp · L69-L84 (16 LOC)
Source/VaultCore/Private/Data/ItemDefinitionRegistry.cpp
TArray<UItemDefinition*> UItemDefinitionRegistry::GetAllDefinitions() const
{
	FReadScopeLock ReadLock(RegistryLock);

	TArray<UItemDefinition*> Result;
	Result.Reserve(DefinitionMap.Num());
	for (const auto& Pair : DefinitionMap)
	{
		if (IsValid(Pair.Value))
		{
			Result.Add(Pair.Value.Get());
		}
	}
	return Result;
}
‹ prevpage 3 / 10next ›