171 lines
5.3 KiB
GDScript
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))
|