Add the campaign shell, pause-safe checkpoint resume, post-shift campaign continue, confirmed campaign reset, difficulty presets, searchable Help, content-matrix validation, recovery events, contextual dialogue, policy/debrief context and eligible-event previews. Extend persistence with atomic separate files and add campaign/checkpoint/tutorial smokes. Headless 247/247, Python 94/94, tutorial/campaign/session/scenario smokes green.
45 lines
2.3 KiB
GDScript
45 lines
2.3 KiB
GDScript
extends RefCounted
|
|
## Mid-shift checkpoint data survives a JSON round-trip and restores the
|
|
## coordinator's systems without replaying completed interactions.
|
|
|
|
const ScenarioFactory := preload("res://src/content/scenario_factory.gd")
|
|
const ShiftCoordinator := preload("res://src/core/shift_coordinator.gd")
|
|
const IncidentRecorder := preload("res://src/core/incident_recorder.gd")
|
|
const Rules := preload("res://src/core/rules.gd")
|
|
|
|
func test_coordinator_snapshot_round_trip() -> bool:
|
|
var scenario := ScenarioFactory.hollywood_building()
|
|
var first := ShiftCoordinator.new()
|
|
first.setup(scenario, 900.0, 42)
|
|
first.start()
|
|
first.elapsed_s = 123.0
|
|
first.recorder.start_incident("guest", "focus")
|
|
first.recorder.add_escalation("guest", Rules.Level.FORMAL_WARNING, "warning")
|
|
first.recorder.close_incident("guest", "peaceful")
|
|
first.reputation.apply("peaceful", 5.0, "test")
|
|
first.crowd.mood = 0.4
|
|
first.radio.battery = 70.0
|
|
var payload: Dictionary = JSON.parse_string(JSON.stringify(first.snapshot()))
|
|
var second := ShiftCoordinator.new()
|
|
second.setup(scenario, 900.0, 42)
|
|
second.restore(payload)
|
|
var a := TestUtils.check(is_equal_approx(second.elapsed_s, 123.0), "elapsed time restores")
|
|
var b := TestUtils.check_eq(second.recorder.to_dict()["open_count"], 0, "incident state restores")
|
|
var c := TestUtils.check_eq(second.recorder.to_dict()["incidents"].size(), 1,
|
|
"closed incidents restore")
|
|
var d := TestUtils.check(is_equal_approx(second.reputation.rating, 75.0), "reputation restores")
|
|
var e := TestUtils.check(is_equal_approx(second.crowd.mood, 0.4), "crowd mood restores")
|
|
var f := TestUtils.check(is_equal_approx(second.radio.battery, 70.0), "radio battery restores")
|
|
return a and b and c and d and e and f
|
|
|
|
func test_open_incident_snapshot_restores_evidence() -> bool:
|
|
var recorder := IncidentRecorder.new()
|
|
recorder.start_incident("guest", "focus")
|
|
recorder.add_access_evidence("guest", {"kind": "wristband", "status": "valid"})
|
|
var restored := IncidentRecorder.new()
|
|
restored.restore(JSON.parse_string(JSON.stringify(recorder.snapshot())))
|
|
var a := TestUtils.check(restored.has_open_incident("guest"), "open incident restores")
|
|
restored.add_event("guest", {"type": "player_action"})
|
|
var b := TestUtils.check(restored.open_incidents_count() == 1, "restored incident accepts events")
|
|
return a and b
|