class_name RegionalStateSupport extends RefCounted static func normalize_id_array(values: Array, allow_empty: bool = true) -> Variant: var seen: Dictionary = {} var normalized: Array[String] = [] for value: Variant in values: if not value is String and not value is StringName: return null var id := String(value) if id.is_empty() or seen.has(id): return null seen[id] = true normalized.append(id) if not allow_empty and normalized.is_empty(): return null normalized.sort() return normalized static func normalize_history_event_ids(values: Array) -> Variant: var seen: Dictionary = {} var normalized: Array[int] = [] for value: Variant in values: if not value is int: return null var event_id := int(value) if event_id < 0 or seen.has(event_id): return null seen[event_id] = true normalized.append(event_id) normalized.sort() return normalized static func normalize_amount_ledger(values: Dictionary) -> Variant: var source_keys: Dictionary = {} for raw_key: Variant in values: if not raw_key is String and not raw_key is StringName: return null var key := String(raw_key) if key.is_empty() or source_keys.has(key): return null var raw_amount: Variant = values[raw_key] if not raw_amount is int and not raw_amount is float: return null var amount := float(raw_amount) if not is_finite(amount) or amount < 0.0: return null source_keys[key] = raw_key var keys: Array = source_keys.keys() keys.sort() var normalized: Dictionary = {} for key: String in keys: normalized[key] = float(values[source_keys[key]]) return normalized static func normalize_count_ledger(values: Dictionary) -> Variant: var source_keys: Dictionary = {} for raw_key: Variant in values: if not raw_key is String and not raw_key is StringName: return null var key := String(raw_key) if key.is_empty() or source_keys.has(key): return null var raw_count: Variant = values[raw_key] if not raw_count is int or int(raw_count) <= 0: return null source_keys[key] = raw_key var keys: Array = source_keys.keys() keys.sort() var normalized: Dictionary = {} for key: String in keys: normalized[key] = int(values[source_keys[key]]) return normalized static func amount_ledger_total(values: Dictionary) -> float: var total := 0.0 for value: Variant in values.values(): total += float(value) return total static func normalize_address(value: Variant) -> Variant: var address: SpatialAddress if value is SpatialAddress: address = value as SpatialAddress elif value is Dictionary: address = SpatialAddress.from_dictionary(value) if address == null or not address.is_valid(): return null return address.to_dictionary() static func address_from_data(value: Variant) -> SpatialAddress: if not value is Dictionary: return null return SpatialAddress.from_dictionary(value) static func address_matches( value: Variant, expected_world_id: StringName, expected_location_id: StringName ) -> bool: var address := address_from_data(value) return ( address != null and address.get_world_id() == expected_world_id and address.get_location_id() == expected_location_id ) static func copy_string_array(values: Variant) -> Array[StringName]: var copied: Array[StringName] = [] if not values is Array: return copied for value: Variant in values: copied.append(StringName(value)) return copied static func copy_int_array(values: Variant) -> Array[int]: var copied: Array[int] = [] if not values is Array: return copied for value: Variant in values: copied.append(int(value)) return copied static func pair_key(first_id: StringName, second_id: StringName) -> String: var first := String(first_id) var second := String(second_id) return "%s\u001f%s" % [first, second] if first < second else "%s\u001f%s" % [second, first] static func is_non_empty_id(value: StringName) -> bool: return not value.is_empty() static func is_valid_tick(value: int, allow_unset: bool = false) -> bool: return value >= (-1 if allow_unset else 0)