From 3c51db64fa8e2961a39404ba0f84e9b319823083 Mon Sep 17 00:00:00 2001 From: walkpan Date: Thu, 19 Mar 2026 20:48:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8A=80=E8=83=BD=E7=B3=BB=E7=BB=9F):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=9C=E7=A8=8B=E6=8A=80=E8=83=BD=E7=9B=AE?= =?UTF-8?q?=E6=A0=87=E9=80=89=E6=8B=A9=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=85=88=E6=94=BB=E5=87=BB=E6=9C=80=E5=89=8D=E6=96=B9=E6=95=8C?= =?UTF-8?q?=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 引入 DTType 判断,当技能为远程类型时,通过 findFrontEnemyInRange 方法筛选范围内最前方的敌人作为目标,而非最近的敌人。这确保了远程单位能正确攻击阵型前端的敌人,符合游戏战斗逻辑。 --- assets/script/game/hero/SCastSystem.ts | 41 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts index 580d95b2..204f047c 100644 --- a/assets/script/game/hero/SCastSystem.ts +++ b/assets/script/game/hero/SCastSystem.ts @@ -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;