118 lines
2.9 KiB
GDScript
118 lines
2.9 KiB
GDScript
#@icon("")
|
||
@tool
|
||
class_name ActManager extends Node
|
||
|
||
##ActManager里记录了一系列的ActID和对应的Act,主要用来同步场景的Act,比如,我们现在使用ActID = 0的Act,那么就会让所有的Act的状态重置回到ActID = 0的Act的状态
|
||
@export var prop_state_map: Dictionary[int, Act] = {}
|
||
|
||
##用于生成一个基础的Act的工具按钮
|
||
@export_tool_button("Generate Default Act")
|
||
var _gen_default_act: Callable = Callable(self, "_editor_generate_default_act")
|
||
|
||
##是否要输出报错信息
|
||
@export var debug_log: bool = false
|
||
|
||
##用来扫描prop
|
||
func _scan_scene_for_props(scene_root: Node) -> Dictionary:
|
||
var result := {}
|
||
|
||
if scene_root == null:
|
||
return result
|
||
|
||
_scan_node_recursive(scene_root, result)
|
||
return result
|
||
|
||
|
||
##递归扫描
|
||
func _scan_node_recursive(node: Node, out: Dictionary) -> void:
|
||
if node is PropComponent:
|
||
var prop := node as PropComponent
|
||
if out.has(prop.prop_id):
|
||
push_warning(
|
||
"[ActManagerInspector] Duplicate prop_id: %d (%s)"
|
||
% [prop.prop_id, node.get_path()]
|
||
)
|
||
else:
|
||
out[prop.prop_id] = {
|
||
"node": prop,
|
||
"path": node.get_path()
|
||
}
|
||
|
||
for child in node.get_children():
|
||
_scan_node_recursive(child, out)
|
||
|
||
func _editor_generate_default_act() -> void:
|
||
if not Engine.is_editor_hint():
|
||
return
|
||
|
||
var scene := _get_owner_scene()
|
||
if scene == null:
|
||
_editor_popup(
|
||
"ActManager must be a child of ReedScene.",
|
||
"Generate Default Act - Failed"
|
||
)
|
||
return
|
||
|
||
var props_root := scene.get_node_or_null(scene.props_root_path)
|
||
if props_root == null:
|
||
_editor_popup(
|
||
"Props root not found:\n%s" % scene.props_root_path,
|
||
"Generate Default Act - Failed"
|
||
)
|
||
return
|
||
|
||
var act := Act.new()
|
||
act.prop_state_map.clear()
|
||
|
||
var count := 0
|
||
|
||
for prop_node in props_root.get_children():
|
||
if not prop_node is Node:
|
||
continue
|
||
|
||
var prop_comp := _find_prop_component_top(prop_node)
|
||
if prop_comp == null:
|
||
continue
|
||
|
||
var pid := prop_comp.prop_id
|
||
var init_state := prop_comp.initial_state_id
|
||
act.prop_state_map[pid] = init_state
|
||
count += 1
|
||
|
||
prop_state_map[0] = act
|
||
|
||
notify_property_list_changed()
|
||
|
||
_editor_popup(
|
||
"Default Act generated successfully.\n\nProp count: %d\nAct ID: 0" % count,
|
||
"Generate Default Act - Success"
|
||
)
|
||
|
||
if debug_log:
|
||
print("[ActManager][Editor] Generated Default Act with", count, "props.")
|
||
|
||
## ==============================
|
||
## 工具函数
|
||
## ==============================
|
||
func _editor_popup(message: String, title: String = "ActManager") -> void:
|
||
if not Engine.is_editor_hint():
|
||
return
|
||
|
||
var dialog := AcceptDialog.new()
|
||
dialog.title = title
|
||
dialog.dialog_text = message
|
||
get_tree().root.add_child(dialog)
|
||
dialog.popup_centered()
|
||
|
||
func _get_owner_scene() -> ReedScene:
|
||
var p := get_parent()
|
||
if p is ReedScene:
|
||
return p as ReedScene
|
||
return null
|
||
|
||
func _find_prop_component_top(prop: Node) -> PropComponent:
|
||
for child in prop.get_children():
|
||
if child is PropComponent:
|
||
return child as PropComponent
|
||
return null
|