refactor(战斗系统): 重构攻击处理逻辑并优化击退机制
- 将闪避、暴击和击退的概率检查统一为checkChance方法 - 移除HeroAtkComp类并清理无用代码 - 新增clearTalBuffByAttr方法用于清除特定属性的天赋buff - 修改HeroViewComp.do_atked方法支持可选击退参数 - 移除Attrs.BACK属性及相关配置
This commit is contained in:
@@ -108,7 +108,6 @@ export enum Attrs {
|
||||
// ========== 武器进化相关 (70-79) ==========
|
||||
PUNCTURE = 70, // 穿刺次数
|
||||
PUNCTURE_DMG = 71, // 穿刺伤害
|
||||
BACK = 73, // 被击退概率(兼容旧代码)
|
||||
MOVE_SPEED = 74, // 移动速度
|
||||
BURN = 75, // 易伤效果
|
||||
WFUNY = 77, // 风怒
|
||||
@@ -220,7 +219,6 @@ export const AttrsType: Record<Attrs, BType> = {
|
||||
// ========== 武器进化相关(混合类型) ==========
|
||||
[Attrs.PUNCTURE]: BType.VALUE, // 穿刺次数 - 数值型
|
||||
[Attrs.PUNCTURE_DMG]: BType.RATIO, // 穿刺伤害 - 百分比型
|
||||
[Attrs.BACK]: BType.RATIO, // 被击退概率(兼容)- 百分比型
|
||||
[Attrs.MOVE_SPEED]: BType.VALUE, // 移动速度 - 数值型
|
||||
[Attrs.BURN]: BType.RATIO, // 易伤效果 - 百分比型
|
||||
[Attrs.WFUNY]: BType.RATIO, // 未知特殊属性 - 百分比型
|
||||
|
||||
@@ -8,14 +8,7 @@ import { HeroViewComp } from "./HeroViewComp";
|
||||
import { DamageQueueComp, DamageEvent, DamageQueueHelper } from "./DamageQueueComp";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
|
||||
/** 业务层对象 */
|
||||
@ecs.register('HeroAtk')
|
||||
export class HeroAtkComp extends ecs.Comp {
|
||||
/** 业务层组件移除时,重置所有数据为默认值 */
|
||||
reset() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** 最终伤害数据接口 */
|
||||
interface FinalData {
|
||||
damage: number;
|
||||
@@ -94,17 +87,17 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
* @returns 最终伤害数据
|
||||
*/
|
||||
private doAttack(target: ecs.Entity, damageEvent: DamageEvent): FinalData {
|
||||
const targetModel = target.get(HeroAttrsComp);
|
||||
const targetAttrs = target.get(HeroAttrsComp);
|
||||
const targetView = target.get(HeroViewComp);
|
||||
let reDate:FinalData={
|
||||
damage:0,
|
||||
isCrit:false,
|
||||
isDodge:false,
|
||||
}
|
||||
if (!targetModel || targetModel.is_dead) return reDate;
|
||||
if (!targetAttrs || targetAttrs.is_dead) return reDate;
|
||||
|
||||
// 获取攻击者数据
|
||||
const caster = damageEvent.caster;
|
||||
const attackerModel = caster?.ent?.get(HeroAttrsComp);
|
||||
|
||||
// 获取技能配置
|
||||
const skillConf = SkillSet[damageEvent.s_uuid];
|
||||
@@ -114,38 +107,40 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
this.onAttacked(target);
|
||||
|
||||
// 闪避判定
|
||||
if (this.checkDodge(targetModel)) {
|
||||
const isDodge =this.checkChance(targetAttrs.Attrs[Attrs.DODGE] || 0);
|
||||
if (isDodge) {
|
||||
// TODO: 触发闪避视图表现
|
||||
reDate.isDodge=true;
|
||||
return reDate;
|
||||
}
|
||||
|
||||
// 暴击判定
|
||||
const isCrit = this.checkCrit(targetModel.Attrs[Attrs.CRITICAL]);
|
||||
const isCrit = this.checkChance(damageEvent.Attrs[Attrs.CRITICAL]);
|
||||
if (isCrit) attackerModel?.clearTalBuffByAttr(Attrs.CRITICAL);
|
||||
// 计算伤害
|
||||
let damage = this.dmgCount(damageEvent.Attrs,damageEvent.s_uuid);
|
||||
if (isCrit) {
|
||||
damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE + targetModel.Attrs[Attrs.CRITICAL_DMG]) / 100));
|
||||
damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE + targetAttrs.Attrs[Attrs.CRITICAL_DMG]) / 100));
|
||||
reDate.isCrit=true;
|
||||
}
|
||||
|
||||
// 伤害计算(考虑易伤等debuff)
|
||||
damage = this.calculateDamage(targetModel, damage);
|
||||
|
||||
damage = this.calculateDamage(targetAttrs, damage);
|
||||
// 护盾吸收
|
||||
damage =Math.floor(this.absorbShield(targetModel, damage))
|
||||
damage =Math.floor(this.absorbShield(targetAttrs, damage))
|
||||
if (damage <= 0) return reDate;
|
||||
|
||||
// 应用伤害到数据层
|
||||
targetModel.hp -= damage;
|
||||
targetModel.atked_count++;
|
||||
|
||||
targetAttrs.hp -= damage;
|
||||
targetAttrs.atked_count++;
|
||||
//击退判定
|
||||
const isBack = this.checkChance(damageEvent.Attrs[Attrs.BACK_CHANCE] || 0);
|
||||
if (isBack) attackerModel?.clearTalBuffByAttr(Attrs.BACK_CHANCE);
|
||||
|
||||
|
||||
// ✅ 触发视图层表现(伤害数字、受击动画、后退)
|
||||
if (targetView) {
|
||||
targetView.do_atked(damage, isCrit, damageEvent.s_uuid);
|
||||
}
|
||||
if (targetView) targetView.do_atked(damage, isCrit, damageEvent.s_uuid, isBack);
|
||||
|
||||
|
||||
// 检查死亡
|
||||
if (targetModel.hp <= 0) {
|
||||
if (targetAttrs.hp <= 0) {
|
||||
this.doDead(target);
|
||||
// ✅ 触发死亡视图表现
|
||||
if (targetView) {
|
||||
@@ -154,7 +149,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
}
|
||||
|
||||
if (this.debugMode) {
|
||||
console.log(`[HeroAtkSystem] ${targetModel.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`);
|
||||
console.log(`[HeroAtkSystem] ${targetAttrs.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`);
|
||||
}
|
||||
|
||||
reDate.damage=damage;
|
||||
@@ -184,31 +179,15 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 闪避判定
|
||||
*/
|
||||
private checkDodge(model: HeroAttrsComp): boolean {
|
||||
if (model.Attrs[Attrs.DODGE] > 0) {
|
||||
const random = Math.random() * 100;
|
||||
if (random < model.Attrs[Attrs.DODGE]) {
|
||||
if (this.debugMode) {
|
||||
console.log(`[HeroBattleSystem] ${model.hero_name} 闪避了攻击`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 暴击判定
|
||||
*/
|
||||
private checkCrit(critRate: number): boolean {
|
||||
if (critRate > 0) {
|
||||
const random = Math.random() * 100;
|
||||
return random < critRate;
|
||||
}
|
||||
return false;
|
||||
private checkChance(rate: number): boolean {
|
||||
if (rate <= 0) return false;
|
||||
const r = Math.random() * 100;
|
||||
return r < rate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -425,6 +425,17 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
delete this.BUFFS_TAL[t_uuid];
|
||||
this.recalculateSingleAttr(attrIndex);
|
||||
}
|
||||
clearTalBuffByAttr(attrIndex: number) {
|
||||
let changed = false;
|
||||
for (const key in this.BUFFS_TAL) {
|
||||
const b = this.BUFFS_TAL[Number(key)];
|
||||
if (b && b.attrIndex === attrIndex) {
|
||||
delete this.BUFFS_TAL[Number(key)];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) this.recalculateSingleAttr(attrIndex);
|
||||
}
|
||||
|
||||
addTalent(eff: number, value: number) {
|
||||
const t = this.Talents[eff] || { value: 0, count: 0 };
|
||||
|
||||
@@ -350,7 +350,7 @@ export class HeroViewComp extends CCComp {
|
||||
this.ent.destroy();
|
||||
|
||||
}
|
||||
do_atked(damage:number,isCrit:boolean,s_uuid:number){
|
||||
do_atked(damage:number,isCrit:boolean,s_uuid:number,isBack:boolean=false){
|
||||
// 受到攻击时显示血条,并设置显示时间(即使伤害为0也显示)
|
||||
this.top_node.active = true;
|
||||
this.hpBarShowCD = this.hpBarShowTime;
|
||||
@@ -359,8 +359,8 @@ export class HeroViewComp extends CCComp {
|
||||
|
||||
// 视图层表现
|
||||
let SConf=SkillSet[s_uuid]
|
||||
this.back()
|
||||
this.showDamage(damage, isCrit, SConf.DAnm); // 暴击状态由战斗系统内部处理, DAnm和EAnm共用设定数组
|
||||
if (isBack) this.back()
|
||||
this.showDamage(damage, isCrit, SConf.DAnm);
|
||||
}
|
||||
|
||||
private isBackingUp: boolean = false; // 🔥 添加后退状态标记
|
||||
|
||||
Reference in New Issue
Block a user