调整舱位容器结构

This commit is contained in:
997146918 2025-10-22 19:31:01 +08:00
parent e3dd0f022f
commit 8106645812
17 changed files with 52 additions and 47 deletions

Binary file not shown.

View File

@ -3,36 +3,12 @@
#include "ContainerInfo.h" #include "ContainerInfo.h"
#include "IDetailTreeNode.h"
#include "PlayerInfoSaveGame.h" #include "PlayerInfoSaveGame.h"
#include "Chaos/PBDRigidClusteringAlgo.h"
#include "Engine/AssetManager.h" #include "Engine/AssetManager.h"
#include "Engine/StreamableManager.h" #include "Engine/StreamableManager.h"
// void UContainerInfo::InitContainer(FPrimaryAssetId ContainerShapeId)
// {
// //加载形状资源
// TSharedPtr<FStreamableHandle> LoadHandle = GEngine->AssetManager->LoadPrimaryAsset(ContainerShapeId);
// if (LoadHandle.IsValid())
// {
// // 等待加载完成,这会阻塞线程
// LoadHandle->WaitUntilComplete();
//
// // 加载完成后,通过句柄获取资源
// UObject* LoadedObject = LoadHandle->GetLoadedAsset();
// if (LoadedObject)
// {
// ContainerShape = Cast<UShapeAsset>(LoadedObject);
// for (int x = 0; x < ContainerShape->GetShapeWidth(); x++)
// {
// for (int y = 0; y < ContainerShape->GetShapeHeight(); y++)
// {
// SlotInUsing.Add(FIntPoint(x, y), false);
// }
// }
// }
// LoadHandle->ReleaseHandle();
// }
//
// }
void UContainerInfo::InitContainerByShape(UShapeAsset* InContainerShape) void UContainerInfo::InitContainerByShape(UShapeAsset* InContainerShape)
{ {
@ -46,18 +22,19 @@ void UContainerInfo::InitContainerByShape(UShapeAsset* InContainerShape)
} }
} }
bool UContainerInfo::AddContainerItem(FContainerItem Item, FIntPoint Position) bool UContainerInfo::AddContainerItem(FContainerItem Item, int32& ItemID)
{ {
if (IsItemInContainerShape(Item, Position)) if (IsItemInContainerShape(Item))
{ {
return false; return false;
} }
if (IsItemOverlapOtherItem(Item, Position)) if (IsItemOverlapOtherItem(Item))
{ {
return false; return false;
} }
ItemID = NextItemID;
Items.Add(Position, Item); Items.Add(NextItemID, Item);
++NextItemID;
//设置容器指定位置的占用状态 //设置容器指定位置的占用状态
for (int x = 0; x < Item.GetItemWIdth(); x++) for (int x = 0; x < Item.GetItemWIdth(); x++)
{ {
@ -65,25 +42,46 @@ bool UContainerInfo::AddContainerItem(FContainerItem Item, FIntPoint Position)
{ {
if (Item.IsSlotUsing(FIntPoint(x, y))) if (Item.IsSlotUsing(FIntPoint(x, y)))
{ {
SlotInUsing.Add(FIntPoint(x + Position.X, y + Position.Y), true); SlotInUsing.Add(FIntPoint(x + Item.ContainerStartPos.X, y + Item.ContainerStartPos.Y), true);
} }
} }
} }
return true; return true;
} }
bool UContainerInfo::IsItemOverlapOtherItem(FContainerItem NewItem, FIntPoint Position) bool UContainerInfo::RemoveContainerItem(const int32& ItemID)
{
if (Items.Contains(ItemID))
{
FContainerItem Item = Items[ItemID];
for (int x = 0; x < Item.GetItemWIdth(); x++)
{
for (int y = 0; y < Item.GetItemHeight(); y++)
{
if (Item.IsSlotUsing(FIntPoint(x + Item.ContainerStartPos.X, y + Item.ContainerStartPos.Y)))
{
SlotInUsing[FIntPoint(x + Item.ContainerStartPos.X, y + Item.ContainerStartPos.Y)] = false;
}
}
}
Items.Remove(ItemID);
return true;
}
return false;
}
bool UContainerInfo::IsItemOverlapOtherItem(FContainerItem NewItem)
{ {
for (int x = 0; x < NewItem.GetItemWIdth(); x++) for (int x = 0; x < NewItem.GetItemWIdth(); x++)
{ {
for (int y = 0; y < NewItem.GetItemHeight(); y++) for (int y = 0; y < NewItem.GetItemHeight(); y++)
{ {
if (NewItem.IsSlotUsing(Position)) if (NewItem.IsSlotUsing(FIntPoint(x, y)))
{ {
if (!ContainerShape->IsSlotActive(Position.X + x, Position.Y + y) || if (!ContainerShape->IsSlotActive(NewItem.ContainerStartPos.X + x, NewItem.ContainerStartPos.Y + y) ||
SlotInUsing[FIntPoint(x + Position.X, y + Position.Y)]) SlotInUsing[FIntPoint(x + NewItem.ContainerStartPos.X, y + NewItem.ContainerStartPos.Y)])
{ {
return true; return true;
} }
@ -94,17 +92,17 @@ bool UContainerInfo::IsItemOverlapOtherItem(FContainerItem NewItem, FIntPoint Po
return false; return false;
} }
bool UContainerInfo::IsItemInContainerShape(FContainerItem NewItem, FIntPoint Position) bool UContainerInfo::IsItemInContainerShape(FContainerItem NewItem)
{ {
for (int x = 0; x < NewItem.GetItemWIdth(); x++) for (int x = 0; x < NewItem.GetItemWIdth(); x++)
{ {
for (int y = 0; y < NewItem.GetItemHeight(); y++) for (int y = 0; y < NewItem.GetItemHeight(); y++)
{ {
if ( (x + Position.X) > 0 && (x + Position.X) < ContainerShape->GetShapeWidth() && if ( (x + NewItem.ContainerStartPos.X) > 0 && (x + NewItem.ContainerStartPos.X) < ContainerShape->GetShapeWidth() &&
(y + Position.Y) > 0 && (y + Position.Y) < ContainerShape->GetShapeHeight() (y + NewItem.ContainerStartPos.Y) > 0 && (y + NewItem.ContainerStartPos.Y) < ContainerShape->GetShapeHeight()
) )
{ {
if (!ContainerShape->IsSlotActive(Position.X + x, Position.Y + y)) if (!ContainerShape->IsSlotActive(NewItem.ContainerStartPos.X + x, NewItem.ContainerStartPos.Y + y))
{ {
return false; return false;
} }
@ -125,8 +123,8 @@ TArray<FContainerItemSaveData> UContainerInfo::GetSaveData() const
for (const auto& ItemPair : Items) for (const auto& ItemPair : Items)
{ {
FContainerItemSaveData SaveData; FContainerItemSaveData SaveData;
SaveData.PosX = ItemPair.Key.X; SaveData.PosX = ItemPair.Value.ContainerStartPos.X;
SaveData.PosY = ItemPair.Key.Y; SaveData.PosY = ItemPair.Value.ContainerStartPos.Y;
SaveData.DegreeType = ItemPair.Value.DegreeType; SaveData.DegreeType = ItemPair.Value.DegreeType;
if (ItemPair.Value.RewardItem) if (ItemPair.Value.RewardItem)
@ -158,13 +156,15 @@ bool UContainerInfo::LoadFromSaveData(FPrimaryAssetId ShapeID, const TArray<FCon
for (const FContainerItemSaveData& ItemData : ContainerItems) for (const FContainerItemSaveData& ItemData : ContainerItems)
{ {
FContainerItem NewItem; FContainerItem NewItem;
NewItem.ContainerStartPos = FIntPoint(ItemData.PosX, ItemData.PosY);
NewItem.DegreeType = ItemData.DegreeType; NewItem.DegreeType = ItemData.DegreeType;
//获得物品形状 //获得物品形状
FSoftObjectPath RewardItemPath = UAssetManager::Get().GetPrimaryAssetPath(ItemData.RewardItemAssetId); FSoftObjectPath RewardItemPath = UAssetManager::Get().GetPrimaryAssetPath(ItemData.RewardItemAssetId);
NewItem.RewardItem = Cast<UFishingRewardDataAsset>(RewardItemPath.TryLoad()); NewItem.RewardItem = Cast<UFishingRewardDataAsset>(RewardItemPath.TryLoad());
//添加物品到容器中 //添加物品到容器中
FIntPoint Position(ItemData.PosX, ItemData.PosY); FIntPoint Position(ItemData.PosX, ItemData.PosY);
AddContainerItem(NewItem, Position); int32 ItemID;
AddContainerItem(NewItem, ItemID);
} }
return true; return true;

View File

@ -44,6 +44,8 @@ struct FContainerItem
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FIntPoint ContainerStartPos;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
EItemDegreeType DegreeType; EItemDegreeType DegreeType;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
@ -110,7 +112,9 @@ public:
void InitContainerByShape(UShapeAsset* InContainerShape); void InitContainerByShape(UShapeAsset* InContainerShape);
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
bool AddContainerItem(FContainerItem Item, FIntPoint Position); bool AddContainerItem(FContainerItem Item, int32& ItemID);
UFUNCTION(BlueprintPure)
bool RemoveContainerItem(const int32& ItemID);
// 获取存档数据 // 获取存档数据
UFUNCTION(BlueprintCallable, Category = "ContainerInfo") UFUNCTION(BlueprintCallable, Category = "ContainerInfo")
@ -125,16 +129,17 @@ public:
private: private:
//要添加的物品是否会覆盖其他物品 //要添加的物品是否会覆盖其他物品
bool IsItemOverlapOtherItem(FContainerItem Item, FIntPoint Position); bool IsItemOverlapOtherItem(FContainerItem Item);
//要添加的物品是否在容器范围内 //要添加的物品是否在容器范围内
bool IsItemInContainerShape(FContainerItem Item, FIntPoint Position); bool IsItemInContainerShape(FContainerItem Item);
public: public:
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
TMap<FIntPoint, FContainerItem> Items; TMap<int32, FContainerItem> Items;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
UShapeAsset* ContainerShape; UShapeAsset* ContainerShape;
private: private:
int32 NextItemID = 0;
TMap<FIntPoint, bool> SlotInUsing; TMap<FIntPoint, bool> SlotInUsing;
}; };