refactor(buff): 统一buff和debuff属性结构及类型区分

- 新增Buff类型枚举BType,区分数值型与百分比型属性
- 定义AttrsType,映射每个属性的类型(数值或百分比)
- 添加辅助方法isRatioAttr和getAttrType用于属性类型判断
- HeroViewComp中buff和debuff相关属性名称重新命名,区分持久型和临时型及属性类型
- 修改buff/debuff的加载、应用、更新逻辑,适配新的属性结构
- 新增HeroViewComp的isStun和isFrost方法判断状态
- BattleMoveSystem中使用新判断方法替代旧列表遍历
- 移除SkillCom中未使用的BuffAttr导入项,优化依赖关系
This commit is contained in:
2025-10-17 18:41:54 +08:00
parent 13874f3618
commit 4706a128f3
4 changed files with 131 additions and 68 deletions

View File

@@ -146,8 +146,9 @@ export enum Attrs {
SPEED = 27, //移动速度加成,默认都是百分比 SPEED = 27, //移动速度加成,默认都是百分比
} }
export const getAttrs=()=>{ export const getAttrs=()=>{
// 遍历枚举的数字值枚举会生成双向映射 // 遍历枚举的数字值(枚举会生成双向映射)
let reAttrs = {}; let reAttrs = {};
Object.keys(Attrs).forEach(key => { Object.keys(Attrs).forEach(key => {
if (!isNaN(Number(key))) { if (!isNaN(Number(key))) {
@@ -157,6 +158,74 @@ export const getAttrs=()=>{
return reAttrs; return reAttrs;
} }
/**
* Buff类型枚举
* VALUE: 数值型 - 直接加减数值
* RATIO: 百分比型 - 按百分比计算
*/
export enum BType {
VALUE=0, //数值型
RATIO=1 //百分比型
}
/**
* 属性类型配置表
* 用于区分每个属性是数值型还是百分比型
* - VALUE: 数值型属性(如生命值、攻击力等绝对数值)
* - RATIO: 百分比型属性(如暴击率、闪避率等百分比数值)
*/
export const AttrsType: Record<Attrs, BType> = {
// ========== 数值型属性 ==========
[Attrs.HP_MAX]: BType.VALUE, // 最大生命值 - 数值型
[Attrs.MP_MAX]: BType.VALUE, // 最大魔法值 - 数值型
[Attrs.SHIELD_MAX]: BType.VALUE, // 最大护盾值 - 数值型
[Attrs.AP]: BType.VALUE, // 攻击力 - 数值型
[Attrs.MAP]: BType.VALUE, // 魔法攻击力 - 数值型
[Attrs.DEF]: BType.VALUE, // 防御 - 数值型
[Attrs.MDEF]: BType.VALUE, // 魔法防御 - 数值型
[Attrs.DIS]: BType.VALUE, // 攻击距离 - 数值型
// ========== 百分比型属性 ==========
[Attrs.CRITICAL]: BType.RATIO, // 暴击率 - 百分比型
[Attrs.CRITICAL_DMG]: BType.RATIO, // 暴击伤害 - 百分比型
[Attrs.DODGE]: BType.RATIO, // 闪避 - 百分比型
[Attrs.HIT]: BType.RATIO, // 命中 - 百分比型
[Attrs.WFUNY]: BType.RATIO, // 风怒 - 百分比型
[Attrs.AS]: BType.RATIO, // 攻击速度 - 百分比型
[Attrs.REFLICT]: BType.RATIO, // 反伤比率 - 百分比型
[Attrs.LIFESTEAL]: BType.RATIO, // 吸血比率 - 百分比型
[Attrs.KNOCKBACK]: BType.RATIO, // 击退概率 - 百分比型
[Attrs.CON_RES]: BType.RATIO, // 控制抗性 - 百分比型
[Attrs.ICE_RES]: BType.RATIO, // 冰冻抗性 - 百分比型
[Attrs.FIRE_RES]: BType.RATIO, // 火抗性 - 百分比型
[Attrs.WIND_RES]: BType.RATIO, // 风抗性 - 百分比型
[Attrs.ICE_POWER]: BType.RATIO, // 冰冻伤害效果提升 - 百分比型
[Attrs.FIRE_POWER]: BType.RATIO, // 火伤害效果提升 - 百分比型
[Attrs.WIND_POWER]: BType.RATIO, // 风伤害效果提升 - 百分比型
[Attrs.SHIELD_UP]: BType.RATIO, // 护盾效果提升 - 百分比型
[Attrs.BUFF_UP]: BType.RATIO, // buff效果提升 - 百分比型
[Attrs.DBUFF_UP]: BType.RATIO, // debuff效果提升 - 百分比型
[Attrs.SPEED]: BType.RATIO, // 移动速度加成 - 百分比型
};
/**
* 判断属性是否为百分比型
* @param attrType 属性类型
* @returns true: 百分比型, false: 数值型
*/
export const isRatioAttr = (attrType: Attrs): boolean => {
return AttrsType[attrType] === BType.RATIO;
};
/**
* 获取属性的类型
* @param attrType 属性类型
* @returns BType.VALUE 或 BType.RATIO
*/
export const getAttrType = (attrType: Attrs): BType => {
return AttrsType[attrType];
};
/** /**
* 获取 debuff 对应的属性字段 * 获取 debuff 对应的属性字段
* @param debuffType DBuff 类型 * @param debuffType DBuff 类型
@@ -214,14 +283,6 @@ export const getAttrFieldFromDebuff = (debuffType: DBuff): number => {
return attrField; return attrField;
}; };
export enum BType {
VALUE=0, //数值型
RATIO=1 //百分比型
}
/* /*
=== 技能配置系统使用说明 === === 技能配置系统使用说明 ===

View File

@@ -29,9 +29,7 @@ export class BattleMoveSystem extends ecs.ComblockSystem implements ecs.ISystemU
if (!shouldStop) { //在攻击范围内停止移动 if (!shouldStop) { //在攻击范围内停止移动
// if(view.fac==1){ // if(view.fac==1){
const isStun = view.V_DBUFF.some(d => d.debuff === DBuff.STUN); if(view.is_stop||view.is_dead||view.isStun()||view.isFrost()) {
const isFrost = view.V_DBUFF.some(d => d.debuff === DBuff.FROST);
if(view.is_stop||view.is_dead||isStun||isFrost) {
view.status_change("idle"); view.status_change("idle");
return; //停止移动或者死亡不移动 return; //停止移动或者死亡不移动
} }

View File

@@ -18,10 +18,10 @@ const { ccclass, property } = _decorator;
* ==================== BUFF 系统使用说明 ==================== * ==================== BUFF 系统使用说明 ====================
* *
* 1. 系统架构: * 1. 系统架构:
* - V_BUFF/V_BUFFS: 数值型 buff持久/临时) * - BUFF_V/BUFFS_V: 数值型 buff持久/临时)
* - R_BUFF/R_BUFFS: 百分比型 buff持久/临时) * - BUFF_R/BUFFS_R: 百分比型 buff持久/临时)
* - V_DBUFF/V_DBUFFS: 数值型 debuff持久/临时) * - DBUFF_V/DBUFFS_V: 数值型 debuff持久/临时)
* - R_DBUFF/R_DBUFFS: 百分比型 debuff持久/临时) * - DBUFF_R/DBUFFS_R: 百分比型 debuff持久/临时)
* *
* 2. 初始化(在英雄加载时自动调用): * 2. 初始化(在英雄加载时自动调用):
* - initBuffsDebuffs(): 从 HeroInfo 读取初始配置 * - initBuffsDebuffs(): 从 HeroInfo 读取初始配置
@@ -108,17 +108,15 @@ export class HeroViewComp extends CCComp {
Attrs:any=[] Attrs:any=[]
//数值型debuff //数值型debuff
V_DBUFF:any[]=[] //持久 DBUFF_V:any[]=[] //持久
V_DBUFFS:any[]=[] //临时 带时间 DBUFF_R:any[]=[] //持久
//百分比型debuff BUFF_V:any[]=[] //持久
R_DBUFF:any[]=[] //持久 BUFF_R:any[]=[] //持久
R_DBUFFS:any[]=[] //临时 带时间
//数值型buff DBUFFS_V:any[]=[] //临时 带时间
V_BUFF:any[]=[] //持久 DBUFFS_R:any[]=[] //临时 带时间
V_BUFFS:any[]=[] //临时 带时间 BUFFS_V:any[]=[] //临时 带时间
//百分比型buff BUFFS_R:any[]=[] //临时 带时间
R_BUFF:any[]=[] //持久
R_BUFFS:any[]=[] //临时 带时间
atk_count: number = 0; atk_count: number = 0;
atked_count: number = 0; atked_count: number = 0;
@@ -173,14 +171,14 @@ export class HeroViewComp extends CCComp {
if (!heroInfo) return; if (!heroInfo) return;
// 清空现有 buff/debuff // 清空现有 buff/debuff
this.V_BUFF = []; this.BUFF_V = [];
this.V_BUFFS = []; this.BUFFS_V = [];
this.R_BUFF = []; this.BUFF_R = [];
this.R_BUFFS = []; this.BUFFS_R = [];
this.V_DBUFF = []; this.DBUFF_V = [];
this.V_DBUFFS = []; this.DBUFFS_V = [];
this.R_DBUFF = []; this.DBUFF_R = [];
this.R_DBUFFS = []; this.DBUFFS_R = [];
// 加载初始 buff // 加载初始 buff
if (heroInfo.buff && heroInfo.buff.length > 0) { if (heroInfo.buff && heroInfo.buff.length > 0) {
@@ -211,10 +209,10 @@ export class HeroViewComp extends CCComp {
// 数值型 buff // 数值型 buff
if (buffConf.buC === 0) { if (buffConf.buC === 0) {
// 持久型 // 持久型
this.V_BUFF.push({...buffConf}); this.BUFF_V.push({...buffConf});
} else { } else {
// 临时型 - 添加剩余时间属性 // 临时型 - 添加剩余时间属性
this.V_BUFFS.push({ this.BUFFS_V.push({
...buffConf, ...buffConf,
remainTime: buffConf.buC remainTime: buffConf.buC
}); });
@@ -223,10 +221,10 @@ export class HeroViewComp extends CCComp {
// 百分比型 buff // 百分比型 buff
if (buffConf.buC === 0) { if (buffConf.buC === 0) {
// 持久型 // 持久型
this.R_BUFF.push({...buffConf}); this.BUFF_R.push({...buffConf});
} else { } else {
// 临时型 - 添加剩余时间属性 // 临时型 - 添加剩余时间属性
this.R_BUFFS.push({ this.BUFFS_R.push({
...buffConf, ...buffConf,
remainTime: buffConf.buC remainTime: buffConf.buC
}); });
@@ -256,13 +254,13 @@ export class HeroViewComp extends CCComp {
// 数值型 debuff // 数值型 debuff
if (dbuffConf.deC === 0) { if (dbuffConf.deC === 0) {
// 持久型 // 持久型
this.V_DBUFF.push({ this.DBUFF_V.push({
...dbuffConf, ...dbuffConf,
attrField: attrField attrField: attrField
}); });
} else { } else {
// 临时型 - 添加剩余时间属性 // 临时型 - 添加剩余时间属性
this.V_DBUFFS.push({ this.DBUFFS_V.push({
...dbuffConf, ...dbuffConf,
attrField: attrField, attrField: attrField,
remainTime: dbuffConf.deC remainTime: dbuffConf.deC
@@ -272,13 +270,13 @@ export class HeroViewComp extends CCComp {
// 百分比型 debuff // 百分比型 debuff
if (dbuffConf.deC === 0) { if (dbuffConf.deC === 0) {
// 持久型 // 持久型
this.R_DBUFF.push({ this.DBUFF_R.push({
...dbuffConf, ...dbuffConf,
attrField: attrField attrField: attrField
}); });
} else { } else {
// 临时型 - 添加剩余时间属性 // 临时型 - 添加剩余时间属性
this.R_DBUFFS.push({ this.DBUFFS_R.push({
...dbuffConf, ...dbuffConf,
attrField: attrField, attrField: attrField,
remainTime: dbuffConf.deC remainTime: dbuffConf.deC
@@ -336,14 +334,14 @@ export class HeroViewComp extends CCComp {
*/ */
private applyValueBuffs() { private applyValueBuffs() {
// 持久型 buff // 持久型 buff
for (const buff of this.V_BUFF) { for (const buff of this.BUFF_V) {
if (buff.buff !== undefined) { if (buff.buff !== undefined) {
this.Attrs[buff.buff] += buff.buV; this.Attrs[buff.buff] += buff.buV;
} }
} }
// 临时型 buff // 临时型 buff
for (const buff of this.V_BUFFS) { for (const buff of this.BUFFS_V) {
if (buff.buff !== undefined) { if (buff.buff !== undefined) {
this.Attrs[buff.buff] += buff.buV; this.Attrs[buff.buff] += buff.buV;
} }
@@ -365,7 +363,7 @@ export class HeroViewComp extends CCComp {
baseValues[Attrs.SPEED] = this.base_speed; baseValues[Attrs.SPEED] = this.base_speed;
// 持久型 buff // 持久型 buff
for (const buff of this.R_BUFF) { for (const buff of this.BUFF_R) {
if (buff.buff !== undefined) { if (buff.buff !== undefined) {
const baseVal = baseValues[buff.buff] || this.Attrs[buff.buff]; const baseVal = baseValues[buff.buff] || this.Attrs[buff.buff];
this.Attrs[buff.buff] += Math.floor(baseVal * (buff.buV / 100)); this.Attrs[buff.buff] += Math.floor(baseVal * (buff.buV / 100));
@@ -373,7 +371,7 @@ export class HeroViewComp extends CCComp {
} }
// 临时型 buff // 临时型 buff
for (const buff of this.R_BUFFS) { for (const buff of this.BUFFS_R) {
if (buff.buff !== undefined) { if (buff.buff !== undefined) {
const baseVal = baseValues[buff.buff] || this.Attrs[buff.buff]; const baseVal = baseValues[buff.buff] || this.Attrs[buff.buff];
this.Attrs[buff.buff] += Math.floor(baseVal * (buff.buV / 100)); this.Attrs[buff.buff] += Math.floor(baseVal * (buff.buV / 100));
@@ -386,7 +384,7 @@ export class HeroViewComp extends CCComp {
*/ */
private applyValueDebuffs() { private applyValueDebuffs() {
// 持久型 debuff // 持久型 debuff
for (const debuff of this.V_DBUFF) { for (const debuff of this.DBUFF_V) {
// 跳过状态类 debuffattrField === -1 // 跳过状态类 debuffattrField === -1
if (debuff.attrField !== undefined && debuff.attrField >= 0) { if (debuff.attrField !== undefined && debuff.attrField >= 0) {
this.Attrs[debuff.attrField] -= debuff.deV; this.Attrs[debuff.attrField] -= debuff.deV;
@@ -394,7 +392,7 @@ export class HeroViewComp extends CCComp {
} }
// 临时型 debuff // 临时型 debuff
for (const debuff of this.V_DBUFFS) { for (const debuff of this.DBUFFS_V) {
// 跳过状态类 debuffattrField === -1 // 跳过状态类 debuffattrField === -1
if (debuff.attrField !== undefined && debuff.attrField >= 0) { if (debuff.attrField !== undefined && debuff.attrField >= 0) {
this.Attrs[debuff.attrField] -= debuff.deV; this.Attrs[debuff.attrField] -= debuff.deV;
@@ -417,7 +415,7 @@ export class HeroViewComp extends CCComp {
this.Attrs[Attrs.SPEED] = this.base_speed; this.Attrs[Attrs.SPEED] = this.base_speed;
// 持久型 debuff // 持久型 debuff
for (const debuff of this.R_DBUFF) { for (const debuff of this.DBUFF_R) {
// 跳过状态类 debuffattrField === -1 // 跳过状态类 debuffattrField === -1
if (debuff.attrField !== undefined && debuff.attrField >= 0) { if (debuff.attrField !== undefined && debuff.attrField >= 0) {
const baseVal = baseValues[debuff.attrField] || this.Attrs[debuff.attrField]; const baseVal = baseValues[debuff.attrField] || this.Attrs[debuff.attrField];
@@ -426,7 +424,7 @@ export class HeroViewComp extends CCComp {
} }
// 临时型 debuff // 临时型 debuff
for (const debuff of this.R_DBUFFS) { for (const debuff of this.DBUFFS_R) {
// 跳过状态类 debuffattrField === -1 // 跳过状态类 debuffattrField === -1
if (debuff.attrField !== undefined && debuff.attrField >= 0) { if (debuff.attrField !== undefined && debuff.attrField >= 0) {
const baseVal = baseValues[debuff.attrField] || this.Attrs[debuff.attrField]; const baseVal = baseValues[debuff.attrField] || this.Attrs[debuff.attrField];
@@ -465,37 +463,37 @@ export class HeroViewComp extends CCComp {
let needRecalculate = false; let needRecalculate = false;
// 更新临时型数值 buff // 更新临时型数值 buff
for (let i = this.V_BUFFS.length - 1; i >= 0; i--) { for (let i = this.BUFFS_V.length - 1; i >= 0; i--) {
this.V_BUFFS[i].remainTime -= dt; this.BUFFS_V[i].remainTime -= dt;
if (this.V_BUFFS[i].remainTime <= 0) { if (this.BUFFS_V[i].remainTime <= 0) {
this.V_BUFFS.splice(i, 1); this.BUFFS_V.splice(i, 1);
needRecalculate = true; needRecalculate = true;
} }
} }
// 更新临时型百分比 buff // 更新临时型百分比 buff
for (let i = this.R_BUFFS.length - 1; i >= 0; i--) { for (let i = this.BUFFS_R.length - 1; i >= 0; i--) {
this.R_BUFFS[i].remainTime -= dt; this.BUFFS_R[i].remainTime -= dt;
if (this.R_BUFFS[i].remainTime <= 0) { if (this.BUFFS_R[i].remainTime <= 0) {
this.R_BUFFS.splice(i, 1); this.BUFFS_R.splice(i, 1);
needRecalculate = true; needRecalculate = true;
} }
} }
// 更新临时型数值 debuff // 更新临时型数值 debuff
for (let i = this.V_DBUFFS.length - 1; i >= 0; i--) { for (let i = this.DBUFFS_V.length - 1; i >= 0; i--) {
this.V_DBUFFS[i].remainTime -= dt; this.DBUFFS_V[i].remainTime -= dt;
if (this.V_DBUFFS[i].remainTime <= 0) { if (this.DBUFFS_V[i].remainTime <= 0) {
this.V_DBUFFS.splice(i, 1); this.DBUFFS_V.splice(i, 1);
needRecalculate = true; needRecalculate = true;
} }
} }
// 更新临时型百分比 debuff // 更新临时型百分比 debuff
for (let i = this.R_DBUFFS.length - 1; i >= 0; i--) { for (let i = this.DBUFFS_R.length - 1; i >= 0; i--) {
this.R_DBUFFS[i].remainTime -= dt; this.DBUFFS_R[i].remainTime -= dt;
if (this.R_DBUFFS[i].remainTime <= 0) { if (this.DBUFFS_R[i].remainTime <= 0) {
this.R_DBUFFS.splice(i, 1); this.DBUFFS_R.splice(i, 1);
needRecalculate = true; needRecalculate = true;
} }
} }
@@ -506,6 +504,12 @@ export class HeroViewComp extends CCComp {
} }
} }
public isStun() {
return this.DBUFF_V.some(d => d.debuff === DBuff.STUN)
}
public isFrost() {
return this.DBUFF_V.some(d => d.debuff === DBuff.FROST)
}
update(dt: number){ update(dt: number){
if(!smc.mission.play||smc.mission.pause) return if(!smc.mission.play||smc.mission.pause) return

View File

@@ -3,7 +3,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { smc } from "../common/SingletonModuleComp"; import { smc } from "../common/SingletonModuleComp";
import { GameEvent } from "../common/config/GameEvent"; import { GameEvent } from "../common/config/GameEvent";
import { AType, BuffAttr, DTType, EType, SkillSet, SType, TGroup } from "../common/config/SkillSet"; import { AType, DTType, EType, SkillSet, SType, TGroup } from "../common/config/SkillSet";
import { BoxSet, FacSet } from "../common/config/BoxSet"; import { BoxSet, FacSet } from "../common/config/BoxSet";
import { HeroViewComp } from "../hero/HeroViewComp"; import { HeroViewComp } from "../hero/HeroViewComp";
import { BezierMove } from "../BezierMove/BezierMove"; import { BezierMove } from "../BezierMove/BezierMove";