Files
TheTree_mock/scripts/authority/evidence.gd
T

171 lines
5.3 KiB
GDScript

class_name AuthorityEvidence
extends RefCounted
enum DiscoveryMethod {
LATENT,
REACHED,
LINE_OF_SIGHT,
TRUSTED_SOURCE,
KNOWN_ILLEGAL,
}
var evidence_id: StringName = &""
var incident_id: StringName = &""
var source: StringName = &""
var severity := 0
var facility_id: StringName = &""
var location_cell := Vector3i.ZERO
var created_at := 0
var expires_at := -1
var discovered_at := -1
var discovered_by: StringName = &""
var discovery_method: DiscoveryMethod = DiscoveryMethod.LATENT
var revision := 0
func configure(
p_evidence_id: StringName,
p_source: StringName,
p_severity: int,
options: Dictionary = {}
) -> AuthorityEvidence:
evidence_id = p_evidence_id
incident_id = StringName(_value(options, &"incident_id", &""))
source = p_source
severity = clampi(p_severity, 0, 100)
facility_id = StringName(_value(options, &"facility_id", &""))
location_cell = _vector3i(_value(options, &"location_cell", Vector3i.ZERO))
created_at = maxi(int(_value(options, &"created_at", 0)), 0)
expires_at = int(_value(options, &"expires_at", -1))
discovered_at = int(_value(options, &"discovered_at", -1))
discovered_by = StringName(_value(options, &"discovered_by", &""))
discovery_method = _method_from_value(_value(options, &"discovery_method", DiscoveryMethod.LATENT))
revision = maxi(int(_value(options, &"revision", 0)), 0)
return self
func is_discovered() -> bool:
return discovered_at >= 0
func is_expired(absolute_minute: int) -> bool:
return expires_at >= 0 and absolute_minute >= expires_at
func mark_discovered(
inspector_id: StringName,
absolute_minute: int,
method: DiscoveryMethod
) -> bool:
if is_discovered() or inspector_id.is_empty() or absolute_minute < created_at:
return false
if method == DiscoveryMethod.LATENT:
return false
discovered_at = absolute_minute
discovered_by = inspector_id
discovery_method = method
revision += 1
return true
func is_valid() -> bool:
if evidence_id.is_empty() or source.is_empty() or severity < 0 or severity > 100:
return false
if created_at < 0 or expires_at < -1 or revision < 0:
return false
if expires_at >= 0 and expires_at < created_at:
return false
if discovered_at < -1:
return false
if discovered_at >= 0:
if discovered_by.is_empty() or discovery_method == DiscoveryMethod.LATENT:
return false
if discovered_at < created_at:
return false
else:
if not discovered_by.is_empty() or discovery_method != DiscoveryMethod.LATENT:
return false
return true
func create_snapshot() -> Dictionary:
return {
&"evidence_id": String(evidence_id),
&"incident_id": String(incident_id),
&"source": String(source),
&"severity": severity,
&"facility_id": String(facility_id),
&"location_cell": [location_cell.x, location_cell.y, location_cell.z],
&"created_at": created_at,
&"expires_at": expires_at,
&"discovered_at": discovered_at,
&"discovered_by": String(discovered_by),
&"discovery_method": DiscoveryMethod.keys()[discovery_method],
&"revision": revision,
}
static func from_snapshot(snapshot: Dictionary) -> AuthorityEvidence:
if not _snapshot_is_valid(snapshot):
return null
var evidence := AuthorityEvidence.new().configure(
StringName(_value(snapshot, &"evidence_id", &"")),
StringName(_value(snapshot, &"source", &"")),
int(_value(snapshot, &"severity", -1)),
snapshot
)
return evidence if evidence.is_valid() else null
static func _snapshot_is_valid(snapshot: Dictionary) -> bool:
for key: StringName in [
&"evidence_id", &"incident_id", &"source", &"severity", &"facility_id",
&"location_cell", &"created_at", &"expires_at", &"discovered_at",
&"discovered_by", &"discovery_method", &"revision",
]:
if not _has_key(snapshot, key):
return false
if StringName(_value(snapshot, &"evidence_id", &"")).is_empty() \
or StringName(_value(snapshot, &"source", &"")).is_empty():
return false
if not _value(snapshot, &"location_cell", null) is Array \
or (_value(snapshot, &"location_cell", []) as Array).size() != 3:
return false
var severity_value := int(_value(snapshot, &"severity", -1))
if severity_value < 0 or severity_value > 100:
return false
if int(_value(snapshot, &"created_at", -1)) < 0 \
or int(_value(snapshot, &"expires_at", -2)) < -1 \
or int(_value(snapshot, &"discovered_at", -2)) < -1 \
or int(_value(snapshot, &"revision", -1)) < 0:
return false
return DiscoveryMethod.keys().has(String(_value(snapshot, &"discovery_method", "")))
static func _method_from_value(value: Variant) -> DiscoveryMethod:
if value is String or value is StringName:
var index := DiscoveryMethod.keys().find(String(value))
return (index as DiscoveryMethod) if index >= 0 else DiscoveryMethod.LATENT
var number := int(value)
return (number as DiscoveryMethod) if number >= 0 and number < DiscoveryMethod.size() else DiscoveryMethod.LATENT
static func _vector3i(value: Variant) -> Vector3i:
if value is Vector3i:
return value
if value is Array and value.size() >= 3:
return Vector3i(int(value[0]), int(value[1]), int(value[2]))
if value is Dictionary:
return Vector3i(int(value.get(&"x", 0)), int(value.get(&"y", 0)), int(value.get(&"z", 0)))
return Vector3i.ZERO
static func _value(source: Dictionary, key: StringName, fallback: Variant) -> Variant:
if source.has(key):
return source[key]
return source.get(String(key), fallback)
static func _has_key(source: Dictionary, key: StringName) -> bool:
return source.has(key) or source.has(String(key))