You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdLike2048/assets/script/ui/BattleGame/BattleGameKillPeachPresente...

90 lines
3.6 KiB

3 weeks ago
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<Vec3>, 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);
});
}
}
}