import '../../../domain/entities/game_entities.dart'; /// وضعیتِ افکتِ «بریدن با حکم»: بالاترین حکمِ دستِ جاری، کمبوِ روبُریدن‌های سریع، /// و «مکثِ آتش» (فریزِ کوتاهِ صحنه پس از آتشِ کمبو). فقط وضعیت و تصمیم را نگه /// می‌دارد؛ افزودنِ کامپوننت‌های افکت و بافرِ وضعیت بر عهده‌ی خودِ صحنه است. class CutFx { static const double comboWindowSec = 6.0; // پنجره‌ی شمارشِ بریدنِ پیاپی static const double holdSec = 1.0; // مدتِ مکثِ آتش int _bestTrumpRank = 0; // بالاترین حکمِ بازی‌شده در دستِ جاری int combo = 0; // شمارِ بریدنِ پیاپیِ سریع (برای شدتِ آتش) double _lastCutAt = -999; bool holding = false; // آیا در «مکثِ آتش» هستیم double _holdUntil = 0; GameState? pending; // آخرین وضعیتِ بافرشده در حینِ مکث /// دستِ جدید (زمین خالی/تک‌کارت) ⇒ بالاترین حکم ریست می‌شود. void resetTrick() => _bestTrumpRank = 0; /// ثبتِ یک بریدن؛ true اگر این حکم «دست را می‌بَرد» (اولین بریدن یا روبُریدنِ /// بالاتر) — در این صورت کمبو هم به‌روزرسانی می‌شود. حکمِ بازنده false می‌دهد. bool registerWinningCut(int rank, double now) { if (rank <= _bestTrumpRank) return false; _bestTrumpRank = rank; combo = (now - _lastCutAt < comboWindowSec) ? combo + 1 : 1; _lastCutAt = now; return true; } /// شروعِ مکثِ آتش (پس از آتشِ کمبو). void startHold(double now) { holding = true; _holdUntil = now + holdSec; } /// آیا مکث به پایان رسیده و باید وضعیتِ بافرشده اعمال شود. bool holdExpired(double now) => holding && now >= _holdUntil; /// لغوِ مکث و پاک‌کردنِ بافر (هنگام خروج از میز). void clearHold() { holding = false; pending = null; } }