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_wildlife_loop.py
T

111 lines
4.2 KiB
Python

import unreal
MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test"
CHARACTER_CLASS_PATH = "/Game/Agrarian/Blueprints/Characters/BP_AgrarianPlayerCharacter"
RABBIT_LABEL = "AGR_RabbitWildlife_01"
def get_actor_label(actor):
try:
return actor.get_actor_label()
except Exception:
return actor.get_name()
def load_blueprint_class(path):
generated_class = unreal.EditorAssetLibrary.load_blueprint_class(path)
if not generated_class:
raise RuntimeError(f"Could not load Blueprint class: {path}")
return generated_class
def find_actor_by_label(label):
for actor in unreal.EditorLevelLibrary.get_all_level_actors():
if get_actor_label(actor) == label:
return actor
return None
def enum_name(value):
return str(value).split(".")[-1].lower()
def get_bool_property(actor, *property_names):
for property_name in property_names:
try:
return bool(actor.get_editor_property(property_name))
except Exception:
continue
raise RuntimeError(f"Could not read any bool property from {property_names}")
def main():
if not unreal.EditorLevelLibrary.load_level(MAP_PATH):
raise RuntimeError(f"Could not load map: {MAP_PATH}")
character_class = load_blueprint_class(CHARACTER_CLASS_PATH)
rabbit = find_actor_by_label(RABBIT_LABEL)
if not rabbit:
raise RuntimeError(f"Could not find placed rabbit wildlife: {RABBIT_LABEL}")
character = unreal.AgrarianEditorAutomationLibrary.spawn_actor_in_editor_world(
character_class,
unreal.Vector(500.0, 320.0, 180.0),
unreal.Rotator(0.0, 0.0, 0.0),
"AGR_AutomationWildlifeCharacter",
)
if not character:
raise RuntimeError("Could not spawn automation character")
inventory = character.get_component_by_class(unreal.AgrarianInventoryComponent)
if not inventory:
raise RuntimeError("Automation character is missing AgrarianInventoryComponent")
starting_health = float(rabbit.get_editor_property("health"))
max_health = float(rabbit.get_editor_property("max_health"))
if starting_health <= 0.0 or max_health <= 0.0:
raise RuntimeError(f"Rabbit starts invalid health={starting_health}, max_health={max_health}")
rabbit.apply_wildlife_damage(1.0, character)
damaged_health = float(rabbit.get_editor_property("health"))
damaged_state = enum_name(rabbit.get_editor_property("wildlife_state"))
if not damaged_health < starting_health:
raise RuntimeError(f"Rabbit non-lethal damage did not reduce health: {starting_health} -> {damaged_health}")
if "fleeing" not in damaged_state:
raise RuntimeError(f"Rabbit expected fleeing after non-lethal damage, got {damaged_state}")
rabbit.apply_wildlife_damage(max_health + 10.0, character)
dead_health = float(rabbit.get_editor_property("health"))
dead_state = enum_name(rabbit.get_editor_property("wildlife_state"))
if dead_health != 0.0:
raise RuntimeError(f"Rabbit lethal damage expected health 0, got {dead_health}")
if "dead" not in dead_state:
raise RuntimeError(f"Rabbit expected dead after lethal damage, got {dead_state}")
if not rabbit.can_interact(character):
raise RuntimeError("Rabbit should be harvestable after death")
meat_before = inventory.get_item_count("meat")
hide_before = inventory.get_item_count("hide")
rabbit.interact(character)
meat_after = inventory.get_item_count("meat")
hide_after = inventory.get_item_count("hide")
if meat_after <= meat_before:
raise RuntimeError(f"Rabbit harvest did not add meat: {meat_before} -> {meat_after}")
if hide_after <= hide_before:
raise RuntimeError(f"Rabbit harvest did not add hide: {hide_before} -> {hide_after}")
if not get_bool_property(rabbit, "b_harvested", "harvested"):
raise RuntimeError("Rabbit harvest did not set bHarvested")
if rabbit.can_interact(character):
raise RuntimeError("Rabbit should not be harvestable twice")
unreal.EditorLevelLibrary.destroy_actor(character)
unreal.log(
"PASS: wildlife damage/death/harvest verified "
f"health {starting_health}->{damaged_health}->0, "
f"meat {meat_before}->{meat_after}, hide {hide_before}->{hide_after}"
)
main()