Build distinct Joke Shop and TV Studio venues
Add the alley walls, warm lantern, shutters, dumpster, AC clutter and door step for the Joke Shop. Build the studio stone facade, bulb canopy, glossy black car, stanchions and barriers. Rebuild only the world container when the venue changes, so the guard and UI survive; add per-venue navigation checks. Capture gallery shots 12/13, update the concept mapping and docs. Headless 231/231, Python 87/87, screenshot gate 13 good/0 bad. The vision-judge retry is tracked separately because the API key is invalid.
This commit is contained in:
1 parent
4cca2af2dd
commit
8b0845bcce
25 files changed
+347
-87
No files matched your search
@@ -207,6 +207,36 @@ func _advance() -> void:
|
||||
_shoot("11-precision-walk.png")
|
||||
Input.action_release("move_forward")
|
||||
Input.action_release("walk_slow")
|
||||
if gm != null:
|
||||
gm.switch_scenario("joke_shop")
|
||||
gm.coordinator.elapsed_s = 620.0
|
||||
state = 12
|
||||
state_frames = 0
|
||||
12:
|
||||
if state_frames == 1 and gm != null:
|
||||
gm.guard.global_position = Vector3(-1.5, 0.1, 8.5)
|
||||
gm.guard.rotation.y = deg_to_rad(-5.0)
|
||||
gm.guard.head.rotation.x = deg_to_rad(2.0)
|
||||
gm.hud.clear_log()
|
||||
gm.hud.set_escalation(0)
|
||||
gm.hud.set_body_camera(false)
|
||||
if state_frames >= 90:
|
||||
_shoot("12-joke-shop.png")
|
||||
if gm != null:
|
||||
gm.switch_scenario("tv_studio")
|
||||
gm.coordinator.elapsed_s = 620.0
|
||||
state = 13
|
||||
state_frames = 0
|
||||
13:
|
||||
if state_frames == 1 and gm != null:
|
||||
gm.guard.global_position = Vector3(0, 0.1, 14.0)
|
||||
gm.guard.rotation.y = 0.0
|
||||
gm.guard.head.rotation.x = deg_to_rad(2.0)
|
||||
gm.hud.clear_log()
|
||||
gm.hud.set_escalation(0)
|
||||
gm.hud.set_body_camera(false)
|
||||
if state_frames >= 120:
|
||||
_shoot("13-studio-arrival.png")
|
||||
quit(0)
|
||||
|
||||
## Put the guard a couple of steps in front of the target so a staged UI capture
|
||||
|
||||
@@ -52,6 +52,38 @@ func test_venue_geometry_specs_are_distinct_and_defaulted() -> bool:
|
||||
root.free()
|
||||
return a and b and c and d and e and f and g
|
||||
|
||||
func test_navigation_mesh_matches_each_venue_bounds() -> bool:
|
||||
var problems: Array[String] = []
|
||||
for id in ["hollywood_building", "joke_shop", "tv_studio"]:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root, id)
|
||||
builder.build()
|
||||
var region := root.find_child("NavRegion", true, false) as NavigationRegion3D
|
||||
if region == null or region.navigation_mesh == null:
|
||||
problems.append("%s has no navmesh" % id)
|
||||
root.free()
|
||||
continue
|
||||
var verts := region.navigation_mesh.get_vertices()
|
||||
var nav_min: Vector2 = builder.spec["nav_min"]
|
||||
var nav_max: Vector2 = builder.spec["nav_max"]
|
||||
var min_x := 999.0
|
||||
var max_x := -999.0
|
||||
var min_z := 999.0
|
||||
var max_z := -999.0
|
||||
for v in verts:
|
||||
min_x = minf(min_x, v.x)
|
||||
max_x = maxf(max_x, v.x)
|
||||
min_z = minf(min_z, v.z)
|
||||
max_z = maxf(max_z, v.z)
|
||||
if absf(min_x - nav_min.x) > 0.01 or absf(max_x - nav_max.x) > 0.01 \
|
||||
or absf(min_z - nav_min.y) > 0.01 or absf(max_z - nav_max.y) > 0.01:
|
||||
problems.append("%s navmesh %s does not match spec %s" % [
|
||||
id, str(Vector4(min_x, max_x, min_z, max_z)),
|
||||
str(Vector4(nav_min.x, nav_max.x, nav_min.y, nav_max.y))])
|
||||
root.free()
|
||||
return TestUtils.check(problems.is_empty(),
|
||||
"each venue builds its own navigation bounds (%s)" % str(problems))
|
||||
|
||||
func test_phase_lighting_config_covered() -> bool:
|
||||
var ok := true
|
||||
for phase in [Rules.Phase.EARLY, Rules.Phase.MIDDAY, Rules.Phase.EVENING, Rules.Phase.LATE]:
|
||||
|
||||
Reference in new issue
Block a user