feat(技能): 优化治疗技能的目标选择逻辑

将治疗技能的目标选择从随机选择后按血量排序改为优先选择缺失生命值最多的目标,提升治疗效率
This commit is contained in:
walkpan
2026-04-04 08:54:19 +08:00
parent 07b8d47760
commit a14115fb6a
4 changed files with 392 additions and 151 deletions

View File

@@ -206,8 +206,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
const sUp = SkillUpList[_s_uuid] ?? SkillUpList[1001];
const sAp =config.ap+sUp.ap*_skillLv;
const sHit=config.hit_count+sUp.hit_count*_skillLv;
const selectedTargets = this.pickRandomFriendlyTargets(targets, sHit);
const applyTargets = kind === SkillKind.Heal ? this.sortTargetsByLowestHp(selectedTargets) : selectedTargets;
const applyTargets = kind === SkillKind.Heal
? this.pickHealTargetsByMostMissingHp(targets, sHit)
: this.pickRandomFriendlyTargets(targets, sHit);
for (const target of applyTargets) {
if (!target.ent) continue;
const model = target.ent.get(HeroAttrsComp);
@@ -254,16 +255,23 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
return selected;
}
private sortTargetsByLowestHp(targets: HeroViewComp[]): HeroViewComp[] {
private pickHealTargetsByMostMissingHp(targets: HeroViewComp[], hitCount: number): HeroViewComp[] {
if (!targets || targets.length === 0) return [];
const validHitCount = Math.max(1, Math.floor(hitCount));
const sortedTargets = this.sortTargetsByMostMissingHp(targets);
return sortedTargets.slice(0, Math.min(validHitCount, sortedTargets.length));
}
private sortTargetsByMostMissingHp(targets: HeroViewComp[]): HeroViewComp[] {
return [...targets].sort((a, b) => {
const aModel = a.ent?.get(HeroAttrsComp);
const bModel = b.ent?.get(HeroAttrsComp);
const aMissingHp = aModel && aModel.hp_max > 0 ? Math.max(0, aModel.hp_max - aModel.hp) : -1;
const bMissingHp = bModel && bModel.hp_max > 0 ? Math.max(0, bModel.hp_max - bModel.hp) : -1;
if (aMissingHp !== bMissingHp) return bMissingHp - aMissingHp;
const aRatio = aModel && aModel.hp_max > 0 ? aModel.hp / aModel.hp_max : 1;
const bRatio = bModel && bModel.hp_max > 0 ? bModel.hp / bModel.hp_max : 1;
if (aRatio !== bRatio) return aRatio - bRatio;
const aHp = aModel?.hp ?? Number.MAX_SAFE_INTEGER;
const bHp = bModel?.hp ?? Number.MAX_SAFE_INTEGER;
return aHp - bHp;
return aRatio - bRatio;
});
}