- UZeusAOIComponent (Game/Network): componente de gameplay do player local com plus de debug. Overlays via DrawDebug* (esfera AOI real; spawn/cell/handoff placeholders) dirigidos pela UI via IZeusAOIDebugTarget + console vars. Estado persiste no componente entre aberturas do menu (IsOverlayEnabled). - AZeusCharacter: anexa o componente + abre/fecha o painel no F8 (UIOnly trava o jogo; Esc/F8 fecham); LoadClass lazy do painel no content do PLUGIN (/ZeusAdminTools/UI/WBP_AdminToolsAIO). - ZMMO.Build.cs: depende de ZeusAdminToolsRuntime. - UIProgressBar_Base: rename EaseOutCubic -> EaseOutCubicPB (fix unity-build). - ZMMO.uproject: remove entrada NwiroIntegrationKit. A UI e o C++ do plugin ZeusAdminTools vivem no repo Server (plugin autocontido). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
200 lines
7.4 KiB
C++
200 lines
7.4 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "GameFramework/Character.h"
|
|
#include "Logging/LogMacros.h"
|
|
#include "ZeusEntityInterface.h"
|
|
#include "ZeusEntityTypes.h"
|
|
#include "ZeusCharacter.generated.h"
|
|
|
|
class USpringArmComponent;
|
|
class UCameraComponent;
|
|
class UInputAction;
|
|
class UZeusNetworkSubsystem;
|
|
class UZeusAOIComponent;
|
|
class UUserWidget;
|
|
struct FInputActionValue;
|
|
|
|
DECLARE_LOG_CATEGORY_EXTERN(LogZeusPlayer, Log, All);
|
|
|
|
/**
|
|
* AZeusCharacter
|
|
*
|
|
* Personagem do jogador local. Parte do pipeline de rede Zeus:
|
|
*
|
|
* - Continua a usar o `UCharacterMovementComponent` LIVRE para correr a
|
|
* fisica do landscape (ADR 0038): o cliente e autoritativo localmente
|
|
* sobre Z/colisao com terreno; o servidor apenas valida input/velocidade.
|
|
* - Envia `C_INPUT_AXIS` ao `UZeusNetworkSubsystem` na cadencia
|
|
* `InputSendRateHz` (com heartbeat 5 Hz quando parado para evitar
|
|
* starvation do `MovementSystem` no servidor).
|
|
* - Implementa `IZeusEntityInterface` para participar do registry do
|
|
* `UZeusWorldSubsystem`, mas `ApplyEntitySnapshot` e `SetEntityRelevant`
|
|
* sao no-op em V0 — o cliente local nao reconcilia (cliente solto).
|
|
*
|
|
* TODO V1: reconciliacao opcional XY quando colisao de objetos chegar; AOI
|
|
* debug spheres; visual smoothing apos correcao do servidor.
|
|
*/
|
|
UCLASS(Blueprintable, BlueprintType)
|
|
class ZMMO_API AZeusCharacter : public ACharacter, public IZeusEntityInterface
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Camera boom positioning the camera behind the character */
|
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
|
|
USpringArmComponent* CameraBoom;
|
|
|
|
/** Follow camera */
|
|
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<UZeusAOIComponent> AOIComponent;
|
|
|
|
// GAS Component vive no PlayerState (AZeusPlayerState + Component Registry).
|
|
// Acesso: GetPlayerState<AZeusPlayerState>()->GetZeusComponent<UZeusGASComponent>().
|
|
|
|
protected:
|
|
UPROPERTY(EditAnywhere, Category = "Input")
|
|
UInputAction* JumpAction;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Input")
|
|
UInputAction* MoveAction;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Input")
|
|
UInputAction* LookAction;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Input")
|
|
UInputAction* MouseLookAction;
|
|
|
|
/// IA_Dash — dispara C_ABILITY_TRY_ACTIVATE pra Zeus.Ability.Movement.Dash
|
|
/// via UZeusGASComponent. Bind padrao no IMC_Default: LeftShift -> Pressed.
|
|
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<UUserWidget> AdminPanelClass;
|
|
|
|
/** Cadencia de envio dos pacotes `C_INPUT_AXIS` (Hz). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zeus|Networking", meta = (ClampMin = "1", ClampMax = "120"))
|
|
int32 InputSendRateHz = 30;
|
|
|
|
/**
|
|
* Intervalo maximo (s) entre envios de `C_INPUT_AXIS` quando os inputs sao
|
|
* vazios (forward=0, right=0, sem jump). Mantem ~5 Hz de heartbeat para
|
|
* evitar starvation do servidor caso pacotes sejam perdidos. Em movimento
|
|
* o envio segue `InputSendRateHz` (30 Hz).
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zeus|Networking", meta = (ClampMin = "0.05", ClampMax = "5.0"))
|
|
float HeartbeatIntervalSec = 0.2f;
|
|
|
|
public:
|
|
AZeusCharacter();
|
|
|
|
virtual void Tick(float DeltaSeconds) override;
|
|
|
|
// --- IZeusEntityInterface ---
|
|
virtual int64 GetZeusEntityId() const override { return ZeusEntityId; }
|
|
virtual EZeusEntityType GetZeusEntityType() const override { return EZeusEntityType::Player; }
|
|
virtual void ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot) override;
|
|
virtual void SetEntityRelevant(bool bRelevant) override;
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Zeus|Entity")
|
|
void SetZeusEntityId(int64 InEntityId) { ZeusEntityId = InEntityId; }
|
|
|
|
FORCEINLINE USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
|
|
FORCEINLINE UCameraComponent* GetFollowCamera() const { return FollowCamera; }
|
|
|
|
protected:
|
|
virtual void BeginPlay() override;
|
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
|
|
|
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
|
|
|
void Move(const FInputActionValue& Value);
|
|
void MoveCompleted(const FInputActionValue& Value);
|
|
void Look(const FInputActionValue& Value);
|
|
void OnJumpPressed();
|
|
void OnJumpReleased();
|
|
|
|
/// IA_Dash Triggered -> resolve UZeusGASComponent do PlayerState e chama
|
|
/// RequestActivateAbilityByTag("Zeus.Ability.Movement.Dash"). Server valida
|
|
/// + 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")
|
|
virtual void DoMove(float Right, float Forward);
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Input")
|
|
virtual void DoLook(float Yaw, float Pitch);
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Input")
|
|
virtual void DoJumpStart();
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "Input")
|
|
virtual void DoJumpEnd();
|
|
|
|
private:
|
|
void ResolveZeusNetworkSubsystem();
|
|
void FlushInputAxisToServer(float DeltaSeconds);
|
|
|
|
/** Liga `OnPlayerSpawned` para captar EntityId local apos o handshake. */
|
|
void BindZeusSpawnDelegate();
|
|
void UnbindZeusSpawnDelegate();
|
|
|
|
/** Caso o spawn ja tenha chegado antes deste pawn existir, aplica via cache. */
|
|
void TryRegisterLocalEntityFromCachedSpawn();
|
|
|
|
/**
|
|
* Memoriza `EntityId` autoritativo e regista o pawn no `UZeusWorldSubsystem`
|
|
* para o registry partilhado por proxies remotos (filtra snapshots locais).
|
|
* Metadados publicos do char (Name/Guild) chegam via S_CHAR_INFO em
|
|
* HandleZeusCharInfo (servidor envia ANTES de S_SPAWN_PLAYER).
|
|
*/
|
|
void HandleLocalSpawnReady(int64 InEntityId, FVector PosCm, float YawDeg, int64 ServerTimeMs);
|
|
|
|
UFUNCTION()
|
|
void HandleZeusPlayerSpawned(int64 InEntityId, bool bIsLocal, FVector PosCm, float YawDeg, int64 ServerTimeMs);
|
|
|
|
UFUNCTION()
|
|
void HandleZeusCharInfo(int64 InEntityId, const FString& CharName, const FString& GuildName);
|
|
|
|
void TryApplyCachedCharInfo();
|
|
|
|
UPROPERTY()
|
|
TObjectPtr<UZeusNetworkSubsystem> ZeusNetwork;
|
|
|
|
/** Instancia viva do painel admin (criada lazy no primeiro F8). */
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UUserWidget> AdminPanelInstance;
|
|
|
|
bool bSpawnDelegateBound = false;
|
|
|
|
/** Identidade autoritativa atribuida quando o servidor envia S_SPAWN_PLAYER local. */
|
|
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "Zeus|Entity", meta = (AllowPrivateAccess = "true"))
|
|
int64 ZeusEntityId = 0;
|
|
|
|
float PendingMoveForward = 0.0f;
|
|
float PendingMoveRight = 0.0f;
|
|
|
|
bool bPendingJumpPressed = false;
|
|
bool bPendingJumpReleased = false;
|
|
bool bPreviousJumpHeld = false;
|
|
/** Último estado IsFalling enviado ao servidor. Usado para forçar um envio
|
|
* imediato em transições walking↔falling, evitando que o rate limit segure
|
|
* a transição até o próximo heartbeat. */
|
|
bool bPreviousFalling = false;
|
|
|
|
float SendAccumulatorSec = 0.0f;
|
|
float TimeSinceLastSendSec = 0.0f;
|
|
int32 InputSequence = 0;
|
|
};
|