feat: let the player live as a citizen with needs and carried inventory
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
class_name PlayerStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_VERSION := 1
|
||||
|
||||
var data: Dictionary
|
||||
|
||||
|
||||
func _init(record_data: Dictionary = {}) -> void:
|
||||
data = record_data.duplicate(true)
|
||||
|
||||
|
||||
static func create_default() -> PlayerStateRecord:
|
||||
return (
|
||||
PlayerStateRecord
|
||||
. new(
|
||||
{
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": 40.0,
|
||||
"energy": 100.0,
|
||||
"inventory": {},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
static func from_dictionary(record_data: Dictionary) -> PlayerStateRecord:
|
||||
if int(record_data.get("schema_version", -1)) != SCHEMA_VERSION:
|
||||
return null
|
||||
if not record_data.has_all(["hunger", "energy", "inventory"]):
|
||||
return null
|
||||
if not record_data["inventory"] is Dictionary:
|
||||
return null
|
||||
var hunger := float(record_data["hunger"])
|
||||
var energy := float(record_data["energy"])
|
||||
if not is_finite(hunger) or not is_finite(energy):
|
||||
return null
|
||||
var normalized_inventory := {}
|
||||
for raw_item_id in record_data["inventory"]:
|
||||
var item_id := String(raw_item_id)
|
||||
var amount := float(record_data["inventory"][raw_item_id])
|
||||
if (
|
||||
item_id.is_empty()
|
||||
or normalized_inventory.has(item_id)
|
||||
or not is_finite(amount)
|
||||
or amount < 0.0
|
||||
):
|
||||
return null
|
||||
normalized_inventory[item_id] = amount
|
||||
return (
|
||||
PlayerStateRecord
|
||||
. new(
|
||||
{
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": clampf(hunger, 0.0, 100.0),
|
||||
"energy": clampf(energy, 0.0, 100.0),
|
||||
"inventory": normalized_inventory,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
func get_hunger() -> float:
|
||||
return clampf(float(data["hunger"]), 0.0, 100.0)
|
||||
|
||||
|
||||
func get_energy() -> float:
|
||||
return clampf(float(data["energy"]), 0.0, 100.0)
|
||||
|
||||
|
||||
func set_hunger(amount: float) -> void:
|
||||
data["hunger"] = clampf(amount, 0.0, 100.0)
|
||||
|
||||
|
||||
func set_energy(amount: float) -> void:
|
||||
data["energy"] = clampf(amount, 0.0, 100.0)
|
||||
|
||||
|
||||
func get_inventory_amount(item_id: StringName) -> float:
|
||||
return float(data["inventory"].get(String(item_id), 0.0))
|
||||
|
||||
|
||||
func get_carried_total() -> float:
|
||||
var total := 0.0
|
||||
for amount in data["inventory"].values():
|
||||
total += float(amount)
|
||||
return total
|
||||
|
||||
|
||||
func add_inventory(item_id: StringName, amount: float) -> void:
|
||||
if item_id.is_empty() or not is_finite(amount) or amount <= 0.0:
|
||||
return
|
||||
data["inventory"][String(item_id)] = get_inventory_amount(item_id) + amount
|
||||
|
||||
|
||||
func remove_inventory(item_id: StringName, requested_amount: float) -> float:
|
||||
if item_id.is_empty() or not is_finite(requested_amount) or requested_amount <= 0.0:
|
||||
return 0.0
|
||||
var removed := minf(requested_amount, get_inventory_amount(item_id))
|
||||
if removed <= 0.0:
|
||||
return 0.0
|
||||
data["inventory"][String(item_id)] = get_inventory_amount(item_id) - removed
|
||||
return removed
|
||||
|
||||
|
||||
func to_dictionary() -> Dictionary:
|
||||
return data.duplicate(true)
|
||||
Reference in New Issue
Block a user