diff --git a/behaviours/priority.gd b/behaviours/priority.gd index 54509b1..cda9e94 100644 --- a/behaviours/priority.gd +++ b/behaviours/priority.gd @@ -9,10 +9,6 @@ class_name Priority ## Emitted when the priority is changed. signal priority_changed(new: int, old: int) -## Emitted when the priority is changed. No args are provided to work around a Godot bug. -signal priority_changed_no_args - - @export var default_priority: int = 0 @export var alternative_priority: int = 1 @@ -61,9 +57,5 @@ func get_ref() -> Node: func log_priority() -> void: Log.p(self, "Priority: %d" % priority) - -func _on_priority_changed(_new: int, _old: int) -> void: - priority_changed_no_args.emit() - func _ready() -> void: priority = default_priority diff --git a/behaviours/sampler.gd b/behaviours/sampler.gd index 00b87eb..bd9dc66 100644 --- a/behaviours/sampler.gd +++ b/behaviours/sampler.gd @@ -9,6 +9,12 @@ class_name Sampler ## [Array] of [Node]s that can be [func sample]d by this [Sampler]. @export var possibilities: Array[Node] = [] +## If true, the [Sampler] will attempt to automatically [method sample_and_enable] on NOTIFICATION_READY. +@export var autoenable_on_ready: bool = true + + +var selected: Node = null + ## Get a reference. func sample() -> Node: @@ -16,14 +22,27 @@ func sample() -> Node: return null ## Set the [field enabled] property to true on a [method sample]d node, and to false on all others. -func enable() -> void: - var selected = sample() - for possibility in get_all_refs(): - possibility.enabled = (selected == possibility) +func sample_and_enable() -> void: + set_enabled(sample()) +func set_enabled(node: Node) -> void: + if node == selected: + return + selected = node + var selected_ref = get_ref(selected) + for possibility in get_all_refs(): + possibility.enabled = (selected_ref == possibility) + +func get_ref(node: Node) -> Node: + return node ## Get all possible nodes referenced by [field possibilities]. ## ## Useful as it may be overridden by some other [Sampler]s, such as [SamplerPriority]. func get_all_refs() -> Array[Node]: - return possibilities \ No newline at end of file + return possibilities + + +func _ready() -> void: + if autoenable_on_ready: + sample_and_enable.call_deferred() diff --git a/behaviours/sampler_priority.gd b/behaviours/sampler_priority.gd index c925afb..1f32196 100644 --- a/behaviours/sampler_priority.gd +++ b/behaviours/sampler_priority.gd @@ -2,8 +2,21 @@ extends Sampler class_name SamplerPriority -## Always sample the object with the highest priority in the queue. +## If true, the [Sampler] will attempt to automatically detect the [field possibilities] on NOTIFICATION_READY. +@export var autodetect_possibilities_on_ready: bool = true +## If true, the [SamplerPriority] will attempt to automatically setup the recommended signals for all the [field possibilities] on NOTIFICATION_READY. +@export var autosetup_signals_on_ready: bool = true + + +## Update [field possibilities] with the most likely subset of nodes. +func autodetect_possibilities() -> void: + possibilities = get_parent().find_children("*", "Priority", true, false) + +## Setup the recommended signals for each node in [field possibilities]. +func autosetup_signals() -> void: + for possibility in possibilities: + possibility.priority_changed.connect(_autosetup_on_possibility_priority_changed.bind(possibility)) ## Get a reference. func sample() -> Priority: @@ -18,11 +31,31 @@ func sample() -> Priority: if highest_possibility == null: return null - - return highest_possibility.get_ref() + + return highest_possibility func get_all_refs() -> Array[Node]: var refs: Array[Node] = [] for possibility in possibilities: refs.append(possibility.get_ref()) return refs + +func get_ref(node: Node) -> Node: + return node.get_ref() + + +func _ready() -> void: + super._ready() + if autodetect_possibilities_on_ready: + autodetect_possibilities() + if autosetup_signals_on_ready: + autosetup_signals() + +func _autosetup_on_possibility_priority_changed(new: int, old: int, node: Priority): + if node == selected: + if new < old: + sample_and_enable() + else: + # A nice optimization! + if selected == null or new > selected.priority: + set_enabled(node) diff --git a/entities/imp.tscn b/entities/imp.tscn index e58fc3e..161275e 100644 --- a/entities/imp.tscn +++ b/entities/imp.tscn @@ -57,8 +57,7 @@ deviation = 4.0 min_secs = 1.0 max_secs = 9.0 -[node name="MovementSampler" parent="." node_paths=PackedStringArray("possibilities") instance=ExtResource("7_ech8d")] -possibilities = [NodePath("../MovementWander/WanderPriority"), NodePath("../MovementHunt/HuntPriority"), NodePath("../MovementDrag/DragPriority")] +[node name="MovementSampler" parent="." instance=ExtResource("7_ech8d")] [node name="MovementWander" parent="." instance=ExtResource("8_ffcw0")] speed = 25.0 @@ -121,14 +120,11 @@ debug_color = Color(1, 0, 0, 0) stream = ExtResource("19_7la6c") [connection signal="timeout" from="GoldSpawner/TimerStddev" to="GoldSpawner" method="spawn"] -[connection signal="ready" from="MovementSampler" to="MovementSampler" method="enable"] [connection signal="changed_direction" from="MovementWander" to="MovementWander/WanderPriority" method="priority_conditional"] [connection signal="move" from="MovementWander" to="." method="_on_move"] -[connection signal="priority_changed_no_args" from="MovementWander/WanderPriority" to="MovementSampler" method="enable"] [connection signal="timeout" from="MovementWander/ChangeDirectionTimer" to="MovementWander" method="randomize_direction"] [connection signal="changed_target" from="MovementHunt" to="MovementHunt/HuntPriority" method="priority_conditional"] [connection signal="move" from="MovementHunt" to="." method="_on_move"] -[connection signal="priority_changed_no_args" from="MovementHunt/HuntPriority" to="MovementSampler" method="enable"] [connection signal="tracked" from="MovementHunt/TrackerMeat" to="MovementHunt/TrackerMeat/TargetPicker" method="sample_target_if_null" unbinds=1] [connection signal="untracked" from="MovementHunt/TrackerMeat" to="MovementHunt/TrackerMeat/TargetPicker" method="clear_if_target"] [connection signal="target_changed" from="MovementHunt/TrackerMeat/TargetPicker" to="MovementHunt" method="set_target" unbinds=1] @@ -140,7 +136,6 @@ stream = ExtResource("19_7la6c") [connection signal="fallen" from="MovementDrag" to="MovementDrag/DragPriority" method="priority_default"] [connection signal="fallen" from="MovementDrag" to="MovementDrag/FallSound" method="play"] [connection signal="move" from="MovementDrag" to="." method="_on_move"] -[connection signal="priority_changed_no_args" from="MovementDrag/DragPriority" to="MovementSampler" method="enable"] [connection signal="dragged" from="MovementDrag/Draggable" to="MovementDrag" method="drag"] [connection signal="dropped" from="MovementDrag/Draggable" to="MovementDrag" method="drop"] [connection signal="eaten" from="Eater" to="." method="_on_eater_eaten"] diff --git a/entities/sheep.tscn b/entities/sheep.tscn index b07e995..e4795f2 100644 --- a/entities/sheep.tscn +++ b/entities/sheep.tscn @@ -107,8 +107,7 @@ libraries = { [node name="Edible" parent="." instance=ExtResource("6_3odsh")] diet = &"Meat" -[node name="MovementSampler" parent="." node_paths=PackedStringArray("possibilities") instance=ExtResource("9_s5lod")] -possibilities = [NodePath("../MovementIdle/IdlePriority"), NodePath("../MovementWander/WanderPriority"), NodePath("../MovementRunFromMouse/RunFromMousePriority"), NodePath("../MovementRunFromHunter/RunFromHunterPriority"), NodePath("../MovementDrag/DragPriority")] +[node name="MovementSampler" parent="." instance=ExtResource("9_s5lod")] [node name="MovementIdle" parent="." instance=ExtResource("10_05kcd")] speed = 0.0 @@ -184,28 +183,23 @@ stream = ExtResource("16_nswfl") [node name="FallSound" type="AudioStreamPlayer2D" parent="MovementDrag"] stream = ExtResource("17_8kst2") -[connection signal="ready" from="MovementSampler" to="MovementSampler" method="enable"] [connection signal="move" from="MovementIdle" to="." method="_on_move"] [connection signal="move_disabled" from="MovementIdle" to="MovementIdle/BoredTimer" method="stop"] [connection signal="move_enabled" from="MovementIdle" to="MovementIdle/BoredTimer" method="start"] -[connection signal="priority_changed_no_args" from="MovementIdle/IdlePriority" to="MovementSampler" method="enable"] [connection signal="timeout" from="MovementIdle/BoredTimer" to="MovementWander" method="randomize_direction"] [connection signal="changed_direction" from="MovementWander" to="MovementWander/WanderPriority" method="priority_conditional"] [connection signal="move" from="MovementWander" to="." method="_on_move"] [connection signal="move_disabled" from="MovementWander" to="MovementWander/TiredTimer" method="stop"] [connection signal="move_enabled" from="MovementWander" to="MovementWander/TiredTimer" method="start"] -[connection signal="priority_changed_no_args" from="MovementWander/WanderPriority" to="MovementSampler" method="enable"] [connection signal="timeout" from="MovementWander/TiredTimer" to="MovementWander" method="clear_direction"] [connection signal="changed_target" from="MovementRunFromMouse" to="MovementRunFromMouse/RunFromMousePriority" method="priority_conditional"] [connection signal="move" from="MovementRunFromMouse" to="." method="_on_move"] [connection signal="move_enabled" from="MovementRunFromMouse" to="MovementWander" method="clear_direction"] -[connection signal="priority_changed_no_args" from="MovementRunFromMouse/RunFromMousePriority" to="MovementSampler" method="enable"] [connection signal="cursor_entered" from="MovementRunFromMouse/CursorSense" to="MovementRunFromMouse" method="set_target"] [connection signal="cursor_exited" from="MovementRunFromMouse/CursorSense" to="MovementRunFromMouse" method="clear_target" unbinds=1] [connection signal="changed_target" from="MovementRunFromHunter" to="MovementRunFromHunter/RunFromHunterPriority" method="priority_conditional"] [connection signal="move" from="MovementRunFromHunter" to="." method="_on_move"] [connection signal="move_disabled" from="MovementRunFromHunter" to="MovementWander" method="clear_direction"] -[connection signal="priority_changed_no_args" from="MovementRunFromHunter/RunFromHunterPriority" to="MovementSampler" method="enable"] [connection signal="tracked" from="MovementRunFromHunter/HunterSense" to="MovementRunFromHunter/HunterSense/TargetPicker" method="set_target_if_null"] [connection signal="untracked" from="MovementRunFromHunter/HunterSense" to="MovementRunFromHunter/HunterSense/TargetPicker" method="clear_if_target"] [connection signal="target_changed" from="MovementRunFromHunter/HunterSense/TargetPicker" to="MovementRunFromHunter" method="set_target" unbinds=1] @@ -217,6 +211,5 @@ stream = ExtResource("17_8kst2") [connection signal="fallen" from="MovementDrag" to="MovementDrag/FallSound" method="play"] [connection signal="move" from="MovementDrag" to="." method="_on_move"] [connection signal="move_enabled" from="MovementDrag" to="MovementWander" method="clear_direction"] -[connection signal="priority_changed_no_args" from="MovementDrag/DragPriority" to="MovementSampler" method="enable"] [connection signal="dragged" from="MovementDrag/Draggable" to="MovementDrag" method="drag"] [connection signal="dropped" from="MovementDrag/Draggable" to="MovementDrag" method="drop"]