merge: integrate remote player quest slices
This commit is contained in:
@@ -4,6 +4,12 @@ extends RefCounted
|
||||
const SCHEMA_VERSION := 2
|
||||
const LEGACY_SCHEMA_VERSION := 1
|
||||
const MAX_HEALTH := 100.0
|
||||
const RESET_HUNGER := 40.0
|
||||
const RESET_ENERGY := 100.0
|
||||
const STACK_THRESHOLD := 80.0
|
||||
const DEATH_STANDING_PENALTY := 0.85
|
||||
const DEFAULT_STARVATION_DEATH_THRESHOLD := 1
|
||||
const DEFAULT_CARRY_CAPACITY := 3.0
|
||||
|
||||
var data: Dictionary
|
||||
|
||||
@@ -18,18 +24,30 @@ static func create_default() -> PlayerStateRecord:
|
||||
. new(
|
||||
{
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": 40.0,
|
||||
"energy": 100.0,
|
||||
"hunger": RESET_HUNGER,
|
||||
"energy": RESET_ENERGY,
|
||||
"health": MAX_HEALTH,
|
||||
"max_health": MAX_HEALTH,
|
||||
"downed": false,
|
||||
"downed_ticks": 0,
|
||||
"dead": false,
|
||||
"deaths": 0,
|
||||
"starvation_ticks": 0,
|
||||
"starvation_death_threshold": DEFAULT_STARVATION_DEATH_THRESHOLD,
|
||||
"carry_capacity": DEFAULT_CARRY_CAPACITY,
|
||||
"inventory": {},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# Compatibility constructor for the first embodied-player slice. New code
|
||||
# should use create_default(), but keeping this alias lets older quest/needs
|
||||
# resources load without introducing a second player-state schema.
|
||||
static func create() -> PlayerStateRecord:
|
||||
return create_default()
|
||||
|
||||
|
||||
static func from_dictionary(record_data: Dictionary) -> PlayerStateRecord:
|
||||
var version := int(record_data.get("schema_version", -1))
|
||||
if version == LEGACY_SCHEMA_VERSION:
|
||||
@@ -76,6 +94,20 @@ static func from_dictionary(record_data: Dictionary) -> PlayerStateRecord:
|
||||
"max_health": max_health,
|
||||
"downed": bool(record_data["downed"]),
|
||||
"downed_ticks": int(record_data["downed_ticks"]),
|
||||
"dead": bool(record_data.get("dead", false)),
|
||||
"deaths": maxi(int(record_data.get("deaths", 0)), 0),
|
||||
"starvation_ticks": maxi(int(record_data.get("starvation_ticks", 0)), 0),
|
||||
"starvation_death_threshold":
|
||||
maxi(
|
||||
int(
|
||||
record_data.get(
|
||||
"starvation_death_threshold", DEFAULT_STARVATION_DEATH_THRESHOLD
|
||||
)
|
||||
),
|
||||
1
|
||||
),
|
||||
"carry_capacity":
|
||||
maxf(float(record_data.get("carry_capacity", DEFAULT_CARRY_CAPACITY)), 0.0),
|
||||
"inventory": normalized_inventory,
|
||||
}
|
||||
)
|
||||
@@ -89,6 +121,11 @@ static func _migrate_v1(legacy_data: Dictionary) -> Dictionary:
|
||||
migrated["max_health"] = MAX_HEALTH
|
||||
migrated["downed"] = false
|
||||
migrated["downed_ticks"] = 0
|
||||
migrated["dead"] = false
|
||||
migrated["deaths"] = 0
|
||||
migrated["starvation_ticks"] = 0
|
||||
migrated["starvation_death_threshold"] = DEFAULT_STARVATION_DEATH_THRESHOLD
|
||||
migrated["carry_capacity"] = DEFAULT_CARRY_CAPACITY
|
||||
return migrated
|
||||
|
||||
|
||||
@@ -112,6 +149,18 @@ func is_downed() -> bool:
|
||||
return bool(data["downed"])
|
||||
|
||||
|
||||
func is_dead() -> bool:
|
||||
return bool(data.get("dead", false))
|
||||
|
||||
|
||||
func is_starving() -> bool:
|
||||
return get_hunger() >= STACK_THRESHOLD and not is_dead()
|
||||
|
||||
|
||||
func get_deaths() -> int:
|
||||
return maxi(int(data.get("deaths", 0)), 0)
|
||||
|
||||
|
||||
func get_downed_ticks() -> int:
|
||||
return int(data["downed_ticks"])
|
||||
|
||||
@@ -124,6 +173,54 @@ func set_energy(amount: float) -> void:
|
||||
data["energy"] = clampf(amount, 0.0, 100.0)
|
||||
|
||||
|
||||
func advance(hunger_rate: float, energy_drain: float) -> bool:
|
||||
if is_dead():
|
||||
return true
|
||||
set_hunger(get_hunger() + maxf(hunger_rate, 0.0))
|
||||
set_energy(get_energy() - maxf(energy_drain, 0.0))
|
||||
if get_hunger() < STACK_THRESHOLD:
|
||||
data["starvation_ticks"] = 0
|
||||
return false
|
||||
data["starvation_ticks"] = int(data.get("starvation_ticks", 0)) + 1
|
||||
if int(data["starvation_ticks"]) >= int(data.get("starvation_death_threshold", 1)):
|
||||
die()
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func eat(amount: float) -> float:
|
||||
if not is_finite(amount) or amount <= 0.0 or is_dead():
|
||||
return 0.0
|
||||
var consumed := minf(amount, get_hunger())
|
||||
set_hunger(get_hunger() - consumed)
|
||||
set_energy(get_energy() + consumed * 0.5)
|
||||
data["starvation_ticks"] = 0
|
||||
return consumed
|
||||
|
||||
|
||||
func die() -> void:
|
||||
if is_dead():
|
||||
return
|
||||
data["dead"] = true
|
||||
data["deaths"] = get_deaths() + 1
|
||||
|
||||
|
||||
func respawn() -> void:
|
||||
data["dead"] = false
|
||||
data["downed"] = false
|
||||
data["downed_ticks"] = 0
|
||||
data["hunger"] = RESET_HUNGER
|
||||
data["energy"] = RESET_ENERGY
|
||||
data["health"] = get_max_health()
|
||||
data["starvation_ticks"] = 0
|
||||
|
||||
|
||||
func get_available_carry() -> float:
|
||||
return maxf(
|
||||
float(data.get("carry_capacity", DEFAULT_CARRY_CAPACITY)) - get_carried_total(), 0.0
|
||||
)
|
||||
|
||||
|
||||
func take_damage(amount: float) -> float:
|
||||
if not is_finite(amount) or amount <= 0.0 or is_downed():
|
||||
return 0.0
|
||||
@@ -157,10 +254,14 @@ func get_carried_total() -> float:
|
||||
return total
|
||||
|
||||
|
||||
func add_inventory(item_id: StringName, amount: float) -> void:
|
||||
func add_inventory(item_id: StringName, amount: float) -> float:
|
||||
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
|
||||
return 0.0
|
||||
var added := minf(amount, get_available_carry())
|
||||
if added <= 0.0:
|
||||
return 0.0
|
||||
data["inventory"][String(item_id)] = get_inventory_amount(item_id) + added
|
||||
return added
|
||||
|
||||
|
||||
func remove_inventory(item_id: StringName, requested_amount: float) -> float:
|
||||
|
||||
Reference in New Issue
Block a user