refactor(hero): 重构英雄死亡与复活机制

1. 统一英雄真实死亡流程:死亡时快照数据到全局列表,动画结束后统一销毁实体
2. 移除回合自动复活逻辑,改为由复活系统主动读取快照重新召唤
3. 修复近战追敌可能脱离战场的问题,增加推进距离上限
4. 重构死亡计数与全员存活检测逻辑,基于死亡快照列表而非实体状态
This commit is contained in:
pan
2026-08-12 16:15:33 +08:00
parent ab6a3b7824
commit 3060ee7df7
6 changed files with 79 additions and 42 deletions

View File

@@ -560,17 +560,15 @@ export class MissionComp extends CCComp {
let allAlive = true;
let hasHero = false;
let heroDeathCount = 0;
ecs.query(this.heroAttrsMatcher).forEach(entity => {
const attrs = entity.get(HeroAttrsComp);
if (attrs && attrs.fac === FacSet.HERO) {
hasHero = true;
if (attrs.is_dead) {
allAlive = false;
heroDeathCount++;
}
}
});
// 英雄为真实死亡(实体已销毁),本回合死亡数取死亡记录长度
const heroDeathCount = smc.mission.dead_heroes.length;
if (heroDeathCount > 0) allAlive = false;
// 【动态难度调节】根据本回合战况自动放水 / 加压
// 清场加速节省的时间还原进口径,避免"打得好"被节奏加速+强度加压双重惩罚
@@ -978,15 +976,14 @@ export class MissionComp extends CCComp {
/** 检测场上英雄是否全员存活(清屏 Perfect 判定用,独立于评分统计逻辑) */
private checkAllHeroAlive(): boolean {
let hasHero = false;
let allAlive = true;
ecs.query(this.heroAttrsMatcher).forEach(entity => {
const attrs = entity.get(HeroAttrsComp);
if (attrs && attrs.fac === FacSet.HERO) {
hasHero = true;
if (attrs.is_dead) allAlive = false;
}
});
return hasHero && allAlive;
// 英雄为真实死亡(实体已销毁),有死亡记录即非全员存活
return hasHero && smc.mission.dead_heroes.length === 0;
}
/**

View File

@@ -15,6 +15,11 @@
* 旧英雄移动合并销毁,新英雄以 **两者最高等级 + 1** 落地(封顶 HERO_MAX_LV
* 等级已达上限时拒绝召唤。英雄也可通过升级卡SpecialUpgrade升级。
*
* 死亡机制:
* 英雄为真实死亡HeroAtkSystem.doDead → 快照至 smc.mission.dead_heroes → 实体销毁),
* 本组件不做回合自动复活;复活由后续复活机制读取 dead_heroes 重新召唤。
* revive 系技能为"濒死回血"(血量归零时消耗次数回血续命),不触发真死。
*
* 依赖:
* - Herohero/Hero.ts—— 英雄 ECS 实体类
* - HeroAttrsComp —— 英雄属性组件
@@ -102,34 +107,28 @@ export class MissionHeroComp extends CCComp {
// ======================== 事件处理 ========================
/** 关卡结束时清理全部英雄 ECS 实体 */
/** 关卡结束时清理全部存活英雄 ECS 实体,并清空本局死亡英雄记录 */
clear_heros() {
const heroes = this.getAllHeroes();
for (let i = 0; i < heroes.length; i++) {
heroes[i].destroy();
}
// 整局结束,死亡记录失效(复活机制仅限局内)
smc.mission.dead_heroes = [];
}
/** 战斗准备阶段:重置出战英雄计数,恢复满血重新登场 */
/**
* 战斗准备阶段:刷新存活英雄计数与血条。
*
* 说明:英雄为真实死亡(实体已销毁,快照存于 smc.mission.dead_heroes
* 本阶段不再做回合自动复活;复活由后续复活机制(重新召唤)显式触发。
*/
fight_ready() {
const heroes = this.getAllHeroes();
smc.vmdata.mission_data.hero_num = heroes.length;
for (let i = 0; i < heroes.length; i++) {
const hero = heroes[i];
const model = hero.get(HeroAttrsComp);
const view = hero.get(HeroViewComp);
if (model && view) {
if (model.is_dead) {
view.alive();
const posIndex = this.pickPositionIndexForHero([hero.eid]);
const landingPos = MissionHeroComp.HERO_POSITIONS[posIndex];
// 计算出生点(空中)
const spawnPos: Vec3 = v3(landingPos.x, landingPos.y + MissionHeroComp.HERO_DROP_HEIGHT, 0);
view.node.setPosition(spawnPos);
model.posIndex = posIndex;
if (posIndex >= 0) smc.mission.heroGrid[posIndex] = hero.eid;
hero.playDropAnim(spawnPos, landingPos.y);
}
const model = heroes[i].get(HeroAttrsComp);
if (model) {
model.dirty_hp = true;
}
}