refactor(hero): 重构英雄死亡与复活机制
1. 统一英雄真实死亡流程:死亡时快照数据到全局列表,动画结束后统一销毁实体 2. 移除回合自动复活逻辑,改为由复活系统主动读取快照重新召唤 3. 修复近战追敌可能脱离战场的问题,增加推进距离上限 4. 重构死亡计数与全员存活检测逻辑,基于死亡快照列表而非实体状态
This commit is contained in:
@@ -220,10 +220,11 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
||||
|
||||
// 检查死亡
|
||||
if (TAttrsComp.hp <= 0) {
|
||||
// 先触发死亡技能(如亡语),不管后续是否复活都应触发
|
||||
// 先触发死亡技能(如亡语),不管后续是否续命都应触发
|
||||
this.triggerDeadSkills(target);
|
||||
|
||||
// 复活机制:如果玩家属性内的复活属性值>=1 则执行复活,原地50%血量复活
|
||||
// 濒死回血(revive 系):不是真正复活,而是血量归零瞬间消耗 1 次续命次数,
|
||||
// 按比例回血继续战斗。次数每回合重置(见 MissionComp.healAllHeroes)。
|
||||
let canRevive = false;
|
||||
let maxReviveCount = 0;
|
||||
let reviveHpPercent = 50; // 默认恢复50%
|
||||
@@ -338,16 +339,16 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
||||
|
||||
/**
|
||||
* 处理角色死亡
|
||||
*
|
||||
*
|
||||
* 死亡处理流程:
|
||||
* 1. 标记死亡状态(is_dead = true)
|
||||
* 2. 触发死亡事件(onDeath)
|
||||
* 3. 记录调试信息(如启用调试模式)
|
||||
*
|
||||
* 2. 英雄阵营:快照死亡状态到 smc.mission.dead_heroes(供后续复活机制重新召唤)
|
||||
* 3. 触发死亡事件(onDeath)
|
||||
*
|
||||
* @param entity 死亡的实体
|
||||
*
|
||||
*
|
||||
* @important 死亡状态一旦设置,该实体将不再处理新的伤害事件
|
||||
* 这确保了死亡逻辑的单一性和一致性
|
||||
* 英雄为真实死亡:视图动画结束后由 HeroViewComp.realDead 销毁实体
|
||||
*/
|
||||
private doDead(entity: ecs.Entity): void {
|
||||
const TAttrsComp = entity.get(HeroAttrsComp);
|
||||
@@ -355,6 +356,11 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
||||
|
||||
TAttrsComp.is_dead = true;
|
||||
|
||||
// 英雄真实死亡:记录快照,供后续复活机制(重新召唤)消费
|
||||
if (TAttrsComp.fac === FacSet.HERO) {
|
||||
this.recordDeadHero(TAttrsComp);
|
||||
}
|
||||
|
||||
// 触发死亡事件
|
||||
this.onDeath(entity);
|
||||
|
||||
@@ -363,6 +369,24 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 快照死亡英雄的静态/成长数据到 smc.mission.dead_heroes。
|
||||
* 仅记录重新召唤所需字段,不含战斗内临时状态(buff、技能 CD 等)。
|
||||
*
|
||||
* @param attrs 死亡英雄的属性组件
|
||||
*/
|
||||
private recordDeadHero(attrs: HeroAttrsComp): void {
|
||||
smc.mission.dead_heroes.push({
|
||||
uuid: attrs.hero_uuid,
|
||||
lv: attrs.lv,
|
||||
card_lv: attrs.card_lv,
|
||||
posIndex: attrs.posIndex,
|
||||
wave: Math.max(1, smc.vmdata?.mission_data?.level ?? 1),
|
||||
});
|
||||
mLogger.log(this.debugMode, 'HeroAtkSystem',
|
||||
` 死亡英雄已记录: ${attrs.hero_name}(uuid=${attrs.hero_uuid}) lv=${attrs.lv} pos=${attrs.posIndex} wave=${smc.vmdata?.mission_data?.level}, 当前共 ${smc.mission.dead_heroes.length} 个`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -516,17 +516,12 @@ export class HeroViewComp extends CCComp {
|
||||
let isHero = this.model.fac === FacSet.HERO;
|
||||
let dirX = isHero ? -800 : 800;
|
||||
|
||||
// 死亡往后飞出屏幕动画
|
||||
// 死亡往后飞出屏幕动画,结束后统一销毁实体
|
||||
// 英雄为真实死亡:快照已在 doDead 阶段写入 smc.mission.dead_heroes,此处直接销毁
|
||||
tween(this.node)
|
||||
.by(0.5, { position: v3(dirX, 700, 0) }, { easing: "quadOut" })
|
||||
.call(() => {
|
||||
if (isHero) {
|
||||
// 将英雄移到玩家看不到的墓地,留待下回合上场
|
||||
this.node.setPosition(v3(-2000, -2000, 0));
|
||||
} else {
|
||||
// 动画结束后销毁怪物实体
|
||||
this.ent.destroy();
|
||||
}
|
||||
this.ent.destroy();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
@@ -223,7 +223,8 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
// 未贴近:向怪物方向推进(攻击范围内也继续移动),于接触距离处停下
|
||||
const dir = enemyX > selfX ? 1 : -1;
|
||||
move.direction = dir;
|
||||
const stopX = enemyX - dir * MoveSystem.MELEE_ENGAGE_X;
|
||||
// 终止点取接触距离与推进上限的较小者,防止越过 300 继续追击
|
||||
const stopX = Math.min(enemyX - dir * MoveSystem.MELEE_ENGAGE_X, MoveSystem.HERO_ADVANCE_LIMIT_X);
|
||||
const speed = model.speed / 3;
|
||||
this.moveEntity(view, dir, speed, stopX);
|
||||
model.is_atking = false;
|
||||
@@ -290,6 +291,8 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
private static readonly FORMATION_STEP_X = 60;
|
||||
/** 近战贴近怪物的固定接触距离:小于攻击距离 dis,使英雄进攻击范围后仍继续贴近到此间距才停 */
|
||||
private static readonly MELEE_ENGAGE_X = 60;
|
||||
/** 英雄向敌人推进的最远终止点 X,防止近战追敌时无限右移脱离战场 */
|
||||
private static readonly HERO_ADVANCE_LIMIT_X = 300;
|
||||
|
||||
/**
|
||||
* 计算某个槽位的目标 X。
|
||||
|
||||
Reference in New Issue
Block a user