feat(buff): 新增间隔触发型buff效果支持
- 在 SkillSet.ts 中添加 BuffRunType 枚举和 interval 配置字段 - 在 HeroAttrsComp 中实现间隔效果处理逻辑,支持持续治疗和流血等效果 - 新增 INTERVAL_EFFECTS 数组和 updateIntervalEffectsBySystem 方法来管理间隔触发 - 添加 10311(持续治疗)和 10312(流血)两个示例buff配置
This commit is contained in:
@@ -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 { GameEvent } from "../common/config/GameEvent";
|
||||
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 { mLogger } from "../common/Logger";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
@@ -14,6 +14,24 @@ interface talTrigger{
|
||||
value: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')
|
||||
export class HeroAttrsComp extends ecs.Comp {
|
||||
public debugMode: boolean = true;
|
||||
@@ -77,8 +95,10 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
|
||||
// ==================== Buff/Debuff 系统 ====================
|
||||
/** 持久型buff数组 - 不会自动过期 */
|
||||
BUFFS: Record<number, Array<{value: number, BType: BType,time:number}>> = {};
|
||||
DEBUFFS: Record<number, Array<{value: number, BType: BType,time:number}>> = {};
|
||||
BUFFS: Record<number, ActiveBuffState[]> = {};
|
||||
DEBUFFS: Record<number, ActiveBuffState[]> = {};
|
||||
INTERVAL_EFFECTS: IntervalBuffState[] = [];
|
||||
private buffInstanceId = 0;
|
||||
|
||||
// ==================== 标记状态 ====================
|
||||
is_dead: boolean = false;
|
||||
@@ -110,6 +130,8 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
// 清空现有 buff/debuff
|
||||
this.BUFFS = {};
|
||||
this.DEBUFFS = {};
|
||||
this.INTERVAL_EFFECTS = [];
|
||||
this.buffInstanceId = 0;
|
||||
// 获取英雄配置
|
||||
const heroInfo = HeroInfo[this.hero_uuid];
|
||||
if (!heroInfo) return;
|
||||
@@ -156,12 +178,24 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
* @param buffConf buff 配置
|
||||
*/
|
||||
addBuff(buffConf: BuffConf) {
|
||||
const applyType = buffConf.BType === BType.BOOLEAN ? BType.BOOLEAN : BType.VALUE;
|
||||
const resolvedValue = applyType === BType.BOOLEAN
|
||||
? buffConf.value
|
||||
: this.resolveBuffValue(buffConf.buff, buffConf.value, buffConf.BType);
|
||||
const normalized = this.normalizeBuffValue(buffConf);
|
||||
if (buffConf.runType === BuffRunType.Interval) {
|
||||
const interval = buffConf.interval && buffConf.interval > 0 ? buffConf.interval : 1;
|
||||
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) {
|
||||
this.applyAttrChange(buffConf.buff, resolvedValue, applyType);
|
||||
this.applyAttrChange(buffConf.buff, normalized.value, normalized.BType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -173,14 +207,27 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
|
||||
const currentBuffs = targetList[attrKey];
|
||||
currentBuffs.push({
|
||||
value: resolvedValue,
|
||||
BType: applyType,
|
||||
id: ++this.buffInstanceId,
|
||||
attr: buffConf.buff,
|
||||
sourceUuid: buffConf.uuid,
|
||||
value: normalized.value,
|
||||
BType: normalized.BType,
|
||||
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 {
|
||||
@@ -286,7 +333,34 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
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) {
|
||||
const buffs = list[attrKey];
|
||||
if (!buffs || buffs.length === 0) continue;
|
||||
@@ -297,14 +371,10 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
buff.time -= dt;
|
||||
|
||||
if (buff.time <= 0) {
|
||||
// Buff 过期,移除属性加成
|
||||
// 注意:key 是 string (from record key),需要转为 Attrs
|
||||
const attrName = attrKey as unknown as Attrs;
|
||||
this.applyAttrChange(attrName, buff.value, buff.BType, true); // reverse = true
|
||||
this.applyAttrChange(buff.attr, buff.value, buff.BType, true);
|
||||
|
||||
// 从列表中移除
|
||||
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.DEBUFFS = {};
|
||||
this.INTERVAL_EFFECTS = [];
|
||||
this.buffInstanceId = 0;
|
||||
// 重置技能距离缓存
|
||||
this.maxSkillDistance = 0;
|
||||
this.minSkillDistance = 0;
|
||||
@@ -463,6 +535,7 @@ export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
const attrs = e.get(HeroAttrsComp);
|
||||
if (!attrs || attrs.is_dead) return;
|
||||
attrs.updateBuffsDebuffs(this.dt);
|
||||
attrs.updateIntervalEffectsBySystem(this.dt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user