feat(m4c): ShellState.for_character derives vitals+location from the real character
This commit is contained in:
@@ -34,3 +34,19 @@ static func seed() -> ShellState:
|
|||||||
s.location_label = "THE LOWER WARD"
|
s.location_label = "THE LOWER WARD"
|
||||||
s.dock_open = true
|
s.dock_open = true
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
static func for_character(state: GameState, log: CanonLog) -> ShellState:
|
||||||
|
## The real HUD state for a constructed character. Vitals + location come from
|
||||||
|
## the character (§2 — code owns them); turn_order/consumables/round_label are
|
||||||
|
## still seed() placeholders because combat (M5) and inventory (M7) own those.
|
||||||
|
var s := ShellState.seed() # start from the placeholders, then overwrite what is real
|
||||||
|
s.vitals = {
|
||||||
|
"hp": state.sheet.hp,
|
||||||
|
"hp_max": state.sheet.max_hp(),
|
||||||
|
"mp": state.sheet.mp,
|
||||||
|
"mp_max": state.sheet.max_mp(),
|
||||||
|
"purse_copper": state.purse_copper,
|
||||||
|
}
|
||||||
|
s.location_label = log.location.name
|
||||||
|
return s
|
||||||
|
|||||||
@@ -1,5 +1,46 @@
|
|||||||
extends "res://addons/gut/test.gd"
|
extends "res://addons/gut/test.gd"
|
||||||
|
|
||||||
|
const NewGame = preload("res://scripts/newgame/new_game.gd")
|
||||||
|
const ContentDB = preload("res://scripts/content/content_db.gd")
|
||||||
|
|
||||||
|
|
||||||
|
func _built():
|
||||||
|
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 test_for_character_derives_vitals_and_location_from_the_real_character():
|
||||||
|
var res = _built()
|
||||||
|
assert_true(res["ok"], str(res["errors"]))
|
||||||
|
var state = res["state"]
|
||||||
|
var log = res["log"]
|
||||||
|
var s := ShellState.for_character(state, log)
|
||||||
|
assert_eq(s.vitals["hp"], state.sheet.hp, "hp from the sheet")
|
||||||
|
assert_eq(s.vitals["hp_max"], state.sheet.max_hp(), "hp_max from the sheet")
|
||||||
|
assert_eq(s.vitals["mp"], state.sheet.mp, "mp from the sheet")
|
||||||
|
assert_eq(s.vitals["mp_max"], state.sheet.max_mp(), "mp_max from the sheet")
|
||||||
|
assert_eq(s.vitals["purse_copper"], state.purse_copper, "purse from origin grants (47c)")
|
||||||
|
assert_eq(s.location_label, log.location.name, "location from the canon log")
|
||||||
|
assert_ne(s.vitals["hp_max"], 60, "NOT the seed's hardcoded 60 — this is a real L1 sheet")
|
||||||
|
|
||||||
|
|
||||||
|
func test_for_character_keeps_the_seed_placeholders_for_combat_and_inventory():
|
||||||
|
# turn_order/consumables/round_label have no real source yet (M5/M7 own them);
|
||||||
|
# for_character must reuse seed()'s placeholders, not invent its own.
|
||||||
|
var res = _built()
|
||||||
|
var s := ShellState.for_character(res["state"], res["log"])
|
||||||
|
var seed := ShellState.seed()
|
||||||
|
assert_eq(s.turn_order.size(), seed.turn_order.size(), "turn rail is still the placeholder")
|
||||||
|
assert_eq(s.consumables, seed.consumables, "consumables are still the placeholder")
|
||||||
|
assert_eq(s.round_label, seed.round_label, "round label is still the placeholder")
|
||||||
|
|
||||||
|
|
||||||
func test_turn_entry_holds_fields():
|
func test_turn_entry_holds_fields():
|
||||||
var e := TurnEntry.new("DW", 12, &"ally")
|
var e := TurnEntry.new("DW", 12, &"ally")
|
||||||
|
|||||||
Reference in New Issue
Block a user