diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index 48235cf..dc5d297 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -803,7 +803,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe - [x] Add crafting UI. Promoted the existing compact crafting HUD panel into the 0.1.N UI pass with `AgrarianToggleCraftingUI`, showing known recipes and ingredient readiness while keeping full crafting menus for later UX expansion. - [x] Add interaction prompts. Promoted the existing centered interactable prompt renderer into the 0.1.N UI pass with `AgrarianToggleInteractionPrompts`, keeping prompt text driven by focused interactables. - [x] Add death/respawn UI. Added a dedicated dead-state MVP panel with last death reason, Ground Zero respawn context, and `AgrarianToggleDeathRespawnUI` while preserving the existing server-authoritative respawn command. -- [ ] Add debug/dev menu. +- [x] Add debug/dev menu. Added a toggleable `bShowDebugDevMenu` HUD panel plus `AgrarianToggleDebugDevMenu`, listing the core MVP frontend, UI, persistence, and recovery commands for tester/admin use. - [ ] Add accessibility basics. - [ ] Ensure UI scales on common resolutions. diff --git a/Scripts/verify_mvp_debug_dev_menu.py b/Scripts/verify_mvp_debug_dev_menu.py new file mode 100644 index 0000000..5dbd424 --- /dev/null +++ b/Scripts/verify_mvp_debug_dev_menu.py @@ -0,0 +1,55 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +FILES = { + "AgrarianDebugHUD.h": ROOT / "Source" / "AgrarianGame" / "AgrarianDebugHUD.h", + "AgrarianDebugHUD.cpp": ROOT / "Source" / "AgrarianGame" / "AgrarianDebugHUD.cpp", + "AgrarianGamePlayerController.h": ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.h", + "AgrarianGamePlayerController.cpp": ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.cpp", + "AGRARIAN_DEVELOPMENT_ROADMAP.md": ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md", +} + +EXPECTED = { + "AgrarianDebugHUD.h": [ + "bShowDebugDevMenu", + "DrawDebugDevMenu", + ], + "AgrarianDebugHUD.cpp": [ + "DrawDebugDevMenu()", + "DEV MENU", + "AgrarianShowMvpScreen main|character|join|loading", + "AgrarianSaveWorld / AgrarianLoadWorld", + "AgrarianRespawn / AgrarianHeal", + ], + "AgrarianGamePlayerController.h": [ + "AgrarianToggleDebugDevMenu", + ], + "AgrarianGamePlayerController.cpp": [ + "AgrarianToggleDebugDevMenu", + "bShowDebugDevMenu = !AgrarianHUD->bShowDebugDevMenu", + "MVP debug/dev menu shown.", + ], + "AGRARIAN_DEVELOPMENT_ROADMAP.md": [ + "[x] Add debug/dev menu.", + "`AgrarianToggleDebugDevMenu`", + ], +} + + +def main(): + missing = [] + for label, path in FILES.items(): + text = path.read_text(encoding="utf-8") + for snippet in EXPECTED[label]: + if snippet not in text: + missing.append(f"{label}: {snippet}") + + if missing: + raise RuntimeError("MVP debug/dev menu verification failed: " + "; ".join(missing)) + + print("Agrarian MVP debug/dev menu verification complete.") + + +if __name__ == "__main__": + main() diff --git a/Source/AgrarianGame/AgrarianDebugHUD.cpp b/Source/AgrarianGame/AgrarianDebugHUD.cpp index df43a02..b21b273 100644 --- a/Source/AgrarianGame/AgrarianDebugHUD.cpp +++ b/Source/AgrarianGame/AgrarianDebugHUD.cpp @@ -25,6 +25,7 @@ void AAgrarianDebugHUD::DrawHUD() DrawMvpHudFrame(AgrarianCharacter); DrawDeathRespawnPanel(AgrarianCharacter); + DrawDebugDevMenu(); DrawInteractionPrompt(AgrarianCharacter); DrawCriticalStats(AgrarianCharacter->GetSurvivalComponent()); const float InventoryBottomY = DrawInventoryPanel(AgrarianCharacter); @@ -69,6 +70,33 @@ void AAgrarianDebugHUD::DrawMvpHudFrame(const AAgrarianGameCharacter* AgrarianCh DrawText(HudText, FColor(225, 235, 220), X + (18.0f * Scale), Y + (16.0f * Scale), nullptr, 0.86f * Scale, false); } +void AAgrarianDebugHUD::DrawDebugDevMenu() +{ + if (!bShowDebugDevMenu || !Canvas) + { + return; + } + + const float Scale = FMath::Max(0.25f, InventoryTextScale); + const float PanelWidth = 410.0f * Scale; + const float PanelHeight = 206.0f * Scale; + const float X = FMath::Max(32.0f, Canvas->ClipX - PanelWidth - 32.0f); + float Y = FMath::Max(32.0f, Canvas->ClipY - PanelHeight - 32.0f); + + DrawRect(FLinearColor(0.018f, 0.022f, 0.018f, 0.82f), X, Y, PanelWidth, PanelHeight); + DrawRect(FLinearColor(0.45f, 0.72f, 0.40f, 0.92f), X, Y, PanelWidth, 3.0f * Scale); + Y += 16.0f * Scale; + + const float TextX = X + (16.0f * Scale); + DrawScaledLine(TEXT("DEV MENU"), TextX, Y, Scale, FColor(160, 220, 140)); + DrawScaledLine(TEXT("AgrarianShowMvpScreen main|character|join|loading"), TextX, Y, 0.78f * Scale, FColor(215, 225, 205)); + DrawScaledLine(TEXT("AgrarianSelectCharacter male|female"), TextX, Y, 0.78f * Scale, FColor(215, 225, 205)); + DrawScaledLine(TEXT("AgrarianToggleInventoryUI / CraftingUI"), TextX, Y, 0.78f * Scale, FColor(215, 225, 205)); + DrawScaledLine(TEXT("AgrarianToggleInteractionPrompts"), TextX, Y, 0.78f * Scale, FColor(215, 225, 205)); + DrawScaledLine(TEXT("AgrarianSaveWorld / AgrarianLoadWorld"), TextX, Y, 0.78f * Scale, FColor(215, 225, 205)); + DrawScaledLine(TEXT("AgrarianRespawn / AgrarianHeal"), TextX, Y, 0.78f * Scale, FColor(215, 225, 205)); +} + void AAgrarianDebugHUD::DrawDeathRespawnPanel(const AAgrarianGameCharacter* AgrarianCharacter) { if (!bShowDeathRespawnUI || !AgrarianCharacter || !Canvas) diff --git a/Source/AgrarianGame/AgrarianDebugHUD.h b/Source/AgrarianGame/AgrarianDebugHUD.h index f8488a7..8ecb623 100644 --- a/Source/AgrarianGame/AgrarianDebugHUD.h +++ b/Source/AgrarianGame/AgrarianDebugHUD.h @@ -54,12 +54,16 @@ public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD") bool bShowDeathRespawnUI = true; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD") + bool bShowDebugDevMenu = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "0.25")) float PromptTextScale = 1.15f; protected: void DrawMvpHudFrame(const class AAgrarianGameCharacter* AgrarianCharacter); void DrawDeathRespawnPanel(const class AAgrarianGameCharacter* AgrarianCharacter); + void DrawDebugDevMenu(); void DrawInteractionPrompt(const class AAgrarianGameCharacter* AgrarianCharacter); void DrawCriticalStats(const UAgrarianSurvivalComponent* SurvivalComponent); float DrawInventoryPanel(const class AAgrarianGameCharacter* AgrarianCharacter); diff --git a/Source/AgrarianGame/AgrarianGamePlayerController.cpp b/Source/AgrarianGame/AgrarianGamePlayerController.cpp index 93f858d..5710660 100644 --- a/Source/AgrarianGame/AgrarianGamePlayerController.cpp +++ b/Source/AgrarianGame/AgrarianGamePlayerController.cpp @@ -333,6 +333,19 @@ void AAgrarianGamePlayerController::AgrarianToggleDeathRespawnUI() ClientMessage(AgrarianHUD->bShowDeathRespawnUI ? TEXT("MVP death/respawn UI shown.") : TEXT("MVP death/respawn UI hidden.")); } +void AAgrarianGamePlayerController::AgrarianToggleDebugDevMenu() +{ + AAgrarianDebugHUD* AgrarianHUD = GetHUD(); + if (!AgrarianHUD) + { + ClientMessage(TEXT("No Agrarian HUD is active.")); + return; + } + + AgrarianHUD->bShowDebugDevMenu = !AgrarianHUD->bShowDebugDevMenu; + ClientMessage(AgrarianHUD->bShowDebugDevMenu ? TEXT("MVP debug/dev menu shown.") : TEXT("MVP debug/dev menu hidden.")); +} + void AAgrarianGamePlayerController::AgrarianSelectCharacter(FName Archetype) { if (!MvpFrontendWidget) diff --git a/Source/AgrarianGame/AgrarianGamePlayerController.h b/Source/AgrarianGame/AgrarianGamePlayerController.h index bfc7795..0c5f58e 100644 --- a/Source/AgrarianGame/AgrarianGamePlayerController.h +++ b/Source/AgrarianGame/AgrarianGamePlayerController.h @@ -103,6 +103,9 @@ public: UFUNCTION(Exec) void AgrarianToggleDeathRespawnUI(); + UFUNCTION(Exec) + void AgrarianToggleDebugDevMenu(); + UFUNCTION(Exec) void AgrarianSelectCharacter(FName Archetype);