## DamageContextPool — 伤害上下文对象池（Autoload: DamageContextPool）
## 权威来源：implementation_plan.md §2.1 E-N2 P6-N67
## 本文件不声明 class_name！禁止将 DamageContext 写入这里
extends Node

const POOL_SIZE: int = 64

var _slots:    Array          = []
var _free_ids: PackedInt32Array = PackedInt32Array()
var _in_use:   PackedByteArray  = PackedByteArray()

func _ready() -> void:
	_slots.resize(POOL_SIZE)
	_free_ids.resize(POOL_SIZE)
	_in_use.resize(POOL_SIZE)
	for i in POOL_SIZE:
		_slots[i]    = DamageContext.new()
		_free_ids[i] = POOL_SIZE - 1 - i
		_in_use[i]   = 0

## acquire 内部已调用 ctx.reset()，P6-N67
func acquire(base_dmg: float, m: float, dtype: int, owner: int, crit: bool, pierce: float) -> int:
	if _free_ids.is_empty():
		push_warning("DamageContextPool: 池已耗尽 (POOL_SIZE=%d)" % POOL_SIZE)
		var new_id: int = _slots.size()
		_slots.append(DamageContext.new())
		_in_use.append(0)
		_fill_slot(new_id, base_dmg, m, dtype, owner, crit, pierce)
		return new_id
	var id: int = _free_ids[_free_ids.size() - 1]
	_free_ids.resize(_free_ids.size() - 1)
	_fill_slot(id, base_dmg, m, dtype, owner, crit, pierce)
	return id

func _fill_slot(id: int, base_dmg: float, m: float, dtype: int, owner: int, crit: bool, pierce: float) -> void:
	var ctx: DamageContext = _slots[id]
	ctx.reset()
	ctx.base_damage = base_dmg
	ctx.mult        = m
	ctx.damage_type = dtype
	ctx.owner_id    = owner
	ctx.is_crit     = crit
	ctx.pierce_rate = pierce
	_in_use[id]     = int(1)

func get_context(id: int) -> DamageContext:
	if id < 0 or id >= _slots.size() or _in_use[id] == 0:
		return null
	return _slots[id]

func release(id: int) -> void:
	if id < 0 or id >= _slots.size() or _in_use[id] == 0:
		push_warning("DamageContextPool.release: 无效或重复归还 ID=%d" % id)
		return
	_in_use[id] = 0
	_free_ids.append(id)

func get_pool_usage() -> String:
	var used: int = 0
	for i in _in_use.size():
		if _in_use[i] != 0:
			used += 1
	return "%d / %d" % [used, _slots.size()]

func reset() -> void:
	_free_ids.clear()
	for i in _slots.size():
		_in_use[i] = 0
		_free_ids.append(i)
