feat: replace activity markers with typed sites
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
class_name ActiveWorldAdapter
|
||||
extends Node
|
||||
|
||||
@export var guard_marker: Marker3D
|
||||
@export var study_marker: Marker3D
|
||||
@export var rest_marker: Marker3D
|
||||
@export var pantry_storage: StorageNode
|
||||
|
||||
|
||||
@@ -18,22 +15,40 @@ func get_resource_candidates(action_id: StringName) -> Array[Dictionary]:
|
||||
return candidates
|
||||
|
||||
|
||||
func get_activity_target(action_id: StringName) -> Dictionary:
|
||||
var marker: Marker3D
|
||||
func get_activity_target(action_id: StringName, origin: Vector3 = Vector3.ZERO) -> Dictionary:
|
||||
match action_id:
|
||||
SimulationIds.ACTION_PATROL:
|
||||
marker = guard_marker
|
||||
return _get_activity_site_target(action_id, origin)
|
||||
SimulationIds.ACTION_STUDY:
|
||||
marker = study_marker
|
||||
return _get_activity_site_target(action_id, origin)
|
||||
SimulationIds.ACTION_REST:
|
||||
marker = rest_marker
|
||||
return _get_activity_site_target(action_id, origin)
|
||||
SimulationIds.ACTION_EAT:
|
||||
return _get_storage_target(pantry_storage)
|
||||
SimulationIds.ACTION_DEPOSIT_FOOD, SimulationIds.ACTION_WITHDRAW_FOOD:
|
||||
return _get_storage_target(pantry_storage)
|
||||
if marker == null:
|
||||
return {}
|
||||
|
||||
|
||||
func _get_activity_site_target(action_id: StringName, origin: Vector3) -> Dictionary:
|
||||
var best_site: ActivitySite
|
||||
var best_distance := INF
|
||||
for candidate in ActivitySite.get_all():
|
||||
var site := candidate as ActivitySite
|
||||
if site == null:
|
||||
continue
|
||||
if not site.supports_action(action_id):
|
||||
continue
|
||||
var distance := origin.distance_squared_to(site.get_interaction_position())
|
||||
if distance < best_distance:
|
||||
best_distance = distance
|
||||
best_site = site
|
||||
if best_site == null:
|
||||
return {}
|
||||
return {"target_id": "", "position": marker.global_position}
|
||||
return {
|
||||
"target_id": String(best_site.site_id),
|
||||
"position": best_site.get_interaction_position()
|
||||
}
|
||||
|
||||
|
||||
func _get_storage_target(storage_node: StorageNode) -> Dictionary:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
class_name ActivitySite
|
||||
extends Node3D
|
||||
|
||||
static var _all: Array = []
|
||||
|
||||
@export var site_id: StringName
|
||||
@export var action_id: StringName = SimulationIds.ACTION_REST
|
||||
@export var display_name := "Activity Site"
|
||||
@export_range(1, 12, 1) var capacity := 1
|
||||
@export var debug_label_enabled := true
|
||||
|
||||
@onready var interaction_point: Marker3D = $InteractionPoint
|
||||
|
||||
var _last_label_text := ""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if site_id.is_empty():
|
||||
push_error("ActivitySite at %s has empty site_id" % get_path())
|
||||
_update_presentation()
|
||||
return
|
||||
var existing := get_by_id(site_id)
|
||||
if existing != null:
|
||||
push_error(
|
||||
(
|
||||
"Duplicate ActivitySite site_id '%s' at %s; first registered at %s"
|
||||
% [site_id, get_path(), existing.get_path()]
|
||||
)
|
||||
)
|
||||
_update_presentation()
|
||||
return
|
||||
_all.append(self)
|
||||
add_to_group("activity_sites")
|
||||
_update_presentation()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if debug_label_enabled:
|
||||
_update_presentation()
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
_all.erase(self)
|
||||
|
||||
|
||||
func get_interaction_position() -> Vector3:
|
||||
return interaction_point.global_position if interaction_point != null else global_position
|
||||
|
||||
|
||||
func supports_action(candidate_action_id: StringName) -> bool:
|
||||
return action_id == candidate_action_id
|
||||
|
||||
|
||||
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\ncap:%d" % [display_name, action_id, capacity]
|
||||
if text == _last_label_text:
|
||||
return
|
||||
_last_label_text = text
|
||||
label.text = text
|
||||
|
||||
|
||||
static func get_by_id(search_id: StringName):
|
||||
for node in _all:
|
||||
if node.site_id == search_id:
|
||||
return node
|
||||
return null
|
||||
|
||||
|
||||
static func get_all() -> Array:
|
||||
return _all.duplicate()
|
||||
+58
-10
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=25 format=3]
|
||||
[gd_scene load_steps=26 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"]
|
||||
@@ -14,6 +14,7 @@
|
||||
[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"]
|
||||
[ext_resource type="Script" path="res://world/activity/ActivitySite.gd" id="15_activity"]
|
||||
|
||||
[sub_resource type="Terrain3DMaterial" id="Terrain3DMaterial_jajce"]
|
||||
_shader_parameters = {
|
||||
@@ -251,29 +252,76 @@ yield_per_action = 3.0
|
||||
[node name="VillagePantry" parent="WorldObjects/StorageSites" instance=ExtResource("14_storage")]
|
||||
position = Vector3(0, 0, -8)
|
||||
|
||||
[node name="LegacyActivityMarkers" type="Node3D" parent="."]
|
||||
[node name="ActivitySites" type="Node3D" parent="WorldObjects"]
|
||||
|
||||
[node name="GuardZone" type="Marker3D" parent="LegacyActivityMarkers"]
|
||||
[node name="GuardPost" type="Node3D" parent="WorldObjects/ActivitySites"]
|
||||
position = Vector3(0, 0, 8)
|
||||
script = ExtResource("15_activity")
|
||||
site_id = &"guard_post"
|
||||
action_id = &"patrol"
|
||||
display_name = "Guard Post"
|
||||
capacity = 2
|
||||
|
||||
[node name="GuardTowerVisual" type="MeshInstance3D" parent="LegacyActivityMarkers/GuardZone"]
|
||||
[node name="GuardTowerVisual" type="MeshInstance3D" parent="WorldObjects/ActivitySites/GuardPost"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.25, 0)
|
||||
mesh = SubResource("Mesh_guard_post")
|
||||
|
||||
[node name="StudyZone" type="Marker3D" parent="LegacyActivityMarkers"]
|
||||
position = Vector3(-6, 0, 6)
|
||||
[node name="InteractionPoint" type="Marker3D" parent="WorldObjects/ActivitySites/GuardPost"]
|
||||
|
||||
[node name="StudyDeskVisual" type="MeshInstance3D" parent="LegacyActivityMarkers/StudyZone"]
|
||||
[node name="DebugLabel" type="Label3D" parent="WorldObjects/ActivitySites/GuardPost"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.8, 0)
|
||||
billboard = 1
|
||||
no_depth_test = true
|
||||
font_size = 18
|
||||
outline_modulate = Color(0, 0, 0, 1)
|
||||
outline_size = 4
|
||||
text = "Guard Post"
|
||||
|
||||
[node name="StudyDesk" type="Node3D" parent="WorldObjects/ActivitySites"]
|
||||
position = Vector3(-6, 0, 6)
|
||||
script = ExtResource("15_activity")
|
||||
site_id = &"study_desk"
|
||||
action_id = &"study"
|
||||
display_name = "Study Desk"
|
||||
|
||||
[node name="StudyDeskVisual" type="MeshInstance3D" parent="WorldObjects/ActivitySites/StudyDesk"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.125, 0)
|
||||
mesh = SubResource("Mesh_study_desk")
|
||||
|
||||
[node name="RestZone" type="Marker3D" parent="LegacyActivityMarkers"]
|
||||
position = Vector3(4, 0, 5)
|
||||
[node name="InteractionPoint" type="Marker3D" parent="WorldObjects/ActivitySites/StudyDesk"]
|
||||
|
||||
[node name="RestBenchVisual" type="MeshInstance3D" parent="LegacyActivityMarkers/RestZone"]
|
||||
[node name="DebugLabel" type="Label3D" parent="WorldObjects/ActivitySites/StudyDesk"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0)
|
||||
billboard = 1
|
||||
no_depth_test = true
|
||||
font_size = 18
|
||||
outline_modulate = Color(0, 0, 0, 1)
|
||||
outline_size = 4
|
||||
text = "Study Desk"
|
||||
|
||||
[node name="RestBench" type="Node3D" parent="WorldObjects/ActivitySites"]
|
||||
position = Vector3(4, 0, 5)
|
||||
script = ExtResource("15_activity")
|
||||
site_id = &"rest_bench"
|
||||
action_id = &"rest"
|
||||
display_name = "Rest Bench"
|
||||
capacity = 2
|
||||
|
||||
[node name="RestBenchVisual" type="MeshInstance3D" parent="WorldObjects/ActivitySites/RestBench"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.15, 0)
|
||||
mesh = SubResource("Mesh_rest_bench")
|
||||
|
||||
[node name="InteractionPoint" type="Marker3D" parent="WorldObjects/ActivitySites/RestBench"]
|
||||
|
||||
[node name="DebugLabel" type="Label3D" parent="WorldObjects/ActivitySites/RestBench"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0)
|
||||
billboard = 1
|
||||
no_depth_test = true
|
||||
font_size = 18
|
||||
outline_modulate = Color(0, 0, 0, 1)
|
||||
outline_size = 4
|
||||
text = "Rest Bench"
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
rotation_degrees = Vector3(-55, -35, 0)
|
||||
light_color = Color(1, 0.87, 0.72, 1)
|
||||
|
||||
@@ -91,15 +91,12 @@ func _update_presentation() -> void:
|
||||
label.text = text
|
||||
|
||||
|
||||
static func get_by_id(search_id: StringName) -> StorageNode:
|
||||
static func get_by_id(search_id: StringName):
|
||||
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
|
||||
static func get_all() -> Array:
|
||||
return _all.duplicate()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cgxnb8qsttpqy
|
||||
Reference in New Issue
Block a user