第一次提交
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "Pickups/GIS_CurrencyPickupComponent.h"
|
||||
#include "GIS_CurrencySystemComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "GIS_InventorySystemComponent.h"
|
||||
#include "GIS_LogChannels.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_CurrencyPickupComponent)
|
||||
|
||||
void UGIS_CurrencyPickupComponent::BeginPlay()
|
||||
{
|
||||
OwningCurrencySystem = UGIS_CurrencySystemComponent::GetCurrencySystemComponent(GetOwner());
|
||||
if (OwningCurrencySystem == nullptr)
|
||||
{
|
||||
GIS_CLOG(Warning, "Mising CurrencySystemComponent!");
|
||||
}
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
bool UGIS_CurrencyPickupComponent::Pickup(UGIS_InventorySystemComponent* Picker)
|
||||
{
|
||||
if (!GetOwner()->HasAuthority())
|
||||
{
|
||||
GIS_CLOG(Warning, "has no authority!");
|
||||
return false;
|
||||
}
|
||||
if (OwningCurrencySystem == nullptr || !IsValid(OwningCurrencySystem))
|
||||
{
|
||||
GIS_CLOG(Warning, "mising CurrencySystemComponent!");
|
||||
return false;
|
||||
}
|
||||
if (Picker == nullptr || !IsValid(Picker))
|
||||
{
|
||||
GIS_CLOG(Warning, "passed-in invalid picker.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UGIS_CurrencySystemComponent* PickerCurrencySystem = Picker->GetCurrencySystem();
|
||||
if (PickerCurrencySystem == nullptr)
|
||||
{
|
||||
GIS_CLOG(Warning, "Picker:%s has no CurrencySystem!", *Picker->GetOwner()->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PickerCurrencySystem->AddCurrencies(OwningCurrencySystem->GetAllCurrencies()))
|
||||
{
|
||||
OwningCurrencySystem->EmptyCurrencies();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "Pickups/GIS_InventoryPickupComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "GIS_InventorySystemComponent.h"
|
||||
#include "GIS_InventoryTags.h"
|
||||
#include "GIS_ItemCollection.h"
|
||||
#include "GIS_LogChannels.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_InventoryPickupComponent)
|
||||
|
||||
void UGIS_InventoryPickupComponent::BeginPlay()
|
||||
{
|
||||
if (!CollectionTag.IsValid())
|
||||
{
|
||||
CollectionTag = GIS_CollectionTags::Main;
|
||||
}
|
||||
|
||||
Inventory = UGIS_InventorySystemComponent::FindInventorySystemComponent(GetOwner());
|
||||
if (!Inventory)
|
||||
{
|
||||
GIS_CLOG(Warning, "InventoryPickup requries an inventory system component on the same actor!")
|
||||
}
|
||||
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
bool UGIS_InventoryPickupComponent::Pickup(UGIS_InventorySystemComponent* Picker)
|
||||
{
|
||||
if (!GetOwner()->HasAuthority())
|
||||
{
|
||||
GIS_CLOG(Warning, "has no authority!");
|
||||
return false;
|
||||
}
|
||||
if (Inventory == nullptr || !IsValid(Inventory))
|
||||
{
|
||||
GIS_CLOG(Warning, "doesn't have an inventory system component to function.")
|
||||
return false;
|
||||
}
|
||||
if (!CollectionTag.IsValid() || !IsValid(Picker))
|
||||
{
|
||||
GIS_CLOG(Warning, "doesn't have valid picker to function.")
|
||||
return false;
|
||||
}
|
||||
|
||||
UGIS_ItemCollection* DestCollection = Picker->GetCollectionByTag(CollectionTag);
|
||||
if (DestCollection == nullptr)
|
||||
{
|
||||
GIS_CLOG(Warning, "picker(%s) doesn't have valid collection named:%s", *Picker->GetOwner()->GetName(), *CollectionTag.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddPickupToCollection(DestCollection);
|
||||
}
|
||||
|
||||
UGIS_InventorySystemComponent* UGIS_InventoryPickupComponent::GetOwningInventory() const
|
||||
{
|
||||
return Inventory;
|
||||
}
|
||||
|
||||
bool UGIS_InventoryPickupComponent::AddPickupToCollection(UGIS_ItemCollection* DestCollection)
|
||||
{
|
||||
TArray<FGIS_ItemInfo> PickupItems = Inventory->GetDefaultCollection()->GetAllItemInfos();
|
||||
bool bAtLeastOneCanBeAdded = false;
|
||||
for (int32 i = 0; i < PickupItems.Num(); i++)
|
||||
{
|
||||
FGIS_ItemInfo ItemInfo = PickupItems[i];
|
||||
FGIS_ItemInfo CanAddedItemInfo;
|
||||
if (DestCollection->CanAddItem(ItemInfo, CanAddedItemInfo))
|
||||
{
|
||||
if (CanAddedItemInfo.Amount != 0)
|
||||
{
|
||||
bAtLeastOneCanBeAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bAtLeastOneCanBeAdded == false)
|
||||
{
|
||||
NotifyPickupFailed();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < PickupItems.Num(); i++)
|
||||
{
|
||||
DestCollection->AddItem(PickupItems[i]);
|
||||
}
|
||||
Inventory->GetDefaultCollection()->RemoveAll();
|
||||
NotifyPickupSuccess();
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "Pickups/GIS_ItemPickupComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "GIS_InventoryTags.h"
|
||||
#include "GIS_InventorySystemComponent.h"
|
||||
#include "GIS_ItemCollection.h"
|
||||
#include "Items/GIS_ItemInstance.h"
|
||||
#include "GIS_LogChannels.h"
|
||||
#include "Pickups/GIS_WorldItemComponent.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_ItemPickupComponent)
|
||||
|
||||
bool UGIS_ItemPickupComponent::Pickup(UGIS_InventorySystemComponent* Picker)
|
||||
{
|
||||
if (!GetOwner()->HasAuthority())
|
||||
{
|
||||
GIS_CLOG(Warning, "has no authority!");
|
||||
return false;
|
||||
}
|
||||
if (!CollectionTag.IsValid() || !IsValid(Picker))
|
||||
{
|
||||
GIS_CLOG(Warning, "passed-in invalid picker.");
|
||||
return false;
|
||||
}
|
||||
if (WorldItemComponent == nullptr && WorldItemComponent->GetItemInstance()->IsItemValid())
|
||||
{
|
||||
GIS_CLOG(Warning, "doesn't have valid WordItem component attached or it has invalid item instance reference.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryAddToCollection(Picker);
|
||||
}
|
||||
|
||||
UGIS_WorldItemComponent* UGIS_ItemPickupComponent::GetWorldItem() const
|
||||
{
|
||||
return WorldItemComponent;
|
||||
}
|
||||
|
||||
// Called when the game starts
|
||||
void UGIS_ItemPickupComponent::BeginPlay()
|
||||
{
|
||||
if (!CollectionTag.IsValid())
|
||||
{
|
||||
CollectionTag = GIS_CollectionTags::Main;
|
||||
}
|
||||
|
||||
Super::BeginPlay();
|
||||
WorldItemComponent = GetOwner()->FindComponentByClass<UGIS_WorldItemComponent>();
|
||||
|
||||
if (WorldItemComponent == nullptr)
|
||||
{
|
||||
GIS_CLOG(Error, "requires GIS_WorldItemComponent to function!")
|
||||
}
|
||||
}
|
||||
|
||||
bool UGIS_ItemPickupComponent::TryAddToCollection(UGIS_InventorySystemComponent* Picker)
|
||||
{
|
||||
UGIS_ItemInstance* NewItemInstance = WorldItemComponent->GetDuplicatedItemInstance(Picker->GetOwner());
|
||||
|
||||
if (NewItemInstance == nullptr)
|
||||
{
|
||||
GIS_CLOG(Error, "referenced invalid item! Pickup failed!");
|
||||
NotifyPickupFailed();
|
||||
return false;
|
||||
}
|
||||
|
||||
FGIS_ItemInfo NewItemInfo;
|
||||
NewItemInfo.Item = NewItemInstance;
|
||||
NewItemInfo.Amount = WorldItemComponent->GetItemAmount();
|
||||
const FGameplayTag TargetCollection = CollectionTag.IsValid() ? CollectionTag : GIS_CollectionTags::Main;
|
||||
NewItemInfo.CollectionTag = TargetCollection;
|
||||
|
||||
FGIS_ItemInfo CanAddedItemInfo;
|
||||
const bool bResult = Picker->CanAddItem(NewItemInfo, CanAddedItemInfo);
|
||||
|
||||
if (!bResult || CanAddedItemInfo.Amount == 0 || (bFailIfFullAmountNotFit && CanAddedItemInfo.Amount != NewItemInfo.Amount))
|
||||
{
|
||||
NotifyPickupFailed();
|
||||
return false;
|
||||
}
|
||||
|
||||
Picker->AddItem(NewItemInfo);
|
||||
NotifyPickupSuccess();
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "Pickups/GIS_PickupActorInterface.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_PickupActorInterface)
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "Pickups/GIS_PickupComponent.h"
|
||||
#include "Sound/SoundBase.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_PickupComponent)
|
||||
|
||||
// Sets default values for this component's properties
|
||||
UGIS_PickupComponent::UGIS_PickupComponent()
|
||||
{
|
||||
PrimaryComponentTick.bStartWithTickEnabled = false;
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
SetIsReplicatedByDefault(true);
|
||||
}
|
||||
|
||||
bool UGIS_PickupComponent::Pickup(UGIS_InventorySystemComponent* Picker)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void UGIS_PickupComponent::NotifyPickupSuccess()
|
||||
{
|
||||
OnPickupSuccess.Broadcast();
|
||||
}
|
||||
|
||||
void UGIS_PickupComponent::NotifyPickupFailed()
|
||||
{
|
||||
OnPickupFail.Broadcast();
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
#include "Pickups/GIS_WorldItemComponent.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "Engine/World.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "GIS_InventorySubsystem.h"
|
||||
#include "GIS_InventorySystemComponent.h"
|
||||
#include "Items/GIS_ItemDefinition.h"
|
||||
#include "Items/GIS_ItemInstance.h"
|
||||
#include "GIS_LogChannels.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GIS_WorldItemComponent)
|
||||
|
||||
UGIS_WorldItemComponent::UGIS_WorldItemComponent(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
PrimaryComponentTick.bStartWithTickEnabled = false;
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
SetIsReplicatedByDefault(true);
|
||||
|
||||
bReplicateUsingRegisteredSubObjectList = true;
|
||||
}
|
||||
|
||||
void UGIS_WorldItemComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
|
||||
FDoRepLifetimeParams Parameters;
|
||||
Parameters.bIsPushBased = true;
|
||||
|
||||
DOREPLIFETIME_WITH_PARAMS_FAST(ThisClass, ItemInfo, Parameters)
|
||||
}
|
||||
|
||||
UGIS_WorldItemComponent* UGIS_WorldItemComponent::GetWorldItemComponent(const AActor* Actor)
|
||||
{
|
||||
if (IsValid(Actor))
|
||||
{
|
||||
return Actor->FindComponentByClass<UGIS_WorldItemComponent>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UGIS_WorldItemComponent::CreateItemFromDefinition(FGIS_ItemDefinitionAmount ItemDefinition)
|
||||
{
|
||||
if (!ItemDefinition.Definition.IsNull() && ItemDefinition.Amount >= 1)
|
||||
{
|
||||
if (!ItemInfo.IsValid())
|
||||
{
|
||||
UGIS_ItemInstance* NewItemInstance = UGIS_InventorySubsystem::Get(GetWorld())->CreateItem(GetOwner(), ItemDefinition.Definition.LoadSynchronous());
|
||||
if (NewItemInstance == nullptr)
|
||||
{
|
||||
GIS_CLOG(Error, "failed to create item instance from definition!");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetItemInfo(NewItemInstance, ItemDefinition.Amount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GIS_CLOG(Warning, "Already have valid item info, skip creation.")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GIS_CLOG(Error, "passed invalid definition setup,skip item instance creating!");
|
||||
}
|
||||
}
|
||||
|
||||
bool UGIS_WorldItemComponent::HasValidDefinition() const
|
||||
{
|
||||
return !Definition.Definition.IsNull() && Definition.Amount >= 1;
|
||||
}
|
||||
|
||||
|
||||
void UGIS_WorldItemComponent::SetItemInfo(UGIS_ItemInstance* InItem, int32 InAmount)
|
||||
{
|
||||
if (InItem == nullptr || InAmount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemInfo.IsValid())
|
||||
{
|
||||
GIS_CLOG(Warning, "Already have valid item info.")
|
||||
return;
|
||||
}
|
||||
|
||||
ItemInfo = FGIS_ItemInfo(InItem, InAmount);
|
||||
MARK_PROPERTY_DIRTY_FROM_NAME(ThisClass, ItemInfo, this)
|
||||
|
||||
// add to ReplicatedSubObject list only if it was created by this component.
|
||||
if (bReplicateUsingRegisteredSubObjectList && InItem->GetOuter() == GetOwner())
|
||||
{
|
||||
AddReplicatedSubObject(ItemInfo.Item);
|
||||
}
|
||||
}
|
||||
|
||||
void UGIS_WorldItemComponent::ResetItemInfo()
|
||||
{
|
||||
if (ItemInfo.IsValid())
|
||||
{
|
||||
// remove from replicated sub object list only if it was created by this component.
|
||||
if (bReplicateUsingRegisteredSubObjectList && ItemInfo.Item->GetOuter() == GetOwner())
|
||||
{
|
||||
RemoveReplicatedSubObject(ItemInfo.Item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UGIS_ItemInstance* UGIS_WorldItemComponent::GetItemInstance()
|
||||
{
|
||||
return ItemInfo.Item;
|
||||
}
|
||||
|
||||
UGIS_ItemInstance* UGIS_WorldItemComponent::GetDuplicatedItemInstance(AActor* NewOwner)
|
||||
{
|
||||
if (ItemInfo.IsValid())
|
||||
{
|
||||
return UGIS_InventorySubsystem::Get(GetWorld())->DuplicateItem(NewOwner, ItemInfo.Item);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FGIS_ItemInfo UGIS_WorldItemComponent::GetItemInfo() const
|
||||
{
|
||||
return ItemInfo;
|
||||
}
|
||||
|
||||
int32 UGIS_WorldItemComponent::GetItemAmount() const
|
||||
{
|
||||
return ItemInfo.Amount;
|
||||
}
|
||||
|
||||
void UGIS_WorldItemComponent::BeginPlay()
|
||||
{
|
||||
if (HasValidDefinition() && GetOwner()->HasAuthority())
|
||||
{
|
||||
CreateItemFromDefinition(Definition);
|
||||
}
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void UGIS_WorldItemComponent::OnRep_ItemInfo()
|
||||
{
|
||||
if (ItemInfo.IsValid())
|
||||
{
|
||||
GIS_CLOG(Verbose, "item:%s replicated!", *ItemInfo.Item->GetDefinition()->GetName());
|
||||
ItemInfoSetEvent.Broadcast(ItemInfo);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user