2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "LyraEquipmentManagerComponent.h"
2022-09-13 07:18:28 +00:00
# include "AbilitySystem/LyraAbilitySet.h"
2022-05-23 18:41:30 +00:00
# include "AbilitySystem/LyraAbilitySystemComponent.h"
2022-09-13 07:18:28 +00:00
# include "AbilitySystemComponent.h"
2022-05-23 18:41:30 +00:00
# include "AbilitySystemGlobals.h"
2022-09-13 07:18:28 +00:00
# include "Components/ActorComponent.h"
# include "Engine/ActorChannel.h"
# include "GameFramework/Actor.h"
2022-05-23 18:41:30 +00:00
# include "LyraEquipmentDefinition.h"
2022-09-13 07:18:28 +00:00
# include "LyraEquipmentInstance.h"
# include "Misc/AssertionMacros.h"
2022-05-23 18:41:30 +00:00
# include "Net/UnrealNetwork.h"
2022-09-13 07:18:28 +00:00
# include "Templates/Casts.h"
# include "UObject/Object.h"
# include "UObject/ObjectPtr.h"
# include "UObject/UObjectBaseUtility.h"
class FLifetimeProperty ;
struct FReplicationFlags ;
2022-05-23 18:41:30 +00:00
//////////////////////////////////////////////////////////////////////
// FLyraAppliedEquipmentEntry
FString FLyraAppliedEquipmentEntry : : GetDebugString ( ) const
{
return FString : : Printf ( TEXT ( " %s of %s " ) , * GetNameSafe ( Instance ) , * GetNameSafe ( EquipmentDefinition . Get ( ) ) ) ;
}
//////////////////////////////////////////////////////////////////////
// FLyraEquipmentList
void FLyraEquipmentList : : PreReplicatedRemove ( const TArrayView < int32 > RemovedIndices , int32 FinalSize )
{
for ( int32 Index : RemovedIndices )
{
const FLyraAppliedEquipmentEntry & Entry = Entries [ Index ] ;
if ( Entry . Instance ! = nullptr )
{
Entry . Instance - > OnUnequipped ( ) ;
}
}
}
void FLyraEquipmentList : : PostReplicatedAdd ( const TArrayView < int32 > AddedIndices , int32 FinalSize )
{
for ( int32 Index : AddedIndices )
{
const FLyraAppliedEquipmentEntry & Entry = Entries [ Index ] ;
if ( Entry . Instance ! = nullptr )
{
Entry . Instance - > OnEquipped ( ) ;
}
}
}
void FLyraEquipmentList : : PostReplicatedChange ( const TArrayView < int32 > ChangedIndices , int32 FinalSize )
{
// for (int32 Index : ChangedIndices)
// {
// const FGameplayTagStack& Stack = Stacks[Index];
// TagToCountMap[Stack.Tag] = Stack.StackCount;
// }
}
ULyraAbilitySystemComponent * FLyraEquipmentList : : GetAbilitySystemComponent ( ) const
{
check ( OwnerComponent ) ;
AActor * OwningActor = OwnerComponent - > GetOwner ( ) ;
return Cast < ULyraAbilitySystemComponent > ( UAbilitySystemGlobals : : GetAbilitySystemComponentFromActor ( OwningActor ) ) ;
}
ULyraEquipmentInstance * FLyraEquipmentList : : AddEntry ( TSubclassOf < ULyraEquipmentDefinition > EquipmentDefinition )
{
ULyraEquipmentInstance * Result = nullptr ;
check ( EquipmentDefinition ! = nullptr ) ;
check ( OwnerComponent ) ;
check ( OwnerComponent - > GetOwner ( ) - > HasAuthority ( ) ) ;
const ULyraEquipmentDefinition * EquipmentCDO = GetDefault < ULyraEquipmentDefinition > ( EquipmentDefinition ) ;
TSubclassOf < ULyraEquipmentInstance > InstanceType = EquipmentCDO - > InstanceType ;
if ( InstanceType = = nullptr )
{
InstanceType = ULyraEquipmentInstance : : StaticClass ( ) ;
}
FLyraAppliedEquipmentEntry & NewEntry = Entries . AddDefaulted_GetRef ( ) ;
NewEntry . EquipmentDefinition = EquipmentDefinition ;
NewEntry . Instance = NewObject < ULyraEquipmentInstance > ( OwnerComponent - > GetOwner ( ) , InstanceType ) ; //@TODO: Using the actor instead of component as the outer due to UE-127172
Result = NewEntry . Instance ;
if ( ULyraAbilitySystemComponent * ASC = GetAbilitySystemComponent ( ) )
{
for ( TObjectPtr < const ULyraAbilitySet > AbilitySet : EquipmentCDO - > AbilitySetsToGrant )
{
AbilitySet - > GiveToAbilitySystem ( ASC , /*inout*/ & NewEntry . GrantedHandles , Result ) ;
}
}
else
{
//@TODO: Warning logging?
}
Result - > SpawnEquipmentActors ( EquipmentCDO - > ActorsToSpawn ) ;
MarkItemDirty ( NewEntry ) ;
return Result ;
}
void FLyraEquipmentList : : RemoveEntry ( ULyraEquipmentInstance * Instance )
{
for ( auto EntryIt = Entries . CreateIterator ( ) ; EntryIt ; + + EntryIt )
{
FLyraAppliedEquipmentEntry & Entry = * EntryIt ;
if ( Entry . Instance = = Instance )
{
if ( ULyraAbilitySystemComponent * ASC = GetAbilitySystemComponent ( ) )
{
Entry . GrantedHandles . TakeFromAbilitySystem ( ASC ) ;
}
Instance - > DestroyEquipmentActors ( ) ;
EntryIt . RemoveCurrent ( ) ;
MarkArrayDirty ( ) ;
}
}
}
//////////////////////////////////////////////////////////////////////
// ULyraEquipmentManagerComponent
ULyraEquipmentManagerComponent : : ULyraEquipmentManagerComponent ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
, EquipmentList ( this )
{
SetIsReplicatedByDefault ( true ) ;
bWantsInitializeComponent = true ;
}
void ULyraEquipmentManagerComponent : : GetLifetimeReplicatedProps ( TArray < FLifetimeProperty > & OutLifetimeProps ) const
{
Super : : GetLifetimeReplicatedProps ( OutLifetimeProps ) ;
DOREPLIFETIME ( ThisClass , EquipmentList ) ;
}
ULyraEquipmentInstance * ULyraEquipmentManagerComponent : : EquipItem ( TSubclassOf < ULyraEquipmentDefinition > EquipmentClass )
{
ULyraEquipmentInstance * Result = nullptr ;
if ( EquipmentClass ! = nullptr )
{
Result = EquipmentList . AddEntry ( EquipmentClass ) ;
if ( Result ! = nullptr )
{
Result - > OnEquipped ( ) ;
2022-09-13 07:18:28 +00:00
if ( IsUsingRegisteredSubObjectList ( ) & & IsReadyForReplication ( ) )
{
AddReplicatedSubObject ( Result ) ;
}
2022-05-23 18:41:30 +00:00
}
}
return Result ;
}
void ULyraEquipmentManagerComponent : : UnequipItem ( ULyraEquipmentInstance * ItemInstance )
{
if ( ItemInstance ! = nullptr )
{
2022-09-13 07:18:28 +00:00
if ( IsUsingRegisteredSubObjectList ( ) )
{
RemoveReplicatedSubObject ( ItemInstance ) ;
}
2022-05-23 18:41:30 +00:00
ItemInstance - > OnUnequipped ( ) ;
EquipmentList . RemoveEntry ( ItemInstance ) ;
}
}
bool ULyraEquipmentManagerComponent : : ReplicateSubobjects ( UActorChannel * Channel , class FOutBunch * Bunch , FReplicationFlags * RepFlags )
{
bool WroteSomething = Super : : ReplicateSubobjects ( Channel , Bunch , RepFlags ) ;
for ( FLyraAppliedEquipmentEntry & Entry : EquipmentList . Entries )
{
ULyraEquipmentInstance * Instance = Entry . Instance ;
if ( IsValid ( Instance ) )
{
WroteSomething | = Channel - > ReplicateSubobject ( Instance , * Bunch , * RepFlags ) ;
}
}
return WroteSomething ;
}
void ULyraEquipmentManagerComponent : : InitializeComponent ( )
{
Super : : InitializeComponent ( ) ;
}
void ULyraEquipmentManagerComponent : : UninitializeComponent ( )
{
TArray < ULyraEquipmentInstance * > AllEquipmentInstances ;
// gathering all instances before removal to avoid side effects affecting the equipment list iterator
for ( const FLyraAppliedEquipmentEntry & Entry : EquipmentList . Entries )
{
AllEquipmentInstances . Add ( Entry . Instance ) ;
}
for ( ULyraEquipmentInstance * EquipInstance : AllEquipmentInstances )
{
UnequipItem ( EquipInstance ) ;
}
Super : : UninitializeComponent ( ) ;
}
2022-09-13 07:18:28 +00:00
void ULyraEquipmentManagerComponent : : ReadyForReplication ( )
{
Super : : ReadyForReplication ( ) ;
// Register existing LyraEquipmentInstances
if ( IsUsingRegisteredSubObjectList ( ) )
{
for ( const FLyraAppliedEquipmentEntry & Entry : EquipmentList . Entries )
{
ULyraEquipmentInstance * Instance = Entry . Instance ;
if ( IsValid ( Instance ) )
{
AddReplicatedSubObject ( Instance ) ;
}
}
}
}
2022-05-23 18:41:30 +00:00
ULyraEquipmentInstance * ULyraEquipmentManagerComponent : : GetFirstInstanceOfType ( TSubclassOf < ULyraEquipmentInstance > InstanceType )
{
for ( FLyraAppliedEquipmentEntry & Entry : EquipmentList . Entries )
{
if ( ULyraEquipmentInstance * Instance = Entry . Instance )
{
if ( Instance - > IsA ( InstanceType ) )
{
return Instance ;
}
}
}
return nullptr ;
}
TArray < ULyraEquipmentInstance * > ULyraEquipmentManagerComponent : : GetEquipmentInstancesOfType ( TSubclassOf < ULyraEquipmentInstance > InstanceType ) const
{
TArray < ULyraEquipmentInstance * > Results ;
for ( const FLyraAppliedEquipmentEntry & Entry : EquipmentList . Entries )
{
if ( ULyraEquipmentInstance * Instance = Entry . Instance )
{
if ( Instance - > IsA ( InstanceType ) )
{
Results . Add ( Instance ) ;
}
}
}
return Results ;
}