## SpellContext — 法术执行上下文（对象池化）
## 权威来源：architecture_design.md §3.2, implementation_plan.md §2.2
## registers 跨帧持久（LOGIC_EVERY_N_SHOTS 必须使用此处，禁用 CastState.registers）
extends RefCounted
class_name SpellContext

var caster_id:       int              = 0
var stats:           CastStats        = null  # 本次施法的修改层
## 跨帧持久寄存器（长度固定 4，P6-N48）
## R1-R4：供 LOGIC_EVERY_N_SHOTS 等指令跨帧计数
var registers:       PackedFloat32Array = PackedFloat32Array()
var hp_cost_accum:   float = 0.0    # 本次施法累积 HP 代价（heavy_cost + infinite），施法末结算
var mana_spent_this_cast: bool = false  # 本次施法是否真实扣过蓝（含 LOOP/CIRCUIT 子路径）→ 决定 heat 上升

func _init() -> void:
	stats = CastStats.new()
	registers.resize(4)
	registers.fill(0.0)

func reset() -> void:
	caster_id = 0
	if stats:
		stats.reset()
	else:
		stats = CastStats.new()
	hp_cost_accum = 0.0
	mana_spent_this_cast = false
	# registers 小心：仅当 Core 没有 PERSISTENT_MEMORY Feature 时才清零
	# 具体清空逻辑在 SpellContextPool.acquire_for_wand() 中处理

func clear_registers() -> void:
	registers.fill(0.0)


## CastState — 单次 execute() 的临时工作状态（不入池，每次 new）
## 注意区分：CastState.registers 每次 execute() 开始时重置，不跨调用保留
## LOGIC_EVERY_N_SHOTS 「必须」使用 SpellContext.registers，严禁使用 CastState.registers
class CastState:
	var trigger_depth: int = 0
	var registers: PackedFloat32Array = PackedFloat32Array()

	func _init() -> void:
		registers.resize(4)
		registers.fill(0.0)

	func reset() -> void:
		trigger_depth = 0
		registers.fill(0.0)
