RealtimeStyleTransferRuntime/Source/LyraGame/Equipment/LyraQuickBarComponent.cpp

229 lines
5.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LyraQuickBarComponent.h"
#include "CoreTypes.h"
#include "Equipment/LyraEquipmentDefinition.h"
#include "Equipment/LyraEquipmentInstance.h"
#include "Equipment/LyraEquipmentManagerComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/GameplayMessageSubsystem.h"
#include "GameFramework/Pawn.h"
#include "Inventory/InventoryFragment_EquippableItem.h"
#include "Inventory/LyraInventoryItemInstance.h"
#include "Misc/AssertionMacros.h"
#include "NativeGameplayTags.h"
#include "Net/UnrealNetwork.h"
#include "Templates/Casts.h"
#include "Templates/SubclassOf.h"
#include "UObject/NameTypes.h"
class FLifetimeProperty;
class ULyraEquipmentDefinition;
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Lyra_QuickBar_Message_SlotsChanged, "Lyra.QuickBar.Message.SlotsChanged");
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Lyra_QuickBar_Message_ActiveIndexChanged, "Lyra.QuickBar.Message.ActiveIndexChanged");
ULyraQuickBarComponent::ULyraQuickBarComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
SetIsReplicatedByDefault(true);
}
void ULyraQuickBarComponent::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ThisClass, Slots);
DOREPLIFETIME(ThisClass, ActiveSlotIndex);
}
void ULyraQuickBarComponent::BeginPlay()
{
if (Slots.Num() < NumSlots)
{
Slots.AddDefaulted(NumSlots - Slots.Num());
}
Super::BeginPlay();
}
void ULyraQuickBarComponent::CycleActiveSlotForward()
{
if (Slots.Num() < 2)
{
return;
}
const int32 OldIndex = (ActiveSlotIndex < 0 ? Slots.Num()-1 : ActiveSlotIndex);
int32 NewIndex = ActiveSlotIndex;
do
{
NewIndex = (NewIndex + 1) % Slots.Num();
if (Slots[NewIndex] != nullptr)
{
SetActiveSlotIndex(NewIndex);
return;
}
} while (NewIndex != OldIndex);
}
void ULyraQuickBarComponent::CycleActiveSlotBackward()
{
if (Slots.Num() < 2)
{
return;
}
const int32 OldIndex = (ActiveSlotIndex < 0 ? Slots.Num()-1 : ActiveSlotIndex);
int32 NewIndex = ActiveSlotIndex;
do
{
NewIndex = (NewIndex - 1 + Slots.Num()) % Slots.Num();
if (Slots[NewIndex] != nullptr)
{
SetActiveSlotIndex(NewIndex);
return;
}
} while (NewIndex != OldIndex);
}
void ULyraQuickBarComponent::EquipItemInSlot()
{
check(Slots.IsValidIndex(ActiveSlotIndex));
check(EquippedItem == nullptr);
if (ULyraInventoryItemInstance* SlotItem = Slots[ActiveSlotIndex])
{
if (const UInventoryFragment_EquippableItem* EquipInfo = SlotItem->FindFragmentByClass<UInventoryFragment_EquippableItem>())
{
TSubclassOf<ULyraEquipmentDefinition> EquipDef = EquipInfo->EquipmentDefinition;
if (EquipDef != nullptr)
{
if (ULyraEquipmentManagerComponent* EquipmentManager = FindEquipmentManager())
{
EquippedItem = EquipmentManager->EquipItem(EquipDef);
if (EquippedItem != nullptr)
{
EquippedItem->SetInstigator(SlotItem);
}
}
}
}
}
}
void ULyraQuickBarComponent::UnequipItemInSlot()
{
if (ULyraEquipmentManagerComponent* EquipmentManager = FindEquipmentManager())
{
if (EquippedItem != nullptr)
{
EquipmentManager->UnequipItem(EquippedItem);
EquippedItem = nullptr;
}
}
}
ULyraEquipmentManagerComponent* ULyraQuickBarComponent::FindEquipmentManager() const
{
if (AController* OwnerController = Cast<AController>(GetOwner()))
{
if (APawn* Pawn = OwnerController->GetPawn())
{
return Pawn->FindComponentByClass<ULyraEquipmentManagerComponent>();
}
}
return nullptr;
}
void ULyraQuickBarComponent::SetActiveSlotIndex_Implementation(int32 NewIndex)
{
if (Slots.IsValidIndex(NewIndex) && (ActiveSlotIndex != NewIndex))
{
UnequipItemInSlot();
ActiveSlotIndex = NewIndex;
EquipItemInSlot();
OnRep_ActiveSlotIndex();
}
}
ULyraInventoryItemInstance* ULyraQuickBarComponent::GetActiveSlotItem() const
{
return Slots.IsValidIndex(ActiveSlotIndex) ? Slots[ActiveSlotIndex] : nullptr;
}
int32 ULyraQuickBarComponent::GetNextFreeItemSlot() const
{
int32 SlotIndex = 0;
for (TObjectPtr<ULyraInventoryItemInstance> ItemPtr : Slots)
{
if (ItemPtr == nullptr)
{
return SlotIndex;
}
++SlotIndex;
}
return INDEX_NONE;
}
void ULyraQuickBarComponent::AddItemToSlot(int32 SlotIndex, ULyraInventoryItemInstance* Item)
{
if (Slots.IsValidIndex(SlotIndex) && (Item != nullptr))
{
if (Slots[SlotIndex] == nullptr)
{
Slots[SlotIndex] = Item;
OnRep_Slots();
}
}
}
ULyraInventoryItemInstance* ULyraQuickBarComponent::RemoveItemFromSlot(int32 SlotIndex)
{
ULyraInventoryItemInstance* Result = nullptr;
if (ActiveSlotIndex == SlotIndex)
{
UnequipItemInSlot();
ActiveSlotIndex = -1;
}
if (Slots.IsValidIndex(SlotIndex))
{
Result = Slots[SlotIndex];
if (Result != nullptr)
{
Slots[SlotIndex] = nullptr;
OnRep_Slots();
}
}
return Result;
}
void ULyraQuickBarComponent::OnRep_Slots()
{
FLyraQuickBarSlotsChangedMessage Message;
Message.Owner = GetOwner();
Message.Slots = Slots;
UGameplayMessageSubsystem& MessageSystem = UGameplayMessageSubsystem::Get(this);
MessageSystem.BroadcastMessage(TAG_Lyra_QuickBar_Message_SlotsChanged, Message);
}
void ULyraQuickBarComponent::OnRep_ActiveSlotIndex()
{
FLyraQuickBarActiveIndexChangedMessage Message;
Message.Owner = GetOwner();
Message.ActiveIndex = ActiveSlotIndex;
UGameplayMessageSubsystem& MessageSystem = UGameplayMessageSubsystem::Get(this);
MessageSystem.BroadcastMessage(TAG_Lyra_QuickBar_Message_ActiveIndexChanged, Message);
}