diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index 7475af7..d983695 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -122,7 +122,7 @@ Open version .01 tasks: - [ ] Create recipe data assets for campfire, primitive shelter, basic tool, and bandage. - [ ] Create Blueprint child actors for wood resource, campfire, primitive shelter, and first wildlife species. - [ ] Place resource nodes, campfire, shelter, and wildlife in the test map. -- [ ] Add a simple HUD/debug display for survival and inventory. +- [x] Add a simple HUD/debug display for survival and inventory. - [ ] Test gather -> inventory -> craft -> place shelter -> save/load loop. - [ ] Test wildlife damage/death/harvest loop. - [ ] Decide whether to keep the current template variants or remove unused starter variants. @@ -252,7 +252,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe - [x] Add stat replication. - [ ] Add stat save/load support. - [x] Add debug commands for modifying stats. -- [ ] Add HUD display for critical stats. +- [x] Add HUD display for critical stats. ## 1.3 Time, Weather, And Environment Pressure @@ -437,7 +437,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe - [ ] Add main menu placeholder. - [ ] Add join server screen. - [ ] Add loading screen. -- [ ] Add HUD. +- [x] Add HUD. - [ ] Add inventory UI. - [ ] Add crafting UI. - [ ] Add interaction prompts. @@ -1086,7 +1086,7 @@ These tracks run across all phases and must not be left as afterthoughts. - [~] Add gatherable resources. - [x] Add campfire. - [x] Add basic crafting. -- [ ] Add basic HUD. +- [x] Add basic HUD. ## Month 3 - Shelter And Persistence @@ -1178,5 +1178,5 @@ Next version .01 priorities: - [ ] Place and test the campfire. - [ ] Place and test the primitive shelter. - [ ] Place and test the first wildlife Blueprint. -- [ ] Add simple survival/inventory HUD feedback. +- [x] Add simple survival/inventory HUD feedback. - [ ] Run the first full gather -> craft -> place -> save -> load test. diff --git a/AGRARIAN_FOUNDATION_STATUS.md b/AGRARIAN_FOUNDATION_STATUS.md index 3fdd635..1d8233d 100644 --- a/AGRARIAN_FOUNDATION_STATUS.md +++ b/AGRARIAN_FOUNDATION_STATUS.md @@ -29,6 +29,7 @@ - [x] Primitive shelter actor is marked as a persistent world actor. - [x] Admin/dev console commands added to the Agrarian player controller. - [x] Wildlife base actor added with replicated health, simple movement states, and harvesting hooks. +- [x] Simple debug HUD added for survival and inventory feedback. ## Next Unreal Editor Tasks @@ -42,7 +43,7 @@ - [ ] Create Blueprint child `BP_AGR_PrimitiveShelter` from `AgrarianShelterActor`. - [ ] Assign placeholder meshes to MVP actors. - [ ] Place resource nodes and campfire in the test map. -- [ ] Add simple HUD/debug display for survival and inventory. +- [x] Add simple HUD/debug display for survival and inventory. - [ ] Test gather -> inventory -> campfire loop. ## Next C++ Foundation Tasks diff --git a/Source/AgrarianGame/AgrarianDebugHUD.cpp b/Source/AgrarianGame/AgrarianDebugHUD.cpp new file mode 100644 index 0000000..7834328 --- /dev/null +++ b/Source/AgrarianGame/AgrarianDebugHUD.cpp @@ -0,0 +1,76 @@ +// Copyright Pacificao. All Rights Reserved. + +#include "AgrarianDebugHUD.h" +#include "AgrarianGameCharacter.h" +#include "AgrarianInventoryComponent.h" +#include "AgrarianSurvivalComponent.h" + +void AAgrarianDebugHUD::DrawHUD() +{ + Super::DrawHUD(); + + if (!bShowDebugHUD || !Canvas) + { + return; + } + + const AAgrarianGameCharacter* AgrarianCharacter = Cast(GetOwningPawn()); + if (!AgrarianCharacter) + { + return; + } + + float Y = 32.0f; + constexpr float X = 32.0f; + + DrawLine(TEXT("AGRARIAN DEV HUD"), X, Y, FColor(160, 220, 140)); + DrawSurvival(AgrarianCharacter->GetSurvivalComponent(), X, Y); + DrawInventory(AgrarianCharacter->GetInventoryComponent(), X, Y); +} + +void AAgrarianDebugHUD::DrawSurvival(const UAgrarianSurvivalComponent* SurvivalComponent, float X, float& Y) const +{ + if (!SurvivalComponent) + { + DrawLine(TEXT("Survival: unavailable"), X, Y, FColor::Red); + return; + } + + const FAgrarianSurvivalSnapshot& Survival = SurvivalComponent->Survival; + DrawLine(FString::Printf(TEXT("Health: %.0f"), Survival.Health), X, Y); + DrawLine(FString::Printf(TEXT("Stamina: %.0f"), Survival.Stamina), X, Y); + DrawLine(FString::Printf(TEXT("Hunger: %.0f"), Survival.Hunger), X, Y); + DrawLine(FString::Printf(TEXT("Thirst: %.0f"), Survival.Thirst), X, Y); + DrawLine(FString::Printf(TEXT("Temp: %.1f C"), Survival.BodyTemperature), X, Y); + DrawLine(FString::Printf(TEXT("Injury: %.0f"), Survival.InjurySeverity), X, Y); + Y += 10.0f * TextScale; +} + +void AAgrarianDebugHUD::DrawInventory(const UAgrarianInventoryComponent* InventoryComponent, float X, float& Y) const +{ + if (!InventoryComponent) + { + DrawLine(TEXT("Inventory: unavailable"), X, Y, FColor::Red); + return; + } + + DrawLine(FString::Printf(TEXT("Inventory: %d/%d slots"), InventoryComponent->Items.Num(), InventoryComponent->MaxSlots), X, Y, FColor(160, 220, 140)); + + if (InventoryComponent->Items.IsEmpty()) + { + DrawLine(TEXT("- empty"), X, Y, FColor::Silver); + return; + } + + for (const FAgrarianItemStack& Stack : InventoryComponent->Items) + { + const FText DisplayName = Stack.DisplayName.IsEmpty() ? FText::FromName(Stack.ItemId) : Stack.DisplayName; + DrawLine(FString::Printf(TEXT("- %s x%d"), *DisplayName.ToString(), Stack.Quantity), X, Y); + } +} + +void AAgrarianDebugHUD::DrawLine(const FString& Text, float X, float& Y, const FColor& Color) const +{ + DrawText(Text, Color, X, Y, nullptr, TextScale, false); + Y += 18.0f * TextScale; +} diff --git a/Source/AgrarianGame/AgrarianDebugHUD.h b/Source/AgrarianGame/AgrarianDebugHUD.h new file mode 100644 index 0000000..50e8784 --- /dev/null +++ b/Source/AgrarianGame/AgrarianDebugHUD.h @@ -0,0 +1,30 @@ +// Copyright Pacificao. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/HUD.h" +#include "AgrarianDebugHUD.generated.h" + +class UAgrarianInventoryComponent; +class UAgrarianSurvivalComponent; + +UCLASS() +class AAgrarianDebugHUD : public AHUD +{ + GENERATED_BODY() + +public: + virtual void DrawHUD() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD") + bool bShowDebugHUD = true; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "0.25")) + float TextScale = 1.0f; + +protected: + void DrawSurvival(const UAgrarianSurvivalComponent* SurvivalComponent, float X, float& Y) const; + void DrawInventory(const UAgrarianInventoryComponent* InventoryComponent, float X, float& Y) const; + void DrawLine(const FString& Text, float X, float& Y, const FColor& Color = FColor::White) const; +}; diff --git a/Source/AgrarianGame/AgrarianGameGameMode.cpp b/Source/AgrarianGame/AgrarianGameGameMode.cpp index 998cf69..9d66d14 100644 --- a/Source/AgrarianGame/AgrarianGameGameMode.cpp +++ b/Source/AgrarianGame/AgrarianGameGameMode.cpp @@ -1,9 +1,11 @@ // Copyright Epic Games, Inc. All Rights Reserved. #include "AgrarianGameGameMode.h" +#include "AgrarianDebugHUD.h" #include "AgrarianGameState.h" AAgrarianGameGameMode::AAgrarianGameGameMode() { GameStateClass = AAgrarianGameState::StaticClass(); + HUDClass = AAgrarianDebugHUD::StaticClass(); }