Connect physical elevators and staff commutes to construction, saves, and cutaway UI
This commit is contained in:
@@ -37,8 +37,6 @@ const SUPPORTED_KINDS: Array[StringName] = [
|
||||
KIND_GUEST_CORRIDOR,
|
||||
KIND_SERVICE_CORRIDOR,
|
||||
KIND_STAFF_DOOR,
|
||||
]
|
||||
const UNSUPPORTED_VERTICAL_KINDS: Array[StringName] = [
|
||||
KIND_GUEST_ELEVATOR,
|
||||
KIND_SERVICE_ELEVATOR,
|
||||
]
|
||||
@@ -50,6 +48,8 @@ const KNOWN_KINDS: Array[StringName] = [
|
||||
KIND_SERVICE_ELEVATOR,
|
||||
]
|
||||
|
||||
const UNSUPPORTED_VERTICAL_KINDS: Array[StringName] = []
|
||||
const VERTICAL_KINDS: Array[StringName] = [KIND_GUEST_ELEVATOR, KIND_SERVICE_ELEVATOR]
|
||||
const REASON_UNSUPPORTED_VERTICAL_TOPOLOGY: StringName = &"UNSUPPORTED_VERTICAL_TOPOLOGY"
|
||||
const QUARANTINE_TRANSACTION_ROLLBACK: StringName = &"TRANSACTION_ROLLBACK_UNCERTAIN"
|
||||
const QUARANTINE_RESTORE_ROLLBACK: StringName = &"RESTORE_ROLLBACK_UNCERTAIN"
|
||||
@@ -60,6 +60,7 @@ const QUARANTINE_REASONS: Array[StringName] = [
|
||||
|
||||
const ROUTE_ENTITY_PREFIX := "infra.route:"
|
||||
const CONNECTOR_PREFIX := "infra.connector:"
|
||||
const SHAFT_OWNER_PREFIX := "infra.shaft:"
|
||||
const ADAPTER_PROJECT_REQUEST_PREFIX := "infra.project:"
|
||||
const ADAPTER_UNPROJECT_REQUEST_PREFIX := "infra.unproject:"
|
||||
const STAFF_ACCESS_ID: StringName = &"staff"
|
||||
@@ -168,16 +169,6 @@ func project_facility(
|
||||
var canonical_input: Dictionary = input_result[&"input"]
|
||||
var definition_input: Dictionary = canonical_input[&"definition"]
|
||||
var kind: StringName = definition_input[&"id"]
|
||||
if kind in UNSUPPORTED_VERTICAL_KINDS:
|
||||
return _failure(
|
||||
CommandResultType.Code.VALIDATION_FAILED,
|
||||
"Vertical facility projection is unsupported until ordinary adjacent walk edges can be suppressed safely.",
|
||||
{
|
||||
&"reason": REASON_UNSUPPORTED_VERTICAL_TOPOLOGY,
|
||||
&"definition_id": kind,
|
||||
&"unchanged": true,
|
||||
}
|
||||
)
|
||||
if kind not in SUPPORTED_KINDS:
|
||||
return _failure(CommandResultType.Code.INVALID_PAYLOAD, "Facility definition is not an infrastructure proxy.")
|
||||
var request_id := StringName(request_id_value)
|
||||
@@ -197,6 +188,7 @@ func project_facility(
|
||||
return _failure(CommandResultType.Code.DUPLICATE_COMMAND_ID, "Facility instance is already projected.")
|
||||
var record := _projection_from_project_input(canonical_input)
|
||||
if _source.has_entity(record[&"route_entity_id"]) \
|
||||
or _path.get_vertical_walk_blockers().has(StringName(SHAFT_OWNER_PREFIX + String(instance_id))) \
|
||||
or (not StringName(record[&"connector_id"]).is_empty() and _path.has_connector(record[&"connector_id"])):
|
||||
return _failure(CommandResultType.Code.DUPLICATE_COMMAND_ID, "Stable infrastructure ID collides with existing authoritative state.")
|
||||
if not _dependencies_match_current_state():
|
||||
@@ -244,6 +236,11 @@ func project_facility(
|
||||
dependency_capture,
|
||||
"Staff-door connector projection failed or callback tampering was detected."
|
||||
)
|
||||
if kind in VERTICAL_KINDS:
|
||||
var shaft_cells: Array[Vector3i] = []
|
||||
shaft_cells.assign(record[&"cells"])
|
||||
if not _path.set_vertical_walk_blockers(StringName(SHAFT_OWNER_PREFIX + String(instance_id)), shaft_cells) or not _owned_state_matches(guard_state):
|
||||
return _rollback_failure(owned_before, dependency_capture, "Elevator shaft projection failed or callback tampering was detected.")
|
||||
var candidate_projections := _projections.duplicate(true)
|
||||
candidate_projections[instance_id] = record.duplicate(true)
|
||||
if not _dependencies_match_projection_map(candidate_projections) \
|
||||
@@ -332,6 +329,9 @@ func unproject_facility(request_id_value: Variant, instance_id_value: Variant) -
|
||||
dependency_capture,
|
||||
"Staff-door connector removal failed or callback tampering was detected."
|
||||
)
|
||||
if record[&"kind"] in VERTICAL_KINDS:
|
||||
if not _path.remove_vertical_walk_blockers(StringName(SHAFT_OWNER_PREFIX + String(instance_id))) or not _owned_state_matches(guard_state):
|
||||
return _rollback_failure(owned_before, dependency_capture, "Elevator shaft unprojection failed or callback tampering was detected.")
|
||||
var route_result := _adapter.remove_route(
|
||||
StringName(ADAPTER_UNPROJECT_REQUEST_PREFIX + String(request_id)),
|
||||
StringName(record[&"route_entity_id"])
|
||||
@@ -977,6 +977,14 @@ func _projection_live_matches(record: Dictionary) -> bool:
|
||||
if connector_id.is_empty() or not _path.has_connector(connector_id):
|
||||
return false
|
||||
return _path.get_connector(connector_id) == _expected_staff_connector(record)
|
||||
if record[&"kind"] in VERTICAL_KINDS:
|
||||
var blockers := _path.get_vertical_walk_blockers()
|
||||
var owner_id := StringName(SHAFT_OWNER_PREFIX + String(record[&"instance_id"]))
|
||||
if not blockers.has(owner_id):
|
||||
return false
|
||||
var cells: Array = (blockers[owner_id] as Array).duplicate()
|
||||
cells.sort_custom(_cell_less)
|
||||
return connector_id.is_empty() and cells == record[&"cells"]
|
||||
return connector_id.is_empty()
|
||||
|
||||
|
||||
@@ -1009,16 +1017,22 @@ static func _has_managed_namespace_collision(
|
||||
) -> bool:
|
||||
var expected_routes: Dictionary = {}
|
||||
var expected_connectors: Dictionary = {}
|
||||
var expected_shafts: Dictionary = {}
|
||||
for record_value: Variant in projections.values():
|
||||
if not record_value is Dictionary:
|
||||
return true
|
||||
var record: Dictionary = record_value
|
||||
expected_routes[record[&"route_entity_id"]] = true
|
||||
if record[&"kind"] in VERTICAL_KINDS:
|
||||
expected_shafts[StringName(SHAFT_OWNER_PREFIX + String(record[&"instance_id"]))] = true
|
||||
if not StringName(record[&"connector_id"]).is_empty():
|
||||
expected_connectors[record[&"connector_id"]] = true
|
||||
for entity_id: StringName in source_service.get_entity_ids(source_service.CATEGORY_ROUTE):
|
||||
if String(entity_id).begins_with(ROUTE_ENTITY_PREFIX) and not expected_routes.has(entity_id):
|
||||
return true
|
||||
for owner_id: Variant in path_service.get_vertical_walk_blockers():
|
||||
if String(owner_id).begins_with(SHAFT_OWNER_PREFIX) and not expected_shafts.has(owner_id):
|
||||
return true
|
||||
var path_snapshot := path_service.create_snapshot()
|
||||
var connector_rows: Variant = path_snapshot.get(&"connectors", null)
|
||||
if not connector_rows is Array:
|
||||
|
||||
Reference in New Issue
Block a user