Initial project sync

This commit is contained in:
wxm
2026-07-06 22:55:14 -07:00
commit 8cca00d0da
1066 changed files with 58585 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
class_name ComboWindow
extends Node
signal combo_updated(inputs: Array[StringName])
signal combo_cleared(reason: StringName)
@export var size := 4
@export var clear_display_time := 0.35
@export var broadcast_to_bus := true
var slots: Array[StringName] = []
var pending_clear_reason: StringName = &""
var _timer: Timer
func _ready() -> void:
_timer = Timer.new()
_timer.one_shot = true
_timer.timeout.connect(flush_pending_clear)
add_child(_timer)
func record(input: StringName) -> void:
if input.is_empty():
return
slots.append(input)
combo_updated.emit(get_slots())
_emit_bus_signal("combo_updated", [get_slots()])
if slots.size() >= size:
queue_clear(&"full")
func rollback_last(expected_input: StringName = &"") -> bool:
if slots.is_empty():
return false
var last := slots[slots.size() - 1]
if not expected_input.is_empty() and last != expected_input:
return false
slots.pop_back()
pending_clear_reason = &""
combo_updated.emit(get_slots())
_emit_bus_signal("combo_updated", [get_slots()])
return true
func get_slots() -> Array[StringName]:
return slots.duplicate()
func has_pending_clear() -> bool:
return not pending_clear_reason.is_empty()
func consume_pending_clear_reason() -> StringName:
var reason := pending_clear_reason
pending_clear_reason = &""
return reason
func get_pattern() -> String:
var pattern := ""
for slot: StringName in slots:
if slot != &"Ø":
pattern += str(slot)
return pattern
func get_contiguous_pattern() -> String:
var pattern := ""
for index: int in range(slots.size() - 1, -1, -1):
var slot := slots[index]
if slot == &"Ø":
break
pattern = str(slot) + pattern
return pattern
func queue_clear(reason: StringName, delay := -1.0) -> void:
pending_clear_reason = reason
if _timer == null:
return
_timer.stop()
_timer.wait_time = clear_display_time if delay < 0.0 else delay
_timer.start()
func cancel_pending_clear() -> void:
pending_clear_reason = &""
if _timer != null:
_timer.stop()
func flush_pending_clear() -> void:
var reason := consume_pending_clear_reason()
if reason.is_empty():
return
if _timer != null:
_timer.stop()
clear(reason)
func clear(reason: StringName = &"") -> void:
slots.clear()
pending_clear_reason = &""
combo_cleared.emit(reason)
_emit_bus_signal("combo_cleared", [reason])
combo_updated.emit(get_slots())
_emit_bus_signal("combo_updated", [get_slots()])
func _emit_bus_signal(signal_name: StringName, args: Array) -> void:
if not broadcast_to_bus or not is_inside_tree():
return
var bus := _event_bus_or_null()
if bus != null:
bus.emit_signal(signal_name, args[0])
func _event_bus_or_null() -> Node:
if not is_inside_tree():
return null
return get_tree().root.get_node_or_null("EventBus")