From 747b6d17cfc70b04044d0497b0262adc4345b72d Mon Sep 17 00:00:00 2001 From: pan Date: Wed, 17 Jun 2026 10:46:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(skill-system):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=BD=91=E6=A0=BCAOE=E6=8A=80=E8=83=BD=E7=9A=84=E7=9B=AE?= =?UTF-8?q?=E6=A0=87=E9=80=89=E6=8B=A9=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增DTType.aoe_grid枚举类型用于标识3*3网格范围攻击技能 实现该类型技能的目标位置解析逻辑,区分敌我单位的中路列选择 调整6201至6206号技能的类型为aoe_grid --- assets/script/game/common/config/SkillSet.ts | 13 +++---- assets/script/game/hero/SCastSystem.ts | 36 +++++++++++++++++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index fc1453c8..f74a6091 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -18,6 +18,7 @@ export enum TGroup { export enum DTType { single = 0, range = 1, + aoe_grid = 2, // 3*3 网格范围攻击,以中路第2、3列为目标 } export enum SkillKind { @@ -294,36 +295,36 @@ export const SkillSet: Record = { **/ 6201: { uuid: 6201, name: "雷墙", sp_name: "box_1", icon: "1173", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max", - DTType: DTType.range, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, + DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, RType: RType.fixed, EType: EType.animationEnd, info: "召唤雷墙阻挡敌人,有概率击晕", }, 6202: { uuid: 6202, name: "火墙", sp_name: "box_2", icon: "1173", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max", - DTType: DTType.range, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, + DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, RType: RType.fixed, EType: EType.animationEnd, info: "召唤雷墙阻挡敌人,有概率击晕", }, 6203: { uuid: 6203, name: "飓风", sp_name: "box_3", icon: "1173", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max", - DTType: DTType.range, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, + DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, RType: RType.fixed, EType: EType.animationEnd, info: "召唤雷墙阻挡敌人,有概率击晕", }, 6204: { uuid: 6204, name: "水墙", sp_name: "box_4", icon: "1173", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max", - DTType: DTType.range, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, + DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, RType: RType.fixed, EType: EType.animationEnd, info: "召唤雷墙阻挡敌人,有概率击晕", }, 6205: { uuid: 6205, name: "风墙", sp_name: "box_5", icon: "1173", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max", - DTType: DTType.range, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, + DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, RType: RType.fixed, EType: EType.animationEnd, info: "召唤风墙困住敌人,有概率击晕", }, 6206: { uuid: 6206, name: "陨石术", sp_name: "box_6", icon: "1173", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max", - DTType: DTType.range, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, + DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote, RType: RType.fixed, EType: EType.animationEnd, info: "召唤陨石范围攻击敌人,有概率击晕", }, diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts index 7d425e3b..20312194 100644 --- a/assets/script/game/hero/SCastSystem.ts +++ b/assets/script/game/hero/SCastSystem.ts @@ -13,6 +13,8 @@ import { GameEvent } from "../common/config/GameEvent"; import { SkillTriggerType } from "../common/config/heroSet"; import { SkillTriggerHelper } from "./SkillTriggerHelper"; import { MissionEconomy } from "../map/MissionEconomy"; +import { MissionMonCompComp } from "../map/MissionMonComp"; +import { MissionHeroComp } from "../map/MissionHeroComp"; /** * ==================== 自动施法系统 ==================== @@ -686,9 +688,41 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate /** * 解析对敌技能目标点: * - 非范围技能:按施法方向生成目标点 - * - 范围技能:优先前排敌人位置 + * - range 范围技能:优先前排敌人位置 + * - aoe_grid 范围技能:以中路第2或第3列为目标(若存在敌人优先第2列,否则第3列;这里简化为直接返回第2列中路的固定坐标,或者根据情况处理) */ private resolveEnemyCastTargetPos(config: SkillConfig, heroAttrs: HeroAttrsComp, heroView: HeroViewComp, nearestEnemy: HeroViewComp, maxRange: number): Vec3 | null { + if (config.DTType === DTType.aoe_grid) { + const isHero = heroAttrs.fac === FacSet.HERO; + if (isHero) { + // 英雄打怪物,目标为怪物网格的第2列(idx 1)中路(row 1)或第3列(idx 2)中路 + // MissionMonComp.MON_POSITIONS 顺序: + // 列1: 0,1,2 (X=60) + // 列2: 3,4,5 (X=140) -> 第2列中路是 index 4 + // 列3: 6,7,8 (X=220) -> 第3列中路是 index 7 + // 简单起见,可以固定取第2列中路(index 4)或第3列中路(index 7) + // 若最近的敌人在更后排,也可以取那个敌人的列。 + // 需求:三类 需要以中路 第 2、 3列为目标。 + // 我们直接返回第2列中路坐标(X=140, Y=GAME_LINE)或者根据最近敌人判断。 + // 需求说明为第 2 或 第 3 列,这里我们可以根据目标位置,如果目标在第3列及以后,打第3列,否则打第2列。 + let targetCol = 1; // 0-based, so 1 is 2nd col + if (nearestEnemy && nearestEnemy.node) { + // 判断目标所在的列 + const ex = nearestEnemy.node.position.x; + // X=60(列1), X=140(列2), X=220(列3), X=300(列4) + if (ex >= 200) targetCol = 2; // 第3列 + } + const targetIdx = targetCol * 3 + 1; // 1是中路 + return MissionMonCompComp.MON_POSITIONS[targetIdx].clone(); + } else { + // 怪物打英雄,英雄网格: + // 列1: 0,1,2 (X=-210) + // 列2: 3,4,5 (X=-300) + // 英雄只有2列,第2列中路是 index 4 + return MissionHeroComp.HERO_POSITIONS[4].clone(); + } + } + if (config.RType === RType.bezier) { return nearestEnemy.node?.position.clone() ?? null; }