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

194 lines
4.5 KiB
GDScript3
Raw Normal View History

2026-01-03 23:21:04 +08:00
'''工具类:用于解析 State / 路径 / 展示信息'''
@tool
class_name StateResolveUtils
# =====================================================
# Section 1: Drag Data → State Path / State Node
# =====================================================
static func is_valid_state_drag(data) -> bool:
return get_state_node_from_drag(data) != null
static func get_state_path_from_drag(data) -> NodePath:
var raw := _extract_node_path_from_drag(data)
if raw.is_empty():
return NodePath()
return _normalize_to_scene_root(raw)
static func get_state_node_from_drag(data) -> ReedPropState:
var path := get_state_path_from_drag(data)
if path.is_empty():
return null
return get_state_node_from_path(path)
# =====================================================
# Section 2: NodePath → State Node
# =====================================================
static func get_state_node_from_path(path: NodePath) -> ReedPropState:
if path.is_empty():
return null
var root := EditorInterface.get_edited_scene_root()
if root == null:
return null
var node := root.get_node_or_null(path)
if node is ReedPropState:
return node
return null
# =====================================================
# Section 3: State Node → 展示信息
# =====================================================
static func resolve_state_display_info(state: ReedPropState) -> Dictionary:
var result := {
"prop_name": "",
"prop_id": "",
"state_name": "",
"state_id": ""
}
if state == null:
return result
# --------------------
# State 信息
# --------------------
2026-01-04 21:21:01 +08:00
result.state_name = state.get_state_name()
2026-01-03 23:21:04 +08:00
result.state_id = str(state.state_id)
# --------------------
# PropComponent
# --------------------
var prop_comp := _find_parent_prop_comp(state)
if prop_comp == null:
return result
result.prop_id = str(prop_comp.prop_id)
# --------------------
# Prop 实体节点PropComponent 的父节点)
# --------------------
var prop_node := prop_comp.get_parent()
if prop_node:
result.prop_name = prop_node.name
return result
# =====================================================
# Section 4: Internal helpers
# =====================================================
static func _extract_node_path_from_drag(data) -> NodePath:
if typeof(data) != TYPE_DICTIONARY:
return NodePath()
# SceneTree 标准nodes = [NodePath / String]
if data.has("nodes") and data["nodes"] is Array and data["nodes"].size() > 0:
var first = data["nodes"][0]
if first is NodePath:
return first
if typeof(first) == TYPE_STRING:
return NodePath(first)
# 少见兜底:直接给了 node
if data.has("node") and data["node"] is Node:
return (data["node"] as Node).get_path()
return NodePath()
static func _normalize_to_scene_root(p: NodePath) -> NodePath:
if p.is_empty():
return p
var root := EditorInterface.get_edited_scene_root()
if root == null:
return p
var root_path := String(root.get_path())
var s := String(p)
# 已经是相对路径
if not s.begins_with("/"):
return p
if s.begins_with(root_path):
s = s.substr(root_path.length())
if s.begins_with("/"):
s = s.substr(1)
return NodePath(s)
static func _find_parent_prop_comp(state: Node) -> PropComponent:
var cur := state.get_parent()
while cur:
if cur is PropComponent:
return cur
cur = cur.get_parent()
return null
## 通过Path返回ID和State
static func resolve_ids_from_state_path(path: NodePath) -> Dictionary:
var result := {
"prop_id": -1,
"state_id": -1
}
var root := EditorInterface.get_edited_scene_root()
if root == null:
return result
var node := root.get_node_or_null(path)
if not (node is ReedPropState):
return result
result.state_id = node.state_id
var prop_comp := _find_parent_prop_comp(node)
if prop_comp == null:
return result
result.prop_id = prop_comp.prop_id
return result
## 通过id 获取Name
static func resolve_names_from_ids(
prop_id: int,
state_id: int
) -> Dictionary:
var result := {
"prop_name": "",
"state_name": ""
}
var root := EditorInterface.get_edited_scene_root()
if root == null:
return result
# 遍历 PropComponent你之后可以优化成表
for prop_comp in root.get_tree().get_nodes_in_group("PropComponent"):
if prop_comp.prop_id != prop_id:
continue
var prop_node := prop_comp.get_parent()
if prop_node:
result.prop_name = prop_node.name
for child in prop_comp.get_children():
if child is ReedPropState and child.state_id == state_id:
result.state_name = child.name
return result
return result