第一次提交

This commit is contained in:
不明不惑
2026-03-03 01:23:02 +08:00
commit 3e434877e8
1053 changed files with 102411 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -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);
}
}