174 lines
3.9 KiB
C++
174 lines
3.9 KiB
C++
// Copyright Pacificao. All Rights Reserved.
|
|
|
|
#include "AgrarianInventoryComponent.h"
|
|
#include "Net/UnrealNetwork.h"
|
|
|
|
UAgrarianInventoryComponent::UAgrarianInventoryComponent()
|
|
{
|
|
PrimaryComponentTick.bCanEverTick = false;
|
|
SetIsReplicatedByDefault(true);
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
|
{
|
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
DOREPLIFETIME(UAgrarianInventoryComponent, Items);
|
|
}
|
|
|
|
bool UAgrarianInventoryComponent::HasItem(FName ItemId, int32 Quantity) const
|
|
{
|
|
return GetItemCount(ItemId) >= Quantity;
|
|
}
|
|
|
|
int32 UAgrarianInventoryComponent::GetItemCount(FName ItemId) const
|
|
{
|
|
int32 Count = 0;
|
|
for (const FAgrarianItemStack& Stack : Items)
|
|
{
|
|
if (Stack.ItemId == ItemId)
|
|
{
|
|
Count += Stack.Quantity;
|
|
}
|
|
}
|
|
return Count;
|
|
}
|
|
|
|
float UAgrarianInventoryComponent::GetTotalWeight() const
|
|
{
|
|
float TotalWeight = 0.0f;
|
|
for (const FAgrarianItemStack& Stack : Items)
|
|
{
|
|
TotalWeight += FMath::Max(0.0f, Stack.UnitWeight) * FMath::Max(0, Stack.Quantity);
|
|
}
|
|
return TotalWeight;
|
|
}
|
|
|
|
bool UAgrarianInventoryComponent::AddItem(const FAgrarianItemStack& Stack)
|
|
{
|
|
if (!GetOwner() || !GetOwner()->HasAuthority() || !Stack.IsValidStack())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (FAgrarianItemStack& Existing : Items)
|
|
{
|
|
if (Existing.ItemId == Stack.ItemId)
|
|
{
|
|
Existing.Quantity += Stack.Quantity;
|
|
BroadcastInventoryChanged();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (Items.Num() >= MaxSlots)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Items.Add(Stack);
|
|
BroadcastInventoryChanged();
|
|
return true;
|
|
}
|
|
|
|
bool UAgrarianInventoryComponent::RemoveItem(FName ItemId, int32 Quantity)
|
|
{
|
|
FAgrarianItemStack RemovedStack;
|
|
return ExtractItem(ItemId, Quantity, RemovedStack);
|
|
}
|
|
|
|
bool UAgrarianInventoryComponent::ExtractItem(FName ItemId, int32 Quantity, FAgrarianItemStack& OutStack)
|
|
{
|
|
OutStack = FAgrarianItemStack();
|
|
|
|
if (!GetOwner() || !GetOwner()->HasAuthority() || Quantity <= 0 || !HasItem(ItemId, Quantity))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int32 Remaining = Quantity;
|
|
for (int32 Index = Items.Num() - 1; Index >= 0 && Remaining > 0; --Index)
|
|
{
|
|
FAgrarianItemStack& Stack = Items[Index];
|
|
if (Stack.ItemId != ItemId)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const int32 Removed = FMath::Min(Stack.Quantity, Remaining);
|
|
if (OutStack.ItemId == NAME_None)
|
|
{
|
|
OutStack = Stack;
|
|
OutStack.Quantity = 0;
|
|
}
|
|
|
|
OutStack.Quantity += Removed;
|
|
Stack.Quantity -= Removed;
|
|
Remaining -= Removed;
|
|
|
|
if (Stack.Quantity <= 0)
|
|
{
|
|
Items.RemoveAt(Index);
|
|
}
|
|
}
|
|
|
|
BroadcastInventoryChanged();
|
|
return true;
|
|
}
|
|
|
|
bool UAgrarianInventoryComponent::SplitStackByIndex(int32 StackIndex, int32 SplitQuantity)
|
|
{
|
|
if (!GetOwner() || !GetOwner()->HasAuthority() || SplitQuantity <= 0 || !Items.IsValidIndex(StackIndex) || Items.Num() >= MaxSlots)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
FAgrarianItemStack& SourceStack = Items[StackIndex];
|
|
if (!SourceStack.IsValidStack() || SplitQuantity >= SourceStack.Quantity)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
FAgrarianItemStack SplitStack = SourceStack;
|
|
SplitStack.Quantity = SplitQuantity;
|
|
SourceStack.Quantity -= SplitQuantity;
|
|
Items.Add(SplitStack);
|
|
BroadcastInventoryChanged();
|
|
return true;
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::RestoreSavedItems(const TArray<FAgrarianItemStack>& SavedItems)
|
|
{
|
|
if (!GetOwner() || !GetOwner()->HasAuthority())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Items = SavedItems;
|
|
BroadcastInventoryChanged();
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::ServerAddItem_Implementation(const FAgrarianItemStack& Stack)
|
|
{
|
|
AddItem(Stack);
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::ServerRemoveItem_Implementation(FName ItemId, int32 Quantity)
|
|
{
|
|
RemoveItem(ItemId, Quantity);
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::ServerSplitStackByIndex_Implementation(int32 StackIndex, int32 SplitQuantity)
|
|
{
|
|
SplitStackByIndex(StackIndex, SplitQuantity);
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::OnRep_Items()
|
|
{
|
|
BroadcastInventoryChanged();
|
|
}
|
|
|
|
void UAgrarianInventoryComponent::BroadcastInventoryChanged()
|
|
{
|
|
OnInventoryChanged.Broadcast();
|
|
}
|