84 lines
2.2 KiB
GDScript
84 lines
2.2 KiB
GDScript
class_name SpatialAddress
|
|
extends RefCounted
|
|
|
|
const SCHEMA_VERSION := 1
|
|
|
|
var _world_id: StringName
|
|
var _location_id: StringName
|
|
var _position: Vector3
|
|
|
|
|
|
func _init(
|
|
world_id: StringName = &"", location_id: StringName = &"", position: Vector3 = Vector3.ZERO
|
|
) -> void:
|
|
_world_id = world_id
|
|
_location_id = location_id
|
|
_position = position
|
|
|
|
|
|
static func create(
|
|
world_id: StringName = &"", location_id: StringName = &"", position: Vector3 = Vector3.ZERO
|
|
) -> SpatialAddress:
|
|
var address := SpatialAddress.new(world_id, location_id, position)
|
|
return address if address.is_valid() else null
|
|
|
|
|
|
static func from_dictionary(record_data: Dictionary) -> SpatialAddress:
|
|
if int(record_data.get("schema_version", -1)) != SCHEMA_VERSION:
|
|
return null
|
|
if not record_data.has_all(["world_id", "location_id", "position"]):
|
|
return null
|
|
var saved_position = record_data["position"]
|
|
if not saved_position is Array or saved_position.size() != 3:
|
|
return null
|
|
return create(
|
|
StringName(record_data["world_id"]),
|
|
StringName(record_data["location_id"]),
|
|
Vector3(float(saved_position[0]), float(saved_position[1]), float(saved_position[2]))
|
|
)
|
|
|
|
|
|
func is_valid() -> bool:
|
|
return is_finite(_position.x) and is_finite(_position.y) and is_finite(_position.z)
|
|
|
|
|
|
func get_world_id() -> StringName:
|
|
return _world_id
|
|
|
|
|
|
func get_location_id() -> StringName:
|
|
return _location_id
|
|
|
|
|
|
func get_position() -> Vector3:
|
|
return _position
|
|
|
|
|
|
func index_key() -> String:
|
|
var address_parts: Array = [String(_world_id), String(_location_id)]
|
|
if _location_id.is_empty():
|
|
address_parts.append([_position.x, _position.y, _position.z])
|
|
return JSON.stringify(address_parts)
|
|
|
|
|
|
func equals(other: SpatialAddress) -> bool:
|
|
return (
|
|
other != null
|
|
and _world_id == other.get_world_id()
|
|
and _location_id == other.get_location_id()
|
|
and (_location_id.is_empty() == false or _position == other.get_position())
|
|
)
|
|
|
|
|
|
func duplicate_address() -> SpatialAddress:
|
|
return SpatialAddress.new(_world_id, _location_id, _position)
|
|
|
|
|
|
func to_dictionary() -> Dictionary:
|
|
return {
|
|
"schema_version": SCHEMA_VERSION,
|
|
"world_id": String(_world_id),
|
|
"location_id": String(_location_id),
|
|
"position": [_position.x, _position.y, _position.z],
|
|
}
|