import { ChapterNewPlayTypeEnum, ICharmProperty } from '../../../game/ChapterPlayTypes'; import { cloneCharmConfig } from '../MechanismConfigClone'; import type { IBattleMechanism, MechanismContext } from '../IBattleMechanism'; import { isCombatPhase, pickRandomCharmTargets, pickRandomDigGrid, playFoxSpiritCharmVisual, } from '../MechanismServices'; /** 狐狸精魅惑机制(Playmode 21) */ export class CharmMechanism implements IBattleMechanism { readonly typeId = ChapterNewPlayTypeEnum.Charm; private _ctx: MechanismContext | null = null; private _config: ICharmProperty | null = null; private _eventIndex = 0; private _checkTimer = 0; private _visualPending = 0; init(ctx: MechanismContext, config: unknown): void { this._ctx = ctx; this._config = cloneCharmConfig(config as ICharmProperty); this._eventIndex = 0; this._checkTimer = 0; this._visualPending = 0; const cfg = this._config; if (!cfg?.timeArr?.length) { console.error('[CharmMechanism] 配表 timeArr 为空,机制不会触发'); return; } } tick(dt: number): void { if (!this._ctx || !this._config || !isCombatPhase(this._ctx)) return; if (this._visualPending > 0) return; this._checkTimer += dt; if (this._checkTimer < 1) return; this._checkTimer = 0; this._tryTriggerDueEvents(); } destroy(): void { this._visualPending = 0; this._ctx = null; this._config = null; this._eventIndex = 0; } private _tryTriggerDueEvents(): void { const ctx = this._ctx; const cfg = this._config; if (!ctx || !cfg) return; while (this._eventIndex < cfg.timeArr.length && ctx.battleTime >= cfg.timeArr[this._eventIndex]) { if (!this._tryTriggerOnce()) break; this._eventIndex++; break; } } private _tryTriggerOnce(): boolean { const ctx = this._ctx; const cfg = this._config; if (!ctx || !cfg) return false; const wave = this._eventIndex; const targetCount = cfg.numArr[wave] ?? 1; const rawDuration = cfg.durationArr[wave]; const durationSec = (typeof rawDuration === 'number' && Number.isFinite(rawDuration) && rawDuration > 0) ? rawDuration : 2; const exclude = ctx.runtime.charmController.getCharmedComposeKeys(); const targets = pickRandomCharmTargets(ctx, targetCount, exclude); if (targets.length === 0) { console.log( '[CharmMechanism] 无可用魅惑目标(需地图上有已激活攻击的武器/英雄),event=', wave, 'battleTime=', ctx.battleTime, 'deployed=', ctx.runtime.getPlayer(0)?.deployedUnits.length ?? 0, ); return false; } let pending = 0; for (const target of targets) { const appearGrid = pickRandomDigGrid(ctx); if (!appearGrid) { console.log('[CharmMechanism] 无可开挖出现落点,target=', target.composeKey); continue; } const ok = playFoxSpiritCharmVisual( ctx, appearGrid, target, durationSec, ctx.runtime.charmController, () => this._onVisualComplete(), ); if (ok) pending++; } if (pending <= 0) return false; this._visualPending = pending; return true; } private _onVisualComplete(): void { if (this._visualPending <= 0) return; this._visualPending--; } }