feat(技能系统): 添加buff技能支持并增强属性变更日志
添加buff技能类型支持,包括目标选择、施放逻辑和效果应用 在HeroAttrsComp中增加属性变更的详细日志输出 为治疗和护盾技能添加执行日志
This commit is contained in:
@@ -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}%)`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user