feat(buff): 新增间隔触发型buff效果支持
- 在 SkillSet.ts 中添加 BuffRunType 枚举和 interval 配置字段 - 在 HeroAttrsComp 中实现间隔效果处理逻辑,支持持续治疗和流血等效果 - 新增 INTERVAL_EFFECTS 数组和 updateIntervalEffectsBySystem 方法来管理间隔触发 - 添加 10311(持续治疗)和 10312(流血)两个示例buff配置
This commit is contained in:
@@ -47,6 +47,11 @@ export enum SkillKind {
|
|||||||
Support = 3
|
Support = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum BuffRunType {
|
||||||
|
Attr = 0,
|
||||||
|
Interval = 1
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 攻击距离类型分类
|
* 攻击距离类型分类
|
||||||
* 用于AI决策和技能配置规范化
|
* 用于AI决策和技能配置规范化
|
||||||
@@ -147,6 +152,8 @@ export interface BuffConf {
|
|||||||
chance:number; // 触发概率
|
chance:number; // 触发概率
|
||||||
info?:string; // 描述
|
info?:string; // 描述
|
||||||
isDebuff?:boolean; // 是否为负面效果
|
isDebuff?:boolean; // 是否为负面效果
|
||||||
|
runType?:BuffRunType;
|
||||||
|
interval?:number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IReady {
|
interface IReady {
|
||||||
@@ -325,6 +332,8 @@ export const BuffsList: Record<number, BuffConf> = {
|
|||||||
10301: { uuid: 10301, name: "治疗", icon: "1292", buff: Attrs.hp, BType: BType.RATIO, value: 30, time: 0, chance: 1, info: "回复30%最大生命值" },
|
10301: { uuid: 10301, name: "治疗", icon: "1292", buff: Attrs.hp, BType: BType.RATIO, value: 30, time: 0, chance: 1, info: "回复30%最大生命值" },
|
||||||
// 护盾 (基于攻击力百分比)
|
// 护盾 (基于攻击力百分比)
|
||||||
10302: { uuid: 10302, name: "护盾", icon: "1255", buff: Attrs.shield, BType: BType.RATIO, value: 30, time: 0, chance: 1, info: "获得30%最大生命值护盾" },
|
10302: { uuid: 10302, name: "护盾", icon: "1255", buff: Attrs.shield, BType: BType.RATIO, value: 30, time: 0, chance: 1, info: "获得30%最大生命值护盾" },
|
||||||
|
10311: { uuid: 10311, name: "持续治疗", icon: "1292", buff: Attrs.hp, BType: BType.RATIO, value: 5, time: 5, interval: 1, chance: 1, runType: BuffRunType.Interval, info: "每秒回复5%最大生命值,持续5秒" },
|
||||||
|
10312: { uuid: 10312, name: "流血", icon: "10211", buff: Attrs.hp, BType: BType.RATIO, value: -4, time: 5, interval: 1, chance: 1, isDebuff: true, runType: BuffRunType.Interval, info: "每秒损失4%最大生命值,持续5秒" },
|
||||||
|
|
||||||
// ========== 减益类 Buff (属性降低) ========== 10200 - 10299
|
// ========== 减益类 Buff (属性降低) ========== 10200 - 10299
|
||||||
// 减速 (移动速度降低)
|
// 减速 (移动速度降低)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
|||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { Attrs, BType } from "../common/config/HeroAttrs";
|
import { Attrs, BType } from "../common/config/HeroAttrs";
|
||||||
import { BuffConf, SkillDisVal, SkillRange } from "../common/config/SkillSet";
|
import { BuffConf, BuffRunType, SkillDisVal, SkillRange } from "../common/config/SkillSet";
|
||||||
import { HeroInfo, HType } from "../common/config/heroSet";
|
import { HeroInfo, HType } from "../common/config/heroSet";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
@@ -14,6 +14,24 @@ interface talTrigger{
|
|||||||
value:number
|
value:number
|
||||||
count:number
|
count:number
|
||||||
}
|
}
|
||||||
|
interface ActiveBuffState {
|
||||||
|
id: number
|
||||||
|
attr: Attrs
|
||||||
|
sourceUuid: number
|
||||||
|
value: number
|
||||||
|
BType: BType
|
||||||
|
time: number
|
||||||
|
}
|
||||||
|
interface IntervalBuffState {
|
||||||
|
id: number
|
||||||
|
attr: Attrs
|
||||||
|
sourceUuid: number
|
||||||
|
value: number
|
||||||
|
BType: BType
|
||||||
|
interval: number
|
||||||
|
remain: number
|
||||||
|
tick: number
|
||||||
|
}
|
||||||
@ecs.register('HeroAttrs')
|
@ecs.register('HeroAttrs')
|
||||||
export class HeroAttrsComp extends ecs.Comp {
|
export class HeroAttrsComp extends ecs.Comp {
|
||||||
public debugMode: boolean = true;
|
public debugMode: boolean = true;
|
||||||
@@ -77,8 +95,10 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
|
|
||||||
// ==================== Buff/Debuff 系统 ====================
|
// ==================== Buff/Debuff 系统 ====================
|
||||||
/** 持久型buff数组 - 不会自动过期 */
|
/** 持久型buff数组 - 不会自动过期 */
|
||||||
BUFFS: Record<number, Array<{value: number, BType: BType,time:number}>> = {};
|
BUFFS: Record<number, ActiveBuffState[]> = {};
|
||||||
DEBUFFS: Record<number, Array<{value: number, BType: BType,time:number}>> = {};
|
DEBUFFS: Record<number, ActiveBuffState[]> = {};
|
||||||
|
INTERVAL_EFFECTS: IntervalBuffState[] = [];
|
||||||
|
private buffInstanceId = 0;
|
||||||
|
|
||||||
// ==================== 标记状态 ====================
|
// ==================== 标记状态 ====================
|
||||||
is_dead: boolean = false;
|
is_dead: boolean = false;
|
||||||
@@ -110,6 +130,8 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
// 清空现有 buff/debuff
|
// 清空现有 buff/debuff
|
||||||
this.BUFFS = {};
|
this.BUFFS = {};
|
||||||
this.DEBUFFS = {};
|
this.DEBUFFS = {};
|
||||||
|
this.INTERVAL_EFFECTS = [];
|
||||||
|
this.buffInstanceId = 0;
|
||||||
// 获取英雄配置
|
// 获取英雄配置
|
||||||
const heroInfo = HeroInfo[this.hero_uuid];
|
const heroInfo = HeroInfo[this.hero_uuid];
|
||||||
if (!heroInfo) return;
|
if (!heroInfo) return;
|
||||||
@@ -156,12 +178,24 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
* @param buffConf buff 配置
|
* @param buffConf buff 配置
|
||||||
*/
|
*/
|
||||||
addBuff(buffConf: BuffConf) {
|
addBuff(buffConf: BuffConf) {
|
||||||
const applyType = buffConf.BType === BType.BOOLEAN ? BType.BOOLEAN : BType.VALUE;
|
const normalized = this.normalizeBuffValue(buffConf);
|
||||||
const resolvedValue = applyType === BType.BOOLEAN
|
if (buffConf.runType === BuffRunType.Interval) {
|
||||||
? buffConf.value
|
const interval = buffConf.interval && buffConf.interval > 0 ? buffConf.interval : 1;
|
||||||
: this.resolveBuffValue(buffConf.buff, buffConf.value, buffConf.BType);
|
const remain = buffConf.time > 0 ? buffConf.time : interval;
|
||||||
|
this.INTERVAL_EFFECTS.push({
|
||||||
|
id: ++this.buffInstanceId,
|
||||||
|
attr: buffConf.buff,
|
||||||
|
sourceUuid: buffConf.uuid,
|
||||||
|
value: normalized.value,
|
||||||
|
BType: normalized.BType,
|
||||||
|
interval,
|
||||||
|
remain,
|
||||||
|
tick: interval
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (buffConf.time <= 0) {
|
if (buffConf.time <= 0) {
|
||||||
this.applyAttrChange(buffConf.buff, resolvedValue, applyType);
|
this.applyAttrChange(buffConf.buff, normalized.value, normalized.BType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,14 +207,27 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
|
|
||||||
const currentBuffs = targetList[attrKey];
|
const currentBuffs = targetList[attrKey];
|
||||||
currentBuffs.push({
|
currentBuffs.push({
|
||||||
value: resolvedValue,
|
id: ++this.buffInstanceId,
|
||||||
BType: applyType,
|
attr: buffConf.buff,
|
||||||
|
sourceUuid: buffConf.uuid,
|
||||||
|
value: normalized.value,
|
||||||
|
BType: normalized.BType,
|
||||||
time: buffConf.time
|
time: buffConf.time
|
||||||
});
|
});
|
||||||
|
|
||||||
this.applyAttrChange(buffConf.buff, resolvedValue, applyType);
|
this.applyAttrChange(buffConf.buff, normalized.value, normalized.BType);
|
||||||
|
|
||||||
mLogger.log(this.debugMode, 'HeroAttrs', `添加Buff: ${buffConf.name}, 属性:${buffConf.buff}, 值:${resolvedValue}, 时间:${buffConf.time}`);
|
mLogger.log(this.debugMode, 'HeroAttrs', `添加Buff: ${buffConf.name}, 属性:${buffConf.buff}, 值:${normalized.value}, 时间:${buffConf.time}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private normalizeBuffValue(buffConf: BuffConf): { value: number; BType: BType } {
|
||||||
|
if (buffConf.BType === BType.BOOLEAN) {
|
||||||
|
return { value: buffConf.value, BType: BType.BOOLEAN };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
value: this.resolveBuffValue(buffConf.buff, buffConf.value, buffConf.BType),
|
||||||
|
BType: BType.VALUE
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private resolveBuffValue(attr: Attrs, value: number, type: BType): number {
|
private resolveBuffValue(attr: Attrs, value: number, type: BType): number {
|
||||||
@@ -286,7 +333,34 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.updateStatusFlags();
|
this.updateStatusFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateList(list: Record<number, Array<{value: number, BType: BType, time: number}>>, dt: number) {
|
updateIntervalEffectsBySystem(dt: number) {
|
||||||
|
for (let i = this.INTERVAL_EFFECTS.length - 1; i >= 0; i--) {
|
||||||
|
const state = this.INTERVAL_EFFECTS[i];
|
||||||
|
state.remain -= dt;
|
||||||
|
state.tick -= dt;
|
||||||
|
while (state.tick <= 0 && state.remain > 0) {
|
||||||
|
this.applyIntervalEffect(state);
|
||||||
|
state.tick += state.interval;
|
||||||
|
}
|
||||||
|
if (state.remain <= 0) {
|
||||||
|
this.INTERVAL_EFFECTS.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private applyIntervalEffect(state: IntervalBuffState) {
|
||||||
|
if (state.attr === Attrs.hp) {
|
||||||
|
this.add_hp(state.value, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.attr === Attrs.shield) {
|
||||||
|
this.add_shield(state.value, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.applyAttrChange(state.attr, state.value, state.BType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateList(list: Record<number, ActiveBuffState[]>, dt: number) {
|
||||||
for (const attrKey in list) {
|
for (const attrKey in list) {
|
||||||
const buffs = list[attrKey];
|
const buffs = list[attrKey];
|
||||||
if (!buffs || buffs.length === 0) continue;
|
if (!buffs || buffs.length === 0) continue;
|
||||||
@@ -297,14 +371,10 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
buff.time -= dt;
|
buff.time -= dt;
|
||||||
|
|
||||||
if (buff.time <= 0) {
|
if (buff.time <= 0) {
|
||||||
// Buff 过期,移除属性加成
|
this.applyAttrChange(buff.attr, buff.value, buff.BType, true);
|
||||||
// 注意:key 是 string (from record key),需要转为 Attrs
|
|
||||||
const attrName = attrKey as unknown as Attrs;
|
|
||||||
this.applyAttrChange(attrName, buff.value, buff.BType, true); // reverse = true
|
|
||||||
|
|
||||||
// 从列表中移除
|
|
||||||
buffs.splice(i, 1);
|
buffs.splice(i, 1);
|
||||||
mLogger.log(this.debugMode, 'HeroAttrs', `Buff过期: 属性:${attrName}, 恢复值:${buff.value}`);
|
mLogger.log(this.debugMode, 'HeroAttrs', `Buff过期: 属性:${buff.attr}, 恢复值:${buff.value}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,6 +491,8 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
|
|
||||||
this.BUFFS = {};
|
this.BUFFS = {};
|
||||||
this.DEBUFFS = {};
|
this.DEBUFFS = {};
|
||||||
|
this.INTERVAL_EFFECTS = [];
|
||||||
|
this.buffInstanceId = 0;
|
||||||
// 重置技能距离缓存
|
// 重置技能距离缓存
|
||||||
this.maxSkillDistance = 0;
|
this.maxSkillDistance = 0;
|
||||||
this.minSkillDistance = 0;
|
this.minSkillDistance = 0;
|
||||||
@@ -463,6 +535,7 @@ export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
const attrs = e.get(HeroAttrsComp);
|
const attrs = e.get(HeroAttrsComp);
|
||||||
if (!attrs || attrs.is_dead) return;
|
if (!attrs || attrs.is_dead) return;
|
||||||
attrs.updateBuffsDebuffs(this.dt);
|
attrs.updateBuffsDebuffs(this.dt);
|
||||||
|
attrs.updateIntervalEffectsBySystem(this.dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user