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, HType } from "../common/config/heroSet"; import { mLogger } from "../common/Logger"; import { Timer } from "db://oops-framework/core/common/timer/Timer"; import { FightSet } from "../common/config/GameSet"; @ecs.register('HeroAttrs') export class HeroAttrsComp extends ecs.Comp { public debugMode: boolean = false; Ebus:any=null! // ==================== 角色基础信息 ==================== hero_uuid: number = 1001; hero_name: string = "hero"; lv: number = 1; type: number = 0; // 0近战 1远程 2辅助 fac: number = 0; // 0:hero 1:monster // ==================== 基础属性(有初始值) ==================== ap: number = 0; // 基础攻击 hp: number = 100; // 基础血量 hp_max: number = 100; // 最大血量 speed: number = 100; // 基础移动速度 dis: number = 100; // 基础距离 shield: number = 0; // 当前护盾 shield_max: number = 0; // 最大护盾值 // ==================== 攻击属性 (补充) ==================== a_cd: number = 0; // 攻击计时 s_cd: number = 0; // 技能计时 a_cd_max: number = 0; // 攻击CD s_cd_max: number = 0; // 技能CD // ==================== 特殊属性 ==================== critical: number = 0; // 暴击率 freeze_chance: number = 0; // 冰冻概率 back_chance: number = 0; // 击退概率 puncture: number = 0; // 穿刺次数 wfuny: number = 0; // 风怒 revive_count: number = 0; // 复活次数 revive_time: number = 0; // 复活时间 invincible_time: number = 0;// 无敌时间 frost_end_time: number = 0; boom: boolean = false; // 自爆怪 // ==================== 脏标签标记 ==================== dirty_hp: boolean = false; // 血量变更标记 dirty_shield: boolean = false; // 护盾变更标记 // ==================== 技能距离缓存 ==================== maxSkillDistance: number = 0; // 最远技能攻击距离(缓存,受MP影响) minSkillDistance: number = 0; // 最近技能攻击距离(缓存,不受MP影响,用于停止位置判断) // ==================== 标记状态 ==================== is_dead: boolean = false; is_count_dead: boolean = false; is_atking: boolean = false; // 是否正在攻击 is_stop: boolean = false; // 是否正在停止 is_boss: boolean = false; is_big_boss: boolean = false; is_master: boolean = false; is_friend: boolean = false; is_kalami: boolean = false; is_reviving: boolean = false; // 是否正在复活中 // ==================== 计数统计 ==================== atk_count: number = 0; // 攻击次数 atked_count: number = 0; // 被攻击次数 killed_count:number=0; atk_id:number=0; //普通攻击技能id skill_id:number=0; //技能攻击技能id can_atk=false can_skill=false combat_target_eid: number = -1; enemy_in_cast_range: boolean = false; start(){ } // ==================== BUFF 系统初始化 ==================== /** * 初始化角色的 buff debuff * 从 HeroInfo 读取初始配置,建立属性系统 */ initAttrs() { this.frost_end_time = 0; } /*******************基础属性管理********************/ add_hp(value:number,isValue:boolean){ const oldHp = this.hp; let addValue = value; if(!isValue){ addValue = value * this.hp_max / 100; } // ✅ 数据层只负责数据修改,不调用视图层 // let heroView = this.ent.get(HeroViewComp); // if(heroView && addValue > 0){ // heroView.health(addValue); // } this.hp += addValue; this.hp = Math.max(0, Math.min(this.hp, this.hp_max)); this.dirty_hp = true; // ✅ 仅标记需要更新 if (this.debugMode) { mLogger.log(this.debugMode, 'HeroAttrs', ` HP变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldHp.toFixed(1)} -> ${this.hp.toFixed(1)}`); } return addValue; } add_shield(value:number,isValue:boolean){ const oldShield = this.shield; let addValue = value; if(!isValue){ addValue = value * this.hp_max / 100; } this.shield += addValue; this.shield_max += addValue; if (this.shield < 0) this.shield = 0; if (this.shield_max < 0) this.shield_max = 0; this.dirty_shield = true; // 标记护盾需要更新 if (this.debugMode) { mLogger.log(this.debugMode, 'HeroAttrs', ` 护盾变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldShield.toFixed(1)} -> ${this.shield.toFixed(1)}`); } } // ==================== BUFF 管理 ==================== /** * 添加 buff 效果 * @param buffConf buff 配置 */ addBuff(buffConf: BuffConf) { this.applyAttrChange(buffConf.buff, buffConf.value); if (this.debugMode) { mLogger.log(this.debugMode, 'HeroAttrs', `添加属性: ${buffConf.name}, 属性:${buffConf.buff}, 值:${buffConf.value}`); } } toFrost(time: number=1) { this.frost_end_time += FightSet.FROST_TIME*time; } /** * 通用属性修改应用 * @param attr 属性名 * @param value 变化值 */ private applyAttrChange(attr: Attrs, value: number,) { const mappedAttr = attr === Attrs.hp ? Attrs.hp_max : (attr === Attrs.shield ? Attrs.shield_max : attr); if (mappedAttr !== Attrs.ap && mappedAttr !== Attrs.hp_max && mappedAttr !== Attrs.shield_max) return; if (mappedAttr === Attrs.ap) { this.ap = Math.max(0, this.ap + value); return; } if (mappedAttr === Attrs.hp_max) { this.hp_max = Math.max(1, this.hp_max + value); if (this.hp > this.hp_max) this.hp = this.hp_max; this.dirty_hp = true; return; } this.shield_max = Math.max(0, this.shield_max + value); this.shield = Math.max(0, Math.min(this.shield + value, this.shield_max)); this.dirty_shield = true; } //======更新cd========// updateCD(dt: number){ if(this.atk_id !=0&&!this.can_atk){ this.a_cd+=dt if(this.a_cd >= this.a_cd_max) this.can_atk = true } if(this.skill_id !=0&&!this.can_skill){ this.s_cd+=dt if(this.s_cd >= this.s_cd_max) this.can_skill = true } } isFrost(): boolean { return this.frost_end_time > 0 } triggerAtkCD() { this.a_cd = 0; this.can_atk = false; } triggerSkillCD() { this.s_cd = 0; this.can_skill = false; } // ==================== 技能距离缓存管理 ==================== /** * 更新技能距离缓存 * 在技能初始化、新增技能、MP变化时调用 * @param skillsComp 技能组件 */ public updateSkillDistanceCache(skill_id:number): void { void skill_id; const rangeType = this.type as HType.Melee | HType.Mid | HType.Long; const maxRange = HeroDisVal[rangeType]; let minRange = 0; if (rangeType === HType.Mid) { minRange = HeroDisVal[HType.Melee]; } else if (rangeType === HType.Long) { minRange = HeroDisVal[HType.Mid]; } this.maxSkillDistance = maxRange; this.minSkillDistance = minRange; } /** * 获取缓存的最远技能攻击距离 * @returns 最远攻击距离 */ public getCachedMaxSkillDistance(): number { return this.maxSkillDistance; } /** * 获取缓存的最近技能攻击距离 * @returns 最近攻击距离 */ public getCachedMinSkillDistance(): number { return this.minSkillDistance; } reset() { // 重置为初始状态 this.hero_uuid = 1001; this.hero_name = "hero"; this.lv = 1; this.type = 0; this.fac = 0; this.ap = 0; this.hp = 100; this.hp_max = 100; this.speed = 100; this.dis = 100; this.shield = 0; this.shield_max = 0; // 重置新增属性 this.a_cd = 0; this.s_cd = 0; this.a_cd_max = 0; this.s_cd_max = 0; this.critical = 0; this.freeze_chance = 0; this.back_chance = 0; this.revive_count = 0; this.revive_time = 0; this.invincible_time = 0; this.puncture = 0; this.wfuny = 0; this.boom = false; this.frost_end_time = 0; // 重置技能距离缓存 this.maxSkillDistance = 0; this.minSkillDistance = 0; this.is_dead = false; this.is_count_dead = false; this.is_atking = false; this.is_stop = false; this.is_boss = false; this.is_big_boss = false; this.is_friend = false; this.is_kalami = false; this.is_reviving = false; this.atk_count = 0; this.atked_count = 0; this.killed_count =0; this.atk_id = 0; this.skill_id = 0; this.can_atk=false this.can_skill=false this.combat_target_eid = -1; this.enemy_in_cast_range = false; // 重置脏标签 this.dirty_hp = false; this.dirty_shield = false; } } @ecs.register('HeroBuffSystem') export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { private timer =new Timer(0.1) filter(): ecs.IMatcher { return ecs.allOf(HeroAttrsComp); } update(e: ecs.Entity): void { if(this.timer.update(this.dt)){ const attrsComp = e.get(HeroAttrsComp); if(attrsComp.frost_end_time > 0){ attrsComp.frost_end_time -= 0.1; if(attrsComp.frost_end_time <= 0){ attrsComp.frost_end_time = 0; } } } void e; } }