fix(技能系统): 修复远程技能目标选择逻辑,优先攻击最前方敌人
引入 DTType 判断,当技能为远程类型时,通过 findFrontEnemyInRange 方法筛选范围内最前方的敌人作为目标,而非最近的敌人。这确保了远程单位能正确攻击阵型前端的敌人,符合游戏战斗逻辑。
This commit is contained in:
@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
||||
import { Vec3 } from "cc";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { BuffsList, SkillConfig, SkillKind, SkillSet, TGroup } from "../common/config/SkillSet";
|
||||
import { BuffsList, DTType, SkillConfig, SkillKind, SkillSet, TGroup } from "../common/config/SkillSet";
|
||||
import { Skill } from "../skill/Skill";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { GameConst } from "../common/config/GameConst";
|
||||
@@ -76,7 +76,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
return { skillId: s_uuid, isFriendly: true, targetPos: null, targetEids: friendlyEids };
|
||||
}
|
||||
if (!target || !heroView.node || !target.node) continue;
|
||||
const targetPos = this.buildEnemyCastTargetPos(heroView, target, maxRange);
|
||||
const targetPos = this.resolveEnemyCastTargetPos(config, heroAttrs, heroView, target, maxRange);
|
||||
if (!targetPos) continue;
|
||||
return { skillId: s_uuid, isFriendly: false, targetPos, targetEids: [] };
|
||||
}
|
||||
return this.emptyCastPlan;
|
||||
@@ -223,6 +224,42 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
return nearest;
|
||||
}
|
||||
|
||||
private findFrontEnemyInRange(heroAttrs: HeroAttrsComp, heroView: HeroViewComp, maxRange: number, nearestEnemy: HeroViewComp): HeroViewComp | null {
|
||||
if (!heroView.node || !nearestEnemy.node) return null;
|
||||
const currentX = heroView.node.position.x;
|
||||
const direction = nearestEnemy.node.position.x >= currentX ? 1 : -1;
|
||||
let frontEnemy: HeroViewComp | null = null;
|
||||
let edgeX = direction > 0 ? Infinity : -Infinity;
|
||||
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
||||
const attrs = entity.get(HeroAttrsComp);
|
||||
const view = entity.get(HeroViewComp);
|
||||
if (!attrs || !view?.node) return;
|
||||
if (attrs.fac === heroAttrs.fac) return;
|
||||
if (attrs.is_dead || attrs.is_reviving) return;
|
||||
const enemyX = view.node.position.x;
|
||||
const dist = Math.abs(currentX - enemyX);
|
||||
if (dist > maxRange) return;
|
||||
if (direction > 0) {
|
||||
if (enemyX >= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
} else {
|
||||
if (enemyX <= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
}
|
||||
frontEnemy = view;
|
||||
});
|
||||
return frontEnemy;
|
||||
}
|
||||
|
||||
private resolveEnemyCastTargetPos(config: SkillConfig, heroAttrs: HeroAttrsComp, heroView: HeroViewComp, nearestEnemy: HeroViewComp, maxRange: number): Vec3 | null {
|
||||
if (config.DTType !== DTType.range) {
|
||||
return this.buildEnemyCastTargetPos(heroView, nearestEnemy, maxRange);
|
||||
}
|
||||
const frontEnemy = this.findFrontEnemyInRange(heroAttrs, heroView, maxRange, nearestEnemy);
|
||||
if (!frontEnemy?.node) return null;
|
||||
return frontEnemy.node.position.clone();
|
||||
}
|
||||
|
||||
private resolveMaxCastRange(heroAttrs: HeroAttrsComp, type: HType): number {
|
||||
const cached = heroAttrs.getCachedMaxSkillDistance();
|
||||
if (cached > 0) return cached;
|
||||
|
||||
Reference in New Issue
Block a user