diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index ee1fc78d..dd54e333 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -7,7 +7,7 @@ import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroViewComp } from "./HeroViewComp"; import { DamageQueueComp, DamageEvent } from "./DamageQueueComp"; import { smc } from "../common/SingletonModuleComp"; -import { HeroInfo } from "../common/config/heroSet"; +import { HeroInfo, MonType } from "../common/config/heroSet"; import { oops } from "db://oops-framework/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; import { SkillTriggerType } from "../common/config/heroSet"; @@ -719,6 +719,8 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda if (TAttrsComp.fac === FacSet.MON) { // 怪物死亡处理 this.scheduleDrop(entity); + // 分类击杀统计:互斥优先级 Boss > 精英 > 近战/远程(供整局结算失败奖励判定) + this.countMonsterKill(TAttrsComp); // oops.message 全局事件总线:怪物死亡(连杀计数等表现层消费) oops.message.dispatchEvent(GameEvent.MonDead, { isBoss: !!TAttrsComp.is_boss, @@ -761,6 +763,38 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda ` ${TAttrsComp.hero_name} 死亡掉落金币 ${gold}(monType=${monType}, isBoss=${TAttrsComp.is_boss})`); } + /** + * 怪物分类击杀统计(写入 smc.vmdata.scores,供整局结算的失败奖励判定)。 + * + * 分类互斥,优先级 Boss > 精英 > 近战/远程: + * - Boss(is_boss) → boss_kill_count + * - 精英(is_elite) → elite_kill_count + * - 近战/重型/刺客 → melee_kill_count + * - 远程/辅助/召唤师(兜底) → remote_kill_count + * + * Why: 互斥计数保证 kills 之和不超过实际击杀数,与 MissionMonComp 的 + * 整局已刷出总数(getTotalSpawnedCount)口径一致,避免击杀比例虚高。 + * + * @param attrs 死亡怪物的属性组件 + */ + private countMonsterKill(attrs: HeroAttrsComp): void { + const scores = smc.vmdata.scores; + if (attrs.is_boss) { + scores.boss_kill_count++; + return; + } + if (attrs.is_elite) { + scores.elite_kill_count++; + return; + } + const monType = HeroInfo[attrs.hero_uuid]?.monType ?? MonType.Melee; + if (monType === MonType.Melee || monType === MonType.Heavy || monType === MonType.Assassin) { + scores.melee_kill_count++; + } else { + scores.remote_kill_count++; + } + } + /** * 延迟执行英雄死亡逻辑 * diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 0304ff84..98c5d5ac 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -125,6 +125,8 @@ export class HeroAttrsComp extends ecs.Comp { is_atking: boolean = false; // 是否正在攻击 is_stop: boolean = false; // 是否正在停止 is_boss: boolean = false; + /** 是否精英怪(刷怪时由 MissionMonComp 写入,驱动精英击杀统计) */ + is_elite: boolean = false; is_big_boss: boolean = false; is_master: boolean = false; is_friend: boolean = false; diff --git a/assets/script/game/map/MissionMonComp.ts b/assets/script/game/map/MissionMonComp.ts index f8cd6be3..e0e5fdab 100644 --- a/assets/script/game/map/MissionMonComp.ts +++ b/assets/script/game/map/MissionMonComp.ts @@ -240,6 +240,8 @@ export class MissionMonCompComp extends CCComp { model.ap = monData.ap; model.hp_max = monData.hp; model.hp = model.hp_max; + // 精英标记:对象池复用实体需显式重置(Boss 与精英互斥,Boss 走 is_boss) + model.is_elite = !monData.isBoss && !!monData.isElite; } this.sectionSpawnedCount++;