Bee State Machine
This commit is contained in:
parent
20bcab01b1
commit
752131c955
16 changed files with 467 additions and 13 deletions
|
|
@ -1,3 +1,48 @@
|
||||||
[gd_scene format=3 uid="uid://deek6uv574xas"]
|
[gd_scene load_steps=8 format=3 uid="uid://deek6uv574xas"]
|
||||||
|
|
||||||
[node name="Bee" type="Node2D"]
|
[ext_resource type="Script" path="res://entities/scripts/bee.gd" id="1_pnu7x"]
|
||||||
|
[ext_resource type="Script" path="res://entities/scripts/finite_state_machine.gd" id="1_t3s5d"]
|
||||||
|
[ext_resource type="Script" path="res://entities/bee/states/bee_idle.gd" id="3_vasc5"]
|
||||||
|
[ext_resource type="Script" path="res://entities/bee/states/bee_traveling.gd" id="4_rr0w6"]
|
||||||
|
[ext_resource type="Script" path="res://entities/bee/states/bee_gather.gd" id="5_4vs4l"]
|
||||||
|
[ext_resource type="Script" path="res://entities/scripts/bee_hit_box.gd" id="5_agq38"]
|
||||||
|
|
||||||
|
[sub_resource type="CircleShape2D" id="CircleShape2D_86nxf"]
|
||||||
|
radius = 22.0907
|
||||||
|
|
||||||
|
[node name="Bee" type="CharacterBody2D"]
|
||||||
|
collision_mask = 0
|
||||||
|
script = ExtResource("1_pnu7x")
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
light_mask = 0
|
||||||
|
shape = SubResource("CircleShape2D_86nxf")
|
||||||
|
|
||||||
|
[node name="HitBox" type="Area2D" parent="."]
|
||||||
|
collision_layer = 6
|
||||||
|
collision_mask = 7
|
||||||
|
script = ExtResource("5_agq38")
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox"]
|
||||||
|
light_mask = 0
|
||||||
|
shape = SubResource("CircleShape2D_86nxf")
|
||||||
|
|
||||||
|
[node name="StateMachine" type="Node2D" parent="." node_paths=PackedStringArray("initial_state")]
|
||||||
|
script = ExtResource("1_t3s5d")
|
||||||
|
initial_state = NodePath("Idle")
|
||||||
|
|
||||||
|
[node name="Idle" type="Node" parent="StateMachine"]
|
||||||
|
script = ExtResource("3_vasc5")
|
||||||
|
|
||||||
|
[node name="Traveling" type="Node" parent="StateMachine"]
|
||||||
|
script = ExtResource("4_rr0w6")
|
||||||
|
|
||||||
|
[node name="Gathering" type="Node" parent="StateMachine"]
|
||||||
|
script = ExtResource("5_4vs4l")
|
||||||
|
|
||||||
|
[node name="Polygon2D" type="Polygon2D" parent="."]
|
||||||
|
color = Color(1, 1, 0.0745098, 1)
|
||||||
|
polygon = PackedVector2Array(-18, -11, -6, -21, 17, -19, 23, 1, 3, 12, -18, 7)
|
||||||
|
|
||||||
|
[connection signal="area_entered" from="HitBox" to="HitBox" method="_on_area_entered"]
|
||||||
|
[connection signal="area_exited" from="HitBox" to="HitBox" method="_on_area_exited"]
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,19 @@
|
||||||
[gd_scene format=3 uid="uid://nxq2fd04ehcu"]
|
[gd_scene load_steps=2 format=3 uid="uid://nxq2fd04ehcu"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://entities/scripts/director_drone.gd" id="1_3v6jp"]
|
||||||
|
|
||||||
[node name="DirectorDrone" type="Node2D"]
|
[node name="DirectorDrone" type="Node2D"]
|
||||||
|
script = ExtResource("1_3v6jp")
|
||||||
|
|
||||||
[node name="Polygon2D" type="Polygon2D" parent="."]
|
[node name="Polygon2D" type="Polygon2D" parent="."]
|
||||||
position = Vector2(1, -1)
|
position = Vector2(1, -1)
|
||||||
color = Color(0.703926, 0.656042, 0.441124, 1)
|
color = Color(0.703926, 0.656042, 0.441124, 1)
|
||||||
polygon = PackedVector2Array(-28, -25, 25, -28, 26, 33, -32, 19)
|
polygon = PackedVector2Array(-28, -25, 25, -28, 26, 33, -32, 19)
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="."]
|
||||||
|
offset_left = -16.0
|
||||||
|
offset_top = -12.0
|
||||||
|
offset_right = 24.0
|
||||||
|
offset_bottom = 11.0
|
||||||
|
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||||
|
text = "999"
|
||||||
|
|
|
||||||
29
entities/bee/states/bee_gather.gd
Normal file
29
entities/bee/states/bee_gather.gd
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
extends State
|
||||||
|
class_name BeeGathering
|
||||||
|
|
||||||
|
@export var animator : AnimationPlayer
|
||||||
|
@onready var bee = get_parent().get_parent() as Bee # I think this is bad but I dont care it works
|
||||||
|
|
||||||
|
var time_at_patch : float = 0.0
|
||||||
|
|
||||||
|
func enter(_msg := {}):
|
||||||
|
Log.pr("I am going to attempt to gather some stuff!")
|
||||||
|
#animator.play("Idle")
|
||||||
|
|
||||||
|
#if !bee.in_range_of_flowers:
|
||||||
|
# ## Go home bee, you're drunk
|
||||||
|
# state_transition.emit(self, "Idle")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func update(_delta : float):
|
||||||
|
|
||||||
|
if bee.in_range_of_flowers:
|
||||||
|
#animator.play("Gathering")
|
||||||
|
time_at_patch += _delta
|
||||||
|
if time_at_patch > 5.0:
|
||||||
|
bee.nectar += 1
|
||||||
|
state_transition.emit(self, "Idle")
|
||||||
|
else:
|
||||||
|
state_transition.emit(self, "Idle")
|
||||||
|
|
||||||
37
entities/bee/states/bee_idle.gd
Normal file
37
entities/bee/states/bee_idle.gd
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
extends State
|
||||||
|
class_name BeeIdle
|
||||||
|
|
||||||
|
@export var animator : AnimationPlayer
|
||||||
|
|
||||||
|
@onready var bee = get_parent().get_parent() # I think this is bad but I dont care it works
|
||||||
|
|
||||||
|
var idle_time : float = 0.0
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
Log.pr(bee, bee.nectar)
|
||||||
|
|
||||||
|
func enter(_msg := {}):
|
||||||
|
Log.pr("I sit by idl-bee")
|
||||||
|
#animator.play("Idle")
|
||||||
|
pass
|
||||||
|
|
||||||
|
func update(delta : float):
|
||||||
|
|
||||||
|
idle_time += delta
|
||||||
|
|
||||||
|
if idle_time > 2.0:
|
||||||
|
Log.pr("Been idle for 2 seconds, check for something to do...")
|
||||||
|
find_something_to_do()
|
||||||
|
idle_time = 0.0
|
||||||
|
pass
|
||||||
|
|
||||||
|
func find_something_to_do():
|
||||||
|
if bee.nectar > 0:
|
||||||
|
## Bee has pollen - head home
|
||||||
|
Log.pr(bee, "I have nectar, I should return to the hive")
|
||||||
|
state_transition.emit(self, "Traveling")
|
||||||
|
else:
|
||||||
|
## Bee has no pollen - they should move to a flower
|
||||||
|
Log.pr(bee, "I have no nectar, I should find a flower")
|
||||||
|
state_transition.emit(self, "Traveling")
|
||||||
|
pass
|
||||||
37
entities/bee/states/bee_traveling.gd
Normal file
37
entities/bee/states/bee_traveling.gd
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
extends State
|
||||||
|
class_name BeeTraveling
|
||||||
|
|
||||||
|
@export var animator : AnimationPlayer
|
||||||
|
|
||||||
|
@export var target : Drone = null
|
||||||
|
|
||||||
|
@onready var bee = get_parent().get_parent() as Bee # I think this is bad but I dont care it works
|
||||||
|
|
||||||
|
var t = 0
|
||||||
|
|
||||||
|
func enter(_msg := {}):
|
||||||
|
Log.pr("I am on the move!")
|
||||||
|
## Get the next target location from the bee
|
||||||
|
target = bee.get_next_target()
|
||||||
|
|
||||||
|
#animator.play("Idle")
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
func update(delta : float):
|
||||||
|
|
||||||
|
if target:
|
||||||
|
if bee.position.distance_to(target.position) > 3:
|
||||||
|
|
||||||
|
bee.velocity = (target.get_global_position() - bee.position).normalized() * bee.speed * delta
|
||||||
|
bee.move_and_collide(bee.velocity)
|
||||||
|
bee.look_at(target.position)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Bee has arrived at location, if its the hive or a collector drone do the things
|
||||||
|
if(target.name == "CollectorDrone"):
|
||||||
|
state_transition.emit(self, "Gathering")
|
||||||
|
else:
|
||||||
|
state_transition.emit(self, "Idle")
|
||||||
|
|
||||||
|
pass
|
||||||
55
entities/scripts/bee.gd
Normal file
55
entities/scripts/bee.gd
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
extends Node2D
|
||||||
|
class_name Bee
|
||||||
|
|
||||||
|
@onready var fsm = $StateMachine as FiniteStateMachine
|
||||||
|
@onready var drone_manager = get_tree().get_first_node_in_group("dronemanager") as DroneManager
|
||||||
|
|
||||||
|
@export var nectar : int = 0
|
||||||
|
@export var speed : int = 30
|
||||||
|
|
||||||
|
var latest_target_director : int = 0
|
||||||
|
|
||||||
|
# This is updated when the bee enters or exits a flower patch
|
||||||
|
var in_range_of_flowers : bool = false
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
Log.pr("I have never bee-n so ready!")
|
||||||
|
|
||||||
|
Log.pr(fsm.current_state.name)
|
||||||
|
|
||||||
|
## Get the next target to move to
|
||||||
|
## If we have no nectar, we need to go up the director list
|
||||||
|
## If we have nectar, we need to go down the director list
|
||||||
|
## If we are at the lower director, we need to go the hive
|
||||||
|
## If we are at the highest director, we need to go to a flower
|
||||||
|
func get_next_target():
|
||||||
|
if nectar == 0:
|
||||||
|
Log.pr("I have no nectar")
|
||||||
|
|
||||||
|
## If there is a next directory drone, lets go to it
|
||||||
|
var next_drone = drone_manager.get_next_director(latest_target_director)
|
||||||
|
if next_drone:
|
||||||
|
Log.pr("Next drone target", next_drone)
|
||||||
|
latest_target_director = next_drone.visit_order
|
||||||
|
return next_drone
|
||||||
|
|
||||||
|
## If there is no next drone, check for a collector drone
|
||||||
|
var collector_drone = drone_manager.get_collector()
|
||||||
|
if collector_drone:
|
||||||
|
Log.pr("Collector drone target", collector_drone)
|
||||||
|
return collector_drone
|
||||||
|
else:
|
||||||
|
Log.pr("I have nectar")
|
||||||
|
|
||||||
|
## Let's go home, we need the previous director drones location
|
||||||
|
var previous_drone = drone_manager.get_previous_director(latest_target_director)
|
||||||
|
if previous_drone:
|
||||||
|
Log.pr("Previous drone target", previous_drone)
|
||||||
|
latest_target_director = previous_drone.visit_order
|
||||||
|
return previous_drone
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
19
entities/scripts/bee_hit_box.gd
Normal file
19
entities/scripts/bee_hit_box.gd
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
extends Area2D
|
||||||
|
|
||||||
|
@onready var bee = get_parent() as Bee
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
func _on_area_entered(area:Area2D):
|
||||||
|
## Check if the area entered is a flower patch
|
||||||
|
if area.is_in_group("flowers"):
|
||||||
|
bee.in_range_of_flowers = true
|
||||||
|
Log.pr("I found some flowers!")
|
||||||
|
|
||||||
|
func _on_area_exited(area:Area2D):
|
||||||
|
## Check if the area exited is a flower patch
|
||||||
|
if area.is_in_group("flowers"):
|
||||||
|
bee.in_range_of_flowers = false
|
||||||
|
Log.pr("I left the flowers!")
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
class_name DirectorDrone extends Drone
|
class_name DirectorDrone extends Drone
|
||||||
|
|
||||||
|
@export var visit_order : int = 0 :
|
||||||
|
get:
|
||||||
|
return visit_order
|
||||||
|
set(value):
|
||||||
|
visit_order = value
|
||||||
|
update_label_value()
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready():
|
func _ready():
|
||||||
pass # Replace with function body.
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
func update_label_value():
|
||||||
|
$Label.text = str(visit_order)
|
||||||
69
entities/scripts/finite_state_machine.gd
Normal file
69
entities/scripts/finite_state_machine.gd
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
@icon("res://resources/icons/fsm.png")
|
||||||
|
extends Node
|
||||||
|
class_name FiniteStateMachine
|
||||||
|
|
||||||
|
var states : Dictionary = {}
|
||||||
|
var current_state : State
|
||||||
|
@export var initial_state : State
|
||||||
|
|
||||||
|
#NOTE This is a generic finite_state_machine, it handles all states, changes to this code will affect
|
||||||
|
# everything that uses a state machine!
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
Log.pr("FSM Ready")
|
||||||
|
for child in get_children():
|
||||||
|
if child is State:
|
||||||
|
states[child.name.to_lower()] = child
|
||||||
|
child.state_transition.connect(change_state)
|
||||||
|
|
||||||
|
Log.pr(states)
|
||||||
|
|
||||||
|
if initial_state:
|
||||||
|
initial_state.enter()
|
||||||
|
current_state = initial_state
|
||||||
|
|
||||||
|
# Call the current states update function
|
||||||
|
func _process(delta):
|
||||||
|
if current_state:
|
||||||
|
current_state.update(delta)
|
||||||
|
|
||||||
|
# Use force_change_state cautiously, it immediately switches to a state regardless of any transitions.
|
||||||
|
# This is used to force us into a 'death state' when killed
|
||||||
|
func force_change_state(new_state : String):
|
||||||
|
var newState = states.get(new_state.to_lower())
|
||||||
|
|
||||||
|
if !newState:
|
||||||
|
print(new_state + " does not exist in the dictionary of states")
|
||||||
|
return
|
||||||
|
|
||||||
|
if current_state == newState:
|
||||||
|
print("State is same, aborting")
|
||||||
|
return
|
||||||
|
|
||||||
|
# NOTE Calling exit like so: (current_state.Exit()) may cause warnings when flushing queries, like when the enemy is being removed after death.
|
||||||
|
# call_deferred is safe and prevents this from occuring. We get the Exit function from the state as a callable and then call it in a thread-safe manner
|
||||||
|
if current_state:
|
||||||
|
var exit_callable = Callable(current_state, "exit")
|
||||||
|
exit_callable.call_deferred()
|
||||||
|
|
||||||
|
newState.enter()
|
||||||
|
|
||||||
|
current_state = newState
|
||||||
|
|
||||||
|
func change_state(source_state : State, new_state_name : String):
|
||||||
|
if source_state != current_state:
|
||||||
|
#print("Invalid change_state trying from: " + source_state.name + " but currently in: " + current_state.name)
|
||||||
|
#This typically only happens when trying to switch from death state following a force_change
|
||||||
|
return
|
||||||
|
|
||||||
|
var new_state = states.get(new_state_name.to_lower())
|
||||||
|
if !new_state:
|
||||||
|
print("New state is empty")
|
||||||
|
return
|
||||||
|
|
||||||
|
if current_state:
|
||||||
|
current_state.exit()
|
||||||
|
|
||||||
|
new_state.enter()
|
||||||
|
|
||||||
|
current_state = new_state
|
||||||
15
entities/scripts/state.gd
Normal file
15
entities/scripts/state.gd
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
@icon("res://resources/icons/fsm.png")
|
||||||
|
extends Node
|
||||||
|
class_name State
|
||||||
|
|
||||||
|
signal state_transition
|
||||||
|
|
||||||
|
func enter(_msg := {}):
|
||||||
|
pass
|
||||||
|
|
||||||
|
func exit():
|
||||||
|
pass
|
||||||
|
|
||||||
|
func update(_delta:float):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
@ -24,3 +24,9 @@ window/vsync/vsync_mode=0
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/log/plugin.cfg")
|
enabled=PackedStringArray("res://addons/log/plugin.cfg")
|
||||||
|
|
||||||
|
[layer_names]
|
||||||
|
|
||||||
|
2d_physics/layer_1="bees"
|
||||||
|
2d_physics/layer_2="hazards"
|
||||||
|
2d_physics/layer_3="flowers"
|
||||||
|
|
|
||||||
BIN
resources/icons/fsm.png
Normal file
BIN
resources/icons/fsm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
34
resources/icons/fsm.png.import
Normal file
34
resources/icons/fsm.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ct5paeky0cexp"
|
||||||
|
path="res://.godot/imported/fsm.png-8987802cee881c94358eee3cb13f0556.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resources/icons/fsm.png"
|
||||||
|
dest_files=["res://.godot/imported/fsm.png-8987802cee881c94358eee3cb13f0556.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
|
||||||
29
scenes/scripts/bee_spawner.gd
Normal file
29
scenes/scripts/bee_spawner.gd
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
extends Node2D
|
||||||
|
class_name BeeSpawner
|
||||||
|
|
||||||
|
var bee = preload("res://entities/Bee.tscn")
|
||||||
|
|
||||||
|
@onready var beehive = get_node("../Beehive")
|
||||||
|
|
||||||
|
var bee_count = 0
|
||||||
|
var max_bees = 10
|
||||||
|
var spawn_interval = 3
|
||||||
|
var spawn_timer = 0.0
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
Log.pr("Bee Spawner ready")
|
||||||
|
|
||||||
|
func spawn_bee():
|
||||||
|
var bee_instance = bee.instantiate()
|
||||||
|
add_child(bee_instance)
|
||||||
|
bee_instance.position = beehive.position
|
||||||
|
# bee_instance.connect("bee_died", self, "bee_died")
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
spawn_timer += delta
|
||||||
|
|
||||||
|
if spawn_timer > spawn_interval and bee_count < max_bees:
|
||||||
|
spawn_bee()
|
||||||
|
spawn_timer = 0.0
|
||||||
|
bee_count += 1
|
||||||
|
Log.pr("Bee count: " + str(bee_count))
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
class_name DroneManager
|
||||||
|
|
||||||
var spawning_drone : bool = false
|
var spawning_drone : bool = false
|
||||||
var spawning_type : String = ""
|
var spawning_type : String = ""
|
||||||
|
|
||||||
|
var director_drones : Array = [] # List of all director drones in the world
|
||||||
|
|
||||||
@onready var drone_controls = %DroneControls
|
@onready var drone_controls = %DroneControls
|
||||||
@onready var spawned_drones_container = get_node("SpawnedDrones")
|
@onready var spawned_drones_container = get_node("SpawnedDrones")
|
||||||
@onready var cursor = preload("res://resources/cursors/launch_drone.png")
|
@onready var cursor = preload("res://resources/cursors/launch_drone.png")
|
||||||
|
|
@ -33,6 +36,7 @@ func spawn_drone(drone_type : String) -> void:
|
||||||
# Create a new instance of the drone
|
# Create a new instance of the drone
|
||||||
if drone_type == "director":
|
if drone_type == "director":
|
||||||
new_drone = director_drone.instantiate()
|
new_drone = director_drone.instantiate()
|
||||||
|
# new_drone.visit_order = spawned_drones_container.get_child_count()
|
||||||
elif drone_type == "dancer":
|
elif drone_type == "dancer":
|
||||||
new_drone = dancer_drone.instantiate()
|
new_drone = dancer_drone.instantiate()
|
||||||
elif drone_type == "distractor":
|
elif drone_type == "distractor":
|
||||||
|
|
@ -45,6 +49,12 @@ func spawn_drone(drone_type : String) -> void:
|
||||||
spawned_drones_container.add_child(new_drone)
|
spawned_drones_container.add_child(new_drone)
|
||||||
new_drone.position = get_viewport().get_mouse_position()
|
new_drone.position = get_viewport().get_mouse_position()
|
||||||
|
|
||||||
|
if drone_type == "director":
|
||||||
|
# Set this drones visit order to the next in line
|
||||||
|
new_drone.visit_order = director_drones.size() + 1
|
||||||
|
# Update the director drone list
|
||||||
|
update_director_drone_list()
|
||||||
|
|
||||||
func place_drone(drone_type : String) -> void:
|
func place_drone(drone_type : String) -> void:
|
||||||
if !spawning_drone:
|
if !spawning_drone:
|
||||||
Input.set_custom_mouse_cursor(cursor, Input.CURSOR_ARROW, Vector2(32, 32))
|
Input.set_custom_mouse_cursor(cursor, Input.CURSOR_ARROW, Vector2(32, 32))
|
||||||
|
|
@ -53,8 +63,6 @@ func place_drone(drone_type : String) -> void:
|
||||||
spawning_drone = true
|
spawning_drone = true
|
||||||
spawning_type = drone_type
|
spawning_type = drone_type
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func cancel_spawning() -> void:
|
func cancel_spawning() -> void:
|
||||||
Input.set_custom_mouse_cursor(null)
|
Input.set_custom_mouse_cursor(null)
|
||||||
drone_controls.reset_button_focus()
|
drone_controls.reset_button_focus()
|
||||||
|
|
@ -73,3 +81,31 @@ func _on_spawn_distractor_pressed() -> void:
|
||||||
|
|
||||||
func _on_spawn_dancer_pressed() -> void:
|
func _on_spawn_dancer_pressed() -> void:
|
||||||
place_drone("dancer")
|
place_drone("dancer")
|
||||||
|
|
||||||
|
func update_director_drone_list():
|
||||||
|
director_drones.clear()
|
||||||
|
for drone in spawned_drones_container.get_children():
|
||||||
|
if drone is DirectorDrone:
|
||||||
|
director_drones.append(drone)
|
||||||
|
|
||||||
|
Log.pr(director_drones.size())
|
||||||
|
|
||||||
|
func get_next_director(current_director_number : int) -> DirectorDrone:
|
||||||
|
for drone in director_drones:
|
||||||
|
if drone.visit_order == current_director_number + 1:
|
||||||
|
return drone
|
||||||
|
return null
|
||||||
|
|
||||||
|
func get_previous_director(current_director_number : int) -> DirectorDrone:
|
||||||
|
for drone in director_drones:
|
||||||
|
if drone.visit_order == current_director_number - 1:
|
||||||
|
return drone
|
||||||
|
return null
|
||||||
|
|
||||||
|
## For now this just returns the first collector drone it finds
|
||||||
|
## This will need to be updated to return the closest collector drone potentially?
|
||||||
|
func get_collector():
|
||||||
|
for drone in spawned_drones_container.get_children():
|
||||||
|
if drone is CollectorDrone:
|
||||||
|
return drone
|
||||||
|
return null
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
[gd_scene load_steps=4 format=3 uid="uid://mk5n0hrwk4yi"]
|
[gd_scene load_steps=7 format=3 uid="uid://mk5n0hrwk4yi"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scenes/scripts/test_level.gd" id="1_lgt1m"]
|
[ext_resource type="Script" path="res://scenes/scripts/test_level.gd" id="1_lgt1m"]
|
||||||
[ext_resource type="Script" path="res://scenes/scripts/drone_manager.gd" id="2_474nc"]
|
[ext_resource type="Script" path="res://scenes/scripts/drone_manager.gd" id="2_474nc"]
|
||||||
|
[ext_resource type="Script" path="res://scenes/scripts/bee_spawner.gd" id="2_qqqq4"]
|
||||||
[ext_resource type="Script" path="res://scenes/scripts/drone_controls.gd" id="3_rqkyv"]
|
[ext_resource type="Script" path="res://scenes/scripts/drone_controls.gd" id="3_rqkyv"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://deek6uv574xas" path="res://entities/Bee.tscn" id="4_336fp"]
|
||||||
|
|
||||||
|
[sub_resource type="CircleShape2D" id="CircleShape2D_usqp5"]
|
||||||
|
radius = 142.316
|
||||||
|
|
||||||
[node name="TestLevel" type="Node2D"]
|
[node name="TestLevel" type="Node2D"]
|
||||||
script = ExtResource("1_lgt1m")
|
script = ExtResource("1_lgt1m")
|
||||||
|
|
@ -18,11 +23,25 @@ color = Color(0.588235, 0.423529, 0.423529, 1)
|
||||||
polygon = PackedVector2Array(95, 146, 203, 134, 186, 274, 78, 287)
|
polygon = PackedVector2Array(95, 146, 203, 134, 186, 274, 78, 287)
|
||||||
|
|
||||||
[node name="Flower" type="Polygon2D" parent="."]
|
[node name="Flower" type="Polygon2D" parent="."]
|
||||||
position = Vector2(648, 225)
|
position = Vector2(278, -97)
|
||||||
scale = Vector2(0.435897, 0.276596)
|
|
||||||
color = Color(0.301961, 0.607843, 0.901961, 1)
|
color = Color(0.301961, 0.607843, 0.901961, 1)
|
||||||
polygon = PackedVector2Array(752, 145, 875, 200, 893, 272, 866, 359, 781, 427, 715, 362, 659, 226)
|
polygon = PackedVector2Array(752, 145, 875, 200, 893, 272, 866, 359, 781, 427, 715, 362, 659, 226)
|
||||||
|
|
||||||
|
[node name="Area2D" type="Area2D" parent="Flower" groups=["flowers"]]
|
||||||
|
position = Vector2(777.707, 282)
|
||||||
|
collision_layer = 7
|
||||||
|
collision_mask = 7
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="Flower/Area2D"]
|
||||||
|
shape = SubResource("CircleShape2D_usqp5")
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Flower"]
|
||||||
|
offset_left = 721.0
|
||||||
|
offset_top = 243.0
|
||||||
|
offset_right = 852.0
|
||||||
|
offset_bottom = 266.0
|
||||||
|
text = "Flower patch bro"
|
||||||
|
|
||||||
[node name="Pesticide" type="Polygon2D" parent="."]
|
[node name="Pesticide" type="Polygon2D" parent="."]
|
||||||
position = Vector2(74.7948, -103.963)
|
position = Vector2(74.7948, -103.963)
|
||||||
scale = Vector2(0.851611, 0.815599)
|
scale = Vector2(0.851611, 0.815599)
|
||||||
|
|
@ -34,7 +53,11 @@ position = Vector2(-354, 53)
|
||||||
color = Color(0.803922, 0.407843, 0.239216, 1)
|
color = Color(0.803922, 0.407843, 0.239216, 1)
|
||||||
polygon = PackedVector2Array(819, 301, 866, 278, 888, 364, 842, 319, 832, 373, 806, 423, 775, 424, 754, 377, 762, 319, 728, 360, 739, 263, 765, 284)
|
polygon = PackedVector2Array(819, 301, 866, 278, 888, 364, 842, 319, 832, 373, 806, 423, 775, 424, 754, 377, 762, 319, 728, 360, 739, 263, 765, 284)
|
||||||
|
|
||||||
[node name="DroneManager" type="Node2D" parent="."]
|
[node name="BeeSpawner" type="Node2D" parent="."]
|
||||||
|
script = ExtResource("2_qqqq4")
|
||||||
|
|
||||||
|
[node name="DroneManager" type="Node2D" parent="." groups=["dronemanager"]]
|
||||||
|
unique_name_in_owner = true
|
||||||
script = ExtResource("2_474nc")
|
script = ExtResource("2_474nc")
|
||||||
|
|
||||||
[node name="SpawnedDrones" type="Node2D" parent="DroneManager"]
|
[node name="SpawnedDrones" type="Node2D" parent="DroneManager"]
|
||||||
|
|
@ -89,6 +112,9 @@ layout_mode = 2
|
||||||
tooltip_text = "Spawn a dancing drone that will encourage bees to leave the hive. Best to put this near to the hive. "
|
tooltip_text = "Spawn a dancing drone that will encourage bees to leave the hive. Best to put this near to the hive. "
|
||||||
text = "Dancer"
|
text = "Dancer"
|
||||||
|
|
||||||
|
[node name="Bee" parent="." instance=ExtResource("4_336fp")]
|
||||||
|
position = Vector2(704, 196)
|
||||||
|
|
||||||
[connection signal="pressed" from="DroneManager/Control/MarginContainer/DroneControls/SpawnDirector" to="DroneManager" method="_on_spawn_director_pressed"]
|
[connection signal="pressed" from="DroneManager/Control/MarginContainer/DroneControls/SpawnDirector" to="DroneManager" method="_on_spawn_director_pressed"]
|
||||||
[connection signal="pressed" from="DroneManager/Control/MarginContainer/DroneControls/SpawnCollector" to="DroneManager" method="_on_spawn_collector_pressed"]
|
[connection signal="pressed" from="DroneManager/Control/MarginContainer/DroneControls/SpawnCollector" to="DroneManager" method="_on_spawn_collector_pressed"]
|
||||||
[connection signal="pressed" from="DroneManager/Control/MarginContainer/DroneControls/SpawnDistractor" to="DroneManager" method="_on_spawn_distractor_pressed"]
|
[connection signal="pressed" from="DroneManager/Control/MarginContainer/DroneControls/SpawnDistractor" to="DroneManager" method="_on_spawn_distractor_pressed"]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue