import { Vec3 } from 'cc'; import { schedulePresentation } from '../../battle/skill/BattlePresentationClock'; import { BattleBuffCarryStore } from '../../manager/battleBuff/BattleBuffCarryStore'; import { rollCarriedKillPeachBonus } from '../../manager/battleBuff/BattleBuffPassiveSkillUtil'; import type { EntityId } from 'db://assets/mx/module/battle'; import type { CocosBagBoardView } from '../../battle/view/CocosBagBoardView'; import type { ProjectBattleHandle } from '../../battle/runtime/BattleRuntime'; import type { BattlePeachCoinFlyPresenter } from './BattlePeachCoinFlyPresenter'; /** * 武财神(functiontype=25):本机击杀小怪概率额外蟠桃(飞币表现)。 * AI 侧额外桃在 BattleRuntime 直接入账,不走本 Presenter。 */ export class BattleGameKillPeachPresenter { private _battle: ProjectBattleHandle | null = null; private _bagView: CocosBagBoardView | null = null; private _peachFly: BattlePeachCoinFlyPresenter | null = null; private _resolveDeathWorldPos: ((victim: EntityId) => Vec3 | null) | null = null; /** 并行倒计时世代(unbind 时递增以作废待触发回调) */ private _scheduleGen = 0; /** 绑定战斗、背包与死亡坐标解析 */ bind( battle: ProjectBattleHandle | null, bagView: CocosBagBoardView | null, peachFly: BattlePeachCoinFlyPresenter | null, resolveDeathWorldPos: (victim: EntityId) => Vec3 | null, ): void { this.unbind(); this._battle = battle; this._bagView = bagView; this._peachFly = peachFly; this._resolveDeathWorldPos = resolveDeathWorldPos; } /** 注销并中断进行中的演出 */ unbind(): void { this._scheduleGen++; this._battle = null; this._bagView = null; this._peachFly = null; this._resolveDeathWorldPos = null; } /** * 击杀回调:仅本机归属时掷骰;小怪且概率成功时逐枚产桃。 * @param killer 击杀者 * @param victim 死亡实体 */ onEntityKilled(killer: EntityId, victim: EntityId): void { const battle = this._battle; const bagView = this._bagView; const peachFly = this._peachFly; const resolvePos = this._resolveDeathWorldPos; if (!battle || !bagView || !peachFly || !resolvePos) return; if (!battle.isSmallMonsterVictim(victim)) return; const ownerId = battle.resolveKillPeachOwnerPlayerId(killer, victim); if (ownerId !== battle.localPlayerId) return; const peachCount = rollCarriedKillPeachBonus(BattleBuffCarryStore.getPassives(ownerId)); if (peachCount <= 0) return; const startWorld = resolvePos(victim); if (!startWorld) { console.log('[KillPeach] 击杀额外蟠桃无死亡坐标', victim); return; } this._playBonusPeachSequence(startWorld, peachCount); } /** 死亡点逐枚弹出 coinFly;枚间间隔 = 本次枚数(秒) */ private _playBonusPeachSequence(startWorld: Readonly, peachCount: number): void { const bagView = this._bagView; const peachFly = this._peachFly; if (!bagView || !peachFly) return; const intervalSec = peachCount; const scheduleGen = ++this._scheduleGen; for (let i = 0; i < peachCount; i++) { const delay = i * intervalSec; schedulePresentation(delay, () => { if (scheduleGen !== this._scheduleGen) return; peachFly.playKillDrop(startWorld, 1); bagView.grantBattlePeach(1); }); } } }