Files
BusyRabbit/Source/BusyRabbit/Private/Components/InventoryComponent.cpp

227 lines
6.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Fill out your copyright notice in the Description page of Project Settings.
#include "Components/InventoryComponent.h"
#include "Math/UnrealMathUtility.h"
UInventoryComponent::UInventoryComponent() : Capacity(20) {
}
bool UInventoryComponent::DepositItems(int32 ItemID, int32 ItemCnt) {
int32 RemainItemCnt = ItemCnt;
if (ItemCnt <= 0) {
return true;
}
if (!IsCanContain(ItemID, ItemCnt)) {
return false;
}
while (RemainItemCnt > 0) {
FInventoryGrid& Grid = GetOrCreateGrid(ItemID);
int32 GridRemainCapacity = Grid.MaxCount - Grid.CurrentCount;
int32 AddCount = FMath::Min(RemainItemCnt, GridRemainCapacity);
Grid.CurrentCount += AddCount;
RemainItemCnt -= AddCount;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><EFBFBD>¼<EFBFBD>
OnInventoryChanged.Broadcast(ItemID);
return true;
}
bool UInventoryComponent::WithdrawItems(int32 ItemID, int32 ItemCnt) {
if (ItemCnt <= 0) {
return true;
}
if (!IsEnough(ItemID, ItemCnt)) {
return false;
}
int32 RemainToWithdraw = ItemCnt;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBAF><EFBFBD>
for (int32 i = InventoryList.Num() - 1; i >= 0 && RemainToWithdraw > 0; --i) {
FInventoryGrid& Grid = InventoryList[i];
if (Grid.ItemID == ItemID) {
int32 RemoveCount = FMath::Min(RemainToWithdraw, Grid.CurrentCount);
Grid.CurrentCount -= RemoveCount;
RemainToWithdraw -= RemoveCount;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><EFBFBD>¼<EFBFBD>
OnInventoryChanged.Broadcast(ItemID);
return true;
}
bool UInventoryComponent::ConsumeItems(int32 Index, int32 ItemCnt) {
if (ItemCnt <= 0) {
return true;
}
if (!InventoryList.IsValidIndex(Index)) {
return false;
}
FInventoryGrid& SpecifiedGrid = InventoryList[Index];
int32 ItemID = SpecifiedGrid.ItemID;
if (!IsEnough(ItemID, ItemCnt)) {
return false;
}
// <20>ȿ۳<C8BF>ָ<EFBFBD><D6B8>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>Ʒ
int32 RemoveFromSpecified = FMath::Min(ItemCnt, SpecifiedGrid.CurrentCount);
SpecifiedGrid.CurrentCount -= RemoveFromSpecified;
int32 RemainToConsume = ItemCnt - RemoveFromSpecified;
// <20>ٿ۳<D9BF><DBB3><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>Ʒ
if (RemainToConsume > 0) {
for (int32 i = InventoryList.Num() - 1; i >= 0 && RemainToConsume > 0; --i) {
if (i == Index) continue; // <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>λ<EFBFBD><CEBB>
FInventoryGrid& Grid = InventoryList[i];
if (Grid.ItemID == ItemID) {
int32 RemoveCount = FMath::Min(RemainToConsume, Grid.CurrentCount);
Grid.CurrentCount -= RemoveCount;
RemainToConsume -= RemoveCount;
}
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><EFBFBD>¼<EFBFBD>
OnInventoryChanged.Broadcast(ItemID);
return true;
}
void UInventoryComponent::SetInventoryCapacity(int MaxCapacity) {
int32 NewCapacity = FMath::Max(0, MaxCapacity);
if (Capacity != NewCapacity) {
Capacity = NewCapacity;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
OnInventoryCapacityChanged.Broadcast();
}
}
void UInventoryComponent::ReSortAllItem() {
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA>ĸ<EFBFBD><C4B8><EFBFBD>
for (int32 i = InventoryList.Num() - 1; i >= 0; --i) {
if (InventoryList[i].CurrentCount <= 0) {
InventoryList.RemoveAt(i);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
InventoryList.Sort([](const FInventoryGrid& A, const FInventoryGrid& B) {
return A.Priority > B.Priority; // <20><><EFBFBD>ȼ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ǰ
});
}
bool UInventoryComponent::IsCanContain(int32 ItemID, int32 Count) {
if (Count <= 0) return true;
int32 EmptySlotCount= 0;
int32 ExistingSpace = 0;
int32 ExistingGrids = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>пռ<D0BF>
for (const FInventoryGrid& Grid : InventoryList) {
if (Grid.ItemID == ItemID) {
ExistingSpace += (Grid.MaxCount - Grid.CurrentCount);
ExistingGrids++;
}else if (Grid.ItemID == 0 || Grid.CurrentCount == 0) {
EmptySlotCount++;
}
}
if (ExistingSpace >= Count) {
return true;
}
int32 NeededSpace = Count - ExistingSpace;
// <20><><EFBFBD><EFBFBD><EFBFBD>¸<EFBFBD><C2B8>ӿ<EFBFBD><D3BF>ÿռ<C3BF>
int32 AvailableGridSlots = Capacity - InventoryList.Num() + EmptySlotCount;
if (AvailableGridSlots <= 0) {
return false;
}
// <20><>ȡ<EFBFBD><C8A1>ƷĬ<C6B7>϶ѵ<CFB6><D1B5><EFBFBD>С
FInventoryGrid TempGrid;
TempGrid.ItemID = ItemID;
InitItemGrid(TempGrid);
int32 NewGridSpace = AvailableGridSlots * TempGrid.MaxCount;
return (ExistingSpace + NewGridSpace) >= Count;
}
bool UInventoryComponent::IsEnough(int32 ItemID, int32 Count) {
if (Count <= 0) return true;
int32 Total = 0;
for (const FInventoryGrid& Grid : InventoryList) {
if (Grid.ItemID == ItemID) {
Total += Grid.CurrentCount;
}
}
return Total >= Count;
}
FInventoryGrid UInventoryComponent::GetGridWithIndex(int32 Index) {
return InventoryList.IsValidIndex(Index) ? InventoryList[Index] : FInventoryGrid();
}
void UInventoryComponent::InitItemGrid_Implementation(FInventoryGrid& Grid) {
Grid.CurrentCount = 0;
Grid.MaxCount = 20; // Ĭ<>϶ѵ<CFB6><D1B5><EFBFBD>С
Grid.Priority = 1; // Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
}
void UInventoryComponent::ForEach(const FVisitInventoryGridDelegate& VisitDelegate) {
for (int32 i = 0; i < InventoryList.Num(); ++i) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><C6B7>CurrentCount <= 0<><30>
if (InventoryList[i].CurrentCount > 0) {
VisitDelegate.ExecuteIfBound(i, InventoryList[i]);
}
}
}
FInventoryGrid& UInventoryComponent::GetOrCreateGrid(int32 ItemID) {
// <20><><EFBFBD>ҷ<EFBFBD><D2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8><EFBFBD>
for (FInventoryGrid& Grid : InventoryList) {
if (Grid.ItemID == 0 || Grid.CurrentCount == 0) {
Grid.ItemID = ItemID;
InitItemGrid(Grid);
return Grid;
}
if (Grid.ItemID == ItemID && Grid.CurrentCount < Grid.MaxCount) {
return Grid;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (InventoryList.Num() >= Capacity) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static FInventoryGrid DummyGrid;
DummyGrid = FInventoryGrid();
InitItemGrid(DummyGrid);
DummyGrid.ItemID = ItemID;
return DummyGrid;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>¸<EFBFBD><C2B8><EFBFBD>
FInventoryGrid NewGrid;
NewGrid.ItemID = ItemID;
InitItemGrid(NewGrid);
// <20><><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EBB5BD>ȷλ<C8B7><CEBB>
int32 InsertIndex = 0;
for (; InsertIndex < InventoryList.Num(); InsertIndex++) {
if (NewGrid.Priority > InventoryList[InsertIndex].Priority) {
break;
}
}
return InventoryList.Insert_GetRef(NewGrid, InsertIndex);
}