89 lines
2.7 KiB
GDScript
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
|