refactor(hero): 将触发技能配置从 HeroInfo 移至 HeroAttrsComp

重构英雄和怪物实体的创建逻辑,将 call、dead、fstart、fend、atking、atked 等触发技能配置从静态 HeroInfo 表复制到 HeroAttrsComp 组件实例中。
修改 SCastSystem、HeroAtkSystem、MissionComp 和 HeroViewComp 中的技能触发逻辑,改为直接读取组件内的配置。
这消除了对全局静态配置的依赖,使技能触发逻辑与实体数据更紧密地绑定,提高了代码的内聚性和可维护性。
This commit is contained in:
walkpan
2026-04-15 22:27:38 +08:00
parent ba3e416ab0
commit e3c6aad172
7 changed files with 53 additions and 28 deletions

View File

@@ -104,6 +104,14 @@ export class Hero extends ecs.Entity {
model.type = hero.type; model.type = hero.type;
model.fac = FacSet.HERO; model.fac = FacSet.HERO;
// 复制触发技能配置
model.call = hero.call;
model.dead = hero.dead;
model.fstart = hero.fstart;
model.fend = hero.fend;
model.atking = hero.atking;
model.atked = hero.atked;
// 基础属性按等级倍率初始化 // 基础属性按等级倍率初始化
// 使用指数增长公式等级2时为原来的3倍等级3时为原来的9倍 (若需线性增长可改为 hero.ap * (1 + (model.lv - 1) * (FightSet.H_HERO_POW - 1))) // 使用指数增长公式等级2时为原来的3倍等级3时为原来的9倍 (若需线性增长可改为 hero.ap * (1 + (model.lv - 1) * (FightSet.H_HERO_POW - 1)))
model.ap = hero.ap * Math.pow(FightSet.MERGE_NEED, model.lv - 1); model.ap = hero.ap * Math.pow(FightSet.MERGE_NEED, model.lv - 1);
@@ -165,8 +173,8 @@ export class Hero extends ecs.Entity {
} }
// 落地后触发 call 技能 // 落地后触发 call 技能
if (hero.call && hero.call.length > 0) { if (model.call && model.call.length > 0) {
hero.call.forEach(uuid => { model.call.forEach(uuid => {
oops.message.dispatchEvent(GameEvent.TriggerSkill, { oops.message.dispatchEvent(GameEvent.TriggerSkill, {
s_uuid: uuid, s_uuid: uuid,
heroAttrs: model, heroAttrs: model,

View File

@@ -93,10 +93,9 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
/** 检查并触发受击附加技能 (atked) */ /** 检查并触发受击附加技能 (atked) */
private checkAndTriggerAtkedSkills(heroAttrs: HeroAttrsComp, heroView: HeroViewComp) { private checkAndTriggerAtkedSkills(heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
const heroInfo = HeroInfo[heroAttrs.hero_uuid]; if (!heroAttrs.atked || heroAttrs.atked.length === 0) return;
if (!heroInfo || !heroInfo.atked || heroInfo.atked.length === 0) return;
heroInfo.atked.forEach(atkConfig => { heroAttrs.atked.forEach(atkConfig => {
if (heroAttrs.atked_count > 0 && heroAttrs.atked_count % atkConfig.t_num === 0) { if (heroAttrs.atked_count > 0 && heroAttrs.atked_count % atkConfig.t_num === 0) {
oops.message.dispatchEvent(GameEvent.TriggerSkill, { oops.message.dispatchEvent(GameEvent.TriggerSkill, {
s_uuid: atkConfig.s_uuid, s_uuid: atkConfig.s_uuid,
@@ -274,11 +273,10 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
TAttrsComp.is_dead = true; TAttrsComp.is_dead = true;
// 触发死亡技能 // 触发死亡技能
const heroInfo = HeroInfo[TAttrsComp.hero_uuid]; if (TAttrsComp.dead && TAttrsComp.dead.length > 0) {
if (heroInfo && heroInfo.dead && heroInfo.dead.length > 0) {
const view = entity.get(HeroViewComp); const view = entity.get(HeroViewComp);
if (view) { if (view) {
heroInfo.dead.forEach((uuid: number) => { TAttrsComp.dead.forEach((uuid: number) => {
oops.message.dispatchEvent(GameEvent.TriggerSkill, { oops.message.dispatchEvent(GameEvent.TriggerSkill, {
s_uuid: uuid, s_uuid: uuid,
heroAttrs: TAttrsComp, heroAttrs: TAttrsComp,

View File

@@ -1,6 +1,4 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { Attrs } from "../common/config/HeroAttrs";
import { BuffConf } from "../common/config/SkillSet";
import { HeroDisVal, HSkillInfo, HType } from "../common/config/heroSet"; import { HeroDisVal, HSkillInfo, HType } from "../common/config/heroSet";
import { mLogger } from "../common/Logger"; import { mLogger } from "../common/Logger";
import { Timer } from "db://oops-framework/core/common/timer/Timer"; import { Timer } from "db://oops-framework/core/common/timer/Timer";
@@ -27,6 +25,15 @@ export class HeroAttrsComp extends ecs.Comp {
// ==================== 攻击属性 (补充) ==================== // ==================== 攻击属性 (补充) ====================
skills: Record<number, HSkillInfo> = {}; skills: Record<number, HSkillInfo> = {};
// ==================== 触发类技能 ====================
call?: number[];
dead?: number[];
fstart?: number[];
fend?: number[];
atking?: {s_uuid: number, t_num: number}[];
atked?: {s_uuid: number, t_num: number}[];
// ==================== 特殊属性 ==================== // ==================== 特殊属性 ====================
critical: number = 0; // 暴击率 critical: number = 0; // 暴击率
freeze_chance: number = 0; // 冰冻概率 freeze_chance: number = 0; // 冰冻概率
@@ -180,7 +187,6 @@ export class HeroAttrsComp extends ecs.Comp {
// ==================== 技能距离缓存管理 ==================== // ==================== 技能距离缓存管理 ====================
/** /**
* 更新技能距离缓存 * 更新技能距离缓存
@@ -232,6 +238,12 @@ export class HeroAttrsComp extends ecs.Comp {
// 重置新增属性 // 重置新增属性
this.skills = {}; this.skills = {};
this.call = undefined;
this.dead = undefined;
this.fstart = undefined;
this.fend = undefined;
this.atking = undefined;
this.atked = undefined;
this.critical = 0; this.critical = 0;
this.freeze_chance = 0; this.freeze_chance = 0;
this.revive_count = 0; this.revive_count = 0;

View File

@@ -428,9 +428,8 @@ export class HeroViewComp extends CCComp {
this.realDeadTime = this.monDeadTime; this.realDeadTime = this.monDeadTime;
} }
// 如果角色带有死亡触发技能,则由 SCastSystem 播放 playReady("dead"),不播放原有的 deaded 特效 // 如果角色带有死亡触发技能,则由 SCastSystem 播放 playReady("dead")
const heroInfo = HeroInfo[this.model.hero_uuid]; if (this.model && this.model.dead && this.model.dead.length > 0) {
if (heroInfo && heroInfo.dead) {
// SCastSystem will handle the "dead" ready animation // SCastSystem will handle the "dead" ready animation
} else { } else {
// 播放默认死亡特效 // 播放默认死亡特效

View File

@@ -166,6 +166,15 @@ export class Monster extends ecs.Entity {
model.speed = hero.speed; model.speed = hero.speed;
model.type = hero.type; model.type = hero.type;
model.fac = FacSet.MON; model.fac = FacSet.MON;
// 复制触发技能配置
model.call = hero.call;
model.dead = hero.dead;
model.fstart = hero.fstart;
model.fend = hero.fend;
model.atking = hero.atking;
model.atked = hero.atked;
// 标记是否 Boss非 Boss 默认记作杂兵 // 标记是否 Boss非 Boss 默认记作杂兵
model.is_boss =is_boss model.is_boss =is_boss
if(!model.is_boss){ if(!model.is_boss){
@@ -219,8 +228,8 @@ export class Monster extends ecs.Entity {
} }
// 落地后触发 call 技能 // 落地后触发 call 技能
if (hero.call && hero.call.length > 0) { if (model.call && model.call.length > 0) {
hero.call.forEach((uuid: number) => { model.call.forEach((uuid: number) => {
oops.message.dispatchEvent(GameEvent.TriggerSkill, { oops.message.dispatchEvent(GameEvent.TriggerSkill, {
s_uuid: uuid, s_uuid: uuid,
heroAttrs: model, heroAttrs: model,

View File

@@ -338,10 +338,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
/** 检查并触发攻击附加技能 (atking) */ /** 检查并触发攻击附加技能 (atking) */
private checkAndTriggerAtkingSkills(heroAttrs: HeroAttrsComp, heroView: HeroViewComp) { private checkAndTriggerAtkingSkills(heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
const heroInfo = HeroInfo[heroAttrs.hero_uuid]; if (!heroAttrs.atking || heroAttrs.atking.length === 0) return;
if (!heroInfo || !heroInfo.atking || heroInfo.atking.length === 0) return;
heroInfo.atking.forEach(atkConfig => { heroAttrs.atking.forEach(atkConfig => {
if (heroAttrs.atk_count > 0 && heroAttrs.atk_count % atkConfig.t_num === 0) { if (heroAttrs.atk_count > 0 && heroAttrs.atk_count % atkConfig.t_num === 0) {
oops.message.dispatchEvent(GameEvent.TriggerSkill, { oops.message.dispatchEvent(GameEvent.TriggerSkill, {
s_uuid: atkConfig.s_uuid, s_uuid: atkConfig.s_uuid,

View File

@@ -439,15 +439,15 @@ export class MissionComp extends CCComp {
const attrs = entity.get(HeroAttrsComp); const attrs = entity.get(HeroAttrsComp);
const view = entity.get(HeroViewComp); const view = entity.get(HeroViewComp);
if (!attrs || !view || attrs.is_dead || attrs.fac !== FacSet.HERO) return; if (!attrs || !view || attrs.is_dead || attrs.fac !== FacSet.HERO) return;
const info = HeroInfo[attrs.hero_uuid]; const skillUuids = isStart ? attrs.fstart : attrs.fend;
if (!info) return; if (skillUuids && skillUuids.length > 0) {
const skillUuid = isStart ? info.fstart : info.fend; skillUuids.forEach(uuid => {
if (skillUuid) { oops.message.dispatchEvent(GameEvent.TriggerSkill, {
oops.message.dispatchEvent(GameEvent.TriggerSkill, { s_uuid: uuid,
s_uuid: skillUuid, heroAttrs: attrs,
heroAttrs: attrs, heroView: view,
heroView: view, triggerType: isStart ? 'fstart' : 'fend'
triggerType: isStart ? 'fstart' : 'fend' });
}); });
} }
}); });