godot-plateformer/addons/reedscene/act/ActManager.gd

120 lines
3.0 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#@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
signal act_changed(from_act_id: int, to_act_id: int)
##用来扫描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].state_id = 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