121 lines
2.9 KiB
GDScript
121 lines
2.9 KiB
GDScript
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)
|