Files
spellforge/scripts/domain/spell_system/spell_deck.gd
T
2026-07-20 10:56:52 +08:00

75 lines
2.1 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.
## SpellDeck — 运行时执行游标
## 权威来源:implementation_plan.md §2.2
extends RefCounted
class_name SpellDeck
var _nodes: Array = [] # Array[SpellNode]
var _cursor: int = 0
var _consumed: PackedByteArray = PackedByteArray() # 消费掩码(共鸣 consume_inputsP6-N29);1=跳过
func setup(nodes: Array, consumed_indices: Array = []) -> void:
_nodes = nodes
_cursor = 0
_consumed = PackedByteArray()
_consumed.resize(_nodes.size()) # 全 0
for idx in consumed_indices:
if idx >= 0 and idx < _consumed.size():
_consumed[idx] = int(1)
func has_next() -> bool:
var c: int = _cursor
while c < _nodes.size() and c < _consumed.size() and _consumed[c] != 0:
c += 1
return c < _nodes.size()
func pop() -> SpellNode:
while _cursor < _nodes.size() and _cursor < _consumed.size() and _consumed[_cursor] != 0:
_cursor += 1 # 跳过被共鸣消费的槽位
if _cursor >= _nodes.size():
return null
var node: SpellNode = _nodes[_cursor]
_cursor += 1
return node
func peek() -> SpellNode:
if _cursor >= _nodes.size():
return null
return _nodes[_cursor]
func reset_cursor() -> void:
_cursor = 0
## 跳过直到遇到 SCOPE_CLOSE(深度计数器处理嵌套)
func skip_until_scope_end() -> void:
var depth := 1
while _cursor < _nodes.size():
var n: SpellNode = _nodes[_cursor]
_cursor += 1
if n.type == SpellNode.SpellType.SCOPE_CLOSE:
depth -= 1
if depth <= 0:
return
elif n.type == SpellNode.SpellType.TRIGGER or n.type == SpellNode.SpellType.LOGIC:
depth += 1
## 将游标到下一个 SCOPE_CLOSE 之间的节点列表取出(用于打包 SubPayload)
func consume_until_scope_end() -> Array:
var result: Array = []
var depth := 1
while _cursor < _nodes.size():
var n: SpellNode = _nodes[_cursor]
_cursor += 1
if n.type == SpellNode.SpellType.SCOPE_CLOSE:
depth -= 1
if depth <= 0:
break
result.append(n)
else:
if n.type == SpellNode.SpellType.TRIGGER or n.type == SpellNode.SpellType.LOGIC:
depth += 1
result.append(n)
return result
func get_remaining_count() -> int:
return _nodes.size() - _cursor