战斗管理系统基础

This commit is contained in:
2025-02-03 22:02:26 +08:00
parent 060046a6a6
commit 36a8aff783
27 changed files with 375 additions and 619 deletions

View File

@@ -23,8 +23,13 @@ export class DamageSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
const sourceView = req.source.get(HeroViewComp);
let final = req.baseValue;
// 伤害浮动±10%
const damageFloat = 0.9 + Math.random() * 0.2; // 0.9~1.1
final *= damageFloat;
final = Math.round(final);
// 闪避判定
if (Math.random() < targetView.dodge) {
if (Math.random()*100 < targetView.dodge) {
const result = new DamageResult();
result.isDodged = true;
return result;
@@ -32,21 +37,24 @@ export class DamageSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
// 护甲减伤
if (!req.ignoreDefense) {
final -= targetView.def * 0.5;
const effectiveArmor = Math.min(targetView.def, 300); // 最大减伤75%
const damageReduction = effectiveArmor / (effectiveArmor + 100);
final *= (1 - damageReduction);
final = Math.round(final); // 四舍五入取整
}
// 暴击判定
let isCrit = false;
if (req.canCrit) {
const critRate = sourceView.crit;
if (Math.random() < critRate) {
if (Math.random() * 100 < critRate) {
final *= 1.5;
isCrit = true;
}
}
const result = new DamageResult();
result.value = Math.max(0, final);
result.value = Math.max(1, final); // 确保最小伤害为1
result.isCrit = isCrit;
result.position = req.target.get(HeroViewComp).node.position;
result.delay = req.delay;
@@ -55,20 +63,52 @@ export class DamageSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
private applyDamage(target: ecs.Entity, result: DamageResult) {
const view = target.get(HeroViewComp);
view.hp -= result.value;
// 添加伤害结果组件
const comp = target.add(DamageResult);
comp.value = result.value;
comp.isCrit = result.isCrit;
comp.position = result.position;
comp.delay = result.delay;
comp.isDodged = result.isDodged;
if (!view.ent.has(HeroViewComp)) return;
this.scheduleOnce(()=>{
// 护盾优先吸收伤害
let remainingDamage = result.value;
if(result.isDodged){
view.BUFFCOMP.tooltip(5,"*闪避*");
return;
}
if (view.shield > 0) {
const shieldAbsorb = Math.min(view.shield, remainingDamage);
view.shield -= shieldAbsorb;
remainingDamage -= shieldAbsorb;
if (view.shield <= 0) {
view.BUFFCOMP.show_shield(false);
}
}
// 剩余伤害扣除血量
if (remainingDamage > 0) {
view.hp -= remainingDamage;
view.showDamage(result.value, result.isCrit);
}else{
view.BUFFCOMP.tooltip(5,"*吸收*");
}
// 触发伤害事件
}, result.delay)
// 直接触发事件
oops.message.dispatchEvent("OnDamage", {
target,
damage: result.value,
isCrit: result.isCrit
});
}
private scheduleOnce(callback: () => void, delay: number) {
const timer = setTimeout(() => {
callback();
delete this._timers[timer];
}, delay * 1000);
this._timers[timer] = timer;
}
onDestroy() {
Object.values(this._timers).forEach(clearTimeout);
}
}