This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AgrarianGameArchive/Scripts/setup_playable_blueprints.py
T

216 lines
7.3 KiB
Python

import unreal
BLUEPRINT_ROOT = "/Game/Agrarian/Blueprints"
RESOURCE_FOLDER = f"{BLUEPRINT_ROOT}/Resources"
STRUCTURE_FOLDER = f"{BLUEPRINT_ROOT}/Structures"
WILDLIFE_FOLDER = f"{BLUEPRINT_ROOT}/Wildlife"
WORLD_FOLDER = f"{BLUEPRINT_ROOT}/World"
WOOD_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Wood"
FIBER_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Fiber"
STONE_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Stone"
PLACEHOLDER_MESH_FOLDER = "/Game/Agrarian/Environment/PlaceholderMeshes"
PLACEHOLDER_MESH_SOURCES = {
"SM_AGR_Placeholder_Cube": "/Game/LevelPrototyping/Meshes/SM_Cube",
"SM_AGR_Placeholder_Cylinder": "/Game/LevelPrototyping/Meshes/SM_Cylinder",
}
PLACEHOLDER_MESHES = {
name: f"{PLACEHOLDER_MESH_FOLDER}/{name}"
for name in PLACEHOLDER_MESH_SOURCES
}
MESH_CUBE_PATH = PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cube"]
MESH_CYLINDER_PATH = PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cylinder"]
BLUEPRINTS = [
{
"asset": "BP_WoodResourceNode",
"folder": RESOURCE_FOLDER,
"parent": unreal.AgrarianResourceNode,
"defaults": {
"yield_item_definition": WOOD_ITEM_PATH,
"remaining_harvests": 16,
"quantity_per_harvest": 2,
},
"mesh": MESH_CUBE_PATH,
"scale": unreal.Vector(1.0, 1.0, 1.5),
},
{
"asset": "BP_FiberResourceNode",
"folder": RESOURCE_FOLDER,
"parent": unreal.AgrarianResourceNode,
"defaults": {
"yield_item_definition": FIBER_ITEM_PATH,
"remaining_harvests": 10,
"quantity_per_harvest": 3,
},
"mesh": MESH_CYLINDER_PATH,
"scale": unreal.Vector(0.8, 0.8, 1.0),
},
{
"asset": "BP_StoneResourceNode",
"folder": RESOURCE_FOLDER,
"parent": unreal.AgrarianResourceNode,
"defaults": {
"yield_item_definition": STONE_ITEM_PATH,
"remaining_harvests": 12,
"quantity_per_harvest": 2,
},
"mesh": MESH_CUBE_PATH,
"scale": unreal.Vector(0.9, 0.75, 0.45),
},
{
"asset": "BP_Campfire",
"folder": STRUCTURE_FOLDER,
"parent": unreal.AgrarianCampfire,
"defaults": {
"fuel_seconds": 180.0,
"warmth_radius": 650.0,
"warmth_per_second": 0.03,
},
"mesh": MESH_CYLINDER_PATH,
"scale": unreal.Vector(1.3, 1.3, 0.25),
},
{
"asset": "BP_FreshWaterSource",
"folder": WORLD_FOLDER,
"parent": unreal.AgrarianWaterSource,
"defaults": {
"water_restore_amount": 45.0,
"display_name": "Fresh Water Spring",
},
"mesh": MESH_CYLINDER_PATH,
"scale": unreal.Vector(2.2, 2.2, 0.12),
},
{
"asset": "BP_PrimitiveShelter",
"folder": STRUCTURE_FOLDER,
"parent": unreal.AgrarianShelterActor,
"defaults": {
"weather_protection": 0.7,
},
"mesh": MESH_CUBE_PATH,
"scale": unreal.Vector(3.0, 2.0, 1.4),
},
{
"asset": "BP_RabbitWildlife",
"folder": WILDLIFE_FOLDER,
"parent": unreal.AgrarianWildlifeBase,
"defaults": {
"wildlife_id": "rabbit",
"display_name": "Rabbit",
"max_health": 12.0,
"health": 12.0,
"wander_radius": 900.0,
"wander_speed": 160.0,
"flee_speed": 520.0,
"aggro_radius": 0.0,
"flee_radius": 750.0,
"decision_interval_seconds": 1.5,
"harvest_yields": [
{
"item_id": "meat",
"display_name": "Meat",
"quantity": 1,
"unit_weight": 0.5,
},
{
"item_id": "hide",
"display_name": "Hide",
"quantity": 2,
"unit_weight": 0.7,
},
],
},
},
]
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 ensure_native_placeholder_meshes():
unreal.EditorAssetLibrary.make_directory(PLACEHOLDER_MESH_FOLDER)
for asset_name, source_path in PLACEHOLDER_MESH_SOURCES.items():
destination_path = f"{PLACEHOLDER_MESH_FOLDER}/{asset_name}"
if unreal.EditorAssetLibrary.does_asset_exist(destination_path):
continue
if not unreal.EditorAssetLibrary.duplicate_asset(source_path, destination_path):
raise RuntimeError(f"Could not create native placeholder mesh {destination_path} from {source_path}")
unreal.EditorAssetLibrary.save_asset(destination_path)
unreal.log(f"Created native placeholder mesh: {destination_path}")
def create_or_load_blueprint(asset_name, folder, parent_class):
path = f"{folder}/{asset_name}"
existing = unreal.EditorAssetLibrary.load_asset(path)
if existing:
return existing
factory = unreal.BlueprintFactory()
factory.set_editor_property("parent_class", parent_class)
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
blueprint = asset_tools.create_asset(asset_name, folder, None, factory)
if not blueprint:
raise RuntimeError(f"Could not create {path}")
return blueprint
def make_stack(data):
stack = unreal.AgrarianItemStack()
stack.set_editor_property("item_id", data["item_id"])
stack.set_editor_property("display_name", data["display_name"])
stack.set_editor_property("quantity", data["quantity"])
stack.set_editor_property("unit_weight", data["unit_weight"])
return stack
def apply_defaults(blueprint, config):
blueprint_path = f"{config['folder']}/{config['asset']}"
unreal.BlueprintEditorLibrary.compile_blueprint(blueprint)
generated_class = unreal.EditorAssetLibrary.load_blueprint_class(blueprint_path)
if not generated_class:
raise RuntimeError(f"Could not load generated class for {blueprint_path}")
cdo = unreal.get_default_object(generated_class)
for property_name, value in config.get("defaults", {}).items():
if property_name == "yield_item_definition":
value = load_required_asset(value)
elif property_name == "harvest_yields":
value = [make_stack(stack_data) for stack_data in value]
cdo.set_editor_property(property_name, value)
mesh_path = config.get("mesh")
if mesh_path:
mesh_component = cdo.get_editor_property("mesh")
mesh_component.set_editor_property("static_mesh", load_required_asset(mesh_path))
mesh_component.set_editor_property("relative_scale3d", config.get("scale", unreal.Vector(1.0, 1.0, 1.0)))
unreal.BlueprintEditorLibrary.compile_blueprint(blueprint)
unreal.EditorAssetLibrary.save_loaded_asset(blueprint)
def main():
ensure_native_placeholder_meshes()
for folder in (RESOURCE_FOLDER, STRUCTURE_FOLDER, WILDLIFE_FOLDER, WORLD_FOLDER):
unreal.EditorAssetLibrary.make_directory(folder)
for config in BLUEPRINTS:
blueprint = create_or_load_blueprint(config["asset"], config["folder"], config["parent"])
apply_defaults(blueprint, config)
unreal.log(f"Configured Blueprint: {config['folder']}/{config['asset']}")
unreal.log("Agrarian playable Blueprint setup complete.")
main()