Add Ground Zero weather exposure zones
This commit is contained in:
@@ -258,6 +258,36 @@ WATER_SOURCE_ACTORS = [
|
||||
},
|
||||
]
|
||||
|
||||
WEATHER_EXPOSURE_ZONES = [
|
||||
{
|
||||
"label": "AGR_GZ_WeatherExposure_Ridge_01",
|
||||
"zone_id": "ground_zero_ridge_exposed",
|
||||
"location_xy": unreal.Vector(36000.0, 29200.0, 0.0),
|
||||
"z_offset": 450.0,
|
||||
"extent": unreal.Vector(11500.0, 9200.0, 2200.0),
|
||||
"exposure_multiplier": 1.45,
|
||||
"temperature_offset_c": -1.8,
|
||||
},
|
||||
{
|
||||
"label": "AGR_GZ_WeatherExposure_CoastalWind_01",
|
||||
"zone_id": "ground_zero_coastal_wind",
|
||||
"location_xy": unreal.Vector(-31500.0, -14600.0, 0.0),
|
||||
"z_offset": 350.0,
|
||||
"extent": unreal.Vector(10500.0, 7600.0, 1600.0),
|
||||
"exposure_multiplier": 1.25,
|
||||
"temperature_offset_c": -0.9,
|
||||
},
|
||||
{
|
||||
"label": "AGR_GZ_WeatherExposure_DrainageCool_01",
|
||||
"zone_id": "ground_zero_drainage_cool",
|
||||
"location_xy": unreal.Vector(-7200.0, 10400.0, 0.0),
|
||||
"z_offset": 260.0,
|
||||
"extent": unreal.Vector(7200.0, 5400.0, 1100.0),
|
||||
"exposure_multiplier": 1.1,
|
||||
"temperature_offset_c": -1.2,
|
||||
},
|
||||
]
|
||||
|
||||
ENVIRONMENT_VARIATION_ACTORS = [
|
||||
{
|
||||
"label": "AGR_GZ_EnvVar_Tree_Canopy_01",
|
||||
@@ -690,6 +720,30 @@ def spawn_environment_variation_actor(spec, height_values, materials):
|
||||
return actor
|
||||
|
||||
|
||||
def spawn_weather_exposure_zone(spec, height_values):
|
||||
location_xy = spec["location_xy"]
|
||||
z = terrain_z_cm(height_values, location_xy.x, location_xy.y) + spec.get("z_offset", 0.0)
|
||||
actor = unreal.AgrarianEditorAutomationLibrary.spawn_actor_in_editor_world(
|
||||
unreal.AgrarianWeatherExposureZone,
|
||||
unreal.Vector(location_xy.x, location_xy.y, z),
|
||||
unreal.Rotator(0.0, 0.0, 0.0),
|
||||
spec["label"],
|
||||
)
|
||||
if not actor:
|
||||
raise RuntimeError(f"Could not spawn {spec['label']}")
|
||||
|
||||
set_actor_label(actor, spec["label"])
|
||||
actor.set_editor_property("exposure_zone_id", spec["zone_id"])
|
||||
actor.set_editor_property("exposure_multiplier", spec["exposure_multiplier"])
|
||||
actor.set_editor_property("temperature_offset_c", spec["temperature_offset_c"])
|
||||
actor.exposure_volume.set_box_extent(spec["extent"], True)
|
||||
unreal.log(
|
||||
f"Placed {spec['label']} at {actor.get_actor_location()} "
|
||||
f"exposure x{spec['exposure_multiplier']} temp {spec['temperature_offset_c']} C"
|
||||
)
|
||||
return actor
|
||||
|
||||
|
||||
def main():
|
||||
if not unreal.EditorLevelLibrary.load_level(MAP_PATH):
|
||||
raise RuntimeError(f"Could not load map: {MAP_PATH}")
|
||||
@@ -700,6 +754,7 @@ def main():
|
||||
labels.update(LEGACY_DEMO_LIGHTING_LABELS)
|
||||
labels.update(spec["label"] for spec in BIOME_RESOURCE_ACTORS)
|
||||
labels.update(spec["label"] for spec in WATER_SOURCE_ACTORS)
|
||||
labels.update(spec["label"] for spec in WEATHER_EXPOSURE_ZONES)
|
||||
labels.update(spec["label"] for spec in ENVIRONMENT_VARIATION_ACTORS)
|
||||
labels.add(FOLIAGE_LABEL)
|
||||
remove_existing_demo_actors(labels)
|
||||
@@ -712,6 +767,8 @@ def main():
|
||||
spawn_demo_actor(spec, height_values, materials)
|
||||
for spec in WATER_SOURCE_ACTORS:
|
||||
spawn_demo_actor(spec, height_values, materials)
|
||||
for spec in WEATHER_EXPOSURE_ZONES:
|
||||
spawn_weather_exposure_zone(spec, height_values)
|
||||
for spec in ENVIRONMENT_VARIATION_ACTORS:
|
||||
spawn_environment_variation_actor(spec, height_values, materials)
|
||||
for spec in DEMO_ACTORS:
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import unreal
|
||||
|
||||
|
||||
MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test"
|
||||
EXPECTED_ZONES = {
|
||||
"AGR_GZ_WeatherExposure_Ridge_01": {
|
||||
"zone_id": "ground_zero_ridge_exposed",
|
||||
"exposure_multiplier_min": 1.4,
|
||||
"temperature_offset_max": -1.0,
|
||||
},
|
||||
"AGR_GZ_WeatherExposure_CoastalWind_01": {
|
||||
"zone_id": "ground_zero_coastal_wind",
|
||||
"exposure_multiplier_min": 1.2,
|
||||
"temperature_offset_max": -0.5,
|
||||
},
|
||||
"AGR_GZ_WeatherExposure_DrainageCool_01": {
|
||||
"zone_id": "ground_zero_drainage_cool",
|
||||
"exposure_multiplier_min": 1.05,
|
||||
"temperature_offset_max": -0.5,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_actor_label(actor):
|
||||
try:
|
||||
return actor.get_actor_label()
|
||||
except Exception:
|
||||
return actor.get_name()
|
||||
|
||||
|
||||
def main():
|
||||
if not unreal.EditorLevelLibrary.load_level(MAP_PATH):
|
||||
raise RuntimeError(f"Could not load map: {MAP_PATH}")
|
||||
|
||||
failures = []
|
||||
actors = unreal.EditorLevelLibrary.get_all_level_actors()
|
||||
zones_by_label = {
|
||||
get_actor_label(actor): actor
|
||||
for actor in actors
|
||||
if isinstance(actor, unreal.AgrarianWeatherExposureZone)
|
||||
}
|
||||
|
||||
if len(zones_by_label) != len(EXPECTED_ZONES):
|
||||
failures.append(f"expected {len(EXPECTED_ZONES)} weather exposure zones, found {len(zones_by_label)}")
|
||||
|
||||
for label, expected in EXPECTED_ZONES.items():
|
||||
zone = zones_by_label.get(label)
|
||||
if not zone:
|
||||
failures.append(f"missing weather exposure zone: {label}")
|
||||
continue
|
||||
|
||||
zone_id = str(zone.get_editor_property("exposure_zone_id"))
|
||||
if zone_id != expected["zone_id"]:
|
||||
failures.append(f"{label} zone id expected {expected['zone_id']}, got {zone_id}")
|
||||
|
||||
exposure_multiplier = zone.get_editor_property("exposure_multiplier")
|
||||
if exposure_multiplier < expected["exposure_multiplier_min"]:
|
||||
failures.append(
|
||||
f"{label} exposure multiplier expected >= {expected['exposure_multiplier_min']}, got {exposure_multiplier}"
|
||||
)
|
||||
|
||||
temperature_offset_c = zone.get_editor_property("temperature_offset_c")
|
||||
if temperature_offset_c > expected["temperature_offset_max"]:
|
||||
failures.append(
|
||||
f"{label} temperature offset expected <= {expected['temperature_offset_max']}, got {temperature_offset_c}"
|
||||
)
|
||||
|
||||
if not zone.exposure_volume:
|
||||
failures.append(f"{label} has no exposure volume")
|
||||
continue
|
||||
|
||||
extent = zone.exposure_volume.get_unscaled_box_extent()
|
||||
if min(extent.x, extent.y, extent.z) <= 0.0:
|
||||
failures.append(f"{label} has invalid exposure volume extent {extent}")
|
||||
|
||||
roadmap = unreal.Paths.convert_relative_path_to_full(unreal.Paths.project_dir()) + "AGRARIAN_DEVELOPMENT_ROADMAP.md"
|
||||
technical_design = unreal.Paths.convert_relative_path_to_full(unreal.Paths.project_dir()) + "Docs/TechnicalDesignDocument.md"
|
||||
for path, snippet in [
|
||||
(roadmap, "[x] Add weather exposure zones if needed"),
|
||||
(technical_design, "Weather exposure zones"),
|
||||
]:
|
||||
with open(path, "r", encoding="utf-8") as handle:
|
||||
text = handle.read()
|
||||
if snippet not in text:
|
||||
failures.append(f"{path} missing `{snippet}`")
|
||||
|
||||
if failures:
|
||||
raise RuntimeError("Weather exposure zone verification failed: " + "; ".join(failures))
|
||||
|
||||
unreal.log(
|
||||
"Weather exposure zone verification complete: "
|
||||
f"{len(zones_by_label)} zones with exposure multipliers and temperature offsets."
|
||||
)
|
||||
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user