diff --git a/Source/ZMMO/Game/Entity/ZeusCharacter.cpp b/Source/ZMMO/Game/Entity/ZeusCharacter.cpp index 2538956..eff9f5f 100644 --- a/Source/ZMMO/Game/Entity/ZeusCharacter.cpp +++ b/Source/ZMMO/Game/Entity/ZeusCharacter.cpp @@ -20,7 +20,10 @@ #include "GameplayTagContainer.h" #include "GameplayTagsManager.h" #include "ZeusGASComponent.h" +#include "ZeusAOIComponent.h" #include "ZeusPlayerState.h" +#include "Blueprint/UserWidget.h" +#include "GameFramework/PlayerController.h" #include "ZeusWorldSubsystem.h" #include "ZeusNetworkSubsystem.h" #include "UI/FrontEnd/UIFrontEndFlowSubsystem.h" @@ -57,6 +60,14 @@ AZeusCharacter::AZeusCharacter() FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); FollowCamera->bUsePawnControlRotation = false; + // AOI do cliente (+ overlays de debug). Implementa IZeusAOIDebugTarget; o + // Zeus Admin Tools acha este componente no pawn e dirige os overlays. + AOIComponent = CreateDefaultSubobject(TEXT("ZeusAOIComponent")); + + // AdminPanelClass NAO e' resolvido aqui via FClassFinder: na criacao do CDO + // (load do modulo) o asset registry pode nao estar pronto e o static cacheia + // null pra sempre. Resolvido lazy em ToggleAdminPanel (LoadClass em runtime). + // AttributeComponent migrou pro PlayerState (AZeusPlayerState + Component // Registry config-driven). Pawn fica leve — so' movement/input/camera. @@ -181,6 +192,61 @@ void AZeusCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputCompo { UE_LOG(LogZeusPlayer, Error, TEXT("'%s' Failed to find an Enhanced Input component."), *GetNameSafe(this)); } + + // Debug: F8 abre/fecha o Zeus Admin Tools (AIO Debug). Legacy BindKey + // convive com Enhanced Input. Trocar a tecla aqui se conflitar. + PlayerInputComponent->BindKey(EKeys::F8, IE_Pressed, this, &AZeusCharacter::ToggleAdminPanel); +} + +void AZeusCharacter::ToggleAdminPanel() +{ + APlayerController* PC = Cast(GetController()); + if (!PC) + { + return; + } + + // Aberto -> fecha + devolve input pro jogo. + if (AdminPanelInstance && AdminPanelInstance->IsInViewport()) + { + AdminPanelInstance->RemoveFromParent(); + PC->SetInputMode(FInputModeGameOnly()); + PC->bShowMouseCursor = false; + return; + } + + // Lazy load (runtime): no F8 o asset ja' esta carregavel; evita o pitfall do + // FClassFinder na criacao do CDO. Path do generated class (_C). + // A UI vive no CONTENT DO PLUGIN (mount /ZeusAdminTools/), nao no /Game do projeto: + // o plugin ZeusAdminTools e' autocontido (C++ + UI no repo Server). + if (!AdminPanelClass) + { + AdminPanelClass = LoadClass(nullptr, + TEXT("/ZeusAdminTools/UI/WBP_AdminToolsAIO.WBP_AdminToolsAIO_C")); + } + if (!AdminPanelClass) + { + UE_LOG(LogZeusPlayer, Warning, TEXT("[AdminPanel] AdminPanelClass nao resolvido (WBP_AdminToolsAIO ausente?).")); + return; + } + + if (!AdminPanelInstance) + { + AdminPanelInstance = CreateWidget(PC, AdminPanelClass); + } + if (AdminPanelInstance) + { + AdminPanelInstance->AddToViewport(1000); + + // UIOnly: trava a acao do jogo enquanto o menu esta aberto e garante que + // os cliques vao 100% pra UI (no GameAndUI o viewport rouba o clique). + // O mundo continua renderizando + os overlays de debug seguem desenhando. + FInputModeUIOnly Mode; + Mode.SetWidgetToFocus(AdminPanelInstance->TakeWidget()); + Mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); + PC->SetInputMode(Mode); + PC->bShowMouseCursor = true; + } } void AZeusCharacter::Move(const FInputActionValue& Value) diff --git a/Source/ZMMO/Game/Entity/ZeusCharacter.h b/Source/ZMMO/Game/Entity/ZeusCharacter.h index c9b5c57..03f957e 100644 --- a/Source/ZMMO/Game/Entity/ZeusCharacter.h +++ b/Source/ZMMO/Game/Entity/ZeusCharacter.h @@ -11,6 +11,8 @@ class USpringArmComponent; class UCameraComponent; class UInputAction; class UZeusNetworkSubsystem; +class UZeusAOIComponent; +class UUserWidget; struct FInputActionValue; DECLARE_LOG_CATEGORY_EXTERN(LogZeusPlayer, Log, All); @@ -46,6 +48,10 @@ class ZMMO_API AZeusCharacter : public ACharacter, public IZeusEntityInterface UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true")) UCameraComponent* FollowCamera; + /** AOI do cliente (+ overlays de debug dirigidos pelo Zeus Admin Tools). */ + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Zeus|AOI", meta = (AllowPrivateAccess = "true")) + TObjectPtr AOIComponent; + // GAS Component vive no PlayerState (AZeusPlayerState + Component Registry). // Acesso: GetPlayerState()->GetZeusComponent(). @@ -67,6 +73,11 @@ protected: UPROPERTY(EditAnywhere, Category = "Input") UInputAction* DashAction; + /** Painel Zeus Admin Tools (AIO Debug), aberto/fechado por F8. Default = + * WBP_AdminToolsAIO (resolvido no construtor). */ + UPROPERTY(EditAnywhere, Category = "Zeus|Admin") + TSubclassOf AdminPanelClass; + /** Cadencia de envio dos pacotes `C_INPUT_AXIS` (Hz). */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zeus|Networking", meta = (ClampMin = "1", ClampMax = "120")) int32 InputSendRateHz = 30; @@ -114,6 +125,9 @@ protected: /// + responde S_ABILITY_ACTIVATED (HP/SP atualizado, montage roda local). void OnDashTriggered(); + /** F8: cria/mostra ou esconde o painel Zeus Admin Tools (input mode UI + cursor). */ + void ToggleAdminPanel(); + public: /** Wrappers expostos a Blueprint (UI / mobile / automation). */ UFUNCTION(BlueprintCallable, Category = "Input") @@ -158,6 +172,10 @@ private: UPROPERTY() TObjectPtr ZeusNetwork; + /** Instancia viva do painel admin (criada lazy no primeiro F8). */ + UPROPERTY(Transient) + TObjectPtr AdminPanelInstance; + bool bSpawnDelegateBound = false; /** Identidade autoritativa atribuida quando o servidor envia S_SPAWN_PLAYER local. */ diff --git a/Source/ZMMO/Game/Network/ZeusAOIComponent.cpp b/Source/ZMMO/Game/Network/ZeusAOIComponent.cpp new file mode 100644 index 0000000..c52275c --- /dev/null +++ b/Source/ZMMO/Game/Network/ZeusAOIComponent.cpp @@ -0,0 +1,134 @@ +// Copyright Zeus Server Engine. All rights reserved. + +#include "ZeusAOIComponent.h" + +#include "DrawDebugHelpers.h" +#include "GameFramework/Actor.h" + +// Console vars — espelham as flags do painel (overlay liga se flag OU CVar). +static TAutoConsoleVariable CVarShowAOI( + TEXT("zeus.debug.aoi"), 0, TEXT("Desenha a esfera de AOI do player local."), ECVF_Default); +static TAutoConsoleVariable CVarShowSpawn( + TEXT("zeus.debug.spawn"), 0, TEXT("Desenha a zona de spawn (placeholder)."), ECVF_Default); +static TAutoConsoleVariable CVarShowCell( + TEXT("zeus.debug.cell"), 0, TEXT("Desenha os bounds da celula (placeholder)."), ECVF_Default); +static TAutoConsoleVariable CVarShowProxy( + TEXT("zeus.debug.proxy"), 0, TEXT("Desenha labels de proxy (TODO)."), ECVF_Default); +static TAutoConsoleVariable CVarShowHandoff( + TEXT("zeus.debug.handoff"), 0, TEXT("Desenha a linha de handoff (placeholder)."), ECVF_Default); +static TAutoConsoleVariable CVarShowDrift( + TEXT("zeus.debug.drift"), 0, TEXT("Desenha o drift autoritativo (TODO)."), ECVF_Default); + +namespace +{ + const FColor kColorAOI(93, 213, 255); + const FColor kColorSpawn(122, 219, 138); + const FColor kColorCell(232, 192, 96); + const FColor kColorHandoff(255, 155, 190); +} + +UZeusAOIComponent::UZeusAOIComponent() +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + SetIsReplicatedByDefault(false); // debug/cliente; gameplay AOI real entra depois +} + +void UZeusAOIComponent::TickComponent(float DeltaTime, ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + if (AnyOverlayActive()) + { + DrawOverlays(); + } +} + +bool UZeusAOIComponent::ResolveOverlay(EZeusAOIOverlay Overlay) const +{ + switch (Overlay) + { + case EZeusAOIOverlay::AOIRadius: return bShowAOIRadius || CVarShowAOI.GetValueOnGameThread() > 0; + case EZeusAOIOverlay::SpawnZone: return bShowSpawnZone || CVarShowSpawn.GetValueOnGameThread() > 0; + case EZeusAOIOverlay::CellBounds: return bShowCellBounds || CVarShowCell.GetValueOnGameThread() > 0; + case EZeusAOIOverlay::ProxyLabels: return bShowProxyLabels || CVarShowProxy.GetValueOnGameThread() > 0; + case EZeusAOIOverlay::HandoffLine: return bShowHandoffLine || CVarShowHandoff.GetValueOnGameThread() > 0; + case EZeusAOIOverlay::AuthDrift: return bShowAuthDrift || CVarShowDrift.GetValueOnGameThread() > 0; + default: return false; + } +} + +bool UZeusAOIComponent::AnyOverlayActive() const +{ + return ResolveOverlay(EZeusAOIOverlay::AOIRadius) + || ResolveOverlay(EZeusAOIOverlay::SpawnZone) + || ResolveOverlay(EZeusAOIOverlay::CellBounds) + || ResolveOverlay(EZeusAOIOverlay::ProxyLabels) + || ResolveOverlay(EZeusAOIOverlay::HandoffLine) + || ResolveOverlay(EZeusAOIOverlay::AuthDrift); +} + +void UZeusAOIComponent::DrawOverlays() +{ + const AActor* Owner = GetOwner(); + UWorld* World = GetWorld(); + if (!Owner || !World) { return; } + + const FVector Loc = Owner->GetActorLocation(); + + if (ResolveOverlay(EZeusAOIOverlay::AOIRadius)) + { + DrawDebugSphere(World, Loc, AOIRadiusCm, 32, kColorAOI, false, -1.0f, 0, LineThickness); + } + if (ResolveOverlay(EZeusAOIOverlay::SpawnZone)) + { + // PLACEHOLDER: box em volta do player. TODO spawn zones reais do servidor. + DrawDebugBox(World, Loc, FVector(SpawnZoneExtentCm), kColorSpawn, false, -1.0f, 0, LineThickness); + } + if (ResolveOverlay(EZeusAOIOverlay::CellBounds)) + { + // PLACEHOLDER: box grande centrada no player. TODO bounds reais da cell. + DrawDebugBox(World, Loc, FVector(CellBoundsExtentCm, CellBoundsExtentCm, 2000.0f), + kColorCell, false, -1.0f, 0, LineThickness); + } + if (ResolveOverlay(EZeusAOIOverlay::HandoffLine)) + { + // PLACEHOLDER: vetor pra frente. TODO apontar pro centro da cell vizinha. + const FVector End = Loc + Owner->GetActorForwardVector() * AOIRadiusCm; + DrawDebugDirectionalArrow(World, Loc, End, 200.0f, kColorHandoff, false, -1.0f, 0, LineThickness); + } + // ProxyLabels / AuthDrift: TODO (precisam do registry de proxies/snapshots). +} + +void UZeusAOIComponent::SetOverlayEnabled_Implementation(EZeusAOIOverlay Overlay, bool bEnabled) +{ + switch (Overlay) + { + case EZeusAOIOverlay::AOIRadius: bShowAOIRadius = bEnabled; break; + case EZeusAOIOverlay::SpawnZone: bShowSpawnZone = bEnabled; break; + case EZeusAOIOverlay::CellBounds: bShowCellBounds = bEnabled; break; + case EZeusAOIOverlay::ProxyLabels: bShowProxyLabels = bEnabled; break; + case EZeusAOIOverlay::HandoffLine: bShowHandoffLine = bEnabled; break; + case EZeusAOIOverlay::AuthDrift: bShowAuthDrift = bEnabled; break; + default: break; + } +} + +void UZeusAOIComponent::SetAllOverlays_Implementation(bool bEnabled) +{ + bShowAOIRadius = bShowSpawnZone = bShowCellBounds = bEnabled; + bShowProxyLabels = bShowHandoffLine = bShowAuthDrift = bEnabled; +} + +bool UZeusAOIComponent::IsOverlayEnabled_Implementation(EZeusAOIOverlay Overlay) const +{ + // Reflete o estado real (flag OU CVar) p/ a UI mostrar o que esta' desenhando. + return ResolveOverlay(Overlay); +} + +int32 UZeusAOIComponent::GetEnabledOverlayCount() const +{ + return (bShowAOIRadius ? 1 : 0) + (bShowSpawnZone ? 1 : 0) + (bShowCellBounds ? 1 : 0) + + (bShowProxyLabels ? 1 : 0) + (bShowHandoffLine ? 1 : 0) + (bShowAuthDrift ? 1 : 0); +} diff --git a/Source/ZMMO/Game/Network/ZeusAOIComponent.h b/Source/ZMMO/Game/Network/ZeusAOIComponent.h new file mode 100644 index 0000000..f901606 --- /dev/null +++ b/Source/ZMMO/Game/Network/ZeusAOIComponent.h @@ -0,0 +1,60 @@ +// Copyright Zeus Server Engine. All rights reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/ActorComponent.h" +#include "ZeusAOIDebugTarget.h" // plugin ZeusAdminToolsRuntime: interface + EZeusAOIOverlay +#include "ZeusAOIComponent.generated.h" + +/** + * UZeusAOIComponent (cliente / jogo) + * + * Componente de gameplay do player local. Dominio principal: Area of Interest + * do cliente (proxies, despawn coordenado, interpolacao — ver + * [[project_aoi_client_component]]). AQUI, alem disso, expoe um "plus" de + * DEBUG: overlays via DrawDebug* dirigidos pelo painel admin (plugin) atraves + * de IZeusAOIDebugTarget, e/ou por console vars (zeus.debug.aoi etc.). + * + * Vive na src do ZMMO (nao no plugin): e' um componente do JOGO. O plugin + * ZeusAdminTools apenas COMUNICA com ele via a interface — direcao da + * dependencia: ZMMO -> plugin (implementa a interface). + */ +UCLASS(ClassGroup = (Zeus), meta = (BlueprintSpawnableComponent), DisplayName = "Zeus AOI Component") +class ZMMO_API UZeusAOIComponent : public UActorComponent, public IZeusAOIDebugTarget +{ + GENERATED_BODY() + +public: + UZeusAOIComponent(); + + virtual void TickComponent(float DeltaTime, ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) override; + + // === IZeusAOIDebugTarget (dirigido pelo painel admin) === + virtual void SetOverlayEnabled_Implementation(EZeusAOIOverlay Overlay, bool bEnabled) override; + virtual void SetAllOverlays_Implementation(bool bEnabled) override; + virtual bool IsOverlayEnabled_Implementation(EZeusAOIOverlay Overlay) const override; + + // === Flags de debug por overlay === + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowAOIRadius = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowSpawnZone = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowCellBounds = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowProxyLabels = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowHandoffLine = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowAuthDrift = false; + + // === Parametros === + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Params") float AOIRadiusCm = 3000.0f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Params") float SpawnZoneExtentCm = 800.0f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Params") float CellBoundsExtentCm = 50000.0f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Params") float LineThickness = 2.0f; + + UFUNCTION(BlueprintPure, Category = "Zeus|AOI Debug") + int32 GetEnabledOverlayCount() const; + +private: + void DrawOverlays(); + bool ResolveOverlay(EZeusAOIOverlay Overlay) const; + bool AnyOverlayActive() const; +}; diff --git a/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp b/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp index 08f7c50..505dd85 100644 --- a/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp +++ b/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp @@ -47,7 +47,7 @@ namespace static const FName P_EdgeGlowWidth("EdgeGlowWidth"); static const FName P_EdgeGlowIntensity("EdgeGlowIntensity"); - FORCEINLINE float EaseOutCubic(float Alpha) + FORCEINLINE float EaseOutCubicPB(float Alpha) { return 1.f - FMath::Pow(1.f - Alpha, 3.f); } @@ -195,7 +195,7 @@ void UUIProgressBar_Base::NativeTick(const FGeometry& MyGeometry, float InDeltaT PrimaryElapsed += InDeltaTime; const float Duration = FMath::Max(PrimaryAnimationSeconds, MinAnimSeconds); const float Alpha = FMath::Clamp(PrimaryElapsed / Duration, 0.f, 1.f); - CurrentPrimaryLevel = FMath::Lerp(PrimaryStart, TargetPrimaryLevel, EaseOutCubic(Alpha)); + CurrentPrimaryLevel = FMath::Lerp(PrimaryStart, TargetPrimaryLevel, EaseOutCubicPB(Alpha)); ApplyPrimaryToMID(CurrentPrimaryLevel); if (Alpha >= 1.f) { @@ -210,7 +210,7 @@ void UUIProgressBar_Base::NativeTick(const FGeometry& MyGeometry, float InDeltaT SecondaryElapsed += InDeltaTime; const float Duration = FMath::Max(SecondaryAnimationSeconds, MinAnimSeconds); const float Alpha = FMath::Clamp(SecondaryElapsed / Duration, 0.f, 1.f); - CurrentSecondaryLevel = FMath::Lerp(SecondaryStart, TargetSecondaryLevel, EaseOutCubic(Alpha)); + CurrentSecondaryLevel = FMath::Lerp(SecondaryStart, TargetSecondaryLevel, EaseOutCubicPB(Alpha)); ApplySecondaryToMID(CurrentSecondaryLevel); if (Alpha >= 1.f) { diff --git a/Source/ZMMO/ZMMO.Build.cs b/Source/ZMMO/ZMMO.Build.cs index c509c55..322e700 100644 --- a/Source/ZMMO/ZMMO.Build.cs +++ b/Source/ZMMO/ZMMO.Build.cs @@ -21,7 +21,8 @@ public class ZMMO : ModuleRules "GameplayAbilities", // GAS: UAttributeSet, FGameplayAttributeData "ZeusNetwork", "ZeusGAS", // UZeusGASComponent, UZeusAttributeSet, FZeusAttributesSnapshot - "ZeusJobs" + "ZeusJobs", + "ZeusAdminToolsRuntime" // IZeusAOIDebugTarget + EZeusAOIOverlay (admin panel dirige o componente) }); PrivateDependencyModuleNames.AddRange(new string[] { diff --git a/ZMMO.uproject b/ZMMO.uproject index 1c695b2..d50db3d 100644 --- a/ZMMO.uproject +++ b/ZMMO.uproject @@ -76,10 +76,6 @@ { "Name": "CommonUI", "Enabled": true - }, - { - "Name": "NwiroIntegrationKit", - "Enabled": false } ], "AdditionalPluginDirectories": [