Add explicit stairs and measure elevator congestion with real actors

This commit is contained in:
Takeshi
2026-09-09 14:26:38 +09:00
parent e246ce382b
commit fb4ad23190
57 changed files with 3030 additions and 162 deletions
+19 -5
View File
@@ -82,12 +82,15 @@ func _read_progress() -> Dictionary:
if reception == null:
return _build_step(&"reception", &"reception", "1/6 受付をつくる", "表の地表階に受付を配置します。完成した受付の上に客室を増築できます。", &"build_reception")
if rooms.is_empty():
return _build_step(&"room", &"standard_room", "2/6 客室をつくる", "受付が支えになる位置に一般客室を配置します。", &"build_room")
return _build_step(&"room", &"standard_room", "2/6 客室をつくる", "受付が支えになる位置に一般客室を配置します。上階へは客用階段で道をつなぎます。", &"build_room")
var accessible_room := false
for room: FacilityInstance in rooms:
accessible_room = accessible_room or room.access_available
if not reception.access_available or not accessible_room:
return _step(&"access", "3/6 道をつなぐ", "客室の出入口まで客用通路をつなぎます。施設を選択すると、通行不可など営業できない理由を確認できます。", &"build_corridor", "客用通路を選ぶ")
accessible_room = accessible_room or _can_reach_facility(room)
if not _can_reach_facility(reception) or not accessible_room:
var upper_room := false
for room: FacilityInstance in rooms:
upper_room = upper_room or room.origin.y != 0
return _step(&"access", "3/6 道をつなぐ", "上下階は客用階段でつなぎます。上階のマスに置くと、直下の通路へ接続します。同じ階は客用通路を延ばし、客室の左右の出入口まで道をつなぎましょう。", &"build_stairs" if upper_room else &"build_corridor", "客用階段を選ぶ" if upper_room else "客用通路を選ぶ")
if not _has_reception_assignment(reception):
return _step(&"staff", "4/6 受付係を配属", "従業員から受付係を雇い、雇用済み一覧でこの受付と勤務帯を選び「配属・勤務帯を変更」を押します。", &"staff", "従業員を開く")
if first_sale < 0:
@@ -95,8 +98,19 @@ func _read_progress() -> Dictionary:
return _step(&"close", "6/6 翌朝の決算へ", "最初の宿泊売上が入りました。06:00に営業日が締まり、給与・利益・未払いを帳簿で確認できます。", &"resume" if _clock.paused else &"ledger", "時間を進める" if _clock.paused else "帳簿を見る")
func _can_reach_facility(facility: FacilityInstance) -> bool:
if not facility.access_available:
return false
# Runtime uses the same public entrance and access cells as real guests.
# Component-only guide fixtures retain their explicit availability flags.
if _runtime.has_method(&"get_facility_access_report"):
var report: Dictionary = _runtime.call(&"get_facility_access_report", facility.instance_id)
return bool(report.get(&"reachable", false))
return true
func _reception_score(facility: FacilityInstance) -> int:
return (2 if facility.access_available else 0) + (1 if _has_reception_assignment(facility) else 0)
return (2 if _can_reach_facility(facility) else 0) + (1 if _has_reception_assignment(facility) else 0)
func _has_reception_assignment(reception: FacilityInstance) -> bool:
+27
View File
@@ -17,6 +17,9 @@ static func tile(canvas: CanvasItem, texture: Texture2D, index: int, target: Rec
static func room(canvas: CanvasItem, rect: Rect2, id: StringName, pixel: float, dungeon: Texture2D, town: Texture2D, back: bool, decoration_seed := 0) -> void:
var p := pixel
if id in [&"guest_stairs", &"service_stairs"]:
stairs(canvas, rect, p, id == &"service_stairs")
return
if id in [&"guest_corridor", &"service_corridor"]:
canvas.draw_rect(rect, Color("c6b999") if not back else Color("a6b6a0"))
canvas.draw_rect(Rect2(rect.position.x,rect.end.y-4*p,rect.size.x,3*p),WOOD_LIGHT)
@@ -101,6 +104,30 @@ static func room(canvas: CanvasItem, rect: Rect2, id: StringName, pixel: float,
table(canvas, Vector2(mid-6*p, floor_y-7*p), p)
## The upper landing owns a short flight down to the floor below. Six square
## treads and a stepped handrail keep the shape legible at the 16 px room scale.
static func stairs(canvas: CanvasItem, rect: Rect2, p: float, staff_only: bool, compact := false) -> void:
if not compact:
canvas.draw_rect(rect, INK)
canvas.draw_rect(rect.grow(-p), Color("c7c6a6") if not staff_only else Color("a8b6aa"))
canvas.draw_rect(Rect2(rect.position.x, rect.end.y-4*p, rect.size.x, 3*p), WOOD)
canvas.draw_rect(Rect2(rect.position.x, rect.end.y-p, rect.size.x, p), INK)
var at := Vector2(rect.get_center().x-6*p, rect.end.y-5*p)
var tread := Color("d8bf89") if not staff_only else Color("aec0bf")
var rise := Color("8a7155") if not staff_only else Color("617f82")
for step: int in range(6):
var top := at + Vector2(step*2, -step*2)*p
canvas.draw_rect(Rect2(top, Vector2(2, 2+step*2)*p), rise)
canvas.draw_rect(Rect2(top, Vector2(3, 1)*p), tread)
canvas.draw_rect(Rect2(top+Vector2(0,-5)*p, Vector2(2,1)*p), INK)
if step % 2 == 0:
canvas.draw_rect(Rect2(top+Vector2(0,-4)*p, Vector2(1,4)*p), WOOD if not staff_only else TEAL)
canvas.draw_rect(Rect2(at+Vector2(10,-11)*p, Vector2(3,2)*p), tread)
if staff_only and not compact:
canvas.draw_rect(Rect2(rect.position+Vector2(2,2)*p, Vector2(3,3)*p), TEAL)
canvas.draw_rect(Rect2(rect.position+Vector2(3,3)*p, Vector2(1,1)*p), CREAM)
## Static shaft rails remain when a car is stopped or the transport service is
## unavailable. The car itself is drawn once from its authoritative trip state.
static func elevator_shaft(canvas: CanvasItem, rect: Rect2, p: float, back: bool) -> void:
+8 -8
View File
@@ -31,26 +31,26 @@ func prepare(runtime: Variant, clock: Variant, tree: SceneTree) -> bool:
return false
for facility: Dictionary in _runtime.construction_service.get_facilities():
facility_ids[facility[&"definition_id"]] = facility[&"instance_id"]
# Four rooms sit on the completed reception and dining structure. Corridor
# cells are ordinary supported construction; unfinished elevator topology is
# deliberately excluded from this scenario.
# Four rooms sit on the completed reception and dining structure. One
# continuous, paid staircase in the center joins all three upper landings;
# same-floor corridor construction links the rooms on either side.
for x: int in [-8, -6, 2, 4]:
if not _build(&"standard_room", Vector3i(x, 2, 0)):
return false
for x: int in range(-4, 2):
if not _build(&"guest_corridor", Vector3i(x, 1, 0)):
if not _build(&"guest_stairs" if x == -4 else &"guest_corridor", Vector3i(x, 1, 0)):
return false
if not await advance(60):
return false
for x: int in range(-4, 2):
if not _build(&"guest_corridor", Vector3i(x, 2, 0)):
if not _build(&"guest_stairs" if x == -4 else &"guest_corridor", Vector3i(x, 2, 0)):
return false
if not await advance(10):
return false
# This walkway follows the upper side of the rooms. Its authoritative Path
# projection allows real guests and workers to move between the three levels.
# This walkway follows the upper side of the rooms. The final stair segment
# gives real guests and the cleaner a legal route to this floor.
for x: int in range(-8, 6):
if not _build(&"guest_corridor", Vector3i(x, 3, 0)):
if not _build(&"guest_stairs" if x == -4 else &"guest_corridor", Vector3i(x, 3, 0)):
return false
if not await advance(10):
return false