技能逻辑修改,怪物只攻击最前方,友方和地方逻辑分开

This commit is contained in:
2025-03-18 16:17:46 +08:00
parent 3a7b0e4762
commit 7f82edf4f9

View File

@@ -131,59 +131,49 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
view.at = view.at-view.cd; // 重置普攻计时器
break;
}
if (config.TargetGroup === TargetGroup.Enemy) {
const targets = this.selectEnemyTargets(caster, config);
if (targets.length === 0) return;
const skillEntity = ecs.getEntity<Skill>(Skill);
skillEntity.load(
view.node.position, // 起始位置
view.fac, // 阵营
view.node.parent, // 父节点
config.uuid, // 技能ID
targets[0]?.get(HeroViewComp).node.position // 目标位置
);
targets.forEach(target => {
this.applySkillEffect(caster, target, config);
});
}
if (config.TargetGroup === TargetGroup.Ally) {
const targets = this.selectAllyTargets(caster, config);
if (targets.length === 0) return;
targets.forEach(target => {
this.applySkillEffect(caster, target, config);
});
}
// 选择目标
const targets = this.selectTargets(caster, config);
if (targets.length === 0) return;
// 创建技能实体
const skillEntity = ecs.getEntity<Skill>(Skill);
skillEntity.load(
view.node.position, // 起始位置
view.fac, // 阵营
view.node.parent, // 父节点
config.uuid, // 技能ID
targets[0]?.get(HeroViewComp).node.position // 目标位置
);
// 应用技能效果
targets.forEach(target => {
this.applySkillEffect(caster, target, config);
});
if (config.TargetGroup === TargetGroup.Self) {
this.applySkillEffect(caster, caster, config);
}
}
/** 选择技能目标 */
private selectTargets(caster: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]): ecs.Entity[] {
private selectEnemyTargets(caster: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]): ecs.Entity[] {
const casterView = caster.get(HeroViewComp);
const team = casterView.fac;
const isEnemyTeam = team === 0 ? 1 : 0;
// 第一阶段:基础目标筛选
let candidates = ecs.query(ecs.allOf(HeroViewComp)).filter(e => {
const view = e.get(HeroViewComp);
// 根据技能目标类型筛选
switch(config.TargetGroup) {
case TargetGroup.Enemy:
return view.fac !== team;
case TargetGroup.Ally:
return view.fac === team && e !== caster;
case TargetGroup.Self:
return e === caster;
default:
return true;
}
});
const candidates= ecs.query(ecs.allOf(HeroViewComp)).filter(e => e.get(HeroViewComp).fac !== team);
return this.filterFrontRow(candidates, isEnemyTeam);
}
private selectAllyTargets(caster: ecs.Entity, config: typeof SkillSet[keyof typeof SkillSet]): ecs.Entity[] {
const casterView = caster.get(HeroViewComp);
const team = casterView.fac;
const candidates= ecs.query(ecs.allOf(HeroViewComp)).filter(e => e.get(HeroViewComp).fac === team);
// 第二阶段:位置/血量等精细筛选
switch(config.TargetType) {
case TargetType.Frontline:
return this.filterFrontRow(candidates, isEnemyTeam);
// case TargetType.Backline:
// return this.filterBackRow(candidates, isEnemyTeam);
// case TargetType.LowestHP:
// return this.filterLowestHealth(candidates);
// case TargetType.HighestHP:
// return this.filterHighestHealth(candidates);
case TargetType.Melee:
return candidates.filter(e => e.get(HeroViewComp).type === 0);
case TargetType.Ranged:
@@ -196,7 +186,7 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
return candidates;
}
}
/** 筛选最前排单位 */
private filterFrontRow(entities: ecs.Entity[], isEnemyTeam: number): ecs.Entity[] {
// 敌方最前排是x坐标最大的我方最前排是x坐标最小的
@@ -209,30 +199,6 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
);
}
/** 筛选最后排单位 */
private filterBackRow(entities: ecs.Entity[], isEnemyTeam: number): ecs.Entity[] {
// 敌方最后排是x坐标最小的我方最后排是x坐标最大的
const keyPos = isEnemyTeam ?
Math.max(...entities.map(e => e.get(HeroViewComp).node.position.x)) :
Math.min(...entities.map(e => e.get(HeroViewComp).node.position.x));
return entities.filter(e =>
Math.abs(e.get(HeroViewComp).node.position.x - keyPos) < 10
);
}
/** 筛选血量最低单位 */
private filterLowestHealth(entities: ecs.Entity[]): ecs.Entity[] {
const minHp = Math.min(...entities.map(e => e.get(HeroViewComp).hp));
return entities.filter(e => e.get(HeroViewComp).hp === minHp);
}
/** 筛选血量最高单位 */
private filterHighestHealth(entities: ecs.Entity[]): ecs.Entity[] {
const maxHp = Math.max(...entities.map(e => e.get(HeroViewComp).hp));
return entities.filter(e => e.get(HeroViewComp).hp === maxHp);
}
/** 随机选择目标 */
private pickRandomTarget(entities: ecs.Entity[], count: number): ecs.Entity[] {
const shuffled = [...entities].sort(() => 0.5 - Math.random());
@@ -272,7 +238,6 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
result.delay = distance / config.speed;
}
const targetView = target.get(HeroViewComp);
const sourceView = caster.get(HeroViewComp);
let final = sourceView.ap * config.ap / 100;
@@ -281,34 +246,8 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
final *= damageFloat;
final = Math.round(final);
// 闪避判定
if (Math.random()*100 < targetView.dodge) {
result.isDodged = true
return result
}
// 护甲减伤
if (!result.ignoreDefense) {
const effectiveArmor = Math.min(targetView.def, 300); // 最大减伤75%
const damageReduction = effectiveArmor / (effectiveArmor + 100);
final *= (1 - damageReduction);
final = Math.round(final); // 四舍五入取整
}
// 暴击判定
let isCrit = false;
if (result.canCrit) {
const critRate = sourceView.crit;
if (Math.random() * 100 < critRate) {
final *= 1.5;
isCrit = true;
}
}
result.value = Math.max(1, final); // 确保最小伤害为1
result.isCrit = isCrit;
result.isCrit = false;
return result;
}
@@ -318,12 +257,7 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
callback: () => {
const view = target.get(HeroViewComp);
if (!view?.ent.has(HeroViewComp)) return;
if(result.isDodged){
view.BUFFCOMP.tooltip(5,"*闪避*");
return;
}
let remainingDamage = result.value;
if (view.shield > 0) {
const shieldAbsorb = Math.min(view.shield, remainingDamage);
@@ -341,7 +275,7 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
view.BUFFCOMP.dead()
view.to_grave();
}
view.showDamage(result.value, result.isCrit);
view.showDamage(result.value, true);
} else {
view.BUFFCOMP.tooltip(5,"*吸收*");
}
@@ -364,17 +298,6 @@ export class HeroSkillSystem extends ecs.ComblockSystem implements ecs.ISystemUp
// 实现debuff逻辑...
}
/** 外部调用重置冷却 */
public resetSkillCooldown(entity: ecs.Entity, skillId: number) {
const comp = entity.get(HeroSkillsComp);
comp.resetCooldown(skillId);
}
/** 重置所有技能冷却 */
public resetAllCooldowns(entity: ecs.Entity) {
const comp = entity.get(HeroSkillsComp);
comp.resetAllCooldowns();
}
}