fix(enemy): 应用 Task 3 代码审查意见

补上池化路径的防重复记忆重置——ResetRepeatMemory 此前文档承诺了
「对象池复用时清除」却无任何调用点,而它要取代的 BossBase.LastUsedSkillId
恰好在 OnSpawn 里有重置。放 EnemyBase.OnSpawn 以覆盖全部池化敌人。

折扣系数改为每次选招前刷新,与 attackSelectionMode 的读取时机对齐——
此前策划在播放模式下调系数无效、调模式却立即生效,容易误判为功能没生效。
默认值收敛为 EnemyAttackSelector.DefaultAntiRepeatFactor 单一常量。

测试:IneligiblePrevious 用例改用系数 0.5——原先用 0 时,把折扣错写在
eligibility 归零之前也照样通过,是个永远不会失败的测试;统计用例边界由
7σ 收紧到 5σ 使其真正验证该系数;补 ResetRepeatMemory 的确定性用例、
系数 1.0 无惩罚、三候选三条。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-30 13:00:28 +08:00
co-authored by Claude Opus 5
parent eb3f4888a4
commit 0a92d21ce1
5 changed files with 104 additions and 15 deletions
@@ -109,6 +109,9 @@ namespace BaseGames.Enemies
var mode = _enemy.StatsSO != null
? _enemy.StatsSO.attackSelectionMode
: Abilities.AttackSelectionMode.WeightedRandom;
// 折扣系数与 mode 同步每次刷新,使播放模式下调参立即生效(不必重进场景)
if (_enemy.StatsSO != null)
sel.AntiRepeatFactor = _enemy.StatsSO.attackAntiRepeatFactor;
bool grounded = _enemy.Movement != null && _enemy.Movement.IsGrounded;
var pick = sel.Select(_enemy.IsPlayerVisible(), grounded, mode);
return pick != null && pick.Execute();