feat: add typed pantry storage site
This commit is contained in:
@@ -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
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user