pollen-not-included/entities/scripts/finite_state_machine.gd
Dan f0a7c5ca05 Added health bar and snail behavior enhancements
- Introduced a health bar for flowers, which updates based on the current GameState values.
- Enhanced snail behavior with eating and sleeping states. Snails now have a chance to switch to the sleeping state while eating.
- Improved mouse interaction with snails, allowing them to potentially switch to sleep mode when clicked.
- Refactored cursor management into its own class for better code organization and readability.
- Updated drone placement logic to use the new CursorManager class.
- Added functionality for bees to replenish flower nectar levels after a certain number of deposits.
2024-05-15 13:57:31 +01:00

76 lines
2.3 KiB
GDScript

@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() -> void:
for child : Node in get_children():
if child is State:
states[child.name.to_lower()] = child
child.state_transition.connect(change_state)
if initial_state:
initial_state.enter()
current_state = initial_state
# Call the current states update function
func _process(delta : float) -> void:
if current_state:
current_state.update(delta)
func _physics_process(delta : float) -> void:
if current_state:
current_state.physics_update(delta)
func get_current_state_name() -> String:
if current_state:
return current_state.name.to_lower()
else:
return ""
# 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) -> void:
var newState : State = 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 = Callable(current_state, "exit")
exit_callable.call_deferred()
newState.enter()
current_state = newState
func change_state(source_state : State, new_state_name : String) -> void:
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 : 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