Add MVP crafting HUD

This commit is contained in:
2026-05-17 17:57:17 -07:00
parent ef658a380e
commit 3509641df8
10 changed files with 254 additions and 10 deletions
@@ -10,6 +10,17 @@ DEST_CHARACTER = f"{DEST_ROOT}/BP_AgrarianPlayerCharacter"
DEST_CONTROLLER = f"{DEST_ROOT}/BP_AgrarianPlayerController"
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):
if not unreal.EditorAssetLibrary.does_directory_exist(path):
@@ -40,6 +51,13 @@ def load_blueprint_class(path):
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():
ensure_directory(DEST_ROOT)
@@ -49,11 +67,21 @@ def main():
character_class = load_blueprint_class(DEST_CHARACTER)
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.set_editor_property("default_pawn_class", character_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(controller_bp)
unreal.EditorAssetLibrary.save_loaded_asset(game_mode_bp)
+23 -1
View File
@@ -4,6 +4,16 @@ import unreal
CHARACTER_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerCharacter"
CONTROLLER_BLUEPRINT_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerController"
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):
@@ -48,6 +58,19 @@ def main():
character_cdo = unreal.get_default_object(character_class)
if not character_cdo:
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)
if not controller_cdo:
@@ -63,4 +86,3 @@ def main():
main()
+63
View File
@@ -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()