1
Fork 0
mirror of https://github.com/Steffo99/hella-farm.git synced 2024-11-25 01:24:23 +00:00

Implement the new behaviour system on Sheep to test it out

This commit is contained in:
Steffo 2024-04-17 04:52:11 +02:00
parent 6328c2ef0d
commit 1f8a553294
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
17 changed files with 216 additions and 73 deletions

View file

@ -4,3 +4,6 @@ class_name Move
signal move(norm: Vector2) signal move(norm: Vector2)
## Whether this component should emit [signal move].
@export var enabled: bool = true

View file

@ -1,11 +1,18 @@
extends Move extends Move
class_name MoveStraight class_name MoveStraight
## A [Move] that moves in a fixed direction. ## A [Move] that moves in a fixed direction.
@export var direction: Vector2 signal changed_direction(new: Vector2)
@export var direction: Vector2:
get:
return direction
set(value):
direction = value
changed_direction.emit(direction)
func randomize_direction() -> void: func randomize_direction() -> void:
@ -13,4 +20,5 @@ func randomize_direction() -> void:
func _physics_process(_delta: float) -> void: func _physics_process(_delta: float) -> void:
if enabled:
move.emit(direction) move.emit(direction)

View file

@ -5,7 +5,15 @@ class_name MoveTowards
## A [Move] that moves towards the [field position] of a [field target]. ## A [Move] that moves towards the [field position] of a [field target].
@export var target: Node2D = null signal changed_target(target: Node2D)
@export var target: Node2D = null:
get:
return target
set(value):
value = target
changed_target.emit()
func set_target(value: Node2D) -> void: func set_target(value: Node2D) -> void:
@ -15,11 +23,8 @@ func clear_target() -> void:
target = null target = null
func _ready() -> void:
if target == null:
Log.w(self, "No target is set, no signals will be emitted.")
func _physics_process(_delta: float) -> void: func _physics_process(_delta: float) -> void:
if enabled:
if target: if target:
var gap = target.global_position - global_position var gap = target.global_position - global_position
var norm = gap.normalized() var norm = gap.normalized()

View file

@ -3,8 +3,31 @@ extends Node
class_name Priority class_name Priority
## Keeps track of the object's priority
signal priority_changed(new: int, old: int)
signal priority_changed_no_args
@export var priority: int = 0 @export var priority: int = 0
func set_priority(value: int):
var old = priority
priority = value
priority_changed.emit(priority, old)
func set_priority_if_truthy(variant: Variant, truthy: int, falsy: int = 0):
if variant:
set_priority(truthy)
else:
set_priority(falsy)
func get_ref() -> Node: func get_ref() -> Node:
return get_parent() return get_parent()
func _on_priority_changed(new: int, _old: int) -> void:
Log.p(self, "Priority changed to: %s" % new)
priority_changed_no_args.emit()

View file

@ -4,3 +4,5 @@
[node name="Priority" type="Node"] [node name="Priority" type="Node"]
script = ExtResource("1_8u7ji") script = ExtResource("1_8u7ji")
[connection signal="priority_changed" from="." to="." method="_on_priority_changed"]

View file

@ -6,7 +6,24 @@ class_name Sampler
## Abstract base class for sampling a certain reference among multiple. ## Abstract base class for sampling a certain reference among multiple.
signal notify_selected(node: Node)
signal notify_deselected(node: Node)
@export var possibilities: Array[Node] = []
## Get a reference. ## Get a reference.
func sample() -> Object: func sample() -> Node:
Log.e(self, "Not implemented.") Log.e(self, "Not implemented.")
return null return null
## Get all possible nodes referenced by [field possibilities].
func get_refs() -> Array[Node]:
return possibilities
## Set the "enabled" property on
func enable() -> void:
var selected = sample()
for possibility in get_refs():
possibility.enabled = (selected == possibility)

View file

@ -5,9 +5,6 @@ class_name SamplerPriority
## Always sample the object with the highest priority in the queue. ## Always sample the object with the highest priority in the queue.
@export var possibilities: Array[Priority] = []
## Get a reference. ## Get a reference.
func sample() -> Priority: func sample() -> Priority:
if len(possibilities) == 0: if len(possibilities) == 0:
@ -16,10 +13,17 @@ func sample() -> Priority:
# FIXME: Change this to something more efficient when needed # FIXME: Change this to something more efficient when needed
var highest_possibility: Priority = null var highest_possibility: Priority = null
for possibility in possibilities: for possibility in possibilities:
if possibility.priority > highest_possibility.priority: if highest_possibility == null or possibility.priority > highest_possibility.priority:
highest_possibility = possibility highest_possibility = possibility
if highest_possibility == null: if highest_possibility == null:
return null return null
Log.p(self, "Sampled: %s" % highest_possibility)
return highest_possibility.get_ref() return highest_possibility.get_ref()
func get_refs() -> Array[Node]:
var refs: Array[Node] = []
for possibility in possibilities:
refs.append(possibility.get_ref())
return refs

View file

@ -5,10 +5,7 @@ class_name SamplerRandom
## Sample a random reference from the array. ## Sample a random reference from the array.
@export var possibilities: Array = [] func sample() -> Node:
func sample() -> Object:
if len(possibilities) == 0: if len(possibilities) == 0:
return null return null
return Random.sample(possibilities) return Random.sample(possibilities)

View file

@ -5,11 +5,10 @@ class_name SamplerWeighted
## Sample a random reference from the array, considering the given weights. ## Sample a random reference from the array, considering the given weights.
@export var possibilities: Array = []
@export var weights: Array[int] = [] @export var weights: Array[int] = []
func sample() -> Object: func sample() -> Node:
var total = compute_total_weight() var total = compute_total_weight()
if total == 0: if total == 0:
return null return null

View file

@ -1,3 +1,4 @@
@icon("res://behaviours/tracker.svg")
extends Area2D extends Area2D
class_name Tracker class_name Tracker
@ -15,6 +16,9 @@ func track(body: Node2D) -> bool:
if act: if act:
tracking.push_back(body) tracking.push_back(body)
tracked.emit(body) tracked.emit(body)
# Handle TrackerTracker
for tracker_tracker in body.find_children("*", "TrackerTracker", false, false):
tracker_tracker.track(self)
return act return act
func untrack(body: Node2D) -> bool: func untrack(body: Node2D) -> bool:
@ -22,6 +26,9 @@ func untrack(body: Node2D) -> bool:
if act: if act:
tracking.erase(body) tracking.erase(body)
untracked.emit(body) untracked.emit(body)
# Handle TrackerTracker
for tracker_tracker in body.find_children("*", "TrackerTracker", false, false):
tracker_tracker.untrack(self)
return act return act
func log_tracked(body: Node2D) -> void: func log_tracked(body: Node2D) -> void:

39
behaviours/tracker.svg Normal file
View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="tracker.svg"
width="16"
height="16"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="8"
inkscape:cx="21.0625"
inkscape:cy="41.9375"
inkscape:window-width="1280"
inkscape:window-height="964"
inkscape:window-x="0"
inkscape:window-y="60"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. -->
<path
d="m 256,0 c 17.7,0 32,14.3 32,32 v 10.4 c 93.7,13.9 167.7,88 181.6,181.6 H 480 c 17.7,0 32,14.3 32,32 0,17.7 -14.3,32 -32,32 H 469.6 C 455.7,381.7 381.6,455.7 288,469.6 V 480 c 0,17.7 -14.3,32 -32,32 -17.7,0 -32,-14.3 -32,-32 V 469.6 C 130.3,455.7 56.3,381.7 42.4,288 H 32 C 14.3,288 0,273.7 0,256 0,238.3 14.3,224 32,224 H 42.4 C 56.3,130.3 130.3,56.3 224,42.4 V 32 C 224,14.3 238.3,0 256,0 Z M 107.4,288 c 12.5,58.3 58.4,104.1 116.6,116.6 V 384 c 0,-17.7 14.3,-32 32,-32 17.7,0 32,14.3 32,32 v 20.6 C 346.3,392.1 392.1,346.2 404.6,288 H 384 c -17.7,0 -32,-14.3 -32,-32 0,-17.7 14.3,-32 32,-32 h 20.6 C 392.1,165.7 346.3,119.9 288,107.4 V 128 c 0,17.7 -14.3,32 -32,32 -17.7,0 -32,-14.3 -32,-32 V 107.4 C 165.7,119.9 119.9,165.7 107.4,224 H 128 c 17.7,0 32,14.3 32,32 0,17.7 -14.3,32 -32,32 z M 256,224 a 32,32 0 1 1 0,64 32,32 0 1 1 0,-64 z"
id="path1"
style="fill:#699ce8" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -2,16 +2,16 @@
importer="texture" importer="texture"
type="CompressedTexture2D" type="CompressedTexture2D"
uid="uid://8443tt517pkv" uid="uid://b3myvaqud7w0p"
path="res://.godot/imported/tracker_edible.svg-fb108b51d33883549e8e498a16701c4f.ctex" path="res://.godot/imported/tracker.svg-98e9b55805c6d630e7da524610510efd.ctex"
metadata={ metadata={
"vram_texture": false "vram_texture": false
} }
[deps] [deps]
source_file="res://behaviours/tracker_edible.svg" source_file="res://behaviours/tracker.svg"
dest_files=["res://.godot/imported/tracker_edible.svg-fb108b51d33883549e8e498a16701c4f.ctex"] dest_files=["res://.godot/imported/tracker.svg-98e9b55805c6d630e7da524610510efd.ctex"]
[params] [params]

View file

@ -1,4 +1,3 @@
@icon("res://behaviours/tracker_edible.svg")
extends Tracker extends Tracker
class_name EdibleTracker class_name EdibleTracker
@ -9,7 +8,7 @@ class_name EdibleTracker
func check_diet_then_track(body: Node2D) -> void: func check_diet_then_track(body: Node2D) -> void:
var edibles: Array = body.find_children("Edible", "Edible", false, false) var edibles: Array = body.find_children("*", "Edible", false, false)
for edible in edibles: for edible in edibles:
if edible.tag in acceptable_diets: if edible.tag in acceptable_diets:
track(body) track(body)

View file

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="bowl-rice.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
width="16"
height="16"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.6464844"
inkscape:cx="256"
inkscape:cy="256"
inkscape:window-width="1920"
inkscape:window-height="1020"
inkscape:window-x="1280"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. -->
<path
d="m 176,56 c 0,-13.3 10.7,-24 24,-24 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 H 200 C 186.7,80 176,69.3 176,56 Z m 24,48 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 0,-13.3 10.7,-24 24,-24 z M 56,176 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 H 56 C 42.7,224 32,213.3 32,200 32,186.7 42.7,176 56,176 Z M 0,283.4 C 0,268.3 12.3,256 27.4,256 h 457.2 c 15.1,0 27.4,12.3 27.4,27.4 0,70.5 -44.4,130.7 -106.7,154.1 l -1.8,14.5 c -2,16 -15.6,28 -31.8,28 H 140.2 c -16.1,0 -29.8,-12 -31.8,-28 l -1.8,-14.4 C 44.4,414.1 0,353.9 0,283.4 Z M 224,200 c 0,-13.3 10.7,-24 24,-24 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 z m -96,0 c 0,-13.3 10.7,-24 24,-24 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 z m -24,-96 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 0,-13.3 10.7,-24 24,-24 z m 216,96 c 0,-13.3 10.7,-24 24,-24 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 z m -24,-96 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 0,-13.3 10.7,-24 24,-24 z m 120,96 c 0,-13.3 10.7,-24 24,-24 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 z m -24,-96 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 0,-13.3 10.7,-24 24,-24 z M 296,32 h 16 c 13.3,0 24,10.7 24,24 0,13.3 -10.7,24 -24,24 h -16 c -13.3,0 -24,-10.7 -24,-24 0,-13.3 10.7,-24 24,-24 z"
id="path1"
style="fill:#8da5f3" />
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -0,0 +1,6 @@
extends Tracker
class_name TrackerTracker
## Tracks [Tracker]s tracking the parent.
##
## Shape is ignored.

View file

@ -0,0 +1,10 @@
[gd_scene load_steps=2 format=3 uid="uid://c5pyp5hvthdof"]
[ext_resource type="Script" path="res://behaviours/tracker_tracker.gd" id="1_7b21r"]
[node name="TrackerTracker" type="Area2D"]
collision_layer = 0
collision_mask = 0
monitoring = false
monitorable = false
script = ExtResource("1_7b21r")

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=14 format=3 uid="uid://bc2bm8lbol18w"] [gd_scene load_steps=21 format=3 uid="uid://bc2bm8lbol18w"]
[ext_resource type="Script" path="res://entities/sheep.gd" id="1_4dmll"] [ext_resource type="Script" path="res://entities/sheep.gd" id="1_4dmll"]
[ext_resource type="Texture2D" uid="uid://iljp5yn3ehfk" path="res://entities/sheep_left.png" id="2_t13f5"] [ext_resource type="Texture2D" uid="uid://iljp5yn3ehfk" path="res://entities/sheep_left.png" id="2_t13f5"]
@ -8,6 +8,12 @@
[ext_resource type="AudioStream" uid="uid://buxgivpkh8dyl" path="res://entities/drop.wav" id="4_nxjnl"] [ext_resource type="AudioStream" uid="uid://buxgivpkh8dyl" path="res://entities/drop.wav" id="4_nxjnl"]
[ext_resource type="AudioStream" uid="uid://bmfscpnugaejk" path="res://entities/sheep_drag.wav" id="4_oalqu"] [ext_resource type="AudioStream" uid="uid://bmfscpnugaejk" path="res://entities/sheep_drag.wav" id="4_oalqu"]
[ext_resource type="PackedScene" uid="uid://dfdr3e32lohq" path="res://behaviours/edible.tscn" id="6_3odsh"] [ext_resource type="PackedScene" uid="uid://dfdr3e32lohq" path="res://behaviours/edible.tscn" id="6_3odsh"]
[ext_resource type="PackedScene" uid="uid://djcwis8ycrq85" path="res://behaviours/sampler_priority.tscn" id="9_s5lod"]
[ext_resource type="PackedScene" uid="uid://dk1ipq7dhkhf3" path="res://behaviours/move_straight.tscn" id="10_05kcd"]
[ext_resource type="PackedScene" uid="uid://cm67ko1k6kn4u" path="res://behaviours/priority.tscn" id="11_0jlmk"]
[ext_resource type="PackedScene" uid="uid://cml7rqvyfuagx" path="res://behaviours/move_towards.tscn" id="12_x2g3x"]
[ext_resource type="PackedScene" uid="uid://cbg5kgwxusvxf" path="res://behaviours/cursor_detector.tscn" id="13_5fkdr"]
[ext_resource type="PackedScene" uid="uid://c5pyp5hvthdof" path="res://behaviours/tracker_tracker.tscn" id="14_eqowb"]
[sub_resource type="CircleShape2D" id="CircleShape2D_c5tcn"] [sub_resource type="CircleShape2D" id="CircleShape2D_c5tcn"]
radius = 8.0 radius = 8.0
@ -70,6 +76,9 @@ _data = {
"wobble": SubResource("Animation_lxieb") "wobble": SubResource("Animation_lxieb")
} }
[sub_resource type="CircleShape2D" id="CircleShape2D_etpf6"]
radius = 144.0
[node name="Sheep" type="CharacterBody2D"] [node name="Sheep" type="CharacterBody2D"]
collision_layer = 8 collision_layer = 8
collision_mask = 14 collision_mask = 14
@ -97,12 +106,66 @@ stream = ExtResource("4_oalqu")
scale = Vector2(0.5, 0.5) scale = Vector2(0.5, 0.5)
stream = ExtResource("4_nxjnl") stream = ExtResource("4_nxjnl")
[node name="Edible" parent="." instance=ExtResource("6_3odsh")]
[node name="Animator" type="AnimationPlayer" parent="."] [node name="Animator" type="AnimationPlayer" parent="."]
libraries = { libraries = {
"": SubResource("AnimationLibrary_6mutq") "": SubResource("AnimationLibrary_6mutq")
} }
[node name="Edible" parent="." instance=ExtResource("6_3odsh")]
[node name="Movement" parent="." node_paths=PackedStringArray("possibilities") instance=ExtResource("9_s5lod")]
possibilities = [NodePath("Idle/IdlePriority"), NodePath("Wander/WanderPriority"), NodePath("RunFromMouse/RunFromMousePriority"), NodePath("RunFromHunter/RunFromHunterPriority")]
[node name="Idle" parent="Movement" instance=ExtResource("10_05kcd")]
enabled = false
[node name="IdlePriority" parent="Movement/Idle" instance=ExtResource("11_0jlmk")]
priority = 10
[node name="BoredTimer" type="Timer" parent="Movement/Idle"]
one_shot = true
autostart = true
[node name="Wander" parent="Movement" instance=ExtResource("10_05kcd")]
enabled = false
[node name="WanderPriority" parent="Movement/Wander" instance=ExtResource("11_0jlmk")]
[node name="TiredTimer" type="Timer" parent="Movement/Wander"]
one_shot = true
[node name="RunFromMouse" parent="Movement" instance=ExtResource("12_x2g3x")]
enabled = false
[node name="RunFromMousePriority" parent="Movement/RunFromMouse" instance=ExtResource("11_0jlmk")]
[node name="CursorDetector" parent="Movement/RunFromMouse" instance=ExtResource("13_5fkdr")]
[node name="Shape" type="CollisionShape2D" parent="Movement/RunFromMouse/CursorDetector"]
shape = SubResource("CircleShape2D_etpf6")
debug_color = Color(1, 0, 0, 0.0470588)
[node name="RunFromHunter" parent="Movement" instance=ExtResource("12_x2g3x")]
enabled = false
[node name="RunFromHunterPriority" parent="Movement/RunFromHunter" instance=ExtResource("11_0jlmk")]
[node name="TrackerTracker" parent="Movement/RunFromHunter" instance=ExtResource("14_eqowb")]
[connection signal="dragged" from="Draggable" to="." method="_on_draggable_dragged"] [connection signal="dragged" from="Draggable" to="." method="_on_draggable_dragged"]
[connection signal="dropped" from="Draggable" to="." method="_on_draggable_dropped"] [connection signal="dropped" from="Draggable" to="." method="_on_draggable_dropped"]
[connection signal="ready" from="Movement" to="Movement" method="enable"]
[connection signal="priority_changed_no_args" from="Movement/Idle/IdlePriority" to="Movement" method="enable"]
[connection signal="timeout" from="Movement/Idle/BoredTimer" to="Movement/Wander" method="randomize_direction"]
[connection signal="changed_direction" from="Movement/Wander" to="Movement/Wander/WanderPriority" method="set_priority_if_truthy" binds= [20]]
[connection signal="changed_direction" from="Movement/Wander" to="Movement/Wander/TiredTimer" method="start" unbinds=1]
[connection signal="priority_changed_no_args" from="Movement/Wander/WanderPriority" to="Movement" method="enable"]
[connection signal="timeout" from="Movement/Wander/TiredTimer" to="Movement/Wander/WanderPriority" method="set_priority" binds= [0]]
[connection signal="changed_target" from="Movement/RunFromMouse" to="Movement/RunFromMouse/RunFromMousePriority" method="set_priority_if_truthy" binds= [30]]
[connection signal="priority_changed_no_args" from="Movement/RunFromMouse/RunFromMousePriority" to="Movement" method="enable"]
[connection signal="cursor_entered" from="Movement/RunFromMouse/CursorDetector" to="Movement/RunFromMouse" method="set_target"]
[connection signal="cursor_exited" from="Movement/RunFromMouse/CursorDetector" to="Movement/RunFromMouse" method="clear_target" unbinds=1]
[connection signal="changed_target" from="Movement/RunFromHunter" to="Movement/RunFromHunter/RunFromHunterPriority" method="set_priority_if_truthy" binds= [40]]
[connection signal="priority_changed_no_args" from="Movement/RunFromHunter/RunFromHunterPriority" to="Movement" method="enable"]
[connection signal="tracked" from="Movement/RunFromHunter/TrackerTracker" to="Movement/RunFromHunter" method="set_target"]
[connection signal="untracked" from="Movement/RunFromHunter/TrackerTracker" to="Movement/RunFromHunter" method="clear_target" unbinds=1]