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

194 lines
4.5 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.

'''工具类:用于解析 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": -1,
"state_name": "",
"state_id": -1
}
if state == null:
return result
# --------------------
# State 信息
# --------------------
result.state_name = state.get_state_name()
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