feat: shared creature root, enemy definitions, defend duty, and player downing
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
class_name PlayerStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_VERSION := 1
|
||||
const SCHEMA_VERSION := 2
|
||||
const LEGACY_SCHEMA_VERSION := 1
|
||||
const MAX_HEALTH := 100.0
|
||||
|
||||
var data: Dictionary
|
||||
|
||||
@@ -18,6 +20,10 @@ static func create_default() -> PlayerStateRecord:
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": 40.0,
|
||||
"energy": 100.0,
|
||||
"health": MAX_HEALTH,
|
||||
"max_health": MAX_HEALTH,
|
||||
"downed": false,
|
||||
"downed_ticks": 0,
|
||||
"inventory": {},
|
||||
}
|
||||
)
|
||||
@@ -25,15 +31,27 @@ static func create_default() -> PlayerStateRecord:
|
||||
|
||||
|
||||
static func from_dictionary(record_data: Dictionary) -> PlayerStateRecord:
|
||||
if int(record_data.get("schema_version", -1)) != SCHEMA_VERSION:
|
||||
var version := int(record_data.get("schema_version", -1))
|
||||
if version == LEGACY_SCHEMA_VERSION:
|
||||
record_data = _migrate_v1(record_data)
|
||||
elif version != SCHEMA_VERSION:
|
||||
return null
|
||||
if not record_data.has_all(["hunger", "energy", "inventory"]):
|
||||
if not record_data.has_all(
|
||||
["hunger", "energy", "health", "max_health", "downed", "downed_ticks", "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):
|
||||
var health := float(record_data["health"])
|
||||
var max_health := float(record_data["max_health"])
|
||||
if (
|
||||
not is_finite(hunger)
|
||||
or not is_finite(energy)
|
||||
or not is_finite(health)
|
||||
or not is_finite(max_health)
|
||||
):
|
||||
return null
|
||||
var normalized_inventory := {}
|
||||
for raw_item_id in record_data["inventory"]:
|
||||
@@ -54,12 +72,26 @@ static func from_dictionary(record_data: Dictionary) -> PlayerStateRecord:
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": clampf(hunger, 0.0, 100.0),
|
||||
"energy": clampf(energy, 0.0, 100.0),
|
||||
"health": clampf(health, 0.0, max_health),
|
||||
"max_health": max_health,
|
||||
"downed": bool(record_data["downed"]),
|
||||
"downed_ticks": int(record_data["downed_ticks"]),
|
||||
"inventory": normalized_inventory,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
static func _migrate_v1(legacy_data: Dictionary) -> Dictionary:
|
||||
var migrated := legacy_data.duplicate(true)
|
||||
migrated["schema_version"] = SCHEMA_VERSION
|
||||
migrated["health"] = MAX_HEALTH
|
||||
migrated["max_health"] = MAX_HEALTH
|
||||
migrated["downed"] = false
|
||||
migrated["downed_ticks"] = 0
|
||||
return migrated
|
||||
|
||||
|
||||
func get_hunger() -> float:
|
||||
return clampf(float(data["hunger"]), 0.0, 100.0)
|
||||
|
||||
@@ -68,6 +100,22 @@ func get_energy() -> float:
|
||||
return clampf(float(data["energy"]), 0.0, 100.0)
|
||||
|
||||
|
||||
func get_health() -> float:
|
||||
return clampf(float(data["health"]), 0.0, get_max_health())
|
||||
|
||||
|
||||
func get_max_health() -> float:
|
||||
return maxf(float(data["max_health"]), 1.0)
|
||||
|
||||
|
||||
func is_downed() -> bool:
|
||||
return bool(data["downed"])
|
||||
|
||||
|
||||
func get_downed_ticks() -> int:
|
||||
return int(data["downed_ticks"])
|
||||
|
||||
|
||||
func set_hunger(amount: float) -> void:
|
||||
data["hunger"] = clampf(amount, 0.0, 100.0)
|
||||
|
||||
@@ -76,6 +124,28 @@ func set_energy(amount: float) -> void:
|
||||
data["energy"] = clampf(amount, 0.0, 100.0)
|
||||
|
||||
|
||||
func take_damage(amount: float) -> float:
|
||||
if not is_finite(amount) or amount <= 0.0 or is_downed():
|
||||
return 0.0
|
||||
var previous := get_health()
|
||||
data["health"] = clampf(previous - amount, 0.0, get_max_health())
|
||||
if get_health() <= 0.0:
|
||||
data["downed"] = true
|
||||
data["downed_ticks"] = 20
|
||||
return previous - get_health()
|
||||
|
||||
|
||||
func advance_health() -> void:
|
||||
if is_downed():
|
||||
data["downed_ticks"] = maxi(get_downed_ticks() - 1, 0)
|
||||
if get_downed_ticks() <= 0:
|
||||
data["downed"] = false
|
||||
data["health"] = get_max_health() * 0.5
|
||||
return
|
||||
if get_health() < get_max_health():
|
||||
data["health"] = clampf(get_health() + 0.25, 0.0, get_max_health())
|
||||
|
||||
|
||||
func get_inventory_amount(item_id: StringName) -> float:
|
||||
return float(data["inventory"].get(String(item_id), 0.0))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user