class_name PlayerStandingRecord extends RefCounted const SCHEMA_VERSION := 1 const MAX_STANDING := 100.0 const TIER_STRANGER := 0 const TIER_KNOWN_HAND := 1 const TIER_TRUSTED := 2 const TIER_VILLAGE_STEWARD := 3 const TIER_VOICE_OF_JAJCE := 4 const TIER_THRESHOLDS := { TIER_STRANGER: 0.0, TIER_KNOWN_HAND: 15.0, TIER_TRUSTED: 35.0, TIER_VILLAGE_STEWARD: 60.0, TIER_VOICE_OF_JAJCE: 85.0, } const TIER_NAMES := { TIER_STRANGER: "Stranger", TIER_KNOWN_HAND: "Known Hand", TIER_TRUSTED: "Trusted", TIER_VILLAGE_STEWARD: "Village Steward", TIER_VOICE_OF_JAJCE: "Voice of Jajce", } var data: Dictionary func _init(record_data: Dictionary = {}) -> void: data = record_data.duplicate(true) static func create() -> PlayerStandingRecord: return ( PlayerStandingRecord . new( { "schema_version": SCHEMA_VERSION, "standing": 0.0, "resolved_needs": 0, "gratitude": {}, } ) ) static func from_dictionary(record_data: Dictionary) -> PlayerStandingRecord: if int(record_data.get("schema_version", -1)) != SCHEMA_VERSION: return null if not record_data.has_all(["standing", "resolved_needs", "gratitude"]): return null var standing := float(record_data["standing"]) var resolved_needs := int(record_data["resolved_needs"]) var gratitude = record_data["gratitude"] if ( not is_finite(standing) or standing < 0.0 or standing > MAX_STANDING or resolved_needs < 0 or not gratitude is Dictionary ): return null var normalized_gratitude := {} for raw_npc_id in gratitude: var npc_id := int(raw_npc_id) var value := float(gratitude[raw_npc_id]) if npc_id < 0 or not is_finite(value) or value < 0.0 or value > 1.0: return null normalized_gratitude[npc_id] = value return ( PlayerStandingRecord . new( { "schema_version": SCHEMA_VERSION, "standing": standing, "resolved_needs": resolved_needs, "gratitude": normalized_gratitude, } ) ) func grant_standing(amount: float, requester_npc_id: int) -> void: if not is_finite(amount) or amount <= 0.0 or requester_npc_id < 0: return data["standing"] = minf(get_standing() + amount, MAX_STANDING) data["resolved_needs"] = int(data["resolved_needs"]) + 1 var gratitude := get_gratitude(requester_npc_id) data["gratitude"][requester_npc_id] = minf(gratitude + 0.1, 1.0) func get_standing() -> float: return float(data["standing"]) func get_resolved_needs() -> int: return int(data["resolved_needs"]) func get_gratitude(npc_id: int) -> float: return float(data["gratitude"].get(npc_id, 0.0)) func get_tier() -> int: var current := TIER_STRANGER for tier in [TIER_VOICE_OF_JAJCE, TIER_VILLAGE_STEWARD, TIER_TRUSTED, TIER_KNOWN_HAND]: if get_standing() >= float(TIER_THRESHOLDS[tier]): current = tier break return current func get_tier_name() -> String: return String(TIER_NAMES[get_tier()]) func to_dictionary() -> Dictionary: return data.duplicate(true)