feat(skill): add timed buff support for skills

1. 新增timed_buff_id配置项到SkillConfig和SkillOverrides接口
2. 实现计时buff逻辑:配置该id时通过buffManager添加限时buff,跳过永久buff逻辑
3. 优化代码格式和空行规范,修复部分代码细节问题
This commit is contained in:
pan
2026-07-23 16:25:08 +08:00
parent 9a5093d2a4
commit 2381812d06
3 changed files with 9619 additions and 9324 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -154,6 +154,7 @@ export interface SkillConfig {
stun?: number, // 额外击晕概率 stun?: number, // 额外击晕概率
bck?: number, // 额外击退概率 bck?: number, // 额外击退概率
buff_type?: Attrs, // Buff 类型 (单一职责) buff_type?: Attrs, // Buff 类型 (单一职责)
timed_buff_id?: number, // 计时性 buff 配置 id指向 BuffList存在时走 buffManager 而非永久 add_*
call_hero?: number, // 召唤技能召唤英雄id(可选) call_hero?: number, // 召唤技能召唤英雄id(可选)
is_accel?: boolean, // 是否逐渐加速飞行 is_accel?: boolean, // 是否逐渐加速飞行
info: string, // 技能描述 info: string, // 技能描述
@@ -170,6 +171,7 @@ export interface SkillOverrides {
stun?: number; stun?: number;
bck?: number; bck?: number;
buff_type?: Attrs; buff_type?: Attrs;
timed_buff_id?: number;
call_hero?: number; call_hero?: number;
is_accel?: boolean; is_accel?: boolean;
} }

View File

@@ -14,6 +14,7 @@ import { SkillTriggerType } from "../common/config/heroSet";
import { SkillTriggerHelper } from "./SkillTriggerHelper"; import { SkillTriggerHelper } from "./SkillTriggerHelper";
import { MissionEconomy } from "../map/MissionEconomy"; import { MissionEconomy } from "../map/MissionEconomy";
import { MissionHeroComp } from "../map/MissionHeroComp"; import { MissionHeroComp } from "../map/MissionHeroComp";
import { buffManager } from "./BuffManager";
/** /**
* ==================== 自动施法系统 ==================== * ==================== 自动施法系统 ====================
@@ -205,9 +206,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
* 3. 选取本帧可施放技能并执行施法 * 3. 选取本帧可施放技能并执行施法
*/ */
update(e: ecs.Entity): void { update(e: ecs.Entity): void {
if(!smc.mission.play ) return; if (!smc.mission.play) return;
if(smc.mission.pause) return if (smc.mission.pause) return
if(!smc.mission.in_fight) return if (!smc.mission.in_fight) return
const heroAttrs = e.get(HeroAttrsComp); const heroAttrs = e.get(HeroAttrsComp);
const heroView = e.get(HeroViewComp); const heroView = e.get(HeroViewComp);
if (!heroAttrs || !heroView || !heroView.node) return; if (!heroAttrs || !heroView || !heroView.node) return;
@@ -231,7 +232,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
heroView.playReady("yellow"); heroView.playReady("yellow");
} else if (triggerType === 'dead') { } else if (triggerType === 'dead') {
heroView.playOther("dead"); heroView.playOther("dead");
}else{ } else {
heroView.playOther('yellow') heroView.playOther('yellow')
} }
@@ -273,11 +274,11 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
const sUp = SkillUpList[s_uuid] ? SkillUpList[s_uuid] : SkillUpList[1001]; const sUp = SkillUpList[s_uuid] ? SkillUpList[s_uuid] : SkillUpList[1001];
const cNum = Math.min(2, Math.max(0, Math.floor(sUp.num ?? 0))); const cNum = Math.min(2, Math.max(0, Math.floor(sUp.num ?? 0)));
const castTimes = 1 + cNum; const castTimes = 1 + cNum;
let val="" let val = ""
if(castTimes >1){ if (castTimes > 1) {
val = "*"+castTimes.toString val = "*" + castTimes.toString
} }
heroView.skill_name(val,s_uuid,triggerType) heroView.skill_name(val, s_uuid, triggerType)
for (let i = 0; i < castTimes; i++) { for (let i = 0; i < castTimes; i++) {
if (!heroView.node || !heroView.node.isValid) return; if (!heroView.node || !heroView.node.isValid) return;
if (isFriendly) { if (isFriendly) {
@@ -340,7 +341,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
const skillLv = castPlan.skillLv; const skillLv = castPlan.skillLv;
const overrides = castPlan.overrides; const overrides = castPlan.overrides;
let config = SkillSet[s_uuid]; let config = SkillSet[s_uuid];
const sUp = SkillUpList[s_uuid] ? SkillUpList[s_uuid]:SkillUpList[1001]; const sUp = SkillUpList[s_uuid] ? SkillUpList[s_uuid] : SkillUpList[1001];
const cNum = Math.min(2, Math.max(0, Math.floor(sUp.num ?? 0))); const cNum = Math.min(2, Math.max(0, Math.floor(sUp.num ?? 0)));
if (!config) return; if (!config) return;
@@ -407,7 +408,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
* 创建技能实体(投射物/范围体等)。 * 创建技能实体(投射物/范围体等)。
* 仅用于对敌伤害技能的实体化表现与碰撞伤害分发。 * 仅用于对敌伤害技能的实体化表现与碰撞伤害分发。
*/ */
private createSkillEntity(s_uuid: number, skillLv: number, caster: HeroViewComp,cAttrsComp: HeroAttrsComp, targetPos: Vec3, castIndex: number = 0, overrides?: SkillOverrides) { private createSkillEntity(s_uuid: number, skillLv: number, caster: HeroViewComp, cAttrsComp: HeroAttrsComp, targetPos: Vec3, castIndex: number = 0, overrides?: SkillOverrides) {
if (!caster.node || !caster.node.isValid) return; if (!caster.node || !caster.node.isValid) return;
const parent = caster.node.parent; const parent = caster.node.parent;
if (!parent) return; if (!parent) return;
@@ -443,8 +444,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
private applyFriendlySkillEffects(_s_uuid: number, _skillLv: number, config: SkillConfig, _heroView: HeroViewComp, _cAttrsComp: HeroAttrsComp, targets: HeroViewComp[], _targetPos: Vec3 | null, isCardSkill: boolean = false) { private applyFriendlySkillEffects(_s_uuid: number, _skillLv: number, config: SkillConfig, _heroView: HeroViewComp, _cAttrsComp: HeroAttrsComp, targets: HeroViewComp[], _targetPos: Vec3 | null, isCardSkill: boolean = false) {
const kind = config.kind ?? SkillKind.Support; const kind = config.kind ?? SkillKind.Support;
const sUp = SkillUpList[_s_uuid] ?? SkillUpList[1001]; const sUp = SkillUpList[_s_uuid] ?? SkillUpList[1001];
const sAp =config.ap+sUp.ap*_skillLv; const sAp = config.ap + sUp.ap * _skillLv;
const sHit=config.hit_count+sUp.hit_count*_skillLv; const sHit = config.hit_count + sUp.hit_count * _skillLv;
const applyTargets = kind === SkillKind.Heal const applyTargets = kind === SkillKind.Heal
? this.pickHealTargetsByMostMissingHp(targets, sHit) ? this.pickHealTargetsByMostMissingHp(targets, sHit)
: this.pickRandomFriendlyTargets(targets, sHit); : this.pickRandomFriendlyTargets(targets, sHit);
@@ -466,7 +467,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
} }
if (kind === SkillKind.Heal && sAp !== 0) { if (kind === SkillKind.Heal && sAp !== 0) {
const addHp = Math.floor(sAp*_cAttrsComp.ap/100); const addHp = Math.floor(sAp * _cAttrsComp.ap / 100);
model.add_hp(addHp); model.add_hp(addHp);
target.health(addHp); target.health(addHp);
if (_cAttrsComp.fac === FacSet.HERO) { if (_cAttrsComp.fac === FacSet.HERO) {
@@ -485,6 +486,18 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
} }
if (config.buff_type !== undefined) { if (config.buff_type !== undefined) {
// 计时性 buff配置了 timed_buff_id 时走 buffManager 限时路径,
// 同一技能不应既永久加成又限时加成,故提前 return 跳过下方永久 add_* 逻辑
if (config.timed_buff_id) {
buffManager.applyBuff(
target.ent,
config.timed_buff_id,
_cAttrsComp.hero_uuid,
_cAttrsComp.ap
);
return;
}
const baseValue = config.ap; const baseValue = config.ap;
let upgradeValue = 0; let upgradeValue = 0;
@@ -496,7 +509,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
const totalBuffValue = baseValue + upgradeValue; const totalBuffValue = baseValue + upgradeValue;
switch (config.buff_type){ switch (config.buff_type) {
case Attrs.ap: case Attrs.ap:
model.add_ap(totalBuffValue); model.add_ap(totalBuffValue);
break; break;