feat(技能系统): 添加buff技能支持并增强属性变更日志

添加buff技能类型支持,包括目标选择、施放逻辑和效果应用
在HeroAttrsComp中增加属性变更的详细日志输出
为治疗和护盾技能添加执行日志
This commit is contained in:
walkpan
2026-01-01 14:40:13 +08:00
parent a5e6426296
commit a156ddfc2f
2 changed files with 101 additions and 1 deletions

View File

@@ -122,6 +122,7 @@ export class HeroAttrsComp extends ecs.Comp {
/*******************基础属性管理********************/
add_hp(value:number,isValue:boolean){
const oldHp = this.hp;
let addValue = value;
if(!isValue){
addValue = value * this.Attrs[Attrs.HP_MAX] / 100;
@@ -136,8 +137,10 @@ export class HeroAttrsComp extends ecs.Comp {
this.hp += addValue;
this.hp = Math.max(0, Math.min(this.hp, this.Attrs[Attrs.HP_MAX]));
this.dirty_hp = true; // ✅ 仅标记需要更新
console.log(`[HeroAttrs] HP变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldHp.toFixed(1)} -> ${this.hp.toFixed(1)}`);
}
add_mp(value:number,isValue:boolean){
const oldMp = this.mp;
let addValue = value;
if(!isValue){
addValue = value * this.Attrs[Attrs.MP_MAX] / 100;
@@ -152,14 +155,17 @@ export class HeroAttrsComp extends ecs.Comp {
this.mp += addValue;
this.mp = Math.max(0, Math.min(this.mp, this.Attrs[Attrs.MP_MAX]));
this.dirty_mp = true; // ✅ 仅标记需要更新
console.log(`[HeroAttrs] MP变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldMp.toFixed(1)} -> ${this.mp.toFixed(1)}`);
}
add_shield(value:number,isValue:boolean){
const oldShield = this.shield;
let addValue = value;
if(!isValue){
addValue = value * this.Attrs[Attrs.HP_MAX] / 100;
}
this.shield += addValue;
this.dirty_shield = true; // 标记护盾需要更新
console.log(`[HeroAttrs] 护盾变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldShield.toFixed(1)} -> ${this.shield.toFixed(1)}`);
}
// ==================== BUFF 管理 ====================
/**
@@ -213,6 +219,7 @@ export class HeroAttrsComp extends ecs.Comp {
* @param attrIndex 属性索引
*/
recalculateSingleAttr(attrIndex: number) {
const oldVal = this.Attrs[attrIndex] || 0;
const baseVal = this.getBaseValue(attrIndex);
// 2. 收集所有数值型 buff/debuff
@@ -281,6 +288,10 @@ export class HeroAttrsComp extends ecs.Comp {
// 5. 确保属性值合理
this.clampSingleAttr(attrIndex);
if (oldVal !== this.Attrs[attrIndex]) {
console.log(`[HeroAttrs] 属性重算: ${this.hero_name}, 属性ID=${attrIndex}, ${oldVal} -> ${this.Attrs[attrIndex]} (Base=${baseVal}, Add=${totalValue-baseVal}, Ratio=${totalRatio}%)`);
}
}
/**

View File

@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { Vec3, v3 } from "cc";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp";
import { HSSet, SkillSet, SType } from "../common/config/SkillSet";
import { HSSet, SkillSet, SType, TGroup } from "../common/config/SkillSet";
import { HeroSkillsComp, SkillSlot } from "./HeroSkills";
import { Skill } from "../skill/Skill";
import { smc } from "../common/SingletonModuleComp";
@@ -64,6 +64,8 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
if (!this.hasEnemyInSkillRange(heroView, heroAttrs, skill.dis)) continue;
} else if (config.SType === SType.heal || config.SType === SType.shield) {
if (!this.hasTeamInSkillRange(heroView, heroAttrs, skill.dis)) continue;
} else if (config.SType === SType.buff) {
if (!this.hasBuffTarget(heroView, heroAttrs, skill.dis, config.TGroup)) continue;
}
// ✅ 开始执行施法
@@ -161,6 +163,8 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
return this.executeHealSkill(casterEntity, s_uuid, heroView, hset);
} else if (config.SType === SType.shield) {
return this.executeShieldSkill(casterEntity, s_uuid, heroView, hset);
} else if (config.SType === SType.buff) {
return this.executeBuffSkill(casterEntity, s_uuid, heroView, hset);
}
// 获取目标位置(伤害技能)
@@ -386,6 +390,89 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
return found;
}
/**
* 检查Buff技能是否有目标
*/
private hasBuffTarget(heroView: HeroViewComp, heroAttrs: HeroAttrsComp, skillDistance: number, tGroup: TGroup): boolean {
if (tGroup === TGroup.Self) return true; // 自身Buff总是可以释放
// 如果是团队Buff检查范围内是否有队友
if (tGroup === TGroup.Team || tGroup === TGroup.Ally) {
return this.hasTeamInSkillRange(heroView, heroAttrs, skillDistance);
}
return false;
}
/**
* 执行Buff技能
*/
private executeBuffSkill(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp, hset: HSSet): boolean {
const hAttrsCom = casterEntity.get(HeroAttrsComp);
const config = SkillSet[s_uuid];
if (!config || !config.buffs || config.buffs.length === 0) return false;
const targets = this.sBuffTargets(casterEntity, heroView, hAttrsCom, config);
if (targets.length === 0) return false;
const delay = 0.3;
heroView.scheduleOnce(() => {
for (const targetEntity of targets) {
const targetAttrs = targetEntity.get(HeroAttrsComp);
if (!targetAttrs) continue;
// 应用所有配置的Buff
for (const buffConf of config.buffs) {
// 检查概率
if (buffConf.chance >= 1 || Math.random() < buffConf.chance) {
targetAttrs.addBuff(buffConf);
console.log(`[SACastSystem] Buff生效: 施法者=${casterEntity.get(HeroAttrsComp)?.hero_name}, 技能=${config.name}, 目标=${targetAttrs.hero_name}, Buff类型=${buffConf.buff}, 值=${buffConf.value}`);
}
}
}
}, delay);
return true;
}
/**
* 选择Buff目标
*/
private sBuffTargets(casterEntity: ecs.Entity, casterView: HeroViewComp, heroAttrs: HeroAttrsComp, config: any): ecs.Entity[] {
const targets: ecs.Entity[] = [];
const tGroup = config.TGroup;
// 1. 自身
if (tGroup === TGroup.Self) {
targets.push(casterEntity);
return targets;
}
// 2. 团队/友军
if (tGroup === TGroup.Team || tGroup === TGroup.Ally) {
const maxTargets = Math.max(1, Number(config.t_num ?? 1));
const range = Number(config.dis ?? 300);
ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).forEach(e => {
const model = e.get(HeroAttrsComp);
const view = e.get(HeroViewComp);
if (!model || !view || !view.node) return;
if (model.fac !== heroAttrs.fac) return; // 必须是同阵营
if (model.is_dead) return;
const distance = Math.abs(casterView.node.position.x - view.node.position.x);
if (distance <= range) {
targets.push(e);
}
});
return targets.slice(0, maxTargets);
}
return targets;
}
/**
* 执行治疗技能
*/
@@ -408,6 +495,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
targetAttrs.add_hp(healAmount, false);
targetView.health(healAmount);
console.log(`[SACastSystem] 治疗生效: 施法者=${casterEntity.get(HeroAttrsComp)?.hero_name}, 技能=${config.name}, 目标=${targetAttrs.hero_name}, 治疗量=${healAmount}`);
}
}, delay);
@@ -436,6 +524,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
targetAttrs.add_shield(shieldAmount, false);
targetView.add_shield(shieldAmount);
console.log(`[SACastSystem] 护盾生效: 施法者=${casterEntity.get(HeroAttrsComp)?.hero_name}, 技能=${config.name}, 目标=${targetAttrs.hero_name}, 护盾量=${shieldAmount}`);
}
}, delay);