feat(skill): 支持技能参数自定义覆盖
本次修改实现同技能不同角色的差异化技能效果: 1. 新增SkillOverrides接口与mergeSkillParams工具函数,用于合并基础技能配置和角色覆盖参数 2. 更新英雄配置、属性组件、触发辅助系统与施法系统以适配该机制 3. 为盾骑士、医师添加示例差异化配置,验证功能可行性 4. 整理技能配置,删除冗余重复的旧技能条目 5. 新增技能重构设计计划文档,替换旧的迁移计划文档
This commit is contained in:
@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
||||
import { Vec3, Prefab, instantiate, tween, Node } from "cc";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { DTType, RType, SkillConfig, SkillKind, SkillSet, SkillUpList, TGroup } from "../common/config/SkillSet";
|
||||
import { DTType, RType, SkillConfig, SkillKind, SkillSet, SkillUpList, TGroup, SkillOverrides, mergeSkillParams } from "../common/config/SkillSet";
|
||||
import { Skill } from "../skill/Skill";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { HeroDisVal, HeroInfo, HType } from "../common/config/heroSet";
|
||||
@@ -48,7 +48,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
triggerType?: string,
|
||||
isCardSkill?: boolean,
|
||||
card_lv?: number,
|
||||
targetPos?: Vec3
|
||||
targetPos?: Vec3,
|
||||
overrides?: any
|
||||
}) {
|
||||
if (!args || !args.s_uuid) return;
|
||||
|
||||
@@ -60,7 +61,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
|
||||
// 常规英雄技能触发
|
||||
if (!args.heroAttrs || !args.heroView) return;
|
||||
this.forceCastTriggerSkill(args.s_uuid, args.heroAttrs, args.heroView, args.triggerType);
|
||||
this.forceCastTriggerSkill(args.s_uuid, args.heroAttrs, args.heroView, args.triggerType, args.overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +141,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
skill.load(actualStartPos, parent, s_uuid, targetPos.clone(), mockView, mockAttrs, skillLv, 0);
|
||||
}
|
||||
/** 空施法计划:用于“当前无可施法技能”时的统一返回 */
|
||||
private readonly emptyCastPlan = { skillId: 0, skillLv: 1, isFriendly: false, targetPos: null as Vec3 | null, targetEids: [] as number[] };
|
||||
private readonly emptyCastPlan = { skillId: 0, skillLv: 1, isFriendly: false, targetPos: null as Vec3 | null, targetEids: [] as number[], overrides: undefined as SkillOverrides | undefined };
|
||||
/** 查询缓存:避免每帧重复创建 matcher */
|
||||
private heroMatcher: ecs.IMatcher | null = null;
|
||||
|
||||
@@ -188,7 +189,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* 强制执行触发技能(召唤/死亡触发)
|
||||
* 忽略CD、状态、动画前摇,直接生效
|
||||
*/
|
||||
public forceCastTriggerSkill(s_uuid: number, heroAttrs: HeroAttrsComp, heroView: HeroViewComp, triggerType?: string) {
|
||||
public forceCastTriggerSkill(s_uuid: number, heroAttrs: HeroAttrsComp, heroView: HeroViewComp, triggerType?: string, overrides?: SkillOverrides) {
|
||||
// 播放相应的触发动画
|
||||
if (triggerType === 'call') {
|
||||
heroView.playReady("yellow");
|
||||
@@ -199,8 +200,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
// 如果是敌方攻击技能,必须在战斗中才能释放;友方增益/护盾则允许在非战斗中释放
|
||||
const config = SkillSet[s_uuid];
|
||||
let config = SkillSet[s_uuid];
|
||||
if (!config) return;
|
||||
config = mergeSkillParams(config, overrides);
|
||||
|
||||
const isEnemyTarget = !this.isSelfSkill(config.TGroup) && !this.isFriendlySkill(config.TGroup);
|
||||
if (isEnemyTarget && !smc.mission.in_fight) return;
|
||||
@@ -245,7 +247,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
this.applyFriendlySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, friendlyTargets, null);
|
||||
} else {
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +257,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* 选择顺序:技能候选列表顺序 + 条件过滤(CD、目标可达、目标类型匹配)。
|
||||
* 返回内容同时包含“对敌施法”和“友方施法”两种执行所需数据。
|
||||
*/
|
||||
private pickCastSkill(heroAttrs: HeroAttrsComp, heroView: HeroViewComp): { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[] } {
|
||||
private pickCastSkill(heroAttrs: HeroAttrsComp, heroView: HeroViewComp): { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[]; overrides?: SkillOverrides } {
|
||||
const type = heroAttrs.type as HType;
|
||||
const maxRange = this.resolveMaxCastRange(heroAttrs, type);
|
||||
const target = this.findNearestEnemyInRange(heroAttrs, heroView, maxRange);
|
||||
@@ -263,24 +265,26 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const selfEid = heroView.ent?.eid;
|
||||
for (const s_uuid of skillCandidates) {
|
||||
if (!s_uuid) continue;
|
||||
const config = SkillSet[s_uuid];
|
||||
let config = SkillSet[s_uuid];
|
||||
if (!config) continue;
|
||||
if (!heroAttrs.isSkillReady(s_uuid)) continue;
|
||||
const skillLv = heroAttrs.getSkillLevel(s_uuid);
|
||||
const overrides = heroAttrs.skills[s_uuid]?.overrides;
|
||||
config = mergeSkillParams(config, overrides);
|
||||
if (this.isSelfSkill(config.TGroup)) {
|
||||
if (typeof selfEid !== "number") continue;
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: [selfEid] };
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: [selfEid], overrides };
|
||||
}
|
||||
if (this.isFriendlySkill(config.TGroup)) {
|
||||
const includeSelf = config.TGroup === TGroup.Ally;
|
||||
const friendlyEids = this.collectFriendlyTargetEids(heroAttrs.fac, selfEid, includeSelf);
|
||||
if (friendlyEids.length === 0) continue;
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: friendlyEids };
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: friendlyEids, overrides };
|
||||
}
|
||||
if (!target || !heroView.node || !target.node) continue;
|
||||
const targetPos = this.resolveEnemyCastTargetPos(config, heroAttrs, heroView, target, maxRange);
|
||||
if (!targetPos) continue;
|
||||
return { skillId: s_uuid, skillLv, isFriendly: false, targetPos, targetEids: [] };
|
||||
return { skillId: s_uuid, skillLv, isFriendly: false, targetPos, targetEids: [], overrides };
|
||||
}
|
||||
return this.emptyCastPlan;
|
||||
}
|
||||
@@ -291,14 +295,18 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* - 延迟到出手时机后,按技能目标类型分发到对敌/友方效果处理
|
||||
* - 触发技能CD
|
||||
*/
|
||||
private castSkill(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[] }, heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
|
||||
private castSkill(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[]; overrides?: SkillOverrides }, heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
|
||||
if (!smc.mission.in_fight) return;
|
||||
const s_uuid = castPlan.skillId;
|
||||
const skillLv = castPlan.skillLv;
|
||||
const config = SkillSet[s_uuid];
|
||||
const overrides = castPlan.overrides;
|
||||
let config = SkillSet[s_uuid];
|
||||
const sUp = SkillUpList[s_uuid] ? SkillUpList[s_uuid]:SkillUpList[1001];
|
||||
const cNum = Math.min(2, Math.max(0, Math.floor(sUp.num ?? 0)));
|
||||
if (!config) return;
|
||||
|
||||
config = mergeSkillParams(config, overrides);
|
||||
|
||||
//播放前摇技能动画
|
||||
heroView.playReady(config.readyAnm);
|
||||
//播放角色攻击动画
|
||||
@@ -331,7 +339,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
continue;
|
||||
}
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(castPlan.targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
}
|
||||
}, delay);
|
||||
heroAttrs.triggerSkillCD(s_uuid);
|
||||
@@ -360,24 +368,24 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* 创建技能实体(投射物/范围体等)。
|
||||
* 仅用于对敌伤害技能的实体化表现与碰撞伤害分发。
|
||||
*/
|
||||
private createSkillEntity(s_uuid: number, skillLv: number, caster: HeroViewComp,cAttrsComp: HeroAttrsComp, targetPos: Vec3, castIndex: number = 0) {
|
||||
private createSkillEntity(s_uuid: number, skillLv: number, caster: HeroViewComp,cAttrsComp: HeroAttrsComp, targetPos: Vec3, castIndex: number = 0, overrides?: SkillOverrides) {
|
||||
if (!caster.node || !caster.node.isValid) return;
|
||||
const parent = caster.node.parent;
|
||||
if (!parent) return;
|
||||
const skill = ecs.getEntity<Skill>(Skill);
|
||||
const startPos = this.resolveRepeatCastStartPos(caster.node.position, castIndex);
|
||||
skill.load(startPos, parent, s_uuid, targetPos.clone(), caster, cAttrsComp, skillLv, 0);
|
||||
skill.load(startPos, parent, s_uuid, targetPos.clone(), caster, cAttrsComp, skillLv, 0, overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对敌技能效果处理。
|
||||
* 当前职责:仅处理伤害技能并创建技能实体。
|
||||
*/
|
||||
private applyEnemySkillEffects(s_uuid: number, skillLv: number, config: SkillConfig, heroView: HeroViewComp, cAttrsComp: HeroAttrsComp, targetPos: Vec3 | null, castIndex: number = 0) {
|
||||
private applyEnemySkillEffects(s_uuid: number, skillLv: number, config: SkillConfig, heroView: HeroViewComp, cAttrsComp: HeroAttrsComp, targetPos: Vec3 | null, castIndex: number = 0, overrides?: SkillOverrides) {
|
||||
const kind = config.kind ?? SkillKind.Damage;
|
||||
if (kind !== SkillKind.Damage) return;
|
||||
if (config.ap <= 0 || !targetPos) return;
|
||||
this.createSkillEntity(s_uuid, skillLv, heroView, cAttrsComp, targetPos, castIndex);
|
||||
this.createSkillEntity(s_uuid, skillLv, heroView, cAttrsComp, targetPos, castIndex, overrides);
|
||||
}
|
||||
|
||||
private resolveRepeatCastStartPos(startPos: Readonly<Vec3>, castIndex: number): Vec3 {
|
||||
@@ -512,7 +520,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
/** 判定施法计划是否具备有效目标 */
|
||||
private hasCastTarget(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[] }): boolean {
|
||||
private hasCastTarget(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[]; overrides?: SkillOverrides }): boolean {
|
||||
if (castPlan.skillId === 0) return false;
|
||||
if (castPlan.isFriendly) return castPlan.targetEids.length > 0;
|
||||
return !!castPlan.targetPos;
|
||||
|
||||
Reference in New Issue
Block a user