feat(m4c): shell consumes an injected character (seed stays the F6 fallback)
This commit is contained in:
@@ -19,6 +19,8 @@ extends Control
|
|||||||
const HttpTransport = preload("res://scripts/net/http_transport.gd")
|
const HttpTransport = preload("res://scripts/net/http_transport.gd")
|
||||||
|
|
||||||
var service: DmService = null # injection seam; real HttpTransport built if null
|
var service: DmService = null # injection seam; real HttpTransport built if null
|
||||||
|
var injected_log: CanonLog = null # injection seam; _build_seed_log() if null (F6/standalone)
|
||||||
|
var injected_state: GameState = null # injection seam; ShellState.seed() if null
|
||||||
|
|
||||||
var _state: ShellState
|
var _state: ShellState
|
||||||
var _log: CanonLog
|
var _log: CanonLog
|
||||||
@@ -40,8 +42,10 @@ func _ready() -> void:
|
|||||||
_fit_to_viewport()
|
_fit_to_viewport()
|
||||||
get_viewport().size_changed.connect(_fit_to_viewport)
|
get_viewport().size_changed.connect(_fit_to_viewport)
|
||||||
|
|
||||||
_state = ShellState.seed()
|
# The injected character wins; the seed calls are the F6/standalone fallback —
|
||||||
_log = _build_seed_log()
|
# same shape as `service == null` building a real transport below.
|
||||||
|
_state = ShellState.for_character(injected_state, injected_log) if injected_state != null else ShellState.seed()
|
||||||
|
_log = injected_log if injected_log != null else _build_seed_log()
|
||||||
_bind_state()
|
_bind_state()
|
||||||
|
|
||||||
if service == null:
|
if service == null:
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ extends "res://addons/gut/test.gd"
|
|||||||
const SCENE := "res://scenes/shell/MainWindowShell.tscn"
|
const SCENE := "res://scenes/shell/MainWindowShell.tscn"
|
||||||
const FakeTransport = preload("res://tests/doubles/fake_transport.gd")
|
const FakeTransport = preload("res://tests/doubles/fake_transport.gd")
|
||||||
const DmResponse = preload("res://scripts/net/dm_response.gd")
|
const DmResponse = preload("res://scripts/net/dm_response.gd")
|
||||||
|
const NewGame = preload("res://scripts/newgame/new_game.gd")
|
||||||
|
const ContentDB = preload("res://scripts/content/content_db.gd")
|
||||||
|
|
||||||
|
|
||||||
func _shell() -> MainWindowShell:
|
func _shell() -> MainWindowShell:
|
||||||
@@ -47,3 +49,36 @@ func test_shell_seed_player_has_a_real_race_and_calling():
|
|||||||
assert_true(Races.exists(node._log.player.race_id), "seed race must be a real race")
|
assert_true(Races.exists(node._log.player.race_id), "seed race must be a real race")
|
||||||
assert_true(Callings.exists(node._log.player.calling_id), "seed calling must be a real calling")
|
assert_true(Callings.exists(node._log.player.calling_id), "seed calling must be a real calling")
|
||||||
assert_ne(node._log.player.luck_descriptor, "", "the descriptor must not be lost to an arg-slot shift")
|
assert_ne(node._log.player.luck_descriptor, "", "the descriptor must not be lost to an arg-slot shift")
|
||||||
|
|
||||||
|
|
||||||
|
func _built_character():
|
||||||
|
var world = ContentDB.new()
|
||||||
|
world.load_from(ContentDB.default_content_root())
|
||||||
|
var origin = ContentDB.load_json(ContentDB.origin_path("deserter"))
|
||||||
|
var creation := {
|
||||||
|
"name": "Aldric", "race_id": "human", "calling_id": "sellsword",
|
||||||
|
"seed": 8675309, "spend": {},
|
||||||
|
"skills": ["athletics", "endurance"], "bonus_skill": "perception",
|
||||||
|
}
|
||||||
|
return NewGame.construct(origin, world, creation)
|
||||||
|
|
||||||
|
|
||||||
|
func _shell_with_character(res) -> MainWindowShell:
|
||||||
|
var node = load(SCENE).instantiate()
|
||||||
|
var transport = FakeTransport.new()
|
||||||
|
transport.set_response(DmResponse.ok(200, {"prose": "Rain on the cobbles."}))
|
||||||
|
node.service = DmService.new(transport, FallbackLibrary.new())
|
||||||
|
node.injected_log = res["log"]
|
||||||
|
node.injected_state = res["state"]
|
||||||
|
add_child_autofree(node)
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
func test_shell_shows_the_injected_character_not_the_seed():
|
||||||
|
var res = _built_character()
|
||||||
|
assert_true(res["ok"], str(res["errors"]))
|
||||||
|
var node := _shell_with_character(res)
|
||||||
|
assert_same(node._log, res["log"], "the injected canon log drives narration")
|
||||||
|
var expected := "HP %d / %d" % [res["state"].sheet.hp, res["state"].sheet.max_hp()]
|
||||||
|
assert_eq(node._hp.text, expected, "HP label derives from the real sheet")
|
||||||
|
assert_ne(node._hp.text, "HP 42 / 60", "NOT the seed's Vexcca vitals")
|
||||||
|
|||||||
Reference in New Issue
Block a user