Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

198 lines
4.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SlateIMInGameWidgetBase.h"
#include "EngineUtils.h"
#include "Framework/Application/SlateApplication.h"
#include "GameFramework/PlayerController.h"
#include "SlateIM.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(SlateIMInGameWidgetBase)
ASlateIMInGameWidgetBase::ASlateIMInGameWidgetBase()
{
PrimaryActorTick.bCanEverTick = false;
PrimaryActorTick.bStartWithTickEnabled = false;
bReplicates = true;
bAlwaysRelevant = true;
SetNetUpdateFrequency(3.f);
SetMinNetUpdateFrequency(3.f);
}
void ASlateIMInGameWidgetBase::BeginPlay()
{
Super::BeginPlay();
if (IsLocallyControlled())
{
StartWidget();
}
}
void ASlateIMInGameWidgetBase::EndPlay(EEndPlayReason::Type Reason)
{
if (IsLocallyControlled())
{
StopWidget();
}
Super::EndPlay(Reason);
}
void ASlateIMInGameWidgetBase::OnRep_Owner()
{
Super::OnRep_Owner();
if (HasActorBegunPlay())
{
if (IsLocallyControlled())
{
StartWidget();
}
else
{
StopWidget();
}
}
}
void ASlateIMInGameWidgetBase::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
{
Super::PreReplication(ChangedPropertyTracker);
#if WITH_SERVER_CODE
if (HasAuthority())
{
GenerateServerSnapshot();
}
#endif // WITH_SERVER_CODE
}
bool ASlateIMInGameWidgetBase::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const
{
return GetOwner() != nullptr && GetOwner() == RealViewer;
}
APlayerController* ASlateIMInGameWidgetBase::GetPlayerController() const
{
return Cast<APlayerController>(GetOwner());
}
bool ASlateIMInGameWidgetBase::IsLocallyControlled() const
{
if (APlayerController* OwnerPlayerController = GetPlayerController())
{
return OwnerPlayerController->IsLocalController();
}
return false;
}
ASlateIMInGameWidgetBase* ASlateIMInGameWidgetBase::GetInGameWidget(const APlayerController* Owner, const TSubclassOf<ASlateIMInGameWidgetBase>& InGameWidgetClass)
{
if (ensure(Owner && InGameWidgetClass))
{
for (TActorIterator<ASlateIMInGameWidgetBase> It(Owner->GetWorld(), InGameWidgetClass); It; ++It)
{
if (It->GetOwner() == Owner)
{
return *It;
}
}
}
return nullptr;
}
void ASlateIMInGameWidgetBase::EnableInGameWidget(APlayerController* Owner, const bool bEnable, const TSubclassOf<ASlateIMInGameWidgetBase>& InGameWidgetClass)
{
if (bEnable)
{
GetOrOpenInGameWidget(Owner, InGameWidgetClass);
}
else
{
DestroyInGameWidget(Owner, InGameWidgetClass);
}
}
void ASlateIMInGameWidgetBase::StartWidget()
{
if (!WidgetTickHandle.IsValid())
{
WidgetTickHandle = FSlateApplication::Get().OnPreTick().AddUObject(this, &ASlateIMInGameWidgetBase::TickWidget);
}
}
void ASlateIMInGameWidgetBase::StopWidget()
{
if (WidgetTickHandle.IsValid())
{
FSlateApplication::Get().OnPreTick().Remove(WidgetTickHandle);
WidgetTickHandle.Reset();
}
}
void ASlateIMInGameWidgetBase::TickWidget(const float DeltaTime)
{
if (!SlateIM::CanUpdateSlateIM())
{
return;
}
DrawWidget(DeltaTime);
}
ASlateIMInGameWidgetBase* ASlateIMInGameWidgetBase::GetOrOpenInGameWidget(APlayerController* Owner, const TSubclassOf<ASlateIMInGameWidgetBase>& InGameWidgetClass)
{
if (ensure(Owner && InGameWidgetClass))
{
if (ASlateIMInGameWidgetBase* ExistingWidget = GetInGameWidget(Owner, InGameWidgetClass))
{
return ExistingWidget;
}
if (GetDefault<ASlateIMInGameWidgetBase>(InGameWidgetClass)->bReplicates && Owner->GetWorld()->GetNetMode() == ENetMode::NM_Client)
{
UE_LOG(LogActor, Error, TEXT("In game widget %s was requested but it's replicated and needs server permission."), *InGameWidgetClass->GetName());
}
else
{
FActorSpawnParameters Params;
Params.Owner = Owner;
if (ASlateIMInGameWidgetBase* NewWidget = Owner->GetWorld()->SpawnActor<ASlateIMInGameWidgetBase>(InGameWidgetClass, Params))
{
NewWidget->AttachToActor(Owner, FAttachmentTransformRules::KeepRelativeTransform);
return NewWidget;
}
}
}
return nullptr;
}
void ASlateIMInGameWidgetBase::DestroyInGameWidget(const APlayerController* Owner, const TSubclassOf<ASlateIMInGameWidgetBase>& InGameWidgetClass)
{
if (ensure(Owner && InGameWidgetClass))
{
if (ASlateIMInGameWidgetBase* OpenedWidget = GetInGameWidget(Owner, InGameWidgetClass))
{
if (GetDefault<ASlateIMInGameWidgetBase>(InGameWidgetClass)->bReplicates && Owner->GetWorld()->GetNetMode() == ENetMode::NM_Client)
{
UE_LOG(LogActor, Error, TEXT("Destruction of in game widget %s was requested but it is replicated and needs server permission."), *InGameWidgetClass->GetName());
}
else
{
OpenedWidget->Destroy();
}
}
}
}
void ASlateIMInGameWidgetBase::Server_Destroy_Implementation()
{
Destroy();
}