Files
heros/assets/script/game/hero/HeroSkills.ts

142 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { SkillSet } from "../common/config/SkillSet";
/**
* ==================== 技能槽位数据 ====================
* 单个技能的运行时数据
*/
export interface SkillSlot {
uuid: number; // 技能配置ID
cd: number; // 当前CD时间递减
cd_max: number; // 最大CD时间
cost: number; // MP消耗
level: number; // 技能等级(预留)
}
/**
* ==================== 英雄技能数据组件 ====================
*
* 职责:
* 1. 存储角色拥有的技能列表
* 2. 管理技能CD状态
* 3. 提供技能查询接口
*
* 设计理念:
* - 只存数据,不含施法逻辑
* - CD 更新由 HSkillSystem 负责
* - 施法判定由 HSkillSystem 负责
*/
@ecs.register('HeroSkills')
export class HeroSkillsComp extends ecs.Comp {
// ==================== 技能槽位列表 ====================
/** 技能槽位数组最多4个技能 */
skills: SkillSlot[] = [];
// ==================== 辅助方法 ====================
/**
* 初始化技能列表
* @param skillIds 技能配置ID数组
*/
initSkills(skillIds: number[]) {
this.skills = [];
for (const skillId of skillIds) {
const config = SkillSet[skillId];
if (!config) {
console.warn(`[HeroSkills] 技能配置不存在: ${skillId}`);
continue;
}
this.skills.push({
uuid: config.uuid,
cd: 0, // 初始CD为0可立即施放
cd_max: config.cd,
cost: config.cost,
level: 1
});
}
}
/**
* 添加单个技能
*/
addSkill(skillId: number) {
const config = SkillSet[skillId];
if (!config) {
console.warn(`[HeroSkills] 技能配置不存在: ${skillId}`);
return;
}
this.skills.push({
uuid: config.uuid,
cd: 0,
cd_max: config.cd,
cost: config.cost,
level: 1
});
}
/**
* 获取指定索引的技能
*/
getSkill(index: number): SkillSlot | null {
return this.skills[index] ?? null;
}
/**
* 检查技能是否可施放
* @param index 技能索引
* @param currentMp 当前MP值
*/
canCast(index: number, currentMp: number): boolean {
const skill = this.getSkill(index);
if (!skill) return false;
// 检查CD和MP
return skill.cd <= 0 && currentMp >= skill.cost;
}
/**
* 重置技能CD开始冷却
* @param index 技能索引
*/
resetCD(index: number) {
const skill = this.getSkill(index);
if (skill) {
skill.cd = skill.cd_max;
}
}
/**
* 更新所有技能CD每帧调用
* @param dt 时间增量
*/
updateCDs(dt: number) {
for (const skill of this.skills) {
if (skill.cd > 0) {
skill.cd -= dt;
if (skill.cd < 0) {
skill.cd = 0;
}
}
}
}
/**
* 获取所有可施放的技能索引
*/
getReadySkills(currentMp: number): number[] {
const ready: number[] = [];
for (let i = 0; i < this.skills.length; i++) {
if (this.canCast(i, currentMp)) {
ready.push(i);
}
}
return ready;
}
reset() {
this.skills = [];
}
}