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