Add MVP crafting HUD
This commit is contained in:
@@ -568,7 +568,9 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
|||||||
data assets, using wood, fiber, and hide as MVP ingredients for later
|
data assets, using wood, fiber, and hide as MVP ingredients for later
|
||||||
placed-storage/container systems.
|
placed-storage/container systems.
|
||||||
- [x] Add bandage or basic treatment recipe.
|
- [x] Add bandage or basic treatment recipe.
|
||||||
- [ ] Add crafting UI.
|
- [x] Add crafting UI. Added a compact crafting HUD panel that lists known MVP
|
||||||
|
recipes, shows current ingredient counts, highlights craftable rows, and
|
||||||
|
preloads the Agrarian player Blueprint with primitive recipe assets.
|
||||||
- [x] Add multiplayer authority checks.
|
- [x] Add multiplayer authority checks.
|
||||||
- [~] Add crafting debug tools.
|
- [~] Add crafting debug tools.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -147,6 +147,12 @@ array, shows occupied slots, total carried weight, and a short visible stack
|
|||||||
list, and leaves mutation actions on the existing server-authoritative commands
|
list, and leaves mutation actions on the existing server-authoritative commands
|
||||||
and RPCs until a full UMG inventory screen is introduced.
|
and RPCs until a full UMG inventory screen is introduced.
|
||||||
|
|
||||||
|
The MVP crafting UI is a compact `AAgrarianDebugHUD` crafting panel. The
|
||||||
|
Agrarian player Blueprint preloads primitive `KnownRecipeAssets`, and the HUD
|
||||||
|
reads those recipes plus the replicated inventory to show craftable status and
|
||||||
|
ingredient counts. Interactive UMG recipe browsing, hotkeys, and queued
|
||||||
|
crafting controls are deferred until the primitive loop settles.
|
||||||
|
|
||||||
Inventory persistence saves `UAgrarianInventoryComponent::Items` into
|
Inventory persistence saves `UAgrarianInventoryComponent::Items` into
|
||||||
`FAgrarianSavedPlayer::Inventory` and restores through
|
`FAgrarianSavedPlayer::Inventory` and restores through
|
||||||
`UAgrarianInventoryComponent::RestoreSavedItems`. Restore broadcasts
|
`UAgrarianInventoryComponent::RestoreSavedItems`. Restore broadcasts
|
||||||
|
|||||||
@@ -10,6 +10,17 @@ DEST_CHARACTER = f"{DEST_ROOT}/BP_AgrarianPlayerCharacter"
|
|||||||
DEST_CONTROLLER = f"{DEST_ROOT}/BP_AgrarianPlayerController"
|
DEST_CONTROLLER = f"{DEST_ROOT}/BP_AgrarianPlayerController"
|
||||||
DEST_GAME_MODE = f"{DEST_ROOT}/BP_AgrarianGameMode"
|
DEST_GAME_MODE = f"{DEST_ROOT}/BP_AgrarianGameMode"
|
||||||
|
|
||||||
|
KNOWN_RECIPE_ASSETS = [
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_Campfire",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_PrimitiveFrame",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_PrimitiveWallPanel",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_PrimitiveRoofPanel",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_PrimitiveShelter",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_BasicTool",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_SimpleContainer",
|
||||||
|
"/Game/Agrarian/DataAssets/Recipes/DA_Recipe_Bandage",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def ensure_directory(path):
|
def ensure_directory(path):
|
||||||
if not unreal.EditorAssetLibrary.does_directory_exist(path):
|
if not unreal.EditorAssetLibrary.does_directory_exist(path):
|
||||||
@@ -40,6 +51,13 @@ def load_blueprint_class(path):
|
|||||||
return generated_class
|
return generated_class
|
||||||
|
|
||||||
|
|
||||||
|
def load_required_asset(path):
|
||||||
|
asset = unreal.EditorAssetLibrary.load_asset(path)
|
||||||
|
if not asset:
|
||||||
|
raise RuntimeError(f"Required asset not found: {path}")
|
||||||
|
return asset
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
ensure_directory(DEST_ROOT)
|
ensure_directory(DEST_ROOT)
|
||||||
|
|
||||||
@@ -49,11 +67,21 @@ def main():
|
|||||||
|
|
||||||
character_class = load_blueprint_class(DEST_CHARACTER)
|
character_class = load_blueprint_class(DEST_CHARACTER)
|
||||||
controller_class = load_blueprint_class(DEST_CONTROLLER)
|
controller_class = load_blueprint_class(DEST_CONTROLLER)
|
||||||
|
character_cdo = unreal.get_default_object(character_class)
|
||||||
game_mode_cdo = unreal.get_default_object(game_mode_bp.generated_class())
|
game_mode_cdo = unreal.get_default_object(game_mode_bp.generated_class())
|
||||||
|
|
||||||
game_mode_cdo.set_editor_property("default_pawn_class", character_class)
|
game_mode_cdo.set_editor_property("default_pawn_class", character_class)
|
||||||
game_mode_cdo.set_editor_property("player_controller_class", controller_class)
|
game_mode_cdo.set_editor_property("player_controller_class", controller_class)
|
||||||
|
|
||||||
|
crafting_component = character_cdo.get_editor_property("crafting_component")
|
||||||
|
if not crafting_component:
|
||||||
|
raise RuntimeError("BP_AgrarianPlayerCharacter is missing CraftingComponent")
|
||||||
|
crafting_component.set_editor_property(
|
||||||
|
"known_recipe_assets",
|
||||||
|
[load_required_asset(path) for path in KNOWN_RECIPE_ASSETS],
|
||||||
|
)
|
||||||
|
|
||||||
|
unreal.BlueprintEditorLibrary.compile_blueprint(character_bp)
|
||||||
unreal.EditorAssetLibrary.save_loaded_asset(character_bp)
|
unreal.EditorAssetLibrary.save_loaded_asset(character_bp)
|
||||||
unreal.EditorAssetLibrary.save_loaded_asset(controller_bp)
|
unreal.EditorAssetLibrary.save_loaded_asset(controller_bp)
|
||||||
unreal.EditorAssetLibrary.save_loaded_asset(game_mode_bp)
|
unreal.EditorAssetLibrary.save_loaded_asset(game_mode_bp)
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ import unreal
|
|||||||
CHARACTER_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerCharacter"
|
CHARACTER_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerCharacter"
|
||||||
CONTROLLER_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerController"
|
CONTROLLER_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerController"
|
||||||
GAME_MODE_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianGameMode"
|
GAME_MODE_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianGameMode"
|
||||||
|
EXPECTED_RECIPE_IDS = [
|
||||||
|
"campfire",
|
||||||
|
"primitive_frame",
|
||||||
|
"primitive_wall_panel",
|
||||||
|
"primitive_roof_panel",
|
||||||
|
"primitive_shelter",
|
||||||
|
"basic_tool",
|
||||||
|
"simple_container",
|
||||||
|
"bandage",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def class_path(value):
|
def class_path(value):
|
||||||
@@ -48,6 +58,19 @@ def main():
|
|||||||
character_cdo = unreal.get_default_object(character_class)
|
character_cdo = unreal.get_default_object(character_class)
|
||||||
if not character_cdo:
|
if not character_cdo:
|
||||||
failures.append(f"{CHARACTER_BLUEPRINT_PATH} CDO missing")
|
failures.append(f"{CHARACTER_BLUEPRINT_PATH} CDO missing")
|
||||||
|
else:
|
||||||
|
crafting_component = character_cdo.get_editor_property("crafting_component")
|
||||||
|
recipe_assets = crafting_component.get_editor_property("known_recipe_assets") if crafting_component else []
|
||||||
|
recipe_ids = [
|
||||||
|
str(asset.get_editor_property("recipe").get_editor_property("recipe_id"))
|
||||||
|
for asset in recipe_assets
|
||||||
|
if asset
|
||||||
|
]
|
||||||
|
if recipe_ids != EXPECTED_RECIPE_IDS:
|
||||||
|
failures.append(
|
||||||
|
"BP_AgrarianPlayerCharacter known recipes expected "
|
||||||
|
f"{EXPECTED_RECIPE_IDS}, got {recipe_ids}"
|
||||||
|
)
|
||||||
|
|
||||||
controller_cdo = unreal.get_default_object(controller_class)
|
controller_cdo = unreal.get_default_object(controller_class)
|
||||||
if not controller_cdo:
|
if not controller_cdo:
|
||||||
@@ -63,4 +86,3 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
EXPECTED = {
|
||||||
|
ROOT / "Source" / "AgrarianGame" / "AgrarianDebugHUD.h": [
|
||||||
|
"bool bShowCraftingHUD = true;",
|
||||||
|
"int32 MaxCraftingPanelRows = 8;",
|
||||||
|
"void DrawCraftingPanel",
|
||||||
|
],
|
||||||
|
ROOT / "Source" / "AgrarianGame" / "AgrarianDebugHUD.cpp": [
|
||||||
|
"DrawCraftingPanel(AgrarianCharacter",
|
||||||
|
"CraftingComponent->GetKnownRecipes(Recipes)",
|
||||||
|
"CraftingComponent->CanCraft(Recipe.RecipeId, FailureReason)",
|
||||||
|
"InventoryComponent->GetItemCount(Ingredient.ItemId)",
|
||||||
|
"CRAFTING %d recipes",
|
||||||
|
],
|
||||||
|
ROOT / "Source" / "AgrarianGame" / "AgrarianCraftingComponent.h": [
|
||||||
|
"void GetKnownRecipes(TArray<FAgrarianRecipe>& OutRecipes) const;",
|
||||||
|
],
|
||||||
|
ROOT / "Source" / "AgrarianGame" / "AgrarianCraftingComponent.cpp": [
|
||||||
|
"void UAgrarianCraftingComponent::GetKnownRecipes",
|
||||||
|
"RecipeAsset->Recipe.RecipeId != NAME_None",
|
||||||
|
"OutRecipes.Add(RecipeAsset->Recipe)",
|
||||||
|
],
|
||||||
|
ROOT / "Scripts" / "setup_agrarian_player_blueprints.py": [
|
||||||
|
"KNOWN_RECIPE_ASSETS",
|
||||||
|
"DA_Recipe_SimpleContainer",
|
||||||
|
"known_recipe_assets",
|
||||||
|
],
|
||||||
|
ROOT / "Scripts" / "verify_agrarian_player_blueprints.py": [
|
||||||
|
"EXPECTED_RECIPE_IDS",
|
||||||
|
"simple_container",
|
||||||
|
"known_recipe_assets",
|
||||||
|
],
|
||||||
|
ROOT / "Docs" / "TechnicalDesignDocument.md": [
|
||||||
|
"The MVP crafting UI is a compact `AAgrarianDebugHUD` crafting panel",
|
||||||
|
"`KnownRecipeAssets`",
|
||||||
|
],
|
||||||
|
ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md": [
|
||||||
|
"- [x] Add crafting UI.",
|
||||||
|
"compact crafting HUD panel",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
missing = []
|
||||||
|
for path, snippets in EXPECTED.items():
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
for snippet in snippets:
|
||||||
|
if snippet not in text:
|
||||||
|
missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}")
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
raise RuntimeError("Crafting UI verification failed: " + "; ".join(missing))
|
||||||
|
|
||||||
|
print("PASS: crafting UI HUD panel and known recipe wiring are present.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -133,6 +133,27 @@ bool UAgrarianCraftingComponent::FindRecipe(FName RecipeId, FAgrarianRecipe& Out
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UAgrarianCraftingComponent::GetKnownRecipes(TArray<FAgrarianRecipe>& OutRecipes) const
|
||||||
|
{
|
||||||
|
OutRecipes.Reset();
|
||||||
|
|
||||||
|
for (const UAgrarianRecipeDataAsset* RecipeAsset : KnownRecipeAssets)
|
||||||
|
{
|
||||||
|
if (RecipeAsset && RecipeAsset->Recipe.RecipeId != NAME_None)
|
||||||
|
{
|
||||||
|
OutRecipes.Add(RecipeAsset->Recipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const FAgrarianRecipe& Recipe : KnownRecipes)
|
||||||
|
{
|
||||||
|
if (Recipe.RecipeId != NAME_None)
|
||||||
|
{
|
||||||
|
OutRecipes.Add(Recipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UAgrarianInventoryComponent* UAgrarianCraftingComponent::GetInventory() const
|
UAgrarianInventoryComponent* UAgrarianCraftingComponent::GetInventory() const
|
||||||
{
|
{
|
||||||
return GetOwner() ? GetOwner()->FindComponentByClass<UAgrarianInventoryComponent>() : nullptr;
|
return GetOwner() ? GetOwner()->FindComponentByClass<UAgrarianInventoryComponent>() : nullptr;
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|Crafting")
|
UFUNCTION(BlueprintCallable, Category = "Agrarian|Crafting")
|
||||||
bool FindRecipe(FName RecipeId, FAgrarianRecipe& OutRecipe) const;
|
bool FindRecipe(FName RecipeId, FAgrarianRecipe& OutRecipe) const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Agrarian|Crafting")
|
||||||
|
void GetKnownRecipes(TArray<FAgrarianRecipe>& OutRecipes) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UAgrarianInventoryComponent* GetInventory() const;
|
UAgrarianInventoryComponent* GetInventory() const;
|
||||||
void FailCraft(FName RecipeId, const FText& Reason);
|
void FailCraft(FName RecipeId, const FText& Reason);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright Pacificao. All Rights Reserved.
|
// Copyright Pacificao. All Rights Reserved.
|
||||||
|
|
||||||
#include "AgrarianDebugHUD.h"
|
#include "AgrarianDebugHUD.h"
|
||||||
|
#include "AgrarianCraftingComponent.h"
|
||||||
#include "AgrarianGameCharacter.h"
|
#include "AgrarianGameCharacter.h"
|
||||||
#include "AgrarianInventoryComponent.h"
|
#include "AgrarianInventoryComponent.h"
|
||||||
#include "AgrarianSurvivalComponent.h"
|
#include "AgrarianSurvivalComponent.h"
|
||||||
@@ -24,7 +25,8 @@ void AAgrarianDebugHUD::DrawHUD()
|
|||||||
|
|
||||||
DrawInteractionPrompt(AgrarianCharacter);
|
DrawInteractionPrompt(AgrarianCharacter);
|
||||||
DrawCriticalStats(AgrarianCharacter->GetSurvivalComponent());
|
DrawCriticalStats(AgrarianCharacter->GetSurvivalComponent());
|
||||||
DrawInventoryPanel(AgrarianCharacter);
|
const float InventoryBottomY = DrawInventoryPanel(AgrarianCharacter);
|
||||||
|
DrawCraftingPanel(AgrarianCharacter, InventoryBottomY + 16.0f);
|
||||||
|
|
||||||
if (bShowDebugHUD)
|
if (bShowDebugHUD)
|
||||||
{
|
{
|
||||||
@@ -110,17 +112,17 @@ void AAgrarianDebugHUD::DrawCriticalStats(const UAgrarianSurvivalComponent* Surv
|
|||||||
DrawScaledLine(FString::Printf(TEXT("Sickness %3.0f"), Survival.SicknessSeverity), X, Y, CriticalStatsTextScale, StatusColor(Survival.SicknessSeverity, true));
|
DrawScaledLine(FString::Printf(TEXT("Sickness %3.0f"), Survival.SicknessSeverity), X, Y, CriticalStatsTextScale, StatusColor(Survival.SicknessSeverity, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AAgrarianDebugHUD::DrawInventoryPanel(const AAgrarianGameCharacter* AgrarianCharacter)
|
float AAgrarianDebugHUD::DrawInventoryPanel(const AAgrarianGameCharacter* AgrarianCharacter)
|
||||||
{
|
{
|
||||||
if (!bShowInventoryHUD || !AgrarianCharacter || !Canvas)
|
if (!bShowInventoryHUD || !AgrarianCharacter || !Canvas)
|
||||||
{
|
{
|
||||||
return;
|
return 32.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UAgrarianInventoryComponent* InventoryComponent = AgrarianCharacter->GetInventoryComponent();
|
const UAgrarianInventoryComponent* InventoryComponent = AgrarianCharacter->GetInventoryComponent();
|
||||||
if (!InventoryComponent)
|
if (!InventoryComponent)
|
||||||
{
|
{
|
||||||
return;
|
return 32.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float Scale = FMath::Max(0.25f, InventoryTextScale);
|
const float Scale = FMath::Max(0.25f, InventoryTextScale);
|
||||||
@@ -152,7 +154,7 @@ void AAgrarianDebugHUD::DrawInventoryPanel(const AAgrarianGameCharacter* Agraria
|
|||||||
if (InventoryComponent->Items.IsEmpty())
|
if (InventoryComponent->Items.IsEmpty())
|
||||||
{
|
{
|
||||||
DrawText(TEXT("Empty"), FColor::Silver, X, Y, nullptr, Scale, false);
|
DrawText(TEXT("Empty"), FColor::Silver, X, Y, nullptr, Scale, false);
|
||||||
return;
|
return (32.0f + PanelHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 Index = 0; Index < VisibleRows; ++Index)
|
for (int32 Index = 0; Index < VisibleRows; ++Index)
|
||||||
@@ -175,6 +177,95 @@ void AAgrarianDebugHUD::DrawInventoryPanel(const AAgrarianGameCharacter* Agraria
|
|||||||
false);
|
false);
|
||||||
Y += LineHeight;
|
Y += LineHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (32.0f + PanelHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AAgrarianDebugHUD::DrawCraftingPanel(const AAgrarianGameCharacter* AgrarianCharacter, float TopY)
|
||||||
|
{
|
||||||
|
if (!bShowCraftingHUD || !AgrarianCharacter || !Canvas)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UAgrarianCraftingComponent* CraftingComponent = AgrarianCharacter->GetCraftingComponent();
|
||||||
|
const UAgrarianInventoryComponent* InventoryComponent = AgrarianCharacter->GetInventoryComponent();
|
||||||
|
if (!CraftingComponent || !InventoryComponent)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FAgrarianRecipe> Recipes;
|
||||||
|
CraftingComponent->GetKnownRecipes(Recipes);
|
||||||
|
|
||||||
|
const float Scale = FMath::Max(0.25f, InventoryTextScale);
|
||||||
|
const float PanelWidth = 420.0f * Scale;
|
||||||
|
const float X = FMath::Max(32.0f, Canvas->ClipX - PanelWidth - 32.0f);
|
||||||
|
float Y = FMath::Max(32.0f, TopY);
|
||||||
|
|
||||||
|
const int32 VisibleRows = Recipes.IsEmpty()
|
||||||
|
? 1
|
||||||
|
: FMath::Min(Recipes.Num(), FMath::Max(1, MaxCraftingPanelRows));
|
||||||
|
const float LineHeight = 18.0f * Scale;
|
||||||
|
const float PanelHeight = (56.0f * Scale) + (VisibleRows * LineHeight);
|
||||||
|
|
||||||
|
DrawRect(FLinearColor(0.02f, 0.025f, 0.02f, 0.72f), X - (12.0f * Scale), Y - (10.0f * Scale), PanelWidth, PanelHeight);
|
||||||
|
DrawText(
|
||||||
|
FString::Printf(TEXT("CRAFTING %d recipes"), Recipes.Num()),
|
||||||
|
FColor(160, 220, 140),
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
nullptr,
|
||||||
|
Scale,
|
||||||
|
false);
|
||||||
|
Y += 24.0f * Scale;
|
||||||
|
|
||||||
|
if (Recipes.IsEmpty())
|
||||||
|
{
|
||||||
|
DrawText(TEXT("No known recipes"), FColor::Silver, X, Y, nullptr, Scale, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 Index = 0; Index < VisibleRows; ++Index)
|
||||||
|
{
|
||||||
|
const FAgrarianRecipe& Recipe = Recipes[Index];
|
||||||
|
FText FailureReason;
|
||||||
|
const bool bCanCraft = CraftingComponent->CanCraft(Recipe.RecipeId, FailureReason);
|
||||||
|
FString RecipeName = Recipe.DisplayName.IsEmpty() ? Recipe.RecipeId.ToString() : Recipe.DisplayName.ToString();
|
||||||
|
if (RecipeName.Len() > 18)
|
||||||
|
{
|
||||||
|
RecipeName = RecipeName.Left(15) + TEXT("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
FString IngredientSummary;
|
||||||
|
for (const FAgrarianItemStack& Ingredient : Recipe.Ingredients)
|
||||||
|
{
|
||||||
|
if (!IngredientSummary.IsEmpty())
|
||||||
|
{
|
||||||
|
IngredientSummary += TEXT(" ");
|
||||||
|
}
|
||||||
|
IngredientSummary += FString::Printf(
|
||||||
|
TEXT("%s %d/%d"),
|
||||||
|
*Ingredient.ItemId.ToString(),
|
||||||
|
InventoryComponent->GetItemCount(Ingredient.ItemId),
|
||||||
|
Ingredient.Quantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IngredientSummary.Len() > 28)
|
||||||
|
{
|
||||||
|
IngredientSummary = IngredientSummary.Left(25) + TEXT("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawText(
|
||||||
|
FString::Printf(TEXT("%02d %-18s %-28s"), Index + 1, *RecipeName, *IngredientSummary),
|
||||||
|
bCanCraft ? FColor(225, 235, 220) : FColor(170, 150, 125),
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
nullptr,
|
||||||
|
Scale,
|
||||||
|
false);
|
||||||
|
Y += LineHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AAgrarianDebugHUD::DrawPlayerStatus(const AAgrarianGameCharacter* AgrarianCharacter, float X, float& Y)
|
void AAgrarianDebugHUD::DrawPlayerStatus(const AAgrarianGameCharacter* AgrarianCharacter, float X, float& Y)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "AgrarianDebugHUD.generated.h"
|
#include "AgrarianDebugHUD.generated.h"
|
||||||
|
|
||||||
class UAgrarianInventoryComponent;
|
class UAgrarianInventoryComponent;
|
||||||
|
class UAgrarianCraftingComponent;
|
||||||
class UAgrarianSurvivalComponent;
|
class UAgrarianSurvivalComponent;
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
@@ -26,6 +27,9 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD")
|
||||||
bool bShowInventoryHUD = true;
|
bool bShowInventoryHUD = true;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD")
|
||||||
|
bool bShowCraftingHUD = true;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "0.25"))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "0.25"))
|
||||||
float TextScale = 1.0f;
|
float TextScale = 1.0f;
|
||||||
|
|
||||||
@@ -38,6 +42,9 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "1", ClampMax = "12"))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "1", ClampMax = "12"))
|
||||||
int32 MaxInventoryPanelRows = 6;
|
int32 MaxInventoryPanelRows = 6;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD", meta = (ClampMin = "1", ClampMax = "12"))
|
||||||
|
int32 MaxCraftingPanelRows = 8;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|HUD")
|
||||||
bool bShowInteractionPrompt = true;
|
bool bShowInteractionPrompt = true;
|
||||||
|
|
||||||
@@ -47,7 +54,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void DrawInteractionPrompt(const class AAgrarianGameCharacter* AgrarianCharacter);
|
void DrawInteractionPrompt(const class AAgrarianGameCharacter* AgrarianCharacter);
|
||||||
void DrawCriticalStats(const UAgrarianSurvivalComponent* SurvivalComponent);
|
void DrawCriticalStats(const UAgrarianSurvivalComponent* SurvivalComponent);
|
||||||
void DrawInventoryPanel(const class AAgrarianGameCharacter* AgrarianCharacter);
|
float DrawInventoryPanel(const class AAgrarianGameCharacter* AgrarianCharacter);
|
||||||
|
void DrawCraftingPanel(const class AAgrarianGameCharacter* AgrarianCharacter, float TopY);
|
||||||
void DrawPlayerStatus(const class AAgrarianGameCharacter* AgrarianCharacter, float X, float& Y);
|
void DrawPlayerStatus(const class AAgrarianGameCharacter* AgrarianCharacter, float X, float& Y);
|
||||||
void DrawSurvival(const UAgrarianSurvivalComponent* SurvivalComponent, float X, float& Y);
|
void DrawSurvival(const UAgrarianSurvivalComponent* SurvivalComponent, float X, float& Y);
|
||||||
void DrawInventory(const UAgrarianInventoryComponent* InventoryComponent, float X, float& Y);
|
void DrawInventory(const UAgrarianInventoryComponent* InventoryComponent, float X, float& Y);
|
||||||
|
|||||||
Reference in New Issue
Block a user