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>
80 lines
2.2 KiB
C++
80 lines
2.2 KiB
C++
// Copyright ExByte Studios. Item Interaction Ecosystem.
|
|
|
|
#include "ItemSaveLibrary.h"
|
|
#include "ItemInventoryLog.h"
|
|
#include "InventoryComponent.h"
|
|
#include "ItemDatabaseSubsystem.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
FInventorySaveData UItemSaveLibrary::CaptureInventory(UInventoryComponent* Inventory)
|
|
{
|
|
FInventorySaveData Data;
|
|
if (!Inventory)
|
|
{
|
|
return Data;
|
|
}
|
|
Inventory->GetAllItems(Data.Items);
|
|
for (FItemInstanceData& Item : Data.Items)
|
|
{
|
|
Item.Lock.Clear(); // never persist transient locks (section 26)
|
|
}
|
|
Inventory->GetContainers(Data.Containers);
|
|
return Data;
|
|
}
|
|
|
|
void UItemSaveLibrary::RestoreInventory(const UObject* WorldContext, UInventoryComponent* Inventory, const FInventorySaveData& Data)
|
|
{
|
|
if (!Inventory || !Inventory->GetOwner() || !Inventory->GetOwner()->HasAuthority())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Inventory->SetContainers(Data.Containers);
|
|
Inventory->ClearAllItems();
|
|
|
|
const UItemDatabaseSubsystem* DB = UItemDatabaseSubsystem::Get(WorldContext);
|
|
for (const FItemInstanceData& Saved : Data.Items)
|
|
{
|
|
FItemInstanceData Item = Saved;
|
|
if (DB) { DB->MigrateLoadedItem(Item); }
|
|
Inventory->SetItemInSlot(Item, Item.CurrentContainerId, Item.SlotIndex);
|
|
}
|
|
UE_LOG(LogItemInventory, Log, TEXT("[Save] restored %d items into %s"), Data.Items.Num(), *GetNameSafe(Inventory->GetOwner()));
|
|
}
|
|
|
|
bool UItemSaveLibrary::SaveInventoryToSlot(UInventoryComponent* Inventory, const FString& SlotName, FName Key)
|
|
{
|
|
if (!Inventory)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
UItemSaveGame* Save = Cast<UItemSaveGame>(UGameplayStatics::LoadGameFromSlot(SlotName, 0));
|
|
if (!Save)
|
|
{
|
|
Save = Cast<UItemSaveGame>(UGameplayStatics::CreateSaveGameObject(UItemSaveGame::StaticClass()));
|
|
}
|
|
if (!Save)
|
|
{
|
|
return false;
|
|
}
|
|
Save->Inventories.Add(Key, CaptureInventory(Inventory));
|
|
return UGameplayStatics::SaveGameToSlot(Save, SlotName, 0);
|
|
}
|
|
|
|
bool UItemSaveLibrary::LoadInventoryFromSlot(const UObject* WorldContext, UInventoryComponent* Inventory, const FString& SlotName, FName Key)
|
|
{
|
|
UItemSaveGame* Save = Cast<UItemSaveGame>(UGameplayStatics::LoadGameFromSlot(SlotName, 0));
|
|
if (!Save)
|
|
{
|
|
return false;
|
|
}
|
|
const FInventorySaveData* Data = Save->Inventories.Find(Key);
|
|
if (!Data)
|
|
{
|
|
return false;
|
|
}
|
|
RestoreInventory(WorldContext, Inventory, *Data);
|
|
return true;
|
|
}
|