feat(技能系统): 实现技能冷却时间受攻击速度和技能速度属性影响

新增技能速度(SS)属性,用于减少非基础攻击技能的冷却时间
基础攻击技能冷却时间由英雄的as属性决定
眩晕和冰冻状态下不更新技能CD
合并冗余的canCast和resetCD方法
This commit is contained in:
2025-11-03 20:53:31 +08:00
parent 04aa5f9c78
commit 914ab0e8b9
7 changed files with 71 additions and 69 deletions

View File

@@ -74,7 +74,7 @@ export class Hero extends ecs.Entity {
model.is_master = true;
// ✅ 初始化技能数据(迁移到 HeroSkillsComp
skillsComp.initSkills(hero.skills);
skillsComp.initSkills(hero.skills,uuid);
// 设置基础属性
model.base_ap = hero.ap;

View File

@@ -1,5 +1,8 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { Attrs } from "../common/config/HeroAttrs";
import { HeroInfo } from "../common/config/heroSet";
import { SkillSet } from "../common/config/SkillSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
/**
* ==================== 技能槽位数据 ====================
@@ -39,21 +42,24 @@ export class HeroSkillsComp extends ecs.Comp {
* 初始化技能列表
* @param sUuids 技能配置ID数组
*/
initSkills(sUuids: number[]) {
initSkills(sUuids: number[], uuid: number) {
this.skills = [];
for (const s_uuid of sUuids) {
for (let i = 0; i < sUuids.length; i++) {
const s_uuid = sUuids[i];
const config = SkillSet[s_uuid];
if (!config) {
console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`);
continue;
}
this.skills[s_uuid]={
// 第0个技能的 cd_max 取 herosinfo[uuid].as
const cdMax = i === 0 ? HeroInfo[uuid].as : config.cd;
this.skills[s_uuid] = {
s_uuid: config.uuid,
cd: 0,
cd_max: config.cd,
cd_max: cdMax,
cost: config.cost,
level: 1,
}
};
}
}
@@ -84,9 +90,11 @@ export class HeroSkillsComp extends ecs.Comp {
/**
* 检查技能是否可施放(通过索引
* @param index 技能索引
* 检查技能是否可施放(通过s_uuid
* @param s_uuid 技能配置ID
* @param currentMp 当前MP值
*/
canCast(s_uuid: number, currentMp: number): boolean {
@@ -97,41 +105,28 @@ export class HeroSkillsComp extends ecs.Comp {
return skill.cd <= 0 && currentMp >= skill.cost;
}
/**
* 检查技能是否可施放通过s_uuid
* @param s_uuid 技能配置ID
* @param currentMp 当前MP值
*/
canCastByUuid(s_uuid: number, currentMp: number): boolean {
const skill = this.getSkill(s_uuid);
if (!skill) return false;
// 检查CD和MP
return skill.cd <= 0 && currentMp >= skill.cost;
}
/**
* 重置技能CD开始冷却通过索引
* @param index 技能索引
*/
resetCD(s_uuid: number) {
let attrsCom = this.ent.get(HeroAttrsComp);
if (!attrsCom) return;
const skill = this.getSkill(s_uuid);
if (!skill) return;
// 普通攻击skills[0])受 AS 影响,其余技能受 SS 影响
const isNormalAttack = s_uuid === this.skills[0]?.s_uuid;
const speedAttr = isNormalAttack ? Attrs.AS : Attrs.SS;
const speedBonus = attrsCom.Attrs[speedAttr] / 100; // 100 表示 100% 提速
const speedMultiplier = 1 / (1 + speedBonus); // 提速 100% => cd 减半
skill.cd = skill.cd_max * speedMultiplier;
if (skill) {
skill.cd = skill.cd_max;
}
}
/**
* 重置技能CD开始冷却通过s_uuid
* @param s_uuid 技能配置ID
*/
resetCDByUuid(s_uuid: number) {
const skill = this.getSkill(s_uuid);
if (skill) {
skill.cd = skill.cd_max;
}
}
/**
* 更新所有技能CD每帧调用
* @param dt 时间增量
@@ -154,7 +149,7 @@ export class HeroSkillsComp extends ecs.Comp {
getReadySkills(currentMp: number): number[] {
const ready: number[] = [];
for (const s_uuid in this.skills) {
if (this.canCastByUuid(Number(s_uuid), currentMp)) {
if (this.canCast(Number(s_uuid), currentMp)) {
ready.push(Number(s_uuid));
}
}

View File

@@ -88,7 +88,7 @@ export class Monster extends ecs.Entity {
model.Attrs[Attrs.DIS] = hero.dis;
// ✅ 初始化技能数据(迁移到 HeroSkillsComp
skillsComp.initSkills(hero.skills);
skillsComp.initSkills(hero.skills,uuid);
this.add(view);
oops.message.dispatchEvent("monster_load",this)

View File

@@ -1,5 +1,6 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../common/SingletonModuleComp";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroSkillsComp } from "./HeroSkills";
/**
@@ -27,7 +28,11 @@ export class SkillCDSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
if(!smc.mission.play || smc.mission.pause) return;
const skills = e.get(HeroSkillsComp);
if (!skills) return;
const attrsCom = e.get(HeroAttrsComp);
if (!attrsCom) return;
if (attrsCom.isStun() || attrsCom.isFrost()) { // 眩晕和冰冻状态不更新CD
return;
}
// 更新所有技能CD
skills.updateCDs(this.dt);
}