godot-plateformer/addons/reedscene/prop/StateManager.gd

134 lines
3.4 KiB
GDScript3
Raw Normal View History

2026-01-03 23:21:04 +08:00
'''
PropState
'''
2025-12-31 13:07:31 +08:00
@tool
@icon("res://addons/reedscene/prop/icon/prop_states_manager.svg")
2026-01-03 23:21:04 +08:00
#class_name ReedPropStateManager
2025-12-31 13:07:31 +08:00
extends Node
2026-01-03 23:21:04 +08:00
## FLAG
const IS_PROP_STATES_ROOT := true
2025-12-31 13:07:31 +08:00
@export var auto_refresh: bool = true
2026-01-04 21:21:01 +08:00
func _enter_tree() -> void:
if not Engine.is_editor_hint():
return
_connect_editor_signals()
_refresh_states()
2025-12-31 13:07:31 +08:00
func _ready() -> void:
if not Engine.is_editor_hint():
return
2026-01-04 21:21:01 +08:00
## 链接所有的功能信号
func _connect_editor_signals() -> void:
if not child_entered_tree.is_connected(_on_child_entered_tree):
child_entered_tree.connect(_on_child_entered_tree)
2025-12-31 13:07:31 +08:00
2026-01-04 21:21:01 +08:00
if not child_exiting_tree.is_connected(_on_child_exiting_tree):
child_exiting_tree.connect(_on_child_exiting_tree)
if not child_order_changed.is_connected(_on_child_order_changing):
child_order_changed.connect(_on_child_order_changing)
## 断开所有的功能型号
func _disconnect_editor_signals() -> void:
if child_entered_tree.is_connected(_on_child_entered_tree):
child_entered_tree.disconnect(_on_child_entered_tree)
if child_exiting_tree.is_connected(_on_child_exiting_tree):
child_exiting_tree.disconnect(_on_child_exiting_tree)
if child_order_changed.is_connected(_on_child_order_changing):
child_order_changed.disconnect(_on_child_order_changing)
2025-12-31 13:07:31 +08:00
2026-01-03 23:21:04 +08:00
## 如果子節點進入管理器
2025-12-31 13:07:31 +08:00
func _on_child_entered_tree(node: Node) -> void:
if not Engine.is_editor_hint():
return
2026-01-03 23:21:04 +08:00
if not node.renamed.is_connected(_on_child_renamed):
node.renamed.connect(_on_child_renamed)
2025-12-31 13:07:31 +08:00
if node is ReedPropState and auto_refresh:
call_deferred("_refresh_states")
2026-01-03 23:21:04 +08:00
## 如果子節點離開管理器
2025-12-31 13:07:31 +08:00
func _on_child_exiting_tree(node: Node) -> void:
if not Engine.is_editor_hint():
return
2026-01-03 23:21:04 +08:00
if node.renamed.is_connected(_on_child_renamed):
node.renamed.disconnect(_on_child_renamed)
2025-12-31 13:07:31 +08:00
if node is ReedPropState and auto_refresh:
call_deferred("_refresh_states")
2026-01-03 23:21:04 +08:00
## 如果子節點被重命名
func _on_child_renamed() -> void:
if not Engine.is_editor_hint():
return
call_deferred("_refresh_states")
## 如果子節點的順序修改
func _on_child_order_changing() -> void:
if not Engine.is_editor_hint():
return
call_deferred("_refresh_states")
2025-12-31 13:07:31 +08:00
func _refresh_states() -> void:
var index := 0
for child in get_children():
if not child is ReedPropState:
continue
_assign_state_id(child, index)
_rename_state_node(child, index)
index += 1
func _assign_state_id(state: ReedPropState, id: int) -> void:
if state.state_id == id:
return
state.set("state_id", id)
func _rename_state_node(state: ReedPropState, id: int) -> void:
var base_name := _strip_id_prefix(state.name)
var expected := "[ID_%d] %s" % [id, base_name]
if state.name == expected:
return
state.name = expected
2026-01-03 23:21:04 +08:00
##连续剥离Name防止错乱
2025-12-31 13:07:31 +08:00
func _strip_id_prefix(name: String) -> String:
var result := name
# 连续剥离所有 [ID_x] 前缀,防止叠加
while result.begins_with("[ID_"):
var end := result.find("]")
if end == -1:
break
# 跳过 "] " 或 "]"
var cut := end + 1
if cut < result.length() and result[cut] == " ":
cut += 1
result = result.substr(cut)
return result.strip_edges()
2026-01-03 23:21:04 +08:00
## 提取原本的命名
2025-12-31 13:07:31 +08:00
func _extract_raw_name(name: String) -> String:
if name.begins_with("[ID:"):
var end := name.find("]")
if end != -1 and end + 2 < name.length():
return name.substr(end + 2)
return name