refactor(英雄属性): 重构属性系统为扁平结构并移除技能组件

- 将 Attrs 枚举从数字索引改为字符串键值对,直接映射到 HeroAttrsComp 的字段
- 删除 HeroSkillsComp 组件,将攻击和技能计时器移至 HeroAttrsComp
- 移除复杂的属性类型映射和初始化函数,简化属性访问逻辑
- 更新 HeroViewComp 以直接使用模型字段而非通过 Attrs 枚举
- 重命名 NeAttrs 为 Debuff 并调整相关配置接口
This commit is contained in:
walkpan
2026-03-11 19:36:47 +08:00
parent bbcee36dec
commit 0ce299b0d8
5 changed files with 72 additions and 445 deletions

View File

@@ -10,11 +10,12 @@ export enum BType {
BOOLEAN = 2, // 布尔型
}
export enum NeAttrs {
export enum Debuff {
IN_FROST = 0, // 冰冻状态
IN_STUN = 1, // 眩晕状态
}
// ========== 属性枚举 ==========
/**
* 英雄属性枚举
@@ -22,125 +23,42 @@ export enum NeAttrs {
* 按逻辑分组排序:基础生存 → 攻击属性 → 防御属性 → 特殊效果 → 基础属性
*/
export enum Attrs {
// ========== 基础生存属性 (0-9) ==========
HP_MAX = 0, // 最大生命值
SHIELD_MAX = 2, // 最大护盾值
SPEED = 3, // 移动速度
// ========== 攻击属性 (10-19) ==========
AP = 10, // 攻击力
DIS = 12, // 攻击距离
AS = 13, // 攻击速度减少技能skills[0]CD
SS = 14, // 技能速度 (减少skills[0] 以外的cd)
// ========== 暴击与命中属性 (30-39) ==========
CRITICAL = 30, // 暴击率
CRITICAL_DMG = 31, // 暴击伤害
// ==================== 基础属性 ====================
ap = "ap", // 基础攻击
hp = "hp", // 基础血量
hp_max = "hp_max", // 最大血量
speed = "speed", // 基础移动速度
dis = "dis", // 基础距离
shield = "shield", // 当前护盾
shield_max = "shield_max", // 最大护盾值
// ==================== 攻击属性 ====================
a_cd = "a_cd", // 攻击计时
s_cd = "s_cd", // 技能计时
a_cd_max = "a_cd_max", // 攻击CD
s_cd_max = "s_cd_max", // 技能CD
// ========== 特殊效果属性 (50-59) ==========
FREEZE_CHANCE = 52, // 冰冻概
STUN_CHANCE = 54, // 眩晕概率
BACK_CHANCE = 55, // 击退概率
SLOW_CHANCE = 56, // 减速概率
// ==================== 暴击与命中属性 ====================
critical = "critical", // 暴击
critical_dmg = "critical_dmg", // 暴击伤害
// ========== 增益效果属性 (60-69) ==========
REVIVE_COUNT = 67, // 复活次数
REVIVE_TIME = 68, // 复活时间
INVINCIBLE_TIME = 69, // 无敌时间
// ========== 武器进化相关 (70-79) ==========
PUNCTURE = 70, // 穿刺次数
PUNCTURE_DMG = 71, // 穿刺伤害
WFUNY = 77, // 风怒
BOOM = 92, // 自爆怪
// ==================== 特殊效果属性 ====================
freeze_chance = "freeze_chance", // 冰冻概率
stun_chance = "stun_chance", // 眩晕概率
back_chance = "back_chance", // 击退概率
slow_chance = "slow_chance", // 减速概率
// ==================== 增益效果属性 ====================
revive_count = "revive_count", // 复活次数
revive_time = "revive_time", // 复活时间
invincible_time = "invincible_time",// 无敌时间
// ==================== 武器进化相关 ====================
puncture = "puncture", // 穿刺次数
puncture_dmg = "puncture_dmg", // 穿刺伤害
wfuny = "wfuny", // 风怒
}
export const defaultAttrs = {
[Attrs.BACK_CHANCE]:0,
}
/**
* 初始化英雄属性对象
* 遍历 Attrs 枚举的所有数字值,返回一个属性初始值为 0 的对象
* @returns 属性映射对象 { 属性ID: 0 }
*/
export const getAttrs = () => {
// 遍历枚举的数字值(枚举会生成双向映射)
let reAttrs = {};
Object.keys(Attrs).forEach(key => {
if (!isNaN(Number(key))) {
reAttrs[Number(key)] = 0;
}
});
return reAttrs;
}
export const getNeAttrs = () => {
let reAttrs = {};
Object.keys(NeAttrs).forEach(key => {
if (!isNaN(Number(key))) {
reAttrs[Number(key)] = {
value: 0,
time: 0,
};
}
});
return reAttrs;
}
/**
* 属性类型配置表
* 用于区分每个属性是数值型还是百分比型
* - VALUE: 数值型属性(如生命值、攻击力等绝对数值)
* - RATIO: 百分比型属性(如暴击率、闪避率等百分比数值)
* 按新的Attrs枚举顺序重新组织
*/
export const AttrsType: Record<Attrs, BType> = {
// ========== 基础生存属性(数值型) ==========
[Attrs.HP_MAX]: BType.VALUE, // 最大生命值 - 数值型
[Attrs.SHIELD_MAX]: BType.VALUE, // 最大护盾值 - 数值型
// ========== 攻击属性(数值型) ==========
[Attrs.AP]: BType.VALUE, // 攻击力 - 数值型
[Attrs.DIS]: BType.VALUE, // 攻击距离 - 数值型
[Attrs.AS]: BType.RATIO, // 攻击速度 - 百分比型
[Attrs.SS]: BType.RATIO, // 技能速度 - 百分比型
// ========== 暴击与命中属性(百分比型) ==========
[Attrs.CRITICAL]: BType.RATIO, // 暴击率 - 百分比型
[Attrs.CRITICAL_DMG]: BType.RATIO, // 暴击伤害 - 百分比型
// ========== 特殊效果属性(百分比型) ==========
[Attrs.FREEZE_CHANCE]: BType.RATIO, // 冰冻概率 - 百分比型
[Attrs.STUN_CHANCE]: BType.RATIO, // 眩晕概率 - 百分比型
[Attrs.BACK_CHANCE]: BType.RATIO, // 击退概率 - 百分比型
[Attrs.SLOW_CHANCE]: BType.RATIO, // 减速概率 - 百分比型
// ========== 增益效果属性(百分比型) ==========
[Attrs.REVIVE_COUNT]: BType.VALUE, // 复活次数 - 数值型
[Attrs.REVIVE_TIME]: BType.RATIO, // 复活时间 - 百分比型
[Attrs.INVINCIBLE_TIME]: BType.RATIO, // 无敌时间 - 百分比型
// ========== 武器进化相关(混合类型) ==========
[Attrs.PUNCTURE]: BType.VALUE, // 穿刺次数 - 数值型
[Attrs.PUNCTURE_DMG]: BType.RATIO, // 穿刺伤害 - 百分比型
[Attrs.WFUNY]: BType.RATIO, // 未知特殊属性 - 百分比型
[Attrs.BOOM]: BType.BOOLEAN, // 自爆怪
};
/**
* 判断属性是否为百分比型
* @param attrType 属性类型
* @returns true: 百分比型, false: 数值型
*/
export const isRatioAttr = (attrType: Attrs): boolean => {
return AttrsType[attrType] === BType.RATIO;
};
/**
* 游戏单局统计数据接口
*/

View File

@@ -1,5 +1,5 @@
// ========== 从 HeroAttrs.ts 导入属性相关定义 ==========
import { Attrs, NeAttrs,BType, getAttrs, AttrsType, isRatioAttr } from "./HeroAttrs";
import { Attrs,BType, Debuff } from "./HeroAttrs";
export enum HSSet {
atk = 0, // 普通攻击
@@ -131,6 +131,7 @@ export enum DType {
FIRE=2, // 火元素
WIND=3, // 风元素
}
export const HeroSkillList = [6001,6001,6001,6001,6001,6001]
// Debuff配置接口
@@ -142,11 +143,14 @@ export interface BuffConf {
time:number; // 持续时间
chance:number; // 触发概率
}
export interface NeAttrsConf {
neAttrs:NeAttrs;
export interface DebuffConf {
debuff:Debuff;
BType:BType
value:number;
time:number;
}
interface IReady {
uuid:number,
loop: boolean,
@@ -188,7 +192,7 @@ export interface SkillConfig {
RType:RType, // 技能运行类型(直线/贝塞尔/固定起点/固定终点)
EType:EType, // 结束条件(动画结束/时间结束/距离结束/碰撞/次数结束)
buffs:BuffConf[], // 对施法者的buff配置列表
neAttrs:NeAttrsConf[], // 对施法者的负面配置列表
debuffs:DebuffConf[], // 对施法者的负面配置列表
call_hero?:number, // 召唤技能召唤英雄id(可选)
info:string, // 技能描述
}
@@ -197,57 +201,57 @@ export const SkillSet: Record<number, SkillConfig> = {
5000:{uuid:5000,name:"反伤",sp_name:"thorns",icon:"1168",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,
ap:0,cd:60,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Long],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"反伤",
buffs:[],debuffs:[],info:"反伤",
},
// ========== 基础攻击 ========== 6001-6099
6001: {
uuid:6001,name:"近战攻击",sp_name:"atk_s1",icon:"1026",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,
ap:100,cd:1,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Melee],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"对前方目标造成100%攻击的伤害",
buffs:[],debuffs:[],info:"对前方目标造成100%攻击的伤害",
},
6002: {
uuid:6002,name:"远程攻击",sp_name:"b_arrow_blue",icon:"1135",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,
ap:100,cd:1,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Melee],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"对前方单个目标造成100%攻击的伤害",
buffs:[],debuffs:[],info:"对前方单个目标造成100%攻击的伤害",
},
6003: {
uuid:6003,name:"远程攻击",sp_name:"m_water_ball_1",icon:"1126",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,
ap:100,cd:5,t_num:1,hit_num:1,hit:2,hitcd:0.3,speed:720,with:90,dis:SkillDisVal[SkillRange.Mid],
ready:8001,EAnm:0,DAnm:9001,RType:RType.linear,EType:EType.collision,
buffs:[],neAttrs:[],info:"对前方单个目标造成100%攻击的伤害",
buffs:[],debuffs:[],info:"对前方单个目标造成100%攻击的伤害",
},
6004: {
uuid:6004,name:"蓄力一击",sp_name:"atk_s4",icon:"1173",TGroup:TGroup.Enemy,SType:SType.damage,act:"atk",DTType:DTType.single,
ap:100,cd:3,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Melee],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"对前方目标造成150%攻击的伤害",
buffs:[],debuffs:[],info:"对前方目标造成150%攻击的伤害",
},
// ========== 基础buff ========== 6100-6199
6100: {
uuid:6100,name:"治疗",sp_name:"buff_wind",icon:"1292",TGroup:TGroup.Self,SType:SType.heal,act:"atk",DTType:DTType.single,
ap:30,cd:5,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Long],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"治疗自己,回复30%最大生命值",
buffs:[],debuffs:[],info:"治疗自己,回复30%最大生命值",
},
6101:{
uuid:6101,name:"魔法盾",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,SType:SType.shield,act:"atk",DTType:DTType.single,
ap:30,cd:7,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Long],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],neAttrs:[],info:"获得30%最大生命值的护盾,持续60秒",
buffs:[],debuffs:[],info:"获得30%最大生命值的护盾,持续60秒",
},
6102:{
uuid:6102,name:"强壮",sp_name:"buff_wind",icon:"3036",TGroup:TGroup.Team,SType:SType.buff,act:"atk",DTType:DTType.single,
ap:30,cd:10,t_num:1,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Long],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[{buff:Attrs.AP,BType:BType.VALUE,value:10,time:30,chance:1}],neAttrs:[],info:"增加目标10%攻击力,持续30秒",
buffs:[{buff:Attrs.ap,BType:BType.VALUE,value:10,time:30,chance:1}],debuffs:[],info:"增加目标10%攻击力,持续30秒",
},
6103:{
uuid:6103,name:"群体强壮",sp_name:"buff_wind",icon:"3036",TGroup:TGroup.Team,SType:SType.buff,act:"atk",DTType:DTType.range,
ap:30,cd:10,t_num:3,hit_num:1,hit:1,hitcd:0.2,speed:720,with:0,dis:SkillDisVal[SkillRange.Long],
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[{buff:Attrs.AP,BType:BType.RATIO,value:10,time:30,chance:1}],neAttrs:[],info:"增加目标10%攻击力,持续30秒",
buffs:[{buff:Attrs.ap,BType:BType.RATIO,value:10,time:30,chance:1}],debuffs:[],info:"增加目标10%攻击力,持续30秒",
},
// ========== 怪物基础技能 ========== 6200-6299
6201: {
@@ -255,14 +259,14 @@ export const SkillSet: Record<number, SkillConfig> = {
TGroup:TGroup.Enemy, SType:SType.damage, act:"atk", DTType:DTType.single,
ap:100, cd:1, t_num:1, hit_num:1, hit:1, hitcd:0.2, speed:0, with:0, dis:SkillDisVal[SkillRange.Melee], // 怪物近战特殊距离
ready:0, EAnm:0, DAnm:9001, RType:RType.fixed, EType:EType.animationEnd,
buffs:[], neAttrs:[], info:"怪物基础近战攻击",
buffs:[], debuffs:[], info:"怪物基础近战攻击",
},
6203: {
uuid:6203, name:"怪物射击", sp_name:"arrow_1", icon:"3039",
TGroup:TGroup.Enemy, SType:SType.damage, act:"atk", DTType:DTType.single,
ap:80, cd:2, t_num:1, hit_num:1, hit:1, hitcd:0.2, speed:800, with:0, dis:SkillDisVal[SkillRange.Long], // 怪物远程特殊距离
ready:0, EAnm:0, DAnm:9001, RType:RType.linear, EType:EType.collision,
buffs:[], neAttrs:[], info:"怪物基础远程攻击",
buffs:[], debuffs:[], info:"怪物基础远程攻击",
},
};

View File

@@ -1,11 +1,9 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { Attrs, AttrsType, BType, NeAttrs } from "../common/config/HeroAttrs";
import { BType } from "../common/config/HeroAttrs";
import { BuffConf, SkillRange } from "../common/config/SkillSet";
import { HeroInfo, AttrSet, HType, JobUpConf } from "../common/config/heroSet";
import { HeroSkillsComp } from "./HeroSkills";
import { smc } from "../common/SingletonModuleComp";
import { HeroInfo } from "../common/config/heroSet";
import { mLogger } from "../common/Logger";
import { _decorator } from "cc";
@@ -37,9 +35,10 @@ export class HeroAttrsComp extends ecs.Comp {
shield_max: number = 0; // 最大护盾值
// ==================== 攻击属性 (补充) ====================
as: number = 0; // 攻击速度减少技能skills[0]CD
ss: number = 0; // 技能速度 (减少skills[0] 以外的cd)
a_cd: number = 0; // 攻击计时
s_cd: number = 0; // 技能计时
a_cd_max: number = 0; // 攻击CD
s_cd_max: number = 0; // 技能CD
// ==================== 暴击与命中属性 ====================
critical: number = 0; // 暴击率
critical_dmg: number = 0; // 暴击伤害
@@ -59,6 +58,9 @@ export class HeroAttrsComp extends ecs.Comp {
puncture: number = 0; // 穿刺次数
puncture_dmg: number = 0; // 穿刺伤害
wfuny: number = 0; // 风怒
boom: boolean = false; // 自爆怪
@@ -91,10 +93,9 @@ export class HeroAttrsComp extends ecs.Comp {
atk_count: number = 0; // 攻击次数
atked_count: number = 0; // 被攻击次数
killed_count:number=0;
// 注意:技能数据已迁移到 HeroSkillsComp不再存储在这里
atk_id:number=0; //普通攻击技能id
skill_id:number=0; //技能攻击技能id
start(){
}
// ==================== BUFF 系统初始化 ====================
@@ -216,8 +217,10 @@ export class HeroAttrsComp extends ecs.Comp {
this.shield_max = 0;
// 重置新增属性
this.as = 0;
this.ss = 0;
this.a_cd = 0;
this.s_cd = 0;
this.a_cd_max = 0;
this.s_cd_max = 0;
this.critical = 0;
this.critical_dmg = 0;
this.freeze_chance = 0;

View File

@@ -1,285 +0,0 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { Attrs } from "../common/config/HeroAttrs";
import { HeroInfo } from "../common/config/heroSet";
import { HSSet, SkillSet } from "../common/config/SkillSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { mLogger } from "../common/Logger";
import { _decorator } from "cc";
const { property } = _decorator;
/**
* ==================== 技能槽位数据 ====================
* 单个技能的运行时数据
*/
export interface SkillSlot {
s_uuid: number; // 技能配置ID
cd: number; // 当前CD时间递减
cd_max: number; // 最大CD时间
level: number; // 技能等级(预留)
dis: number; // 攻击距离
hset: HSSet; // 技能设定, 0:普通攻击, 1:一般技能, 2:必杀技
}
/**
* ==================== 英雄技能数据组件 ====================
*
* 职责:
* 1. 存储角色拥有的技能列表
* 2. 管理技能CD状态
* 3. 提供技能查询接口
*
* 设计理念:
* - 只存数据,不含施法逻辑
* - CD 更新由 HSkillSystem 负责
* - 施法判定由 HSkillSystem 负责
*/
@ecs.register('HeroSkills')
export class HeroSkillsComp extends ecs.Comp {
@property({ tooltip: "是否启用调试日志" })
private debugMode: boolean = false;
// ==================== 技能槽位列表 ====================
/** 技能槽位数组最多4个技能 */
skills: Record<number, SkillSlot> = {};
max_auto: boolean = true;
/** AI 检测计时器 */
ai_timer: number = 0;
onLoad() {
}
onDestroy() {
}
// ==================== 辅助方法 ====================
/**
* 初始化技能列表
* @param sUuids 技能配置ID数组
* @param uuid 英雄UUID
* @param entity 实体对象(用于更新技能距离缓存)
*/
initSkills(sUuids: number[], uuid: number) {
this.skills = [];
for (let i = 0; i < sUuids.length; i++) {
const s_uuid = sUuids[i];
const config = SkillSet[s_uuid];
if (!config) {
mLogger.warn(this.debugMode, 'HeroSkills', `[HeroSkills] 技能配置不存在: ${s_uuid}`);
continue;
}
// 第0个技能的 cd_max 取 herosinfo[uuid].as
const cdMax = i === 0 ? HeroInfo[uuid].as : config.cd;
let hset = HSSet.atk;
if(i ===1) hset = HSSet.skill;
if(i ===2) hset = HSSet.max;
this.skills[s_uuid] = {
s_uuid: config.uuid,
cd: 0,
cd_max: cdMax,
level: 1,
dis: Number(config.dis),
hset: hset,
};
}
// 更新技能距离缓存
if (this.ent) {
const attrsComp = this.ent.get(HeroAttrsComp);
if (attrsComp) {
attrsComp.updateSkillDistanceCache(this);
}
}
}
/**
* 添加单个技能
* @param s_uuid 技能配置ID
* @param hset 技能类型
*/
addSkill(s_uuid: number, hset: HSSet=HSSet.skill) {
const config = SkillSet[s_uuid];
if (!config) {
mLogger.warn(this.debugMode, 'HeroSkills', `[HeroSkills] 技能配置不存在: ${s_uuid}`);
return;
}
this.skills[s_uuid] = {
s_uuid: config.uuid,
cd: 0,
cd_max: config.cd,
level: 1,
dis: Number(config.dis),
hset: hset,
};
// 更新技能距离缓存
if (this.ent) {
const attrsComp = this.ent.get(HeroAttrsComp);
if (attrsComp) {
attrsComp.updateSkillDistanceCache(this);
}
}
}
/**
* 获取指定s_uuid的技能
*/
getSkill(s_uuid: number): SkillSlot | null {
return this.skills[s_uuid] ?? null;
}
/**
* 检查技能是否可施放通过s_uuid
* @param s_uuid 技能配置ID
*/
canCast(s_uuid: number): boolean {
const skill = this.getSkill(s_uuid);
if (!skill) return false;
// 检查CD
return skill.cd <= 0;
}
/**
* 重置技能CD开始冷却通过索引
*/
resetCD(s_uuid: number) {
let attrsCom = this.ent.get(HeroAttrsComp);
if (!attrsCom) return;
const skill = this.getSkill(s_uuid);
if (!skill) return;
const speedAttr = skill.hset === HSSet.atk ? Attrs.AS : Attrs.SS;
const rawSpeed = attrsCom.Attrs?.[speedAttr] ?? 0;
const speedBonus = Math.max(-0.9, rawSpeed / 100);
const speedMultiplier = 1 / (1 + speedBonus);
skill.cd = Math.max(0, skill.cd_max * speedMultiplier);
}
/**
* 更新所有技能CD每帧调用
* @param dt 时间增量
*/
updateCDs(dt: number) {
for (const s_uuid in this.skills) {
const skill = this.skills[Number(s_uuid)];
if (skill.cd > 0) {
skill.cd -= dt;
if (skill.cd < 0) {
skill.cd = 0;
}
}
}
}
/**
* 获取所有可施放的技能索引
*/
getReadySkills(): number[] {
const ready: number[] = [];
for (const s_uuid in this.skills) {
if (this.canCast(Number(s_uuid))) {
ready.push(Number(s_uuid));
}
}
return ready;
}
/**
* 检查技能攻击距离是否足够
* @param s_uuid 技能配置ID
* @param distance 目标距离
* @returns 是否在攻击范围内
*/
canReachTarget(s_uuid: number, distance: number): boolean {
const skill = this.getSkill(s_uuid);
if (!skill) {
return false;
}
return distance <= skill.dis;
}
/**
* 获取技能的攻击距离
* @param s_uuid 技能配置ID
* @returns 攻击距离如果技能不存在返回0
*/
getSkillDistance(s_uuid: number): number {
const skill = this.getSkill(s_uuid);
return skill ? skill.dis : 0;
}
/**
* 获取可施放技能中的最远攻击距离
* @returns 最远攻击距离如果没有可用技能返回0
*/
getMaxSkillDistance(): number {
const readySkills = this.getReadySkills();
if (readySkills.length === 0) return 0;
let maxDistance = 0;
for (const s_uuid of readySkills) {
const skill = this.getSkill(s_uuid);
if (skill && skill.dis > maxDistance) {
maxDistance = skill.dis;
}
}
return maxDistance;
}
/**
* 获取可施放技能中的最近攻击距离
* @returns 最近攻击距离如果没有可用技能返回0
*/
getMinSkillDistance(): number {
const readySkills = this.getReadySkills();
if (readySkills.length === 0) return 0;
let minDistance = Number.MAX_VALUE;
for (const s_uuid of readySkills) {
const skill = this.getSkill(s_uuid);
if (skill && skill.dis < minDistance) {
minDistance = skill.dis;
}
}
return minDistance === Number.MAX_VALUE ? 0 : minDistance;
}
/**
* 获取所有技能中的最小攻击距离不考虑MP限制
* 用于移动停止判断,让英雄在合适位置等待回蓝
* @returns 最小攻击距离如果没有技能返回0
*/
getAbsoluteMinSkillDistance(): number {
const skillIds = Object.keys(this.skills).map(Number);
if (skillIds.length === 0) return 0;
let minDistance = Number.MAX_VALUE;
for (const s_uuid of skillIds) {
const skill = this.getSkill(s_uuid);
if (skill && skill.dis < minDistance) {
minDistance = skill.dis;
}
}
return minDistance === Number.MAX_VALUE ? 0 : minDistance;
}
reset() {
this.skills = {};
}
setMaxAuto(on: boolean) {
this.max_auto = on;
}
}

View File

@@ -8,8 +8,7 @@ import { smc } from "../common/SingletonModuleComp";
import { EAnmConf, SkillSet,} from "../common/config/SkillSet";
import { oops } from "db://oops-framework/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { TooltipTypes } from "../common/config/GameSet";
import { Attrs, } from "../common/config/HeroAttrs";
import { TooltipTypes } from "../common/config/GameSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { Tooltip } from "../skill/Tooltip";
import { timedCom } from "../skill/timedCom";
@@ -113,7 +112,6 @@ export class HeroViewComp extends CCComp {
this.top_node = this.node.getChildByName("top");
// let hp_y = this.node.getComponent(UITransform).height+10;
// this.top_node.setPosition(0, hp_y, 0);
smc.updateHeroInfo(this.model)
}
@@ -162,7 +160,7 @@ export class HeroViewComp extends CCComp {
// }
if (this.model.dirty_shield) {
this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
this.show_shield(this.model.shield, this.model.shield_max);
this.model.dirty_shield = false;
}
}
@@ -186,7 +184,7 @@ export class HeroViewComp extends CCComp {
this.lastBarUpdateTime = Date.now() / 1000;
// 不再基于血量是否满来决定显示状态,只更新进度条
let hp=this.model.hp;
let hp_max=this.model.Attrs[Attrs.HP_MAX];
let hp_max=this.model.hp_max;
// mLogger.log(this.debugMode, 'HeroViewComp', "hp_show",hp,hp_max)
let targetProgress = hp / hp_max;
@@ -209,18 +207,7 @@ export class HeroViewComp extends CCComp {
}
}
/** 显示魔法值 */
private mp_show() {
this.lastBarUpdateTime = Date.now() / 1000;
if(!this.top_node.active) return
let mp=this.model.mp;
let mp_max=this.model.Attrs[Attrs.MP_MAX];
mLogger.log(this.debugMode, 'HeroViewComp', "mp_show",mp,mp_max)
this.top_node.getChildByName("mp").getComponent(ProgressBar).progress = mp / mp_max;
this.scheduleOnce(() => {
this.top_node.getChildByName("mp").getChildByName("mpb").getComponent(ProgressBar).progress = mp / mp_max;
}, 0.15);
}
/** 升级特效 */
private lv_up() {
@@ -342,7 +329,7 @@ export class HeroViewComp extends CCComp {
}
add_shield(shield:number){
// 护盾数据更新由 Model 层处理,这里只负责视图表现
if(this.model && this.model.shield>0) this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
if(this.model && this.model.shield>0) this.show_shield(this.model.shield, this.model.shield_max);
}
health(hp: number = 0) {
@@ -369,7 +356,7 @@ export class HeroViewComp extends CCComp {
this.model.is_count_dead=false
this.as.do_buff();
this.status_change("idle");
this.model.hp =this.model.Attrs[Attrs.HP_MAX]*50/100;
this.model.hp =this.model.hp_max*50/100;
this.top_node.active=false
this.lastBarUpdateTime=0