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_ground_zero_demo_map.py
T
2026-05-14 02:28:38 -07:00

174 lines
5.6 KiB
Python

import struct
from pathlib import Path
import unreal
MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test"
PROJECT_ROOT = Path(r"Z:\AgrarianGameBulid")
TILE_ID = "gz_us_ca_pacifica_utm10n_e544_n4160"
HEIGHTMAP_PATH = PROJECT_ROOT / "Data" / "Terrain" / "Unreal" / TILE_ID / f"{TILE_ID}_unreal_1009.r16"
LANDSCAPE_SIZE = 1009
XY_SCALE_CM = 100000.0 / (LANDSCAPE_SIZE - 1)
Z_SCALE_CM = 100.0
LANDSCAPE_MIN_XY = -50000.0
DEMO_ACTORS = [
{
"label": "AGR_DemoPlayerStart",
"class": unreal.PlayerStart,
"location_xy": unreal.Vector(-18500.0, -6400.0, 0.0),
"z_offset": 220.0,
"rotation": unreal.Rotator(0.0, 72.0, 0.0),
},
{
"label": "AGR_DemoWoodResource_01",
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_WoodResourceNode",
"location_xy": unreal.Vector(-16800.0, -5400.0, 0.0),
"z_offset": 80.0,
"rotation": unreal.Rotator(0.0, 25.0, 0.0),
},
{
"label": "AGR_DemoFiberResource_01",
"class_path": "/Game/Agrarian/Blueprints/Resources/BP_FiberResourceNode",
"location_xy": unreal.Vector(-15600.0, -7850.0, 0.0),
"z_offset": 80.0,
"rotation": unreal.Rotator(0.0, -15.0, 0.0),
},
{
"label": "AGR_DemoCampfire_01",
"class_path": "/Game/Agrarian/Blueprints/Structures/BP_Campfire",
"location_xy": unreal.Vector(-13200.0, -6350.0, 0.0),
"z_offset": 90.0,
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
},
{
"label": "AGR_DemoPrimitiveShelter_01",
"class_path": "/Game/Agrarian/Blueprints/Structures/BP_PrimitiveShelter",
"location_xy": unreal.Vector(-11500.0, -7750.0, 0.0),
"z_offset": 120.0,
"rotation": unreal.Rotator(0.0, -30.0, 0.0),
},
{
"label": "AGR_DemoRabbitWildlife_01",
"class_path": "/Game/Agrarian/Blueprints/Wildlife/BP_RabbitWildlife",
"location_xy": unreal.Vector(-19800.0, -8550.0, 0.0),
"z_offset": 120.0,
"rotation": unreal.Rotator(0.0, 135.0, 0.0),
},
{
"label": "AGR_DemoSun",
"class": unreal.DirectionalLight,
"location_xy": unreal.Vector(-22000.0, -9000.0, 0.0),
"fixed_z": 35000.0,
"rotation": unreal.Rotator(-42.0, -35.0, 0.0),
},
{
"label": "AGR_DemoSkyLight",
"class": unreal.SkyLight,
"location_xy": unreal.Vector(-18000.0, -7000.0, 0.0),
"fixed_z": 12000.0,
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
},
{
"label": "AGR_DemoFog",
"class": unreal.ExponentialHeightFog,
"location_xy": unreal.Vector(-18000.0, -7000.0, 0.0),
"fixed_z": 4000.0,
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
},
{
"label": "AGR_DemoNoticeActor",
"class": unreal.AgrarianDemoNoticeActor,
"location_xy": unreal.Vector(-18500.0, -6400.0, 0.0),
"fixed_z": 1600.0,
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
},
]
def get_actor_label(actor):
try:
return actor.get_actor_label()
except Exception:
return actor.get_name()
def set_actor_label(actor, label):
try:
actor.set_actor_label(label, mark_dirty=True)
except TypeError:
actor.set_actor_label(label)
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 load_heightmap():
raw = HEIGHTMAP_PATH.read_bytes()
expected_bytes = LANDSCAPE_SIZE * LANDSCAPE_SIZE * 2
if len(raw) != expected_bytes:
raise RuntimeError(f"Unexpected heightmap size: {len(raw)} != {expected_bytes}")
return struct.unpack(f"<{LANDSCAPE_SIZE * LANDSCAPE_SIZE}H", raw)
def terrain_z_cm(height_values, x_cm, y_cm):
sample_x = max(0, min(LANDSCAPE_SIZE - 1, round((x_cm - LANDSCAPE_MIN_XY) / XY_SCALE_CM)))
sample_y = max(0, min(LANDSCAPE_SIZE - 1, round((y_cm - LANDSCAPE_MIN_XY) / XY_SCALE_CM)))
height_value = height_values[int(sample_y) * LANDSCAPE_SIZE + int(sample_x)]
elevation_m = (float(height_value) - 32768.0) * Z_SCALE_CM / (100.0 * 128.0)
return elevation_m * 100.0
def remove_existing_demo_actors(labels):
for actor in unreal.EditorLevelLibrary.get_all_level_actors():
if get_actor_label(actor) in labels:
unreal.EditorLevelLibrary.destroy_actor(actor)
def spawn_demo_actor(spec, height_values):
location_xy = spec["location_xy"]
z = spec.get("fixed_z")
if z is None:
z = terrain_z_cm(height_values, location_xy.x, location_xy.y) + spec.get("z_offset", 0.0)
actor_class = spec.get("class")
if actor_class is None:
actor_class = load_blueprint_class(spec["class_path"])
actor = unreal.AgrarianEditorAutomationLibrary.spawn_actor_in_editor_world(
actor_class,
unreal.Vector(location_xy.x, location_xy.y, z),
spec["rotation"],
spec["label"],
)
if not actor:
raise RuntimeError(f"Could not spawn {spec['label']}")
set_actor_label(actor, spec["label"])
unreal.log(f"Placed {spec['label']} at {actor.get_actor_location()}")
return actor
def main():
if not unreal.EditorLevelLibrary.load_level(MAP_PATH):
raise RuntimeError(f"Could not load map: {MAP_PATH}")
labels = {spec["label"] for spec in DEMO_ACTORS}
remove_existing_demo_actors(labels)
height_values = load_heightmap()
for spec in DEMO_ACTORS:
spawn_demo_actor(spec, height_values)
unreal.EditorLevelLibrary.save_current_level()
unreal.log("Ground Zero demo map setup complete.")
main()