Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
53 lines
2.1 KiB
GDScript
53 lines
2.1 KiB
GDScript
extends RefCounted
|
|
|
|
## Read-only presentation. Counts refer to people, never storage capacity.
|
|
static func describe(instance: Variant) -> Dictionary:
|
|
if instance == null:
|
|
return {}
|
|
var ids: Array[StringName] = []
|
|
for service: Variant in instance.active_services.values():
|
|
for id: StringName in service.guest_ids:
|
|
if not ids.has(id):
|
|
ids.append(id)
|
|
ids.sort_custom(func(a: StringName, b: StringName) -> bool: return String(a) < String(b))
|
|
return {&"operation": int(instance.operation_state), &"people": ids,
|
|
&"count": ids.size(), &"limit": int(instance.customer_capacity),
|
|
&"staff": instance.active_staff_ids.duplicate(), &"suspension": StringName(instance.suspension_reason)}
|
|
|
|
|
|
static func slots(rect: Rect2, p: float, id: StringName) -> Array[Vector2]:
|
|
# Each anchor owns a 16x18 person footprint. Overflow is reported as a count,
|
|
# not drawn on top of another person. Furniture uses these same anchors.
|
|
var result: Array[Vector2] = []
|
|
var step := 20.0 if id in [&"cafeteria", &"tavern"] else 16.0
|
|
var columns := maxi(int(rect.size.x / p / step), 1)
|
|
var rows := maxi(int((rect.size.y / p - 10.0) / 20.0), 1)
|
|
if id == &"chapel":
|
|
columns = mini(columns, 4)
|
|
rows = maxi(int((rect.size.y / p - 30.0) / 20.0), 1)
|
|
for row: int in rows:
|
|
for col: int in columns:
|
|
if id == &"chapel" and result.size() == 8:
|
|
return result
|
|
result.append(Vector2(rect.position.x + (float(col) + 0.5) * rect.size.x / columns,
|
|
rect.end.y - (4.0 + row * 20.0) * p))
|
|
return result
|
|
|
|
|
|
static func label(data: Dictionary, visible_count: int) -> String:
|
|
if data.is_empty():
|
|
return ""
|
|
var operation := int(data[&"operation"])
|
|
if operation == FacilityInstance.OperationState.SUSPENDED:
|
|
return "休止・摘発" if data[&"suspension"] == &"RAIDED" else "休止・破壊"
|
|
if operation == FacilityInstance.OperationState.INACTIVE:
|
|
return "未稼働"
|
|
var count := int(data[&"count"])
|
|
var limit := int(data[&"limit"])
|
|
var value := "利用%d/%d人" % [count, limit] if limit >= 0 else "利用%d人" % count
|
|
if limit > 0 and count >= limit:
|
|
value = "満員 " + value
|
|
if count > visible_count:
|
|
value += "(他%d人)" % (count - visible_count)
|
|
return value
|