mirror of
https://github.com/Steffo99/hella-farm.git
synced 2024-11-21 15:44:23 +00:00
Refactor movement and entity logic
This commit is contained in:
parent
d0546fb5d1
commit
a3d98df9ff
16 changed files with 265 additions and 104 deletions
23
behaviours/ai_hunter_erratic.tscn
Normal file
23
behaviours/ai_hunter_erratic.tscn
Normal file
|
@ -0,0 +1,23 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://cgq2jkbrw1y0o"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ctpn4hvkhxoi3" path="res://behaviours/edible_tracker.tscn" id="1_h53ag"]
|
||||
[ext_resource type="PackedScene" uid="uid://dti7l0d40hhgt" path="res://behaviours/target_picker.tscn" id="2_h4v3e"]
|
||||
[ext_resource type="Script" path="res://behaviours/move_towards.gd" id="3_ucief"]
|
||||
|
||||
[node name="AIHunterRandom" type="Node2D"]
|
||||
|
||||
[node name="EdibleTracker" parent="." instance=ExtResource("1_h53ag")]
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
wait_time = 2.4
|
||||
autostart = true
|
||||
|
||||
[node name="TargetPicker" parent="." node_paths=PackedStringArray("tracker") instance=ExtResource("2_h4v3e")]
|
||||
tracker = NodePath("../EdibleTracker")
|
||||
|
||||
[node name="MoveTowards" type="Node2D" parent="."]
|
||||
script = ExtResource("3_ucief")
|
||||
|
||||
[connection signal="untracked" from="EdibleTracker" to="TargetPicker" method="clear_if_target"]
|
||||
[connection signal="timeout" from="Timer" to="TargetPicker" method="sample_target"]
|
||||
[connection signal="target_changed" from="TargetPicker" to="MoveTowards" method="set_target" unbinds=1]
|
19
behaviours/ai_hunter_latest.tscn
Normal file
19
behaviours/ai_hunter_latest.tscn
Normal file
|
@ -0,0 +1,19 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://cgnvp5bmtbpxr"]
|
||||
|
||||
[ext_resource type="Script" path="res://behaviours/move_towards.gd" id="1_demja"]
|
||||
[ext_resource type="PackedScene" uid="uid://ctpn4hvkhxoi3" path="res://behaviours/edible_tracker.tscn" id="2_jlt4x"]
|
||||
[ext_resource type="PackedScene" uid="uid://dti7l0d40hhgt" path="res://behaviours/target_picker.tscn" id="3_lfvrb"]
|
||||
|
||||
[node name="AIHunterLatest" type="Node2D"]
|
||||
|
||||
[node name="EdibleTracker" parent="." instance=ExtResource("2_jlt4x")]
|
||||
|
||||
[node name="TargetPicker" parent="." node_paths=PackedStringArray("tracker") instance=ExtResource("3_lfvrb")]
|
||||
tracker = NodePath("../EdibleTracker")
|
||||
|
||||
[node name="MoveTowards" type="Node2D" parent="."]
|
||||
script = ExtResource("1_demja")
|
||||
|
||||
[connection signal="tracked" from="EdibleTracker" to="TargetPicker" method="set_target"]
|
||||
[connection signal="untracked" from="EdibleTracker" to="TargetPicker" method="clear_if_target"]
|
||||
[connection signal="target_changed" from="TargetPicker" to="MoveTowards" method="set_target" unbinds=1]
|
19
behaviours/ai_hunter_persistent.tscn
Normal file
19
behaviours/ai_hunter_persistent.tscn
Normal file
|
@ -0,0 +1,19 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://cpq0ubwun5wec"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ctpn4hvkhxoi3" path="res://behaviours/edible_tracker.tscn" id="1_j87ny"]
|
||||
[ext_resource type="PackedScene" uid="uid://dti7l0d40hhgt" path="res://behaviours/target_picker.tscn" id="2_w2vxl"]
|
||||
[ext_resource type="Script" path="res://behaviours/move_towards.gd" id="3_14yk3"]
|
||||
|
||||
[node name="AIHunterLatest" type="Node2D"]
|
||||
|
||||
[node name="EdibleTracker" parent="." instance=ExtResource("1_j87ny")]
|
||||
|
||||
[node name="TargetPicker" parent="." node_paths=PackedStringArray("tracker") instance=ExtResource("2_w2vxl")]
|
||||
tracker = NodePath("../EdibleTracker")
|
||||
|
||||
[node name="MoveTowards" type="Node2D" parent="."]
|
||||
script = ExtResource("3_14yk3")
|
||||
|
||||
[connection signal="tracked" from="EdibleTracker" to="TargetPicker" method="set_target_if_null"]
|
||||
[connection signal="untracked" from="EdibleTracker" to="TargetPicker" method="clear_if_target"]
|
||||
[connection signal="target_changed" from="TargetPicker" to="MoveTowards" method="set_target" unbinds=1]
|
23
behaviours/ai_hunter_random.tscn
Normal file
23
behaviours/ai_hunter_random.tscn
Normal file
|
@ -0,0 +1,23 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://baiq3nu3p03rh"]
|
||||
|
||||
[ext_resource type="Script" path="res://behaviours/move_towards.gd" id="1_wlo1a"]
|
||||
[ext_resource type="PackedScene" uid="uid://ctpn4hvkhxoi3" path="res://behaviours/edible_tracker.tscn" id="2_suoff"]
|
||||
[ext_resource type="PackedScene" uid="uid://dti7l0d40hhgt" path="res://behaviours/target_picker.tscn" id="3_0uxc2"]
|
||||
|
||||
[node name="AIHunterRandom" type="Node2D"]
|
||||
|
||||
[node name="EdibleTracker" parent="." instance=ExtResource("2_suoff")]
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
wait_time = 2.4
|
||||
autostart = true
|
||||
|
||||
[node name="TargetPicker" parent="." node_paths=PackedStringArray("tracker") instance=ExtResource("3_0uxc2")]
|
||||
tracker = NodePath("../EdibleTracker")
|
||||
|
||||
[node name="MoveTowards" type="Node2D" parent="."]
|
||||
script = ExtResource("1_wlo1a")
|
||||
|
||||
[connection signal="untracked" from="EdibleTracker" to="TargetPicker" method="clear_if_target"]
|
||||
[connection signal="timeout" from="Timer" to="TargetPicker" method="sample_target_if_null"]
|
||||
[connection signal="target_changed" from="TargetPicker" to="MoveTowards" method="set_target" unbinds=1]
|
|
@ -1,34 +1,16 @@
|
|||
@icon("res://behaviours/edible_tracker.svg")
|
||||
extends Area2D
|
||||
extends Tracker
|
||||
class_name EdibleTracker
|
||||
|
||||
## Keeps track of what [Edible]s are inside the area.
|
||||
|
||||
|
||||
signal tracked(body: Node2D)
|
||||
signal untracked(body: Node2D)
|
||||
|
||||
|
||||
@export var acceptable_diets: Array[StringName] = []
|
||||
|
||||
var tracking: Array = []
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
func check_diet_then_track(body: Node2D) -> void:
|
||||
var edibles: Array = body.find_children("Edible", "Edible", false, false)
|
||||
for edible in edibles:
|
||||
if edible.tag in acceptable_diets:
|
||||
tracking.push_back(body)
|
||||
tracked.emit(body)
|
||||
|
||||
func _on_body_exited(body: Node2D) -> void:
|
||||
if body in tracking:
|
||||
tracking.erase(body)
|
||||
untracked.emit(body)
|
||||
|
||||
|
||||
func _on_tracked(body: Node2D) -> void:
|
||||
Log.p(self, "Tracking a new target: %s" % body)
|
||||
|
||||
func _on_untracked(body:Node2D) -> void:
|
||||
Log.p(self, "Not tracking anymore target: %s" % body)
|
||||
track(body)
|
||||
break
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
[ext_resource type="Script" path="res://behaviours/edible_tracker.gd" id="1_vo18u"]
|
||||
|
||||
[node name="EdibleTracker" type="Area2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 56
|
||||
monitorable = false
|
||||
script = ExtResource("1_vo18u")
|
||||
|
||||
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
|
||||
[connection signal="body_exited" from="." to="." method="_on_body_exited"]
|
||||
[connection signal="tracked" from="." to="." method="_on_tracked"]
|
||||
[connection signal="untracked" from="." to="." method="_on_untracked"]
|
||||
[connection signal="body_entered" from="." to="." method="check_diet_then_track"]
|
||||
[connection signal="body_exited" from="." to="." method="untrack"]
|
||||
[connection signal="tracked" from="." to="." method="log_tracked"]
|
||||
[connection signal="untracked" from="." to="." method="log_untracked"]
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
extends Node2D
|
||||
class_name HuntTarget
|
||||
|
||||
|
||||
signal target_selected(target: Node2D)
|
||||
signal target_abandoned(target: Node2D)
|
||||
|
||||
|
||||
@export var tag: StringName:
|
||||
get:
|
||||
return tag
|
||||
set(value):
|
||||
tag = value
|
||||
if hunter != null:
|
||||
hunter.tag = value
|
||||
|
||||
@export var give_up_secs: float = 5.0
|
||||
|
||||
@onready var give_up_timer: Timer = $"GiveUpTimer"
|
||||
@onready var hunter: Hunter = $"Hunter"
|
||||
|
||||
var target: Node2D = null
|
||||
|
||||
|
||||
func pick_new_target():
|
||||
if hunter.possible_targets.is_empty():
|
||||
return
|
||||
|
||||
var idx = Random.rng.randi_range(0, len(hunter.possible_targets) - 1)
|
||||
target = hunter.possible_targets[idx]
|
||||
target_selected.emit(target)
|
||||
give_up_timer.start(give_up_secs)
|
||||
|
||||
func _ready():
|
||||
hunter.tag = tag
|
||||
|
||||
func _on_hunter_tracked(_body: Node2D):
|
||||
if target == null:
|
||||
pick_new_target()
|
||||
|
||||
func _on_hunter_untracked(body: Node2D):
|
||||
if body == target:
|
||||
target = null
|
||||
target_abandoned.emit(body)
|
||||
pick_new_target()
|
||||
|
||||
func _on_give_up_timer_timeout() -> void:
|
||||
target = null
|
||||
pick_new_target()
|
||||
|
||||
func _on_target_selected(body: Node2D) -> void:
|
||||
Log.p(self, "Target selected: %s" % body)
|
||||
|
||||
func _on_target_abandoned(body: Node2D) -> void:
|
||||
Log.p(self, "Target abandoned: %s" % body)
|
|
@ -1,18 +0,0 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://dxmodn8mbvw0i"]
|
||||
|
||||
[ext_resource type="Script" path="res://behaviours/hunt_target.gd" id="1_1ex7u"]
|
||||
[ext_resource type="PackedScene" uid="uid://ctpn4hvkhxoi3" path="res://behaviours/edible_tracker.tscn" id="2_vjdtc"]
|
||||
|
||||
[node name="HuntTarget" type="Node2D"]
|
||||
script = ExtResource("1_1ex7u")
|
||||
give_up_secs = null
|
||||
|
||||
[node name="Hunter" parent="." instance=ExtResource("2_vjdtc")]
|
||||
|
||||
[node name="GiveUpTimer" type="Timer" parent="."]
|
||||
|
||||
[connection signal="target_abandoned" from="." to="." method="_on_target_abandoned"]
|
||||
[connection signal="target_selected" from="." to="." method="_on_target_selected"]
|
||||
[connection signal="tracked" from="Hunter" to="." method="_on_hunter_tracked"]
|
||||
[connection signal="untracked" from="Hunter" to="." method="_on_hunter_untracked"]
|
||||
[connection signal="timeout" from="GiveUpTimer" to="." method="_on_give_up_timer_timeout"]
|
|
@ -12,11 +12,19 @@ signal move(norm: Vector2)
|
|||
@export var target: Node2D = null
|
||||
|
||||
|
||||
func set_target(value: Node2D) -> void:
|
||||
target = value
|
||||
|
||||
func clear_target() -> void:
|
||||
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:
|
||||
var gap = target.global_position - global_position
|
||||
var norm = gap.normalized()
|
||||
move.emit(norm)
|
||||
if target:
|
||||
var gap = target.global_position - global_position
|
||||
var norm = gap.normalized()
|
||||
move.emit(norm)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bvrxvrjlo5130"]
|
||||
|
||||
[ext_resource type="Script" path="res://behaviours/move_towards_mouse.gd" id="1_nbja1"]
|
||||
[ext_resource type="PackedScene" uid="uid://cbg5kgwxusvxf" path="res://behaviours/hover_detector.tscn" id="2_qru2e"]
|
||||
[ext_resource type="PackedScene" uid="uid://cbg5kgwxusvxf" path="res://behaviours/cursor_detector.tscn" id="2_qru2e"]
|
||||
|
||||
[node name="MoveTowardsMouse" type="Node2D"]
|
||||
script = ExtResource("1_nbja1")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://c1wqgyakaultt"]
|
||||
|
||||
[ext_resource type="Script" path="res://behaviours/skitter_from_mouse.gd" id="1_ftcf8"]
|
||||
[ext_resource type="PackedScene" uid="uid://cbg5kgwxusvxf" path="res://behaviours/hover_detector.tscn" id="2_cuaq0"]
|
||||
[ext_resource type="PackedScene" uid="uid://cbg5kgwxusvxf" path="res://behaviours/cursor_detector.tscn" id="2_cuaq0"]
|
||||
|
||||
[node name="SkitterFromMouse" type="Node2D"]
|
||||
script = ExtResource("1_ftcf8")
|
||||
|
|
44
behaviours/target_picker.gd
Normal file
44
behaviours/target_picker.gd
Normal file
|
@ -0,0 +1,44 @@
|
|||
@icon("res://behaviours/target_picker.svg")
|
||||
extends Node
|
||||
class_name TargetPicker
|
||||
|
||||
|
||||
## Pick a random target at random from [field Tracker.tracked], then emit it via [signal target_changed].
|
||||
|
||||
|
||||
signal target_changed(new: Node2D, old: Node2D)
|
||||
|
||||
|
||||
@export var tracker: Tracker
|
||||
|
||||
|
||||
var target: Node2D:
|
||||
get:
|
||||
return target
|
||||
set(value):
|
||||
if target != value:
|
||||
var old = target
|
||||
target = value
|
||||
target_changed.emit(old, target)
|
||||
|
||||
|
||||
func set_target(body: Node2D) -> void:
|
||||
target = body
|
||||
|
||||
func set_target_if_null(body: Node2D) -> void:
|
||||
if target == null:
|
||||
target = body
|
||||
|
||||
func clear_target() -> void:
|
||||
target = null
|
||||
|
||||
func clear_if_target(body: Node2D) -> void:
|
||||
if target == body:
|
||||
clear_target()
|
||||
|
||||
func sample_target() -> void:
|
||||
target = Random.sample(tracker.tracking)
|
||||
|
||||
func sample_target_if_null() -> void:
|
||||
if target == null:
|
||||
sample_target()
|
39
behaviours/target_picker.svg
Normal file
39
behaviours/target_picker.svg
Normal 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="target_picker_random.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="3200"
|
||||
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 448,256 a 192,192 0 1 0 -384,0 192,192 0 1 0 384,0 z M 0,256 a 256,256 0 1 1 512,0 256,256 0 1 1 -512,0 z m 256,80 a 80,80 0 1 0 0,-160 80,80 0 1 0 0,160 z m 0,-224 a 144,144 0 1 1 0,288 144,144 0 1 1 0,-288 z m -32,144 a 32,32 0 1 1 64,0 32,32 0 1 1 -64,0 z"
|
||||
id="path1"
|
||||
style="fill:#e0e0e0" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
37
behaviours/target_picker.svg.import
Normal file
37
behaviours/target_picker.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dd7uvjl416h2k"
|
||||
path="res://.godot/imported/target_picker.svg-d96365c33742930a50d2b51102fd20f0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://behaviours/target_picker.svg"
|
||||
dest_files=["res://.godot/imported/target_picker.svg-d96365c33742930a50d2b51102fd20f0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
6
behaviours/target_picker.tscn
Normal file
6
behaviours/target_picker.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://dti7l0d40hhgt"]
|
||||
|
||||
[ext_resource type="Script" path="res://behaviours/target_picker.gd" id="1_ldiw7"]
|
||||
|
||||
[node name="TargetPicker" type="Node"]
|
||||
script = ExtResource("1_ldiw7")
|
31
behaviours/tracker.gd
Normal file
31
behaviours/tracker.gd
Normal file
|
@ -0,0 +1,31 @@
|
|||
extends Area2D
|
||||
class_name Tracker
|
||||
|
||||
## Abstract base class for [Area2D]s tracking a certain subset of [Node2D]s.
|
||||
|
||||
|
||||
signal tracked(body: Node2D)
|
||||
signal untracked(body: Node2D)
|
||||
|
||||
var tracking: Array = []
|
||||
|
||||
|
||||
func track(body: Node2D) -> bool:
|
||||
var act: bool = not body in tracking
|
||||
if act:
|
||||
tracking.push_back(body)
|
||||
tracked.emit(body)
|
||||
return act
|
||||
|
||||
func untrack(body: Node2D) -> bool:
|
||||
var act: bool = body in tracking
|
||||
if act:
|
||||
tracking.erase(body)
|
||||
untracked.emit(body)
|
||||
return act
|
||||
|
||||
func log_tracked(body: Node2D) -> void:
|
||||
Log.p(self, "Tracking a new target: %s" % body)
|
||||
|
||||
func log_untracked(body: Node2D) -> void:
|
||||
Log.p(self, "Not tracking anymore target: %s" % body)
|
Loading…
Reference in a new issue