70 lines
2.1 KiB
GDScript
70 lines
2.1 KiB
GDScript
## 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)
|