feat: give the player a real carried inventory and deposit transactions

This commit is contained in:
2026-08-08 23:59:19 +02:00
parent 9678526c5a
commit 5e6c963d23
12 changed files with 565 additions and 65 deletions
+1
View File
@@ -4,6 +4,7 @@ extends RefCounted
const KIND_ANIMAL := &"animal"
const KIND_RESOURCE := &"resource"
const KIND_PANTRY := &"pantry"
const KIND_DEPOSIT := &"deposit"
const KIND_GUARD := &"guard"
const KIND_STUDY := &"study"
+93 -8
View File
@@ -11,6 +11,7 @@ signal interaction_feedback(heading: String, message: String, succeeded: bool)
@export var world_view_manager: Node
@export var pantry_storage: StorageNode
@export var woodpile_storage: StorageNode
@export var guard_site: ActivitySite
@export var study_site: ActivitySite
@@ -69,6 +70,8 @@ func try_interact() -> void:
_execute_animal_interaction(context)
PlayerInteractionResult.KIND_RESOURCE:
_execute_resource_interaction(context)
PlayerInteractionResult.KIND_DEPOSIT:
_execute_deposit_interaction(context)
PlayerInteractionResult.KIND_GUARD:
simulation_manager.add_safety(3.0)
interaction_feedback.emit(
@@ -112,6 +115,20 @@ func get_interaction_context() -> PlayerInteractionResult:
"Work here · +2 knowledge",
study_site
)
if is_near_storage(woodpile_storage) and _get_player_carried(SimulationIds.RESOURCE_WOOD) > 0.0:
return _build_deposit_context(
SimulationIds.RESOURCE_WOOD,
SimulationIds.STORAGE_VILLAGE_WOODPILE,
woodpile_storage,
"Village woodpile"
)
if is_near_storage(pantry_storage) and _get_player_carried(SimulationIds.RESOURCE_FOOD) > 0.0:
return _build_deposit_context(
SimulationIds.RESOURCE_FOOD,
SimulationIds.STORAGE_VILLAGE_PANTRY,
pantry_storage,
"Village pantry"
)
if is_near_storage(pantry_storage):
return _build_pantry_context()
return null
@@ -290,14 +307,40 @@ func _build_resource_context(node: ResourceNode) -> PlayerInteractionResult:
definition.display_name if definition != null else String(node.action_id).capitalize()
)
var display_name := String(node.node_id).replace("_", " ").capitalize()
var carried := _get_player_carried(node.resource_id)
var detail := (
"%s · %.1f remaining · carrying %.1f" % [display_name, node.get_amount_remaining(), carried]
)
if _get_available_carry() <= 0.0:
detail = "Hands full — deposit before gathering"
return PlayerInteractionResult.new(
PlayerInteractionResult.KIND_RESOURCE,
node.action_id,
node.node_id,
display_name,
prompt,
"%s · %.1f remaining" % [display_name, node.get_amount_remaining()],
node
detail,
node,
"" if _get_available_carry() > 0.0 else "You cannot carry more right now."
)
func _build_deposit_context(
resource_id: StringName, target_id: StringName, target_node: StorageNode, display_name: String
) -> PlayerInteractionResult:
var carried := _get_player_carried(resource_id)
return PlayerInteractionResult.new(
PlayerInteractionResult.KIND_DEPOSIT,
(
SimulationIds.ACTION_DEPOSIT_FOOD
if resource_id == SimulationIds.RESOURCE_FOOD
else SimulationIds.ACTION_DEPOSIT_WOOD
),
target_id,
display_name,
"Deposit %s" % String(resource_id).capitalize(),
"%.1f %s in your hands" % [carried, String(resource_id).to_lower()],
target_node
)
@@ -349,23 +392,51 @@ func _execute_animal_interaction(context: PlayerInteractionResult) -> void:
func _execute_resource_interaction(context: PlayerInteractionResult) -> void:
var node := context.target_node as ResourceNode
if node == null or not simulation_manager.has_method("harvest_resource_node"):
push_error("Player: SimulationManager cannot harvest the resolved ResourceNode")
if node == null or not simulation_manager.has_method("player_gather"):
push_error("Player: SimulationManager cannot gather the resolved ResourceNode")
return
var extracted: float = simulation_manager.harvest_resource_node(node)
var extracted: float = simulation_manager.player_gather(node)
if extracted <= 0.0:
interaction_feedback.emit(
"%s is unavailable" % context.display_name, "Nothing could be gathered.", false
"%s is unavailable" % context.display_name,
(
context.blocked_reason
if not context.blocked_reason.is_empty()
else "Nothing could be gathered."
),
false
)
return
var destination := "pantry" if node.resource_id == SimulationIds.RESOURCE_FOOD else "woodpile"
var carried := _get_player_carried(node.resource_id)
interaction_feedback.emit(
"%s gathered" % String(node.resource_id).capitalize(),
"%.1f moved to the village %s." % [extracted, destination],
"%.1f added to your hands · carrying %.1f" % [extracted, carried],
true
)
func _deposit_carried(resource_id: StringName) -> float:
if not simulation_manager.has_method("player_deposit"):
push_error("Player: SimulationManager cannot deposit carried resources")
return 0.0
return simulation_manager.player_deposit(resource_id)
func _execute_deposit_interaction(context: PlayerInteractionResult) -> void:
var resource_id := (
SimulationIds.RESOURCE_FOOD
if context.action_id == SimulationIds.ACTION_DEPOSIT_FOOD
else SimulationIds.RESOURCE_WOOD
)
var deposited: float = _deposit_carried(resource_id)
if deposited <= 0.0:
interaction_feedback.emit("Deposit blocked", "You are not carrying that here.", false)
return
interaction_feedback.emit(
"Deposited to %s" % context.display_name, "%.1f moved into the village." % deposited, true
)
func _execute_pantry_interaction(context: PlayerInteractionResult) -> void:
if not context.is_available():
interaction_feedback.emit("The pantry is empty", context.blocked_reason, false)
@@ -424,6 +495,20 @@ func _get_pantry_food() -> float:
return pantry.get_amount(SimulationIds.RESOURCE_FOOD) if pantry != null else 0.0
func _get_player_carried(resource_id: StringName) -> float:
if simulation_manager == null or not simulation_manager.has_method("get_player_state"):
return 0.0
var state: PlayerStateRecord = simulation_manager.get_player_state()
return state.get_inventory_amount(resource_id) if state != null else 0.0
func _get_available_carry() -> float:
if simulation_manager == null or not simulation_manager.has_method("get_player_state"):
return 0.0
var state: PlayerStateRecord = simulation_manager.get_player_state()
return state.get_available_carry() if state != null else 0.0
func is_near_storage(storage_node: StorageNode) -> bool:
if storage_node == null:
return false