Files
TheTree_mock/scripts/data/facility_definition.gd
T
Takeshi 5dde0c5ec2 Record original-alignment implementation and traceability checkpoint
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.
2026-09-30 23:52:24 +09:00

150 lines
5.0 KiB
GDScript

class_name FacilityDefinition
extends Resource
const LEGACY_SCHEMA_VERSION := 1
const DETAILED_SCHEMA_VERSION := 2
enum MapZone {
ANY,
ABOVE_GROUND,
BOUNDARY,
UNDERGROUND,
}
enum ViewLayer {
FRONT,
BACK,
}
@export_group("Identity")
@export_range(LEGACY_SCHEMA_VERSION, DETAILED_SCHEMA_VERSION, 1) var definition_schema_version := LEGACY_SCHEMA_VERSION
@export var id: StringName
@export var display_name := ""
@export_multiline var description := ""
@export var category: StringName = &"uncategorized"
@export var service_types: Array[StringName] = []
@export var default_service_type: StringName = &""
@export var service_profiles: Dictionary = {}
@export_group("Placement")
@export var zone := MapZone.ANY
@export var layer := ViewLayer.FRONT
@export var footprint := Vector2i.ONE
@export var allowed_rotations: Array[int] = [0, 90, 180, 270]
@export var guest_access_offsets: Array[Vector2i] = []
@export var staff_access_offsets: Array[Vector2i] = []
@export var required_connection_tags: Array[StringName] = []
@export var preferred_adjacency_tags: Array[StringName] = []
@export var forbidden_adjacency_tags: Array[StringName] = []
@export_group("Construction")
@export var construction_cost := {&"gold": 100, &"materials": 1}
@export var build_minutes := 60
@export_range(1, 3, 1) var weight_per_cell := 1
@export var pass_through := false
@export_range(0, 100, 1) var demolition_refund_percent := 25
@export_range(1, 5, 1) var max_level := 3
@export var upgrade_costs: Array[Dictionary] = []
@export_group("Upkeep and Power")
@export var maintenance_gold := 0
@export var maintenance_mana := 0
@export_range(0, 100, 1) var power_priority := 50
@export_group("Staffing")
@export var staff_min := 0
@export var staff_max := 0
@export var required_roles: Array[StringName] = []
@export var primary_skill: StringName = &"service"
@export_group("Service")
@export var customer_capacity := -1
@export var service_attribute: StringName = &""
@export var capacity := 0
@export var queue_capacity := 0
@export var base_service_minutes := 1
@export var base_quality := 50
@export var base_price := 0
@export var inventory_inputs: Dictionary = {}
@export var inventory_outputs: Dictionary = {}
@export var opening_schedule := {&"morning": true, &"day": true, &"night": true}
@export var policy_schema: Dictionary = {}
@export_group("Environment and Risk")
@export_range(0, 100, 1) var cleanliness_decay_per_service := 0
@export_range(0, 100, 1) var noise_per_service := 0
@export_range(-100, 100, 1) var beauty_effect := 0
@export_range(-100, 100, 1) var security_effect := 0
@export_range(-100, 100, 1) var concealment_effect := 0
@export_range(0, 100, 1) var heat_per_service := 0
@export var incident_weights: Dictionary = {}
@export_group("Audience and Content")
@export var allowed_guest_tags: Array[StringName] = []
@export var forbidden_guest_tags: Array[StringName] = []
@export var adult_content := false
@export var content_replacement_id: StringName = &""
@export_group("Progression")
@export var faith_per_service := 0
@export_range(1, 7, 1) var unlock_rank := 1
@export var research_requirements: Array[StringName] = []
@export_group("Analytics")
@export var statistics_keys: Array[StringName] = []
@export_group("Classification")
@export var tags: Array[StringName] = []
func is_valid() -> bool:
return not id.is_empty() \
and not display_name.is_empty() \
and footprint.x > 0 \
and footprint.y > 0 \
and build_minutes > 0 \
and weight_per_cell in [1, 2, 3] \
and not allowed_rotations.is_empty() \
and maintenance_gold >= 0 \
and maintenance_mana >= 0 \
and staff_min >= 0 \
and staff_max >= staff_min \
and customer_capacity >= -1 \
and service_attribute in [&"", &"appetite", &"relaxation", &"sexual", &"gambling"] \
and capacity >= 0 \
and queue_capacity >= 0 \
and base_service_minutes > 0 \
and base_price >= 0 \
and faith_per_service >= 0 \
and detailed_profile_is_valid()
func has_detailed_profile() -> bool:
return definition_schema_version == DETAILED_SCHEMA_VERSION
func detailed_profile_is_valid() -> bool:
if definition_schema_version == LEGACY_SCHEMA_VERSION:
return true
if definition_schema_version != DETAILED_SCHEMA_VERSION:
return false
if category.is_empty() or service_types.is_empty() or default_service_type.is_empty():
return false
if not service_types.has(default_service_type) or not service_profiles.has(default_service_type):
return false
if guest_access_offsets.is_empty() and staff_access_offsets.is_empty() and not pass_through:
return false
if demolition_refund_percent < 0 or demolition_refund_percent > 100:
return false
if max_level < 1 or max_level > 5 or upgrade_costs.size() != max_level - 1:
return false
if unlock_rank < 1 or unlock_rank > 7:
return false
for time_band: StringName in [&"morning", &"day", &"night"]:
if not opening_schedule.has(time_band) or not opening_schedule[time_band] is bool:
return false
if opening_schedule.size() != 3:
return false
if adult_content and (not tags.has(&"adult_only") or content_replacement_id.is_empty()):
return false
return true