feat: give the player embodied hunger, energy, and starvation death
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
class_name PlayerStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_VERSION := 1
|
||||
const HUNGER_DEATH_THRESHOLD := 100.0
|
||||
const STACK_THRESHOLD := 90.0
|
||||
const DEATH_STANDING_PENALTY := 0.5
|
||||
const RESET_HUNGER := 20.0
|
||||
const RESET_ENERGY := 70.0
|
||||
|
||||
var data: Dictionary
|
||||
|
||||
|
||||
func _init(record_data: Dictionary = {}) -> void:
|
||||
data = record_data.duplicate(true)
|
||||
|
||||
|
||||
static func create() -> PlayerStateRecord:
|
||||
return (
|
||||
PlayerStateRecord
|
||||
. new(
|
||||
{
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": 20.0,
|
||||
"energy": 90.0,
|
||||
"is_starving": false,
|
||||
"starvation_ticks": 0,
|
||||
"starvation_death_threshold": 600,
|
||||
"is_dead": false,
|
||||
"deaths": 0,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
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",
|
||||
"is_starving",
|
||||
"starvation_ticks",
|
||||
"starvation_death_threshold",
|
||||
"is_dead",
|
||||
"deaths",
|
||||
]
|
||||
)
|
||||
):
|
||||
return null
|
||||
var hunger := float(record_data["hunger"])
|
||||
var energy := float(record_data["energy"])
|
||||
var starvation_ticks := int(record_data["starvation_ticks"])
|
||||
var death_threshold := int(record_data["starvation_death_threshold"])
|
||||
var deaths := int(record_data["deaths"])
|
||||
if (
|
||||
not is_finite(hunger)
|
||||
or hunger < 0.0
|
||||
or hunger > HUNGER_DEATH_THRESHOLD
|
||||
or not is_finite(energy)
|
||||
or energy < 0.0
|
||||
or energy > 100.0
|
||||
or starvation_ticks < 0
|
||||
or death_threshold < 1
|
||||
or deaths < 0
|
||||
):
|
||||
return null
|
||||
return (
|
||||
PlayerStateRecord
|
||||
. new(
|
||||
{
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"hunger": hunger,
|
||||
"energy": energy,
|
||||
"is_starving": bool(record_data["is_starving"]),
|
||||
"starvation_ticks": starvation_ticks,
|
||||
"starvation_death_threshold": death_threshold,
|
||||
"is_dead": bool(record_data["is_dead"]),
|
||||
"deaths": deaths,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
func get_hunger() -> float:
|
||||
return float(data["hunger"])
|
||||
|
||||
|
||||
func get_energy() -> float:
|
||||
return float(data["energy"])
|
||||
|
||||
|
||||
func is_starving() -> bool:
|
||||
return bool(data["is_starving"])
|
||||
|
||||
|
||||
func is_dead() -> bool:
|
||||
return bool(data["is_dead"])
|
||||
|
||||
|
||||
func get_starvation_ticks() -> int:
|
||||
return int(data["starvation_ticks"])
|
||||
|
||||
|
||||
func get_deaths() -> int:
|
||||
return int(data["deaths"])
|
||||
|
||||
|
||||
func eat(amount: float) -> float:
|
||||
if amount <= 0.0 or is_dead():
|
||||
return 0.0
|
||||
var previous := get_hunger()
|
||||
data["hunger"] = clampf(previous - amount, 0.0, HUNGER_DEATH_THRESHOLD)
|
||||
var consumed := previous - get_hunger()
|
||||
if consumed > 0.0:
|
||||
data["energy"] = minf(get_energy() + consumed * 0.5, 100.0)
|
||||
return consumed
|
||||
|
||||
|
||||
func advance(hunger_rate: float, energy_rate: float) -> bool:
|
||||
if is_dead():
|
||||
return false
|
||||
data["hunger"] = minf(get_hunger() + maxf(hunger_rate, 0.0), HUNGER_DEATH_THRESHOLD)
|
||||
data["energy"] = clampf(get_energy() - maxf(energy_rate, 0.0), 0.0, 100.0)
|
||||
data["is_starving"] = get_hunger() >= STACK_THRESHOLD
|
||||
if is_starving():
|
||||
data["starvation_ticks"] = int(data["starvation_ticks"]) + 1
|
||||
if get_starvation_ticks() >= int(data["starvation_death_threshold"]):
|
||||
return true
|
||||
else:
|
||||
data["starvation_ticks"] = 0
|
||||
return false
|
||||
|
||||
|
||||
func die() -> void:
|
||||
data["is_dead"] = true
|
||||
data["deaths"] = int(data["deaths"]) + 1
|
||||
|
||||
|
||||
func respawn() -> void:
|
||||
data["hunger"] = RESET_HUNGER
|
||||
data["energy"] = RESET_ENERGY
|
||||
data["is_starving"] = false
|
||||
data["starvation_ticks"] = 0
|
||||
data["is_dead"] = false
|
||||
|
||||
|
||||
func to_dictionary() -> Dictionary:
|
||||
return data.duplicate(true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://v86fryuks1u3
|
||||
@@ -2,7 +2,7 @@ class_name SimulationStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_NAME := "the_steward.simulation"
|
||||
const SCHEMA_VERSION := 12
|
||||
const SCHEMA_VERSION := 13
|
||||
const LEGACY_SCHEMA_VERSION := 1
|
||||
const EVENT_LEGACY_SCHEMA_VERSION := 2
|
||||
const RELATIONSHIP_LEGACY_SCHEMA_VERSION := 3
|
||||
@@ -14,6 +14,7 @@ const ANIMAL_LEGACY_SCHEMA_VERSION := 9
|
||||
const ROUTINE_LEGACY_SCHEMA_VERSION := 10
|
||||
const PREVIOUS_SCHEMA_VERSION := 7
|
||||
const PLAYER_LEGACY_SCHEMA_VERSION := 11
|
||||
const PLAYER_STATE_LEGACY_SCHEMA_VERSION := 12
|
||||
|
||||
var simulation: Dictionary
|
||||
var village: VillageStateRecord
|
||||
@@ -27,6 +28,7 @@ var event_knowledge: Array[KnownEventStateRecord] = []
|
||||
var opportunities: Array[OpportunityStateRecord] = []
|
||||
var player_standing: PlayerStandingRecord
|
||||
var player_quests: Array[PlayerQuestRecord] = []
|
||||
var player_state: PlayerStateRecord
|
||||
|
||||
|
||||
func to_dictionary() -> Dictionary:
|
||||
@@ -73,7 +75,8 @@ func to_dictionary() -> Dictionary:
|
||||
"event_knowledge": knowledge_data,
|
||||
"opportunities": opportunity_data,
|
||||
"player_standing": player_standing.to_dictionary(),
|
||||
"player_quests": player_quest_data
|
||||
"player_quests": player_quest_data,
|
||||
"player_state": player_state.to_dictionary()
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +109,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
ANIMAL_LEGACY_SCHEMA_VERSION,
|
||||
ROUTINE_LEGACY_SCHEMA_VERSION,
|
||||
PLAYER_LEGACY_SCHEMA_VERSION,
|
||||
PLAYER_STATE_LEGACY_SCHEMA_VERSION,
|
||||
]
|
||||
):
|
||||
record_data = _migrate_legacy(record_data, version)
|
||||
@@ -127,6 +131,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
"opportunities",
|
||||
"player_standing",
|
||||
"player_quests",
|
||||
"player_state",
|
||||
]
|
||||
)
|
||||
):
|
||||
@@ -530,6 +535,14 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
highest_quest_id = maxi(highest_quest_id, quest_id)
|
||||
record.player_quests.append(quest_record)
|
||||
|
||||
var player_state_data = record_data["player_state"]
|
||||
if not player_state_data is Dictionary:
|
||||
return null
|
||||
var player_state_record := PlayerStateRecord.from_dictionary(player_state_data)
|
||||
if player_state_record == null:
|
||||
return null
|
||||
record.player_state = player_state_record
|
||||
|
||||
return record
|
||||
|
||||
|
||||
@@ -850,6 +863,8 @@ static func _migrate_legacy(legacy_data: Dictionary, version: int) -> Dictionary
|
||||
var quest_simulation_data: Dictionary = migrated.get("simulation", {})
|
||||
quest_simulation_data["next_quest_id"] = 0
|
||||
migrated["simulation"] = quest_simulation_data
|
||||
if version <= PLAYER_STATE_LEGACY_SCHEMA_VERSION:
|
||||
migrated["player_state"] = PlayerStateRecord.create().to_dictionary()
|
||||
return migrated
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user