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;