134 lines
3.4 KiB
GDScript
134 lines
3.4 KiB
GDScript
'''
|
||
輔助功能性脚本,可以用來管理所有的PropState,並添加一些幫助性的方法。
|
||
'''
|
||
@tool
|
||
@icon("res://addons/reedscene/prop/icon/prop_states_manager.svg")
|
||
#class_name ReedPropStateManager
|
||
extends Node
|
||
|
||
## FLAG
|
||
const IS_PROP_STATES_ROOT := true
|
||
|
||
@export var auto_refresh: bool = true
|
||
|
||
func _enter_tree() -> void:
|
||
if not Engine.is_editor_hint():
|
||
return
|
||
|
||
_connect_editor_signals()
|
||
_refresh_states()
|
||
|
||
func _ready() -> void:
|
||
if not Engine.is_editor_hint():
|
||
return
|
||
|
||
## 链接所有的功能信号
|
||
func _connect_editor_signals() -> void:
|
||
if not child_entered_tree.is_connected(_on_child_entered_tree):
|
||
child_entered_tree.connect(_on_child_entered_tree)
|
||
|
||
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)
|
||
|
||
## 如果子節點進入管理器
|
||
func _on_child_entered_tree(node: Node) -> void:
|
||
if not Engine.is_editor_hint():
|
||
return
|
||
|
||
if not node.renamed.is_connected(_on_child_renamed):
|
||
node.renamed.connect(_on_child_renamed)
|
||
|
||
if node is ReedPropState and auto_refresh:
|
||
call_deferred("_refresh_states")
|
||
|
||
## 如果子節點離開管理器
|
||
func _on_child_exiting_tree(node: Node) -> void:
|
||
if not Engine.is_editor_hint():
|
||
return
|
||
|
||
if node.renamed.is_connected(_on_child_renamed):
|
||
node.renamed.disconnect(_on_child_renamed)
|
||
|
||
if node is ReedPropState and auto_refresh:
|
||
call_deferred("_refresh_states")
|
||
|
||
## 如果子節點被重命名
|
||
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")
|
||
|
||
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
|
||
|
||
##连续剥离Name,防止错乱
|
||
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()
|
||
|
||
## 提取原本的命名
|
||
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
|