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/verify_playable_blueprints.py

154 lines
5.4 KiB
Python

import unreal
EXPECTED = {
"/Game/Agrarian/Blueprints/Resources/BP_WoodResourceNode": {
"properties": {
"remaining_harvests": 16,
"quantity_per_harvest": 2,
"required_tool_item_id": "basic_tool",
"allow_bare_hand_gathering": True,
"tool_quantity_bonus": 1,
"respawns_for_mvp": True,
"respawn_delay_seconds": 900.0,
"max_harvests": 16,
},
"yield_item_id": "wood",
},
"/Game/Agrarian/Blueprints/Resources/BP_FiberResourceNode": {
"properties": {
"remaining_harvests": 10,
"quantity_per_harvest": 3,
"required_tool_item_id": "basic_tool",
"allow_bare_hand_gathering": True,
"tool_quantity_bonus": 1,
"respawns_for_mvp": True,
"respawn_delay_seconds": 600.0,
"max_harvests": 10,
},
"yield_item_id": "fiber",
},
"/Game/Agrarian/Blueprints/Resources/BP_StoneResourceNode": {
"properties": {
"remaining_harvests": 12,
"quantity_per_harvest": 2,
"required_tool_item_id": "basic_tool",
"allow_bare_hand_gathering": True,
"tool_quantity_bonus": 1,
"respawns_for_mvp": False,
"respawn_delay_seconds": 1800.0,
"max_harvests": 12,
},
"yield_item_id": "stone",
},
"/Game/Agrarian/Blueprints/Resources/BP_EdiblePlantResourceNode": {
"properties": {
"remaining_harvests": 8,
"quantity_per_harvest": 1,
"required_tool_item_id": "None",
"allow_bare_hand_gathering": True,
"tool_quantity_bonus": 0,
"respawns_for_mvp": True,
"respawn_delay_seconds": 1200.0,
"max_harvests": 8,
},
"yield_item_id": "food",
},
"/Game/Agrarian/Blueprints/Structures/BP_Campfire": {
"properties": {
"fuel_seconds": 180.0,
"warmth_radius": 650.0,
"warmth_per_second": 0.03,
},
},
"/Game/Agrarian/Blueprints/World/BP_FreshWaterSource": {
"properties": {
"water_restore_amount": 45.0,
},
},
"/Game/Agrarian/Blueprints/Structures/BP_PrimitiveShelter": {
"properties": {
"weather_protection": 0.7,
},
},
"/Game/Agrarian/Blueprints/Wildlife/BP_RabbitWildlife": {
"properties": {
"wildlife_id": "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_yield_ids": ["meat", "hide"],
},
}
def nearly_equal(left, right):
if isinstance(left, float) or isinstance(right, float):
return abs(float(left) - float(right)) < 0.001
return left == right
def get_property(cdo, property_name, expected_value):
property_names = [property_name]
if isinstance(expected_value, bool):
property_names.append(f"b_{property_name}")
property_names.append("b" + "".join(part.capitalize() for part in property_name.split("_")))
for reflected_name in property_names:
try:
return cdo.get_editor_property(reflected_name)
except Exception:
continue
raise RuntimeError(f"Could not read property {property_name}")
def main():
failures = []
for path, expected in EXPECTED.items():
blueprint = unreal.EditorAssetLibrary.load_asset(path)
if not blueprint:
failures.append(f"{path} missing")
continue
generated_class = unreal.EditorAssetLibrary.load_blueprint_class(path)
if not generated_class:
failures.append(f"{path} parent class mismatch")
continue
cdo = unreal.get_default_object(generated_class)
for property_name, expected_value in expected.get("properties", {}).items():
actual_value = get_property(cdo, property_name, expected_value)
if str(actual_value) != expected_value and not nearly_equal(actual_value, expected_value):
failures.append(f"{path} {property_name} expected {expected_value}, got {actual_value}")
expected_yield_item_id = expected.get("yield_item_id")
if expected_yield_item_id:
item_asset = cdo.get_editor_property("yield_item_definition")
definition = item_asset.get_editor_property("definition") if item_asset else None
item_id = str(definition.get_editor_property("item_id")) if definition else ""
if item_id != expected_yield_item_id:
failures.append(f"{path} yield_item_definition expected {expected_yield_item_id}, got {item_id}")
expected_harvest_ids = expected.get("harvest_yield_ids")
if expected_harvest_ids:
harvest_yields = cdo.get_editor_property("harvest_yields")
actual_ids = [str(stack.get_editor_property("item_id")) for stack in harvest_yields]
if actual_ids != expected_harvest_ids:
failures.append(f"{path} harvest_yields expected {expected_harvest_ids}, got {actual_ids}")
if failures:
raise RuntimeError("Playable Blueprint verification failed: " + "; ".join(failures))
unreal.log("Agrarian playable Blueprint verification complete.")
main()