重构了 技能系统,还需要完善
This commit is contained in:
270
assets/script/game/hero/HSkillSystem.ts
Normal file
270
assets/script/game/hero/HSkillSystem.ts
Normal file
@@ -0,0 +1,270 @@
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { Vec3, v3 } from "cc";
|
||||
import { HeroSkillsComp } from "./HeroSkills";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { SkillSet, SType } from "../common/config/SkillSet";
|
||||
import { SkillEnt } from "../skill/SkillEnt";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
|
||||
/**
|
||||
* ==================== 施法请求标记组件 ====================
|
||||
*
|
||||
* 用途:
|
||||
* - 标记角色想要施放某个技能
|
||||
* - 由外部(如AI系统、玩家输入)添加
|
||||
* - 施法系统处理后自动移除
|
||||
*/
|
||||
@ecs.register('CastSkillRequest')
|
||||
export class CastSkillRequestComp extends ecs.Comp {
|
||||
/** 技能索引(在 HeroSkillsComp.skills 中的位置) */
|
||||
skillIndex: number = 0;
|
||||
|
||||
/** 目标位置数组(由请求者提供) */
|
||||
targetPositions: Vec3[] = [];
|
||||
|
||||
reset() {
|
||||
this.skillIndex = 0;
|
||||
this.targetPositions = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ==================== 技能施法系统 ====================
|
||||
*
|
||||
* 职责:
|
||||
* 1. 监听 CastSkillRequestComp 标记组件
|
||||
* 2. 检查施法条件(CD、MP、状态)
|
||||
* 3. 扣除资源(MP)
|
||||
* 4. 创建技能实体
|
||||
* 5. 触发施法动画
|
||||
* 6. 移除请求标记
|
||||
*
|
||||
* 设计理念:
|
||||
* - 使用标记组件驱动,符合 ECS 理念
|
||||
* - 施法检查与执行分离
|
||||
* - 自动处理资源消耗和CD重置
|
||||
*/
|
||||
export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
|
||||
|
||||
/**
|
||||
* 过滤器:拥有技能数据 + 施法请求的实体
|
||||
*/
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(HeroSkillsComp, HeroAttrsComp, CastSkillRequestComp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体进入时触发(即请求施法时)
|
||||
*/
|
||||
entityEnter(e: ecs.Entity): void {
|
||||
const skillsData = e.get(HeroSkillsComp);
|
||||
const heroModel = e.get(HeroAttrsComp);
|
||||
const request = e.get(CastSkillRequestComp);
|
||||
const heroView = e.get(HeroViewComp);
|
||||
|
||||
// 1. 验证数据完整性
|
||||
if (!skillsData || !heroModel || !request || !heroView) {
|
||||
console.warn("[SkillCastSystem] 数据不完整,取消施法");
|
||||
e.remove(CastSkillRequestComp);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 获取技能数据
|
||||
const skill = skillsData.getSkill(request.skillIndex);
|
||||
if (!skill) {
|
||||
console.warn(`[SkillCastSystem] 技能索引无效: ${request.skillIndex}`);
|
||||
e.remove(CastSkillRequestComp);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 检查施法条件
|
||||
if (!this.checkCastConditions(skillsData, heroModel, request.skillIndex)) {
|
||||
e.remove(CastSkillRequestComp);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 执行施法
|
||||
this.executeCast(e, skill, request.targetPositions, heroView);
|
||||
|
||||
// 5. 扣除资源和重置CD
|
||||
heroModel.mp -= skill.cost;
|
||||
skillsData.resetCD(request.skillIndex);
|
||||
|
||||
// 6. 移除请求标记
|
||||
e.remove(CastSkillRequestComp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查施法条件
|
||||
*/
|
||||
private checkCastConditions(skillsData: HeroSkillsComp, heroModel: HeroAttrsComp, skillIndex: number): boolean {
|
||||
// 检查角色状态
|
||||
if (heroModel.is_dead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查控制状态(眩晕、冰冻)
|
||||
if (heroModel.isStun() || heroModel.isFrost()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查CD和MP
|
||||
if (!skillsData.canCast(skillIndex, heroModel.mp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行施法
|
||||
*/
|
||||
private executeCast(casterEntity: ecs.Entity, skill: any, targetPositions: Vec3[], heroView: HeroViewComp) {
|
||||
const config = SkillSet[skill.uuid];
|
||||
if (!config) {
|
||||
console.error("[SkillCastSystem] 技能配置不存在:", skill.uuid);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 播放施法动画
|
||||
heroView.playSkillEffect(skill.uuid);
|
||||
|
||||
// 2. 延迟创建技能实体(等待动画)
|
||||
const delay = config.with ?? 0.3; // 施法前摇时间
|
||||
heroView.scheduleOnce(() => {
|
||||
this.createSkillEntity(skill.uuid, heroView, targetPositions);
|
||||
}, delay);
|
||||
|
||||
const heroModel = casterEntity.get(HeroAttrsComp);
|
||||
console.log(`[SkillCastSystem] ${heroModel?.hero_name ?? '未知'} 施放技能: ${config.name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建技能实体
|
||||
*/
|
||||
private createSkillEntity(skillId: number, caster: HeroViewComp, targetPositions: Vec3[]) {
|
||||
// 检查节点有效性
|
||||
if (!caster.node || !caster.node.isValid) {
|
||||
console.warn("[SkillCastSystem] 施法者节点无效");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取场景节点
|
||||
const parent = caster.node.parent;
|
||||
if (!parent) {
|
||||
console.warn("[SkillCastSystem] 场景节点无效");
|
||||
return;
|
||||
}
|
||||
|
||||
// ✅ 使用现有的 SkillEnt 创建技能
|
||||
const skillEnt = ecs.getEntity<SkillEnt>(SkillEnt);
|
||||
skillEnt.load(
|
||||
caster.node.position, // 起始位置
|
||||
parent, // 父节点
|
||||
skillId, // 技能ID
|
||||
targetPositions, // 目标位置数组
|
||||
caster, // 施法者
|
||||
0 // 额外伤害(暂时为0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ==================== 技能CD更新系统 ====================
|
||||
*
|
||||
* 职责:
|
||||
* 1. 每帧更新所有角色的技能CD
|
||||
* 2. 自动递减CD时间
|
||||
*
|
||||
* 设计理念:
|
||||
* - 独立的CD管理系统
|
||||
* - 只负责时间递减,不处理施法逻辑
|
||||
*/
|
||||
export class SkillCDSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
||||
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(HeroSkillsComp);
|
||||
}
|
||||
|
||||
update(e: ecs.Entity): void {
|
||||
const skillsData = e.get(HeroSkillsComp);
|
||||
if (!skillsData) return;
|
||||
|
||||
// 更新所有技能CD
|
||||
skillsData.updateCDs(this.dt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ==================== 自动施法系统 ====================
|
||||
*
|
||||
* 职责:
|
||||
* 1. 检测可施放的技能
|
||||
* 2. 根据策略自动施法(AI)
|
||||
* 3. 选择目标
|
||||
* 4. 添加施法请求标记
|
||||
*
|
||||
* 设计理念:
|
||||
* - 负责"何时施法"的决策
|
||||
* - 通过添加 CastSkillRequestComp 触发施法
|
||||
* - 可被玩家输入系统或AI系统复用
|
||||
*/
|
||||
export class SkillAutocastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
||||
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(HeroSkillsComp, HeroAttrsComp, HeroViewComp);
|
||||
}
|
||||
|
||||
update(e: ecs.Entity): void {
|
||||
const skillsData = e.get(HeroSkillsComp);
|
||||
const heroModel = e.get(HeroAttrsComp);
|
||||
const heroView = e.get(HeroViewComp);
|
||||
|
||||
if (!skillsData || !heroModel || !heroView) return;
|
||||
|
||||
// 检查基本条件
|
||||
if (heroModel.is_dead || heroModel.isStun() || heroModel.isFrost()) return;
|
||||
|
||||
// 检查是否正在攻击(只有攻击时才释放技能)
|
||||
if (!heroView.is_atking) return;
|
||||
|
||||
// 获取所有可施放的技能
|
||||
const readySkills = skillsData.getReadySkills(heroModel.mp);
|
||||
if (readySkills.length === 0) return;
|
||||
|
||||
// 选择第一个可施放的伤害技能
|
||||
for (const skillIndex of readySkills) {
|
||||
const skill = skillsData.getSkill(skillIndex);
|
||||
if (!skill) continue;
|
||||
|
||||
const config = SkillSet[skill.uuid];
|
||||
if (!config || config.SType !== SType.damage) continue;
|
||||
|
||||
// ✅ 添加施法请求标记组件
|
||||
const request = e.add(CastSkillRequestComp) as CastSkillRequestComp;
|
||||
request.skillIndex = skillIndex;
|
||||
request.targetPositions = this.selectTargets(heroView);
|
||||
|
||||
// 一次只施放一个技能
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择目标位置
|
||||
*/
|
||||
private selectTargets(caster: HeroViewComp): Vec3[] {
|
||||
// 简化版:选择最前方的敌人
|
||||
const targets: Vec3[] = [];
|
||||
|
||||
// 这里可以调用 SkillConComp 的目标选择逻辑
|
||||
// 暂时返回默认位置
|
||||
const heroModel = caster.ent.get(HeroAttrsComp);
|
||||
const fac = heroModel?.fac ?? 0;
|
||||
const defaultX = fac === 0 ? 400 : -400;
|
||||
targets.push(v3(defaultX, 0, 0));
|
||||
|
||||
return targets;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "846e0307-e55e-4bc3-a9db-b387c89ad671",
|
||||
"uuid": "500ce1a5-24eb-4d18-ac90-11301a372f0e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
@@ -11,29 +11,27 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { SkillSet } from "../common/config/SkillSet";
|
||||
import { time } from "console";
|
||||
import { getNeAttrs, getAttrs ,Attrs} from "../common/config/HeroAttrs";
|
||||
import { TalComp } from "./TalComp";
|
||||
import { EBusComp } from "./EBusComp";
|
||||
import { HeroSkillsComp } from "./HeroSkills";
|
||||
/** 角色实体 */
|
||||
@ecs.register(`Hero`)
|
||||
|
||||
export class Hero extends ecs.Entity {
|
||||
HeroModel!: HeroAttrsComp;
|
||||
HeroSkills!: HeroSkillsComp;
|
||||
View!: HeroViewComp;
|
||||
BattleMove!: BattleMoveComp;
|
||||
protected init() {
|
||||
this.addComponents<ecs.Comp>(
|
||||
BattleMoveComp,
|
||||
HeroAttrsComp,
|
||||
TalComp,
|
||||
EBusComp,
|
||||
HeroSkillsComp,
|
||||
);
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.remove(HeroViewComp);
|
||||
this.remove(HeroAttrsComp);
|
||||
this.remove(TalComp);
|
||||
this.remove(EBusComp);
|
||||
this.remove(HeroSkillsComp);
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@@ -54,6 +52,7 @@ export class Hero extends ecs.Entity {
|
||||
// console.log("hero load",pos)
|
||||
var hv = node.getComponent(HeroViewComp)!;
|
||||
const model = this.get(HeroAttrsComp);
|
||||
const skillsComp = this.get(HeroSkillsComp);
|
||||
let hero = HeroInfo[uuid]; // 共用英雄数据
|
||||
|
||||
// 设置 View 层属性(表现相关)
|
||||
@@ -68,16 +67,8 @@ export class Hero extends ecs.Entity {
|
||||
model.fac = FacSet.HERO;
|
||||
model.is_master = true;
|
||||
|
||||
// 设置技能
|
||||
for(let i=0; i<hero.skills.length; i++){
|
||||
let skill = {
|
||||
uuid: SkillSet[hero.skills[i]].uuid,
|
||||
cd_max: SkillSet[hero.skills[i]].cd,
|
||||
cost: SkillSet[hero.skills[i]].cost,
|
||||
cd: 0
|
||||
};
|
||||
model.skills.push(skill);
|
||||
}
|
||||
// ✅ 初始化技能数据(迁移到 HeroSkillsComp)
|
||||
skillsComp.initSkills(hero.skills);
|
||||
|
||||
// 设置基础属性
|
||||
model.base_ap = hero.ap;
|
||||
|
||||
@@ -46,15 +46,15 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
is_master: boolean = false;
|
||||
is_friend: boolean = false;
|
||||
is_kalami: boolean = false;
|
||||
|
||||
is_atking: boolean = false;
|
||||
is_stop: boolean = false;
|
||||
// ==================== 计数统计 ====================
|
||||
atk_count: number = 0; // 攻击次数
|
||||
atked_count: number = 0; // 被攻击次数
|
||||
|
||||
// ==================== 技能配置 ====================
|
||||
skills: any = [];
|
||||
// 注意:技能数据已迁移到 HeroSkillsComp,不再存储在这里
|
||||
|
||||
start(){
|
||||
this.Ebus=this.ent.get(EBusComp);
|
||||
}
|
||||
// ==================== BUFF 系统初始化 ====================
|
||||
/**
|
||||
@@ -375,8 +375,6 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
this.is_kalami = false;
|
||||
this.atk_count = 0;
|
||||
this.atked_count = 0;
|
||||
this.skills = [];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import { _decorator } from "cc";
|
||||
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 "./HeroViewComp";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** 英雄控制组件 - 处理英雄的装备、强化、天赋等逻辑 */
|
||||
@ccclass('HeroConComp')
|
||||
@ecs.register('HeroCon')
|
||||
export class HeroConComp extends CCComp {
|
||||
private heroView: HeroViewComp = null;
|
||||
|
||||
|
||||
|
||||
protected onLoad(): void {
|
||||
this.heroView = this.node.getComponent(HeroViewComp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** 组件重置 */
|
||||
reset(): void {
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
142
assets/script/game/hero/HeroSkills.ts
Normal file
142
assets/script/game/hero/HeroSkills.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
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 = [];
|
||||
}
|
||||
}
|
||||
9
assets/script/game/hero/HeroSkills.ts.meta
Normal file
9
assets/script/game/hero/HeroSkills.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a23e1b81-c0c9-4aff-bdee-ca5e033792f3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -26,17 +26,17 @@ export interface BuffInfo {
|
||||
@ecs.register('HeroView', false) // 定义ECS 组件
|
||||
export class HeroViewComp extends CCComp {
|
||||
// ==================== View 层属性(表现相关)====================
|
||||
EBus:any=null!
|
||||
as: HeroSpine = null!
|
||||
status:String = "idle"
|
||||
scale: number = 1; // 显示方向
|
||||
box_group:number = BoxSet.HERO; // 碰撞组
|
||||
is_atking:boolean = false; // 是否正在攻击
|
||||
|
||||
// ==================== UI 节点引用 ====================
|
||||
private top_node: Node = null!;
|
||||
|
||||
// ==================== 直接访问 HeroAttrsComp ====================
|
||||
private get model() {
|
||||
get model() {
|
||||
return this.ent.get(HeroAttrsComp);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ export class HeroViewComp extends CCComp {
|
||||
private damageInterval: number = 0.01; // 伤害数字显示间隔
|
||||
onLoad() {
|
||||
this.as = this.getComponent(HeroSpine);
|
||||
this.EBus=this.ent.get(EBusComp);
|
||||
//console.log("[HeroViewComp]:hero view comp ",this.FIGHTCON)
|
||||
this.on(GameEvent.FightEnd,this.do_fight_end,this)
|
||||
const collider = this.node.getComponent(BoxCollider2D);
|
||||
|
||||
@@ -9,14 +9,14 @@ import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp";
|
||||
import { SkillConComp } from "./SkillConComp";
|
||||
import { BuffConf, SkillSet } from "../common/config/SkillSet";
|
||||
import { getNeAttrs, getAttrs ,Attrs} from "../common/config/HeroAttrs";
|
||||
import { TalComp } from "./TalComp";
|
||||
import { getMonAttr, MonType } from "../map/RogueConfig";
|
||||
import { EBusComp } from "./EBusComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { HeroSkillsComp } from "./HeroSkills";
|
||||
/** 角色实体 */
|
||||
@ecs.register(`Monster`)
|
||||
export class Monster extends ecs.Entity {
|
||||
HeroModel!: HeroAttrsComp;
|
||||
HeroSkills!: HeroSkillsComp;
|
||||
HeroView!: HeroViewComp;
|
||||
BattleMove!: BattleMoveComp;
|
||||
|
||||
@@ -24,16 +24,14 @@ export class Monster extends ecs.Entity {
|
||||
this.addComponents<ecs.Comp>(
|
||||
BattleMoveComp,
|
||||
HeroAttrsComp,
|
||||
TalComp,
|
||||
EBusComp,
|
||||
HeroSkillsComp,
|
||||
);
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.remove(HeroViewComp);
|
||||
this.remove(HeroAttrsComp);
|
||||
this.remove(TalComp);
|
||||
this.remove(EBusComp);
|
||||
this.remove(HeroSkillsComp);
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@@ -54,6 +52,7 @@ export class Monster extends ecs.Entity {
|
||||
|
||||
var view = node.getComponent(HeroViewComp)!;
|
||||
const model = this.get(HeroAttrsComp);
|
||||
const skillsComp = this.get(HeroSkillsComp);
|
||||
let hero = HeroInfo[uuid]; // 共用英雄数据
|
||||
// 设置 View 层属性(表现相关)
|
||||
view.scale = scale;
|
||||
@@ -82,18 +81,9 @@ export class Monster extends ecs.Entity {
|
||||
model.Attrs[Attrs.MAP] = map;
|
||||
model.Attrs[Attrs.SPEED] = hero.speed;
|
||||
model.Attrs[Attrs.DIS] = hero.dis;
|
||||
// 初始化师兄
|
||||
|
||||
// 设置技能
|
||||
for(let i=0; i<hero.skills.length; i++){
|
||||
let skill = {
|
||||
uuid: SkillSet[hero.skills[i]].uuid,
|
||||
cd_max: SkillSet[hero.skills[i]].cd,
|
||||
cost: SkillSet[hero.skills[i]].cost,
|
||||
cd: 0
|
||||
};
|
||||
model.skills.push(skill);
|
||||
}
|
||||
|
||||
// ✅ 初始化技能数据(迁移到 HeroSkillsComp)
|
||||
skillsComp.initSkills(hero.skills);
|
||||
|
||||
this.add(view);
|
||||
oops.message.dispatchEvent("monster_load",this)
|
||||
|
||||
@@ -7,6 +7,8 @@ import { FacSet } from '../common/config/BoxSet';
|
||||
import { smc } from '../common/SingletonModuleComp';
|
||||
import { CCComp } from 'db://oops-framework/module/common/CCComp';
|
||||
import { HeroAttrsComp } from './HeroAttrsComp';
|
||||
import { HeroSkillsComp } from './HeroSkills';
|
||||
import { CastSkillRequestComp } from './HSkillSystem';
|
||||
import { SkillEnt } from '../skill/SkillEnt';
|
||||
import { Attrs } from '../common/config/HeroAttrs';
|
||||
import { TalComp } from './TalComp';
|
||||
@@ -29,24 +31,30 @@ export class SkillConComp extends CCComp {
|
||||
this.HeroEntity=this.HeroView.ent
|
||||
}
|
||||
|
||||
/**
|
||||
* ⚠️ 注意:此方法已废弃
|
||||
* 技能CD更新和施法逻辑已迁移到 HSkillSystem(SkillCDSystem + SkillAutocastSystem)
|
||||
* 保留此方法仅用于手动触发技能(如玩家点击技能按钮)
|
||||
*/
|
||||
update(dt: number) {
|
||||
if(!smc.mission.play||smc.mission.pause) return
|
||||
if(!this.HeroView.isStun() && !this.HeroView.isFrost()) {
|
||||
let skills=this.HeroView.skills
|
||||
for(let i=0;i<skills.length;i++){
|
||||
skills[i].cd += dt;
|
||||
if(skills[i].cd > skills[i].cd_max&&this.HeroView.mp >= skills[i].cost){
|
||||
|
||||
if(SkillSet[skills[i].uuid].SType==SType.damage&&this.HeroView.is_atking){
|
||||
this.castSkill(SkillSet[skills[i].uuid])
|
||||
this.HeroView.skills[i].cd = 0
|
||||
this.HeroView.mp -= skills[i].cost
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// 已由 SkillCDSystem 和 SkillAutocastSystem 处理
|
||||
// 此方法可以删除或改为手动施法的入口
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动施放技能(玩家点击技能按钮)
|
||||
* @param skillIndex 技能索引
|
||||
*/
|
||||
manualCastSkill(skillIndex: number) {
|
||||
if (!this.HeroEntity) return;
|
||||
|
||||
// 选择目标
|
||||
const targets = this.selectTargets(1);
|
||||
|
||||
// ✅ 通过添加标记组件请求施法
|
||||
const request = this.HeroEntity.add(CastSkillRequestComp) as CastSkillRequestComp;
|
||||
request.skillIndex = skillIndex;
|
||||
request.targetPositions = targets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user