Files
rthythm_archor_game/scenes/components/state_machine.gd
T
2026-07-06 22:59:47 -07:00

89 lines
2.7 KiB
GDScript

class_name StateMachine
extends Node
signal axis_changed(axis: StringName, previous: StringName, current: StringName)
enum GroundState { GROUNDED, AIRBORNE }
enum ActionPhaseState { NEUTRAL, STARTUP, ACTIVE, RECOVERY, CHARGING }
enum LifeState { ALIVE, HITSTUN, DEAD }
enum DefenseState { VULNERABLE, PARRYING, SUPER_ARMOR, INVINCIBLE }
const GROUND_STATE_NAMES: Array[StringName] = [&"Grounded", &"Airborne"]
const ACTION_PHASE_NAMES: Array[StringName] = [&"Neutral", &"Startup", &"Active", &"Recovery", &"Charging"]
const LIFE_STATE_NAMES: Array[StringName] = [&"Alive", &"Hitstun", &"Dead"]
const DEFENSE_STATE_NAMES: Array[StringName] = [&"Vulnerable", &"Parrying", &"SuperArmor", &"Invincible"]
var ground_state := GroundState.GROUNDED
var action_phase := ActionPhaseState.NEUTRAL
var life_state := LifeState.ALIVE
var defense_state := DefenseState.VULNERABLE
var air_action_count := 0
var max_air_action_count := 1
func build_context() -> Dictionary:
var tags: Array[StringName] = [
get_ground_state(),
get_action_phase(),
get_defense_state(),
get_life_state(),
]
return {
"ground_state": get_ground_state(),
"action_phase": get_action_phase(),
"defense_state": get_defense_state(),
"life_state": get_life_state(),
"air_action_count": air_action_count,
"max_air_action_count": max_air_action_count,
"tags": tags,
}
func get_context() -> Dictionary:
return build_context()
func has_tag(tag: StringName) -> bool:
return build_context()["tags"].has(tag)
func get_ground_state() -> StringName:
return GROUND_STATE_NAMES[ground_state]
func get_action_phase() -> StringName:
return ACTION_PHASE_NAMES[action_phase]
func get_life_state() -> StringName:
return LIFE_STATE_NAMES[life_state]
func get_defense_state() -> StringName:
return DEFENSE_STATE_NAMES[defense_state]
func set_ground_state(next_state: StringName) -> void:
ground_state = _set_axis(&"ground_state", GROUND_STATE_NAMES, ground_state, next_state)
func set_action_phase(next_phase: StringName) -> void:
action_phase = _set_axis(&"action_phase", ACTION_PHASE_NAMES, action_phase, next_phase)
func set_life_state(next_state: StringName) -> void:
life_state = _set_axis(&"life_state", LIFE_STATE_NAMES, life_state, next_state)
func set_defense_state(next_state: StringName) -> void:
defense_state = _set_axis(&"defense_state", DEFENSE_STATE_NAMES, defense_state, next_state)
func _set_axis(axis: StringName, names: Array[StringName], current: int, next_name: StringName) -> int:
var next_index := names.find(next_name)
if next_index == -1 or next_index == current:
return current
var previous := names[current]
axis_changed.emit(axis, previous, names[next_index])
return next_index