// Copyright Epic Games, Inc. All Rights Reserved. #include "LyraPawn.h" #include "Containers/Array.h" #include "Containers/UnrealString.h" #include "Delegates/Delegate.h" #include "GameFramework/Controller.h" #include "Logging/LogCategory.h" #include "Logging/LogMacros.h" #include "LyraLogChannels.h" #include "Misc/AssertionMacros.h" #include "Net/UnrealNetwork.h" #include "Templates/Casts.h" #include "Trace/Detail/Channel.h" #include "UObject/ObjectPtr.h" #include "UObject/UObjectBaseUtility.h" class FLifetimeProperty; class UObject; ALyraPawn::ALyraPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } void ALyraPawn::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(ThisClass, MyTeamID); } void ALyraPawn::PreInitializeComponents() { Super::PreInitializeComponents(); } void ALyraPawn::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); } void ALyraPawn::PossessedBy(AController* NewController) { const FGenericTeamId OldTeamID = MyTeamID; Super::PossessedBy(NewController); // Grab the current team ID and listen for future changes if (ILyraTeamAgentInterface* ControllerAsTeamProvider = Cast(NewController)) { MyTeamID = ControllerAsTeamProvider->GetGenericTeamId(); ControllerAsTeamProvider->GetTeamChangedDelegateChecked().AddDynamic(this, &ThisClass::OnControllerChangedTeam); } ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID); } void ALyraPawn::UnPossessed() { AController* const OldController = Controller; // Stop listening for changes from the old controller const FGenericTeamId OldTeamID = MyTeamID; if (ILyraTeamAgentInterface* ControllerAsTeamProvider = Cast(OldController)) { ControllerAsTeamProvider->GetTeamChangedDelegateChecked().RemoveAll(this); } Super::UnPossessed(); // Determine what the new team ID should be afterwards MyTeamID = DetermineNewTeamAfterPossessionEnds(OldTeamID); ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID); } void ALyraPawn::SetGenericTeamId(const FGenericTeamId& NewTeamID) { if (GetController() == nullptr) { if (HasAuthority()) { const FGenericTeamId OldTeamID = MyTeamID; MyTeamID = NewTeamID; ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID); } else { UE_LOG(LogLyraTeams, Error, TEXT("You can't set the team ID on a pawn (%s) except on the authority"), *GetPathNameSafe(this)); } } else { UE_LOG(LogLyraTeams, Error, TEXT("You can't set the team ID on a possessed pawn (%s); it's driven by the associated controller"), *GetPathNameSafe(this)); } } FGenericTeamId ALyraPawn::GetGenericTeamId() const { return MyTeamID; } FOnLyraTeamIndexChangedDelegate* ALyraPawn::GetOnTeamIndexChangedDelegate() { return &OnTeamChangedDelegate; } void ALyraPawn::OnControllerChangedTeam(UObject* TeamAgent, int32 OldTeam, int32 NewTeam) { const FGenericTeamId MyOldTeamID = MyTeamID; MyTeamID = IntegerToGenericTeamId(NewTeam); ConditionalBroadcastTeamChanged(this, MyOldTeamID, MyTeamID); } void ALyraPawn::OnRep_MyTeamID(FGenericTeamId OldTeamID) { ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID); }