Author the missing scenario content from the PLAN lists
Joke Shop - Reservation list without ID (guest list valid, ID missing) — denied. - Borrowed/mismatched ID (ID valid but mismatched) — denied. - Guest who refuses the wand screen: new `refuses_screening` event flag, copied onto NPCController, handled in _toggle_wand_screening (logs wand.refused, records a wand_refused event, small prop hit, panel stays closed). - Late arrival during the performance (ID + ticket, "arrive" intent). Studio - Filming-boundary event and a later repeat, both using the new `film_boundary` intent which maps to `steps_end` so the influencer stands past the posted line. - Celebrity arrival now pulls in a small crowd via a new `extra_spawns` event field (two tourists + an influencer), spawned through the normal path. Building - Filming-boundary event whose hint points at the body camera and request-reason verbs, plus an unclear-intent event that hints at asking for a reason. Engine support - Events may carry `hint` (string key logged on spawn), `extra_spawns`, and `refuses_screening`; 9 new localized hint strings. Tests/docs - Headless suite 139 -> 149 (test_scenario_content.gd) and a new smoke_scenario_content.gd that spawns the refusal and celebrity events through the real signal path. - README, TODO section moved to DONE, MEMORY. Version 0.2.13.
This commit is contained in:
1 parent
922a990c7a
commit
a2a0ded527
12 files changed
+426
-18
No files matched your search
@@ -0,0 +1,91 @@
|
||||
extends SceneTree
|
||||
## Scenario-content smoke: forces the authored Joke Shop refusal event and the
|
||||
## Studio celebrity arrival through the real spawn path, then checks the extra
|
||||
## bystanders, the hint log, and that a screening refusal is handled.
|
||||
##
|
||||
## Usage:
|
||||
## godot --headless --path . --script res://src/test/smoke_scenario_content.gd
|
||||
|
||||
const MAX_FRAMES := 900
|
||||
|
||||
var frame := 0
|
||||
var gm: Node = null
|
||||
var started := false
|
||||
var step := 0
|
||||
var failures: Array[String] = []
|
||||
|
||||
func _initialize() -> void:
|
||||
root.size = Vector2i(1280, 720)
|
||||
root.add_child(load("res://scenes/main.tscn").instantiate())
|
||||
|
||||
func _process(_delta: float) -> bool:
|
||||
frame += 1
|
||||
if gm == null:
|
||||
gm = root.find_child("GameManager", true, false)
|
||||
return false
|
||||
if not started:
|
||||
gm.call("_on_venue_selected", "joke_shop")
|
||||
started = true
|
||||
return false
|
||||
if frame > MAX_FRAMES:
|
||||
_fail("timeout")
|
||||
return true
|
||||
if frame < 120:
|
||||
return false
|
||||
match step:
|
||||
0:
|
||||
# Force the refusal event through the normal spawn signal.
|
||||
var event := _find_event(gm.selected_scenario.event_pool, "joke_refuses_wand")
|
||||
_check(not event.is_empty(), "the refusal event exists in the Joke Shop pool")
|
||||
var guest: Object = gm.selected_scenario.profile_for(int(event.get("npc_type", 0)))
|
||||
gm.coordinator.npc_spawn_requested.emit(guest, "enter", "smoke_refuser", event)
|
||||
_check(gm.npcs.size() > 0, "the refusing guest spawned")
|
||||
gm.call("_on_guard_target", gm.npcs[gm.npcs.size() - 1])
|
||||
var controller: Object = gm.npcs[gm.npcs.size() - 1].get_npc_controller()
|
||||
_check(controller.refuses_screening, "the refusal flag reached the controller")
|
||||
gm.call("_toggle_wand_screening")
|
||||
_check(not gm.wand_open, "screening does not open for someone who refuses")
|
||||
step = 1
|
||||
1:
|
||||
# Studio: celebrity arrival should bring extra bystanders.
|
||||
gm.call("_on_venue_selected", "tv_studio")
|
||||
step = 2
|
||||
2:
|
||||
if frame % 20 != 0:
|
||||
return false
|
||||
var event := _find_event(gm.selected_scenario.event_pool, "studio_celebrity_arrival")
|
||||
var before: int = gm.npcs.size()
|
||||
var guest: Object = gm.selected_scenario.profile_for(int(event.get("npc_type", 0)))
|
||||
gm.coordinator.npc_spawn_requested.emit(guest, "arrive", "smoke_celeb", event)
|
||||
var added: int = gm.npcs.size() - before
|
||||
_check(added >= 4, "celebrity arrival spawns the guest plus bystanders (%d)" % added)
|
||||
step = 3
|
||||
3:
|
||||
_finish()
|
||||
return true
|
||||
return false
|
||||
|
||||
func _find_event(pool: Array, id: String) -> Dictionary:
|
||||
for event in pool:
|
||||
if str((event as Dictionary).get("id", "")) == id:
|
||||
return event
|
||||
return {}
|
||||
|
||||
func _check(condition: bool, message: String) -> void:
|
||||
if condition:
|
||||
print("ok: " + message)
|
||||
else:
|
||||
_fail(message)
|
||||
|
||||
func _fail(message: String) -> void:
|
||||
failures.append(message)
|
||||
_finish()
|
||||
|
||||
func _finish() -> void:
|
||||
if failures.is_empty():
|
||||
print("SMOKE OK: authored scenario content")
|
||||
quit(0)
|
||||
else:
|
||||
for message in failures:
|
||||
printerr("SMOKE FAIL: " + message)
|
||||
quit(1)
|
||||
Reference in new issue
Block a user