Tales-of-PKMN/game/player/states/state_machine.gd
TheThomaas 250976d170 Squashed commit of the following:
commit 8e7da96bfcd52b230feaf40fbc6d4a42b80c5723
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Sat Oct 17 18:55:14 2026 +0200

    Make state machine more reusable

commit 37da7248b8c33ce95cff7ef9332c5ccf6e3cd418
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Sat Oct 17 18:44:34 2026 +0200

    Change aim state into flag

commit fbb3a84a12e2cabff9b36390da7483b8de7e9379
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Sat Oct 17 18:33:08 2026 +0200

    Replace fixed references with ui references

commit 913955b13e9980780ac88761845d9e1f165f0d0e
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Fri Oct 16 13:32:21 2026 +0200

    Update camera action handling

commit 4ce0ac13ffea473cf62c2fefd1571e9df1fbbcaa
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Fri Oct 16 13:04:39 2026 +0200

    Update mounting system

commit e410eca38760955b2866eecd6ac0281e2041e76d
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Fri Oct 16 12:57:25 2026 +0200

    Update aiming system

commit 4c788df485ccbff5f91fd51d9f480e495f11da5f
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Thu Oct 15 21:50:26 2026 +0200

    Centralize states names into constants

commit 6059479c87d749e986a48adb520ef33121104da5
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Thu Oct 15 21:25:32 2026 +0200

    Refator Crouch state into flag

commit 08faec70e770042d36eed6f173a63f3aac1f67c6
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Wed Oct 14 10:19:35 2026 +0200

    Update player input management and state machine

commit 11a0aecc58c50c5862a03b4fd0b55e8db024031f
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Wed Oct 14 10:17:06 2026 +0200

    Delete charizard.tres

commit 399eac2b6c64f242a1c2e12360d811127f87681c
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Tue Oct 13 18:20:45 2026 +0200

    Remove unused MountedState

commit 42a3668c52fe96a7509a74290a94fc5a8084b713
Author: TheThomaas <thethomaas@protonmail.ch>
Date:   Tue Oct 13 18:18:08 2026 +0200

    Group grounded states under common class
2026-10-17 18:56:13 +02:00

89 lines
3.3 KiB
GDScript

extends Node
class_name StateMachine
#machine a etats generique : elle ne connait ni le joueur, ni le HUD, ni le lancer. Reutilisable pour n'importe quel acteur
#(joueur, PNJ, pokemon sauvage...) : poser la StateMachine sous l'acteur, y mettre des nodes qui heritent de State.
#ce qui est propre au joueur vit ailleurs : le lancer dans GroundedState, les hints dans StateHints.
signal state_changed(from : State, to : State) #from est null pour l'etat initial
@export var initial_state : State
@export var actor : Node #le node pilote par la machine, passe a chaque etat. Par defaut : le parent
var curr_state : State
var curr_state_name : String: #nom du node de l'etat courant (ex : "IdleState")
get: return String(curr_state.name) if curr_state else ""
var states : Dictionary = {} #nom du node (casse exacte) -> State
var blocked_states : Dictionary = {} #noms des etats dont l'entree est refusee
var _warned : Dictionary = {} #noms introuvables deja signales : un seul avertissement par nom, pas un par frame
func _ready() -> void:
if actor == null: actor = get_parent()
#get all the state childrens
for child in get_children():
if child is State:
states[String(child.name)] = child
child.machine = self
#if initial state, transition to it
if initial_state:
await get_tree().create_timer(0.1).timeout
initial_state.enter(actor)
curr_state = initial_state
state_changed.emit(null, initial_state)
func _process(delta : float) -> void:
if curr_state: curr_state.update(delta)
func _physics_process(delta : float) -> void:
if curr_state: curr_state.physics_update(delta)
#---------- requetes ----------
func has_state(state_name : String) -> bool:
return states.has(state_name)
func is_in(state_name : String) -> bool:
return curr_state_name == state_name
func is_blocked(state_name : String) -> bool:
return blocked_states.has(state_name)
func set_state_blocked(state_name : String, blocked : bool) -> void:
if blocked: blocked_states[state_name] = true
else: blocked_states.erase(state_name)
#---------- transitions ----------
func request(from : State, new_state_name : String, data : Dictionary = {}) -> bool:
#appelee par State.request_transition() : renvoie true si la transition a eu lieu
if from != curr_state: return false #l'etat demandeur n'est plus l'etat courant (transition deja faite pendant cette frame)
var new_state : State = states.get(new_state_name)
if new_state == null:
_warn_unknown_state(from, new_state_name)
return false
if is_blocked(new_state_name): return false
#exit the current state : il connait sa destination, et les donnees qu'il envoie (outgoing_data) sont lisibles
from.next_state_name = new_state_name
from.outgoing_data = data
from.exit()
from.outgoing_data = {}
#enter the new state : il recoit les donnees de l'etat qu'on quitte
new_state.enter_data = data
new_state.enter(actor)
curr_state = new_state
state_changed.emit(from, new_state)
return true
func _warn_unknown_state(from : State, new_state_name : String) -> void:
if _warned.has(new_state_name): return
_warned[new_state_name] = true
push_warning("StateMachine : %s demande une transition vers '%s', mais aucun node d'etat ne porte ce nom (etats disponibles : %s). Verifier le nom du node dans la scene." % [from.name, new_state_name, ", ".join(PackedStringArray(states.keys()))])