feat: add typed pantry storage site

This commit is contained in:
2026-07-07 12:57:47 +02:00
parent 33b9c1bdfb
commit e5bd93d705
16 changed files with 304 additions and 69 deletions
+13 -14
View File
@@ -4,7 +4,7 @@ extends Node
@export var guard_marker: Marker3D
@export var study_marker: Marker3D
@export var rest_marker: Marker3D
@export var pantry_marker: Marker3D
@export var pantry_storage: StorageNode
func get_resource_candidates(action_id: StringName) -> Array[Dictionary]:
@@ -28,19 +28,18 @@ func get_activity_target(action_id: StringName) -> Dictionary:
SimulationIds.ACTION_REST:
marker = rest_marker
SimulationIds.ACTION_EAT:
marker = pantry_marker
return _get_storage_target(pantry_storage)
SimulationIds.ACTION_DEPOSIT_FOOD, SimulationIds.ACTION_WITHDRAW_FOOD:
marker = pantry_marker
return _get_storage_target(pantry_storage)
if marker == null:
return {}
var target_id := ""
if (
action_id
in [
SimulationIds.ACTION_EAT,
SimulationIds.ACTION_DEPOSIT_FOOD,
SimulationIds.ACTION_WITHDRAW_FOOD
]
):
target_id = String(SimulationIds.STORAGE_VILLAGE_PANTRY)
return {"target_id": target_id, "position": marker.global_position}
return {"target_id": "", "position": marker.global_position}
func _get_storage_target(storage_node: StorageNode) -> Dictionary:
if storage_node == null:
return {}
return {
"target_id": String(storage_node.storage_id),
"position": storage_node.get_interaction_position()
}
+5 -14
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=26 format=3]
[gd_scene load_steps=25 format=3]
[ext_resource type="Terrain3DAssets" path="res://terrain/jajce/assets.tres" id="1_assets"]
[ext_resource type="PackedScene" path="res://world/resource_nodes/ResourceNode.tscn" id="2_resource"]
@@ -13,6 +13,7 @@
[ext_resource type="PackedScene" path="res://world/jajce/WaterfallMist.tscn" id="11_mist"]
[ext_resource type="PackedScene" path="res://world/jajce/ChimneySmoke.tscn" id="12_smoke"]
[ext_resource type="Script" path="res://world/jajce/day_night_cycle.gd" id="13_daynight"]
[ext_resource type="PackedScene" path="res://world/storage/StorageNode.tscn" id="14_storage"]
[sub_resource type="Terrain3DMaterial" id="Terrain3DMaterial_jajce"]
_shader_parameters = {
@@ -86,10 +87,6 @@ adjustment_brightness = 1.04
adjustment_contrast = 1.03
adjustment_saturation = 1.1
[sub_resource type="StandardMaterial3D" id="Material_pantry"]
albedo_color = Color(0.5, 0.32, 0.2, 1)
roughness = 0.85
[sub_resource type="StandardMaterial3D" id="Material_guard"]
albedo_color = Color(0.55, 0.45, 0.35, 1)
roughness = 0.8
@@ -102,10 +99,6 @@ roughness = 0.82
albedo_color = Color(0.35, 0.28, 0.22, 1)
roughness = 0.88
[sub_resource type="BoxMesh" id="Mesh_pantry_base"]
material = SubResource("Material_pantry")
size = Vector3(1.6, 1.1, 1.6)
[sub_resource type="CylinderMesh" id="Mesh_guard_post"]
material = SubResource("Material_guard")
top_radius = 0.35
@@ -253,14 +246,12 @@ resource_id = &"wood"
initial_amount = 12.0
yield_per_action = 3.0
[node name="LegacyActivityMarkers" type="Node3D" parent="."]
[node name="StorageSites" type="Node3D" parent="WorldObjects"]
[node name="PantryMarker" type="Marker3D" parent="LegacyActivityMarkers"]
[node name="VillagePantry" parent="WorldObjects/StorageSites" instance=ExtResource("14_storage")]
position = Vector3(0, 0, -8)
[node name="PantryVisual" type="MeshInstance3D" parent="LegacyActivityMarkers/PantryMarker"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
mesh = SubResource("Mesh_pantry_base")
[node name="LegacyActivityMarkers" type="Node3D" parent="."]
[node name="GuardZone" type="Marker3D" parent="LegacyActivityMarkers"]
position = Vector3(0, 0, 8)
+1
View File
@@ -0,0 +1 @@
uid://0epmcyfxcn62
+105
View File
@@ -0,0 +1,105 @@
class_name StorageNode
extends Node3D
static var _all: Array = []
@export var storage_id: StringName = SimulationIds.STORAGE_VILLAGE_PANTRY
@export var display_name := "Village Pantry"
@export var accepted_items: Array[StringName] = []
@export var debug_label_enabled := true
@onready var interaction_point: Marker3D = $InteractionPoint
var state: StorageStateRecord
var _last_label_text := ""
func _ready() -> void:
if accepted_items.is_empty():
accepted_items = [SimulationIds.RESOURCE_FOOD]
if storage_id.is_empty():
push_error("StorageNode at %s has empty storage_id" % get_path())
_update_presentation()
return
var existing := get_by_id(storage_id)
if existing != null:
push_error(
(
"Duplicate StorageNode storage_id '%s' at %s; first registered at %s"
% [storage_id, get_path(), existing.get_path()]
)
)
_update_presentation()
return
_all.append(self)
add_to_group("storage_nodes")
_try_register_with_simulation()
_update_presentation()
func _process(_delta: float) -> void:
if debug_label_enabled:
_update_presentation()
func _exit_tree() -> void:
_all.erase(self)
state = null
func bind_state(storage_state: StorageStateRecord) -> bool:
if storage_state == null or storage_state.get_storage_id() != storage_id:
return false
state = storage_state
_update_presentation()
return true
func get_interaction_position() -> Vector3:
return interaction_point.global_position if interaction_point != null else global_position
func accepts_item(item_id: StringName) -> bool:
return accepted_items.is_empty() or item_id in accepted_items
func _try_register_with_simulation() -> void:
var managers := get_tree().get_nodes_in_group("simulation_manager")
if managers.size() != 1:
return
var manager := managers[0]
if manager.has_method("register_storage_node"):
manager.register_storage_node(self)
func _update_presentation() -> void:
if not has_node("DebugLabel"):
return
var label := $DebugLabel as Label3D
label.visible = debug_label_enabled
if not debug_label_enabled:
return
var text := "%s\n%s" % [display_name, storage_id]
if state == null:
text += "\nUNBOUND"
else:
for item_id in accepted_items:
text += "\n%s: %.1f" % [item_id, state.get_amount(item_id)]
if text == _last_label_text:
return
_last_label_text = text
label.text = text
static func get_by_id(search_id: StringName) -> StorageNode:
for node in _all:
if node.storage_id == search_id:
return node
return null
static func get_all() -> Array[StorageNode]:
var nodes: Array[StorageNode] = []
for node in _all:
nodes.append(node as StorageNode)
return nodes
+52
View File
@@ -0,0 +1,52 @@
[gd_scene load_steps=7 format=3]
[ext_resource type="Script" path="res://world/storage/StorageNode.gd" id="1_storage"]
[sub_resource type="StandardMaterial3D" id="Material_crate"]
albedo_color = Color(0.5, 0.32, 0.2, 1)
roughness = 0.85
[sub_resource type="StandardMaterial3D" id="Material_cloth"]
albedo_color = Color(0.72, 0.56, 0.34, 1)
roughness = 0.9
[sub_resource type="BoxMesh" id="Mesh_crate"]
material = SubResource("Material_crate")
size = Vector3(1.6, 1.1, 1.6)
[sub_resource type="BoxMesh" id="Mesh_lid"]
material = SubResource("Material_cloth")
size = Vector3(1.75, 0.12, 1.75)
[sub_resource type="BoxMesh" id="Mesh_sack"]
material = SubResource("Material_cloth")
size = Vector3(0.45, 0.65, 0.45)
[node name="StorageNode" type="Node3D"]
script = ExtResource("1_storage")
[node name="Visual" type="Node3D" parent="."]
[node name="Crate" type="MeshInstance3D" parent="Visual"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
mesh = SubResource("Mesh_crate")
[node name="LidCloth" type="MeshInstance3D" parent="Visual"]
transform = Transform3D(1, 0, 0, 0, 0.7, 0.7173561, 0, -0.7173561, 0.7, 0, 1.15, -0.06)
mesh = SubResource("Mesh_lid")
[node name="FoodSack" type="MeshInstance3D" parent="Visual"]
transform = Transform3D(0.85, 0, 0, 0, 1, 0, 0, 0, 0.85, 0.8, 0.325, 0.55)
mesh = SubResource("Mesh_sack")
[node name="InteractionPoint" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.0)
[node name="DebugLabel" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.1, 0)
billboard = 1
no_depth_test = true
font_size = 20
outline_modulate = Color(0, 0, 0, 1)
outline_size = 4
text = "Storage"
+1
View File
@@ -0,0 +1 @@
uid://cascjhf8lsvay