refactor(skill): 统一技能效果处理逻辑至 SkillView
移除 SCastSystem 中的 applySupportSkill 方法,将治疗、护盾、Buff/Debuff 效果统一在 SkillView 的碰撞逻辑中处理。同时删除 SkillConfig 中的 SType 枚举,改为通过 buffs 和 debuffs 列表配置效果。
This commit is contained in:
@@ -40,15 +40,6 @@ export enum DTType {
|
||||
range = 1,
|
||||
}
|
||||
|
||||
|
||||
export enum SType {
|
||||
damage = 0,
|
||||
heal = 1,
|
||||
shield = 2,
|
||||
zhaohuan = 3,
|
||||
buff = 4,
|
||||
}
|
||||
|
||||
/**
|
||||
* 攻击距离类型分类
|
||||
* 用于AI决策和技能配置规范化
|
||||
@@ -174,7 +165,6 @@ export interface SkillConfig {
|
||||
sp_name:string, // 特效名称
|
||||
icon:string, // 图标ID
|
||||
TGroup:TGroup, // 目标群体(敌方/友方/自身等)
|
||||
SType:SType, // 技能类型(伤害/治疗/护盾等)
|
||||
TType:TType, // 目标类型
|
||||
act:string, // 角色执行的动画
|
||||
DTType:DTType, // 伤害类型(单体/范围)
|
||||
@@ -190,80 +180,81 @@ export interface SkillConfig {
|
||||
RType:RType, // 技能运行类型(直线/贝塞尔/固定起点/固定终点)
|
||||
EType:EType, // 结束条件(动画结束/时间结束/距离结束/碰撞/次数结束)
|
||||
buffs:number[], // 对施法者的buff配置列表(Buff UUID 列表)
|
||||
debuffs:number[], // 对目标的debuff配置列表(Buff UUID 列表)
|
||||
call_hero?:number, // 召唤技能召唤英雄id(可选)
|
||||
info:string, // 技能描述
|
||||
}
|
||||
|
||||
export const SkillSet: Record<number, SkillConfig> = {
|
||||
5000:{uuid:5000,name:"反伤",sp_name:"thorns",icon:"1168",TGroup:TGroup.Enemy,SType:SType.damage,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
5000:{uuid:5000,name:"反伤",sp_name:"thorns",icon:"1168",TGroup:TGroup.Enemy,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
ap:0,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[],info:"反伤",
|
||||
buffs:[],debuffs:[],info:"反伤",
|
||||
},
|
||||
// ========== 基础攻击 ========== 6001-6099
|
||||
6001: {
|
||||
uuid:6001,name:"近战攻击",sp_name:"atk_s1",icon:"1026",TGroup:TGroup.Enemy,SType:SType.damage,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
uuid:6001,name:"近战攻击",sp_name:"atk_s1",icon:"1026",TGroup:TGroup.Enemy,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
ap:100,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[],info:"对前方目标造成100%攻击的伤害",
|
||||
buffs:[],debuffs:[],info:"对前方目标造成100%攻击的伤害",
|
||||
},
|
||||
6002: {
|
||||
uuid:6002,name:"远程攻击",sp_name:"b_arrow_blue",icon:"1135",TGroup:TGroup.Enemy,SType:SType.damage,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
uuid:6002,name:"远程攻击",sp_name:"b_arrow_blue",icon:"1135",TGroup:TGroup.Enemy,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
ap:100,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[],info:"对前方单个目标造成100%攻击的伤害",
|
||||
buffs:[],debuffs:[],info:"对前方单个目标造成100%攻击的伤害",
|
||||
},
|
||||
6003: {
|
||||
uuid:6003,name:"远程攻击",sp_name:"m_water_ball_1",icon:"1126",TGroup:TGroup.Enemy,SType:SType.damage,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
uuid:6003,name:"远程攻击",sp_name:"m_water_ball_1",icon:"1126",TGroup:TGroup.Enemy,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
ap:100,hit_num:1,hit:2,hitcd:0.3,speed:720,with:90,
|
||||
ready:8001,EAnm:0,DAnm:9001,RType:RType.linear,EType:EType.collision,
|
||||
buffs:[],info:"对前方单个目标造成100%攻击的伤害",
|
||||
buffs:[],debuffs:[],info:"对前方单个目标造成100%攻击的伤害",
|
||||
},
|
||||
6004: {
|
||||
uuid:6004,name:"蓄力一击",sp_name:"atk_s4",icon:"1173",TGroup:TGroup.Enemy,SType:SType.damage,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
uuid:6004,name:"蓄力一击",sp_name:"atk_s4",icon:"1173",TGroup:TGroup.Enemy,TType:TType.Frontline,act:"atk",DTType:DTType.single,
|
||||
ap:100,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[],info:"对前方目标造成150%攻击的伤害",
|
||||
buffs:[],debuffs:[],info:"对前方目标造成150%攻击的伤害",
|
||||
},
|
||||
// ========== 基础buff ========== 6100-6199
|
||||
6100: {
|
||||
uuid:6100,name:"治疗",sp_name:"buff_wind",icon:"1292",TGroup:TGroup.Self,SType:SType.heal,TType:TType.LowestHP,act:"atk",DTType:DTType.single,
|
||||
uuid:6100,name:"治疗",sp_name:"buff_wind",icon:"1292",TGroup:TGroup.Self,TType:TType.LowestHP,act:"atk",DTType:DTType.single,
|
||||
ap:30,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[],info:"治疗自己,回复30%最大生命值",
|
||||
buffs:[10301],debuffs:[],info:"治疗自己,回复30%最大生命值",
|
||||
},
|
||||
6101:{
|
||||
uuid:6101,name:"魔法盾",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,SType:SType.shield,TType:TType.LowestHP,act:"atk",DTType:DTType.single,
|
||||
uuid:6101,name:"魔法盾",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,TType:TType.LowestHP,act:"atk",DTType:DTType.single,
|
||||
ap:30,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[],info:"获得30%最大生命值的护盾,持续60秒",
|
||||
buffs:[10302],debuffs:[],info:"获得30%最大生命值的护盾,持续60秒",
|
||||
},
|
||||
6102:{
|
||||
uuid:6102,name:"强壮",sp_name:"buff_wind",icon:"3036",TGroup:TGroup.Team,SType:SType.buff,TType:TType.HighestAP,act:"atk",DTType:DTType.single,
|
||||
uuid:6102,name:"强壮",sp_name:"buff_wind",icon:"3036",TGroup:TGroup.Team,TType:TType.HighestAP,act:"atk",DTType:DTType.single,
|
||||
ap:30,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[10001],info:"增加目标10%攻击力,持续30秒",
|
||||
buffs:[10001],debuffs:[],info:"增加目标10%攻击力,持续30秒",
|
||||
},
|
||||
6103:{
|
||||
uuid:6103,name:"群体强壮",sp_name:"buff_wind",icon:"3036",TGroup:TGroup.Team,SType:SType.buff,TType:TType.HighestAP,act:"atk",DTType:DTType.range,
|
||||
uuid:6103,name:"群体强壮",sp_name:"buff_wind",icon:"3036",TGroup:TGroup.Team,TType:TType.HighestAP,act:"atk",DTType:DTType.range,
|
||||
ap:30,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,
|
||||
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
|
||||
buffs:[10011],info:"增加目标10%攻击力,持续30秒",
|
||||
buffs:[10011],debuffs:[],info:"增加目标10%攻击力,持续30秒",
|
||||
},
|
||||
// ========== 怪物基础技能 ========== 6200-6299
|
||||
6201: {
|
||||
uuid:6201, name:"怪物近战", sp_name:"atk_s1", icon:"3036",
|
||||
TGroup:TGroup.Enemy, SType:SType.damage, TType:TType.Frontline, act:"atk", DTType:DTType.single,
|
||||
TGroup:TGroup.Enemy, TType:TType.Frontline, act:"atk", DTType:DTType.single,
|
||||
ap:100, hit_num:1, hit:1, hitcd:0.2, speed:0, with:0, // 怪物近战特殊距离
|
||||
ready:0, EAnm:0, DAnm:9001, RType:RType.fixed, EType:EType.animationEnd,
|
||||
buffs:[], info:"怪物基础近战攻击",
|
||||
buffs:[], debuffs:[], info:"怪物基础近战攻击",
|
||||
},
|
||||
6203: {
|
||||
uuid:6203, name:"怪物射击", sp_name:"arrow_1", icon:"3039",
|
||||
TGroup:TGroup.Enemy, SType:SType.damage, TType:TType.Frontline, act:"atk", DTType:DTType.single,
|
||||
TGroup:TGroup.Enemy, TType:TType.Frontline, act:"atk", DTType:DTType.single,
|
||||
ap:80, hit_num:1, hit:1, hitcd:0.2, speed:800, with:0, // 怪物远程特殊距离
|
||||
ready:0, EAnm:0, DAnm:9001, RType:RType.linear, EType:EType.collision,
|
||||
buffs:[], info:"怪物基础远程攻击",
|
||||
buffs:[], debuffs:[], info:"怪物基础远程攻击",
|
||||
},
|
||||
|
||||
};
|
||||
@@ -321,6 +312,12 @@ export const BuffsList: Record<number, BuffConf> = {
|
||||
// 护盾 (固定值)
|
||||
10121: { uuid: 10121, name: "护盾", icon: "10121", buff: Attrs.shield, BType: BType.VALUE, value: 100, time: 10, chance: 1, info: "护盾+100" },
|
||||
|
||||
// ========== 治疗与护盾 (转换自原 SType) ========== 10300 - 10399
|
||||
// 治疗 (基于攻击力百分比)
|
||||
10301: { uuid: 10301, name: "治疗", icon: "1292", buff: Attrs.hp, BType: BType.VALUE, value: 30, time: 0, chance: 1, info: "回复30%生命值" },
|
||||
// 护盾 (基于攻击力百分比)
|
||||
10302: { uuid: 10302, name: "护盾", icon: "1255", buff: Attrs.shield, BType: BType.VALUE, value: 30, time: 60, chance: 1, info: "获得30%护盾" },
|
||||
|
||||
// ========== 减益类 Buff (属性降低) ========== 10200 - 10299
|
||||
// 减速 (移动速度降低)
|
||||
10201: { uuid: 10201, name: "减速", icon: "10201", buff: Attrs.speed, BType: BType.VALUE, value: -50, time: 3, chance: 1, info: "移速-50", isDebuff: true },
|
||||
|
||||
@@ -2,11 +2,12 @@ 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, SkillSet, SType, TGroup, TType } from "../common/config/SkillSet";
|
||||
import { BuffsList, SkillConfig, SkillSet, TGroup, TType } from "../common/config/SkillSet";
|
||||
import { Skill } from "../skill/Skill";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { GameConst } from "../common/config/GameConst";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
|
||||
/**
|
||||
* ==================== 自动施法系统 ====================
|
||||
@@ -71,11 +72,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const delay = GameConst.Battle.SKILL_CAST_DELAY;
|
||||
heroView.scheduleOnce(() => {
|
||||
if (!heroView.node || !heroView.node.isValid || heroAttrs.is_dead) return;
|
||||
if (config.SType === SType.damage) {
|
||||
this.createSkillEntity(s_uuid, heroView, targets[0].node.position);
|
||||
} else {
|
||||
this.applySupportSkill(entity, config, targets);
|
||||
}
|
||||
// 始终创建技能实体,所有效果(伤害、Buff、Debuff)均在 SkillView 中处理
|
||||
this.createSkillEntity(s_uuid, heroView, targets[0].node.position);
|
||||
}, delay);
|
||||
if (isMainSkill) {
|
||||
heroAttrs.triggerSkillCD();
|
||||
@@ -92,38 +90,6 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
skill.load(caster.node.position.clone(), parent, s_uuid, targetPos.clone(), caster, 0);
|
||||
}
|
||||
|
||||
private applySupportSkill(casterEntity: ecs.Entity, config: SkillConfig, targets: HeroViewComp[]) {
|
||||
const casterAttrs = casterEntity.get(HeroAttrsComp);
|
||||
if (!casterAttrs) return;
|
||||
const ratio = Number(config.ap ?? 0) / 100;
|
||||
for (const target of targets) {
|
||||
if (!target.ent) continue;
|
||||
const model = target.ent.get(HeroAttrsComp);
|
||||
if (!model || model.is_dead) continue;
|
||||
if (config.SType === SType.heal) {
|
||||
const amount = model.hp_max * ratio;
|
||||
model.add_hp(amount, true);
|
||||
target.health(amount);
|
||||
continue;
|
||||
}
|
||||
if (config.SType === SType.shield) {
|
||||
const amount = model.hp_max * ratio;
|
||||
model.shield_max = Math.max(model.shield_max, amount);
|
||||
model.add_shield(amount, true);
|
||||
continue;
|
||||
}
|
||||
if (config.SType === SType.buff) {
|
||||
for (const buffId of config.buffs) {
|
||||
const buffConf = BuffsList[buffId];
|
||||
if (buffConf) {
|
||||
model.addBuff(buffConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mLogger.log(this.debugMode, "SCastSystem", `[SCastSystem] ${casterAttrs.hero_name} 施放 ${config.name}`);
|
||||
}
|
||||
|
||||
private findTargets(caster: HeroViewComp, casterAttrs: HeroAttrsComp, config: SkillConfig): HeroViewComp[] {
|
||||
const range = casterAttrs.getCachedMaxSkillDistance() || GameConst.Battle.DEFAULT_SEARCH_RANGE;
|
||||
const isEnemy = config.TGroup === TGroup.Enemy;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { _decorator, Animation, CCInteger, Collider2D, Contact2DType, UITransfor
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { DTType, EType, RType, SkillConfig, SkillSet } from "../common/config/SkillSet";
|
||||
import { BuffsList, DTType, EType, RType, SkillConfig, SkillSet } from "../common/config/SkillSet";
|
||||
import { SDataCom } from "./SDataCom";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
@@ -139,6 +139,37 @@ export class SkillView extends CCComp {
|
||||
this.sData.ext_dmg,
|
||||
this.sData.dmg_ratio,
|
||||
);
|
||||
|
||||
// 1. 应用 Buff 效果 (对目标,虽然通常 Buff 是给自己,但这里 target 是碰撞对象)
|
||||
// 注意:如果是增益 Buff (如治疗),通常目标应该是自己或队友。
|
||||
// 但 SkillView 的碰撞逻辑通常是针对"命中目标"。
|
||||
// 如果是治疗技能,target 应该是队友。如果是攻击技能,target 是敌人。
|
||||
// 这里的逻辑假设 SkillView 命中的就是正确的目标。
|
||||
if (this.SConf.buffs && this.SConf.buffs.length > 0) {
|
||||
const targetModel = target.ent.get(HeroAttrsComp);
|
||||
if (targetModel) {
|
||||
for (const buffId of this.SConf.buffs) {
|
||||
const buffConf = BuffsList[buffId];
|
||||
if (buffConf) {
|
||||
targetModel.addBuff(buffConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 应用 Debuff 效果
|
||||
if (this.SConf.debuffs && this.SConf.debuffs.length > 0) {
|
||||
const targetModel = target.ent.get(HeroAttrsComp);
|
||||
if (targetModel) {
|
||||
for (const buffId of this.SConf.debuffs) {
|
||||
const buffConf = BuffsList[buffId];
|
||||
if (buffConf) {
|
||||
targetModel.addBuff(buffConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新技能命中次数
|
||||
this.sData.hit_count++
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user