Implement control pass: focus cone, action wheel, named inputs, boot fixes
- Venue-correct access artifacts (AccessLoadout) and screened-aware verify - Cone focus on NPC heads with billboarded ring + display name (ADR-0008) - Action wheel with de-escalation-first slices (ADR-0009); Esc/RMB cancel - Procedural NPC face/hair/neck/shoes (ADR-0010); named input actions - Fix GameManager parse error (radial typed as ActionRadial) - Fix first-person camera height and guard spawning inside the building - Move building volume back so the door/awning/marquee are visible - Pull the event scheduler once per simulated second; cap live NPCs - Regenerate README screenshots; update TODO/DONE/MEMORY/README; 77 tests Adds src/test/smoke_focus_radial.gd for the windowed focus/radial smoke.
This commit is contained in:
1 parent
69484866db
commit
f11b441c07
28 files changed
+1433
-249
No files matched your search
@@ -31,8 +31,9 @@ func _process(_delta: float) -> bool:
|
||||
quit(1)
|
||||
return true
|
||||
if gm != null and not camera_staged:
|
||||
gm.guard.global_position = Vector3(0, 1.6, 5.0)
|
||||
gm.guard.head.rotation.x = deg_to_rad(-8.0)
|
||||
gm.guard.global_position = Vector3(0, 0.1, 10.5)
|
||||
gm.guard.rotation.y = 0.0
|
||||
gm.guard.head.rotation.x = deg_to_rad(2.0)
|
||||
camera_staged = true
|
||||
if frames > MAX_FRAMES:
|
||||
print("timeout reached")
|
||||
@@ -54,6 +55,7 @@ func _advance() -> void:
|
||||
# Wait for a nearby NPC so the interaction HUD has a target.
|
||||
if gm != null and gm.npcs.size() > 0:
|
||||
gm.call("_cycle_nearby_target")
|
||||
_face_target()
|
||||
targeted = true
|
||||
state = 2
|
||||
state_frames = 0
|
||||
@@ -61,6 +63,7 @@ func _advance() -> void:
|
||||
if state_frames >= 30:
|
||||
_shoot("02-targeting-npc.png")
|
||||
if targeted and gm != null:
|
||||
_face_target()
|
||||
gm.call("_toggle_inspection")
|
||||
state = 3
|
||||
state_frames = 0
|
||||
@@ -80,6 +83,8 @@ func _advance() -> void:
|
||||
# Close the radio form, then jump the shift to the LATE phase.
|
||||
if gm != null:
|
||||
gm.radio_panel.hide()
|
||||
gm.guard.rotation.y = 0.0
|
||||
gm.guard.head.rotation.x = deg_to_rad(2.0)
|
||||
gm.coordinator.elapsed_s = 750.0
|
||||
state = 5
|
||||
state_frames = 0
|
||||
@@ -87,6 +92,8 @@ func _advance() -> void:
|
||||
# Let the phase transition (and street lamps / marquee) settle, then
|
||||
# take the night avenue shot.
|
||||
if state_frames >= 90:
|
||||
gm.guard.rotation.y = 0.0
|
||||
gm.guard.head.rotation.x = deg_to_rad(2.0)
|
||||
_shoot("05-late-night-avenue.png")
|
||||
if gm != null:
|
||||
gm.call("_toggle_flashlight")
|
||||
@@ -98,6 +105,17 @@ func _advance() -> void:
|
||||
state = 7
|
||||
quit(0)
|
||||
|
||||
func _face_target() -> void:
|
||||
var target: Node3D = gm.targeted_npc
|
||||
if target == null:
|
||||
return
|
||||
var to: Vector3 = target.global_position - gm.guard.global_position
|
||||
to.y = 0.0
|
||||
if to.length() < 0.01:
|
||||
return
|
||||
gm.guard.rotation.y = atan2(-to.x, -to.z)
|
||||
gm.guard.head.rotation.x = deg_to_rad(-4.0)
|
||||
|
||||
func _shoot(file_name: String) -> void:
|
||||
var dir := DirAccess.open("user://")
|
||||
if dir == null or not dir.dir_exists("screenshots"):
|
||||
|
||||
Reference in new issue
Block a user