118 lines
3.0 KiB
GDScript
118 lines
3.0 KiB
GDScript
class_name PlayerNeedsSystem
|
|
extends RefCounted
|
|
|
|
var state := PlayerStateRecord.create()
|
|
var economy: RefCounted
|
|
var event_recorder: RefCounted
|
|
var resource_states: Dictionary = {}
|
|
|
|
|
|
func configure(economy_service: RefCounted, recorder: RefCounted) -> void:
|
|
economy = economy_service
|
|
event_recorder = recorder
|
|
|
|
|
|
func set_resource_states(states: Dictionary) -> void:
|
|
resource_states = states
|
|
|
|
|
|
func advance(village: SimVillage) -> bool:
|
|
if state.is_dead():
|
|
return false
|
|
var hunger_rate := 0.125 * village.food_modifier
|
|
if state.advance(hunger_rate, 0.5):
|
|
state.die()
|
|
return true
|
|
return false
|
|
|
|
|
|
func eat(amount: float) -> float:
|
|
return state.eat(amount)
|
|
|
|
|
|
func gather_node(node: ResourceNode) -> float:
|
|
if node == null:
|
|
return 0.0
|
|
var resource_state := resource_states.get(node.node_id) as ResourceStateRecord
|
|
if resource_state == null or not resource_state.can_player_use_resource():
|
|
return 0.0
|
|
var available := state.get_available_carry()
|
|
if available <= 0.0:
|
|
return 0.0
|
|
var extracted := resource_state.extract(minf(resource_state.get_yield_per_action(), available))
|
|
if extracted <= 0.0:
|
|
return 0.0
|
|
var carried := state.add_inventory(resource_state.get_resource_id(), extracted)
|
|
if carried <= 0.0:
|
|
resource_state.data["amount_remaining"] = (
|
|
resource_state.get_amount_remaining() + extracted
|
|
)
|
|
return 0.0
|
|
var event_position := (
|
|
node.interaction_point.global_position
|
|
if node.interaction_point != null
|
|
else node.global_position
|
|
)
|
|
event_recorder.record_economic_at(
|
|
SimulationIds.EVENT_RESOURCE_EXTRACTED,
|
|
-1,
|
|
resource_state.get_node_id(),
|
|
&"player_carry",
|
|
resource_state.get_resource_id(),
|
|
carried,
|
|
event_position
|
|
)
|
|
if resource_state.get_amount_remaining() <= 0.0:
|
|
event_recorder.record_narrative_at(
|
|
SimulationIds.EVENT_RESOURCE_DEPLETED,
|
|
-1,
|
|
resource_state.get_node_id(),
|
|
"",
|
|
event_position
|
|
)
|
|
return carried
|
|
|
|
|
|
func deposit_resource(resource_id: StringName) -> float:
|
|
if resource_id.is_empty():
|
|
return 0.0
|
|
var carried := state.get_inventory_amount(resource_id)
|
|
if carried <= 0.0:
|
|
return 0.0
|
|
if economy == null or not economy.has_method("get_storage_for_resource"):
|
|
return 0.0
|
|
var storage: StorageStateRecord = economy.get_storage_for_resource(resource_id)
|
|
if storage == null:
|
|
return 0.0
|
|
var deposited: float = economy.deposit_resource(resource_id, carried)
|
|
if deposited <= 0.0:
|
|
return 0.0
|
|
state.remove_inventory(resource_id, deposited)
|
|
event_recorder.record_economic(
|
|
SimulationIds.EVENT_STORAGE_DEPOSITED,
|
|
-1,
|
|
&"player_carry",
|
|
storage.get_storage_id(),
|
|
resource_id,
|
|
deposited
|
|
)
|
|
return deposited
|
|
|
|
|
|
func get_carried_amount(item_id: StringName) -> float:
|
|
return state.get_inventory_amount(item_id)
|
|
|
|
|
|
func respawn() -> void:
|
|
if state.is_dead():
|
|
state.respawn()
|
|
|
|
|
|
func apply_death_consequence(standing: PlayerStandingRecord) -> void:
|
|
var reduced := standing.get_standing() * PlayerStateRecord.DEATH_STANDING_PENALTY
|
|
standing.data["standing"] = reduced
|
|
|
|
|
|
func restore(record: PlayerStateRecord) -> void:
|
|
state = record if record != null else PlayerStateRecord.create()
|