This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AgrarianGameArchive/Source/AgrarianGame/AgrarianInventoryComponent.cpp
T
2026-05-17 11:47:44 -07:00

163 lines
3.6 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::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();
}