import { _decorator, Component, Node } from "cc"; import { SlotGame } from "./SlotGame"; import { SlotBar } from "./SlotBar"; import { GAME_DATA, SLOT_BAR_EVENT, SLOT_GAME_EVENT, SYS_GIFT, WIN_TYPE, } from "./Define"; import { SlotMsg } from "./SlotMsg"; import { GameDataManager } from "../../Main/Scripts/managers/GameDataManager"; import { callGameApi, callGameBalanceApi, getGameId } from "../../Main/Scripts/main/comm"; import { I18nManager } from "../../Main/Scripts/managers/I18nManager"; import { UIManager } from "../../Main/Scripts/managers/UIManager"; import { NodePoolManager } from "../../Main/Scripts/managers/NodePoolManager"; import { FreeSpinEnterSpine } from "./FreeSpinEnterSpine"; import { TotalWinSpine } from "./TotalWinSpine"; import { AudioManager } from "../../Main/Scripts/managers/AudioManager"; import { BigWin } from "./BigWin"; import { FreeSpinAgain } from "./FreeSpinAgain"; import { SysGift } from "./SysGift"; import { ErrorManager } from "../../Main/Scripts/managers/ErrorManager"; import { SlotRanking } from "../SlotRanking/scripts/SlotRanking"; import { ChooseDiff } from "./ChooseDiff"; const { ccclass, property } = _decorator; @ccclass("SlotScene") export class SlotScene extends Component { @property(SlotGame) slotGame: SlotGame = null; @property(SlotMsg) slotMsg: SlotMsg = null; @property(SlotBar) slotBar: SlotBar = null; @property(SysGift) sysGift: SysGift = null; @property(SlotRanking) slotRanking: SlotRanking = null; isDebug: boolean = false; isFreeSpin: boolean = false; isFirstFreeSpin: boolean = false; isFeatureBuySpin: boolean = false; isDoubleWin: boolean = false; isFastSpin: boolean = false; isAutoSpin: boolean = false; isReceiveMsg: boolean = false; isOneRoundEnd: boolean = false; isPreviewSpin: boolean = false; hasEliminate: boolean = false; isErr = false; gameInfo: any = null; spinInfo: any = null; lastSpinInfo: any = null; nextSpinInfo: any = null; spinData: any = null; nextSpinInfoPromise: Promise = null; UILayer: Node = null; autoSpinConfig: any = { count: 0, delay: { fast: 0, normal: 0, }, }; deltedRetryCount: number = 0; protected onLoad(): void { this.UILayer = this.node.parent.parent.getChildByName("UILayer"); UIManager.instance.setUILayer(this.UILayer); this.gameInfo = GameDataManager.instance.gameInfo; this.spinInfo = GameDataManager.instance.gameInfo; this.lastSpinInfo = GameDataManager.instance.gameInfo; this.nextSpinInfo = null; this.spinData = GameDataManager.instance.gameInfo.Data; this.slotGame.rollerManager.format = true; this.slotGame.setFeatureBuyActive(!this.gameInfo.CloseBuyGame); this.slotRanking.setSlotScene(this); this.slotBar.node.on(SLOT_BAR_EVENT.ON_SPIN_CLICK, this.onClickSpin, this); this.slotBar.node.on(SLOT_BAR_EVENT.ON_MANUAL_STOP, this.onClickManualStop, this); this.slotBar.node.on(SLOT_BAR_EVENT.FAST_SPIN, this.onClickFastSpin, this); this.slotBar.node.on(SLOT_BAR_EVENT.BET_CHANGE, this.onBetChange, this); this.slotBar.node.on(SLOT_BAR_EVENT.MAX_BET, this.onMaxBet, this); this.slotBar.node.on(SLOT_BAR_EVENT.MIN_BET, this.onMinBet, this); this.slotBar.node.on(SLOT_BAR_EVENT.OPEN_MENU, this.onOpenMenu, this); this.slotBar.node.on(SLOT_BAR_EVENT.CLOSE_MENU, this.onCloseMenu, this); this.slotBar.node.on(SLOT_BAR_EVENT.ON_AUTO_SPIN_CLICK, this.onAutoSpin, this); this.sysGift.node.on(SYS_GIFT.CLICK_CONTINUE, this.onSysGiftClickContinue, this); this.sysGift.node.on(SYS_GIFT.SETTLE_CONTINUE, this.onSysGiftSettleContinue, this); this.slotGame.node.on(SLOT_GAME_EVENT.ALL_ROLLER_STOP, this.allRollerStop, this); this.slotGame.node.on(SLOT_GAME_EVENT.ALL_ROLLER_ICONS_DELETED, this.onAllRollerIconsDeleted, this); this.slotGame.node.on(SLOT_GAME_EVENT.ALL_ROLLER_ICONS_CREATED, this.onAllRollerIconsCreated, this); this.slotGame.node.on(SLOT_GAME_EVENT.ALL_ROLLER_ICONS_FALLEN, this.onAllRollerIconsFallen, this); this.slotGame.node.on(SLOT_GAME_EVENT.FEATURE_BUY, this.onFeatureBuy, this); this.slotGame.node.on(SLOT_GAME_EVENT.ON_DOUBLE_WIN_CLICK, this.onClickDoubleWin, this); } async start() { if (this.isDebug) { this.slotGame.initRollerWithIcon(GAME_DATA); } else { this.slotGame.initRollerWithIcon(this.spinData); } GameDataManager.instance.canClickIconMsg = false; this.slotBar.setGameInfo(this.gameInfo); this.slotGame.updateDiffBg(); this.slotMsg.showLabelMsgForTween(); this.updateGameState(); this.isFreeSpin = this.spinData.FreeSpin != null && this.spinData && this.spinData.FreeSpin && this.spinData.FreeSpin.LeftCount > 0; if (this.isFreeSpin) { this.slotBar.setLeftCount(this.spinData.FreeSpin.LeftCount); } this.slotBar.updateIsFreeSpin(this.isFreeSpin); if (!this.gameInfo.CloseBuyGame) { this.slotGame.setFeatureBuyActive(!(this.slotBar.getBet() * this.gameInfo.BuyMul > this.gameInfo.MaxBuyBet)); } this.slotGame.setCurBet(this.slotBar.getBet()) this.updateBg(this.isFreeSpin, true); let frb = GameDataManager.instance.frb; if (frb && frb.Ongoing?.Popup) { let frb = GameDataManager.instance.frb; if (frb && (frb.Finished || frb.Ongoing)) { this.slotBar.setSystemGiftContinue(); } this.sysGift.showOngingPopup(); } else { this.handleReconnect(); } this.isFreeSpin ? AudioManager.instance.playBGM("Free_Bg_Bgm") : AudioManager.instance.playBGM("Normal_Bg_Bgm"); if (!localStorage.getItem('HasGamePending')) this.openFirstChooseDiff(); // let score = 1000000 // let winType = this.checkWinType(score) // NodePoolManager.instance.getNodeFromPoolDynamic("BigWin", "Prefab/BigWin", "Game").then((prefab: Node) => { // this.node.addChild(prefab); // prefab.getComponent(BigWin).open(winType, score, this.slotBar.getBet(), null, this.isFreeSpin); // }); // NodePoolManager.instance.getNodeFromPoolDynamic("TotalWinSpine", "Prefab/TotalWinSpine", "Game").then((prefab: Node) => { // this.node.addChild(prefab); // prefab.getComponent(TotalWinSpine).showTotalWinSpine(score, () => { // AudioManager.instance.playBGM("Free_Bg_Bgm"); // NodePoolManager.instance.putNodeToPool("FreeSpinEnter", prefab); // }) // }); // NodePoolManager.instance.getNodeFromPoolDynamic("FreeSpinEnter", "Prefab/FreeSpinEnter", "Game").then((prefab: Node) => { // this.node.addChild(prefab); // let freeCount = 15; // prefab.getComponent(FreeSpinEnterSpine).showEnterAni(freeCount, () => { // AudioManager.instance.playBGM("Normal_Bg_Bgm"); // NodePoolManager.instance.putNodeToPool("FreeSpinEnter", prefab); // }); // }); } updateBg(isFreeSpin: boolean, isReconnect: boolean) { if (isReconnect) { if (this.isFirstFreeSpin) return; this.slotGame.updateGameBg(isFreeSpin); } else { this.slotGame.updateGameBg(isFreeSpin); } } async handleReconnect() { this.slotMsg.setTotaleMultiAndMultiMergeTime(this.spinData.WinMultiPlier) if (this.hasEliminate) { this.slotBar.manualStop(this.hasEliminate); this.slotGame.playIconWinAni(this.spinData, this.isFreeSpin); this.slotMsg.showRoundWinMsg(this.spinData.RoundInfo.AllScore); this.slotBar.updateWinMsg(this.spinData.AllScore, true); if (this.isDebug) { this.nextSpinInfo = GAME_DATA; } else { this.nextSpinInfoPromise = this.spinWithRetry(this.slotBar.getBet()); } } else { this.handleRoundEnd(true); } } onClickDoubleWin(doubleWinIsOn: boolean) { this.isDoubleWin = doubleWinIsOn; let bet = this.slotBar.getBet(); let displayBet = doubleWinIsOn ? bet * 1.25 : bet; this.slotBar.setDisplayBet(displayBet); } async onClickSpin(buyType: number = 0, changeDiff: boolean = false, isNewSpin: boolean) { GameDataManager.instance.canClickIconMsg = false; this.nextSpinInfo = null; this.nextSpinInfoPromise = null; this.isReceiveMsg = false; this.isOneRoundEnd = false; this.isErr = false; this.slotGame.startScroll(this.isFreeSpin); // 重置 this.slotMsg.hideWinSpine(); if (isNewSpin) { this.slotMsg.setTotaleMultiAndMultiMergeTime(0) } if (!this.isFreeSpin) { this.slotBar.setWin(0); } let curBalanceData = await callGameBalanceApi({ GameId: getGameId() }) let curBalance = curBalanceData.Balance if (curBalance < (buyType == 1 ? this.slotBar.getBet() * this.gameInfo.BuyMul : (this.isDoubleWin ? this.slotBar.getdisplayBet() : this.slotBar.getBet())) && !this.isFreeSpin && !this.spinInfo.Frb.Ongoing) { //余额不足不经过服务器,在客户端拦截 this.showErrorTip(2, "", () => { this.slotBar.onConfirmErr2() }); this.handleErrSpin(); return } let msg = !this.isFeatureBuySpin && buyType == 0 ? { Bet: this.slotBar.getBet(), IsDouble: this.isDoubleWin, } : { Bet: this.slotBar.getBet(), IsBuy: true, BuyType: buyType, IsDouble: this.isDoubleWin, }; try { if (changeDiff) { let gameinfo = await callGameApi("gameinfo", {}); GameDataManager.instance.gameInfo = gameinfo; this.spinInfo = gameinfo; } else { this.spinInfo = !this.isDebug ? await this.spinWithRetryMsg(msg) : GAME_DATA; this.subBalacne(buyType); } this.handleSpinResult(); this.slotGame.stopScroll(this.spinData); } catch (error) { this.isErr = true; let errCode = parseInt(error.message.split("#")[0]); if (isNaN(errCode)) { ErrorManager.instance.reportError("onClickSpin: " + error.message); this.showErrorTip(5, error.message, null); this.handleErrSpin(); } else { this.showErrorTip(errCode, ""); this.handleErrSpin(); } } } async onClickManualStop() { if (!this.isReceiveMsg) return; if (this.isFreeSpin) return; if (!this.slotGame.isScroll()) return; this.slotBar.manualStop(true); } onClickFastSpin(isFast: boolean) { this.isFastSpin = isFast; let tip = isFast ? I18nManager.instance.t("AID_TIP_TURBO_ENABLED") : I18nManager.instance.t("AID_TIP_TURBO_DISABLED"); this.slotMsg.showTipSmall(tip, isFast ? "onFast" : "offFast"); if (!this.slotGame.isScroll()) this.slotGame.setFastSpin(isFast); } onBetChange(bet: number) { if (!this.gameInfo.CloseBuyGame) { this.slotGame.setFeatureBuyActive( !(bet * this.gameInfo.BuyMul > this.gameInfo.MaxBuyBet) ); } if (this.isDoubleWin) { this.slotBar.setDisplayBet(bet * 1.25); } this.slotGame.refreshDoubleWinCount(); this.slotGame.setCurBet(this.slotBar.getBet()) this.slotGame.updateDoubleWinNeedCount() } onMaxBet() { let tip = I18nManager.instance.t("AID_TIP_MAX_BET"); this.slotMsg.showTipSmall(tip); } onMinBet() { let tip = I18nManager.instance.t("AID_TIP_MIN_BET"); this.slotMsg.showTipSmall(tip); } onOpenMenu() { this.slotGame.hideFeatureBuy(); this.slotGame.setDoubleWinBtnEnable(false); } onCloseMenu() { this.slotGame.setDoubleWinBtnEnable(true); if (this.gameInfo.CloseBuyGame) return; this.slotGame.showFeatureBuy(false); } onAutoSpin(isAutoSpin: boolean) { this.isAutoSpin = isAutoSpin; this.autoSpinConfig.count = GameDataManager.instance.autoCount; if (isAutoSpin) { this.slotGame.setFeatureBuyBtnEnable(false); this.checkAutoSpin(); } else { if (!this.slotGame.rollerManager.isScroll()) { } } } onSysGiftClickContinue(bet: number) { let frb = GameDataManager.instance.frb; if (frb && frb.Ongoing) { frb.Ongoing.Popup = false; } this.handleReconnect(); this.slotBar.setSysGiftBet(bet * 10000); } onSysGiftSettleContinue() { let frb = GameDataManager.instance.frb; if (frb && frb.Finished) { frb.Finished.Popup = false; } GameDataManager.instance.frb.Finished = null; this.slotBar.setSystemGiftConfirm(); this.slotGame.setFeatureBuyBtnEnable(true); this.slotBar.resetAllBtn(); } checkAutoSpin(hasWin: boolean = false) { let handleAutoSpin = () => { if (this.autoSpinConfig.count > 0) { this.autoSpinConfig.count--; this.slotBar.setLeftAutoCount(this.autoSpinConfig.count); this.slotBar.hasClickSpin = false; this.slotBar.hasClickManualStop = false; this.onClickSpin(0, false, true); if (this.autoSpinConfig.count === 0) { this.slotBar.closeAutoSpin(); } } }; let handleNoAutoSpin = (hasWin: boolean) => { let frb = GameDataManager.instance.frb; if (frb.Finished?.Popup) { this.sysGift.showSysFreeWinSettle(); } if (frb.Ongoing?.Popup) { this.sysGift.showOngingPopup(); } if (frb.Finished == null && frb.Ongoing?.Popup == false) { this.slotBar.resetAllBtn(); if (frb && (frb.Finished || frb.Ongoing)) { this.slotBar.setSystemGiftContinue(); this.sysGift.handleSysInfoFreeWin(); } } if (frb.Finished == null && frb.Ongoing == null) { this.slotBar.resetAllBtn(); } if (frb.Ongoing?.Popup) { this.slotBar.resetAllBtn(); this.slotBar.setSystemGiftContinue(); } this.autoSpinConfig.count = 0; }; if (this.isFirstFreeSpin) return; let delay = this.isFastSpin ? this.autoSpinConfig.delay.fast : this.autoSpinConfig.delay.normal; if (this.isAutoSpin && this.autoSpinConfig.count > 0) { this.scheduleOnce(() => { handleAutoSpin(); }, delay); } else { handleNoAutoSpin(hasWin); } } onFeatureBuy() { this.isFeatureBuySpin = true; this.slotBar.featureBuySpin(); this.onClickSpin(1, false, true); } async allRollerStop() { if (this.isPreviewSpin) { this.isPreviewSpin = false; // 停止按钮状态 this.slotBar.manualStop(false); // 清理表现 this.slotMsg.hideWinSpine(); this.slotBar.setWin(0); this.slotBar.updateWinMsg(0, true); this.handlePreviewUIEnd(); return; } this.updateGameState(); this.slotBar.manualStop(this.hasEliminate); if (this.hasEliminate) this.slotBar.spinBtnSpineEliminate(); // 如果本次有消除,则进行删除工作。 if (this.hasEliminate) { this.slotGame.playIconWinAni(this.spinData, this.isFreeSpin); this.slotMsg.showRoundWinMsg(this.spinData.RoundInfo.AllScore); this.slotBar.updateWinMsg(this.spinData.AllScore, false); if (this.isDebug) { this.nextSpinInfo = GAME_DATA; } else { this.nextSpinInfoPromise = this.spinWithRetry(this.slotBar.getBet()); } } else { this.handleRoundEnd(); } } async onAllRollerIconsDeleted() { this.isReceiveMsg = false; this.isErr = false; if (this.nextSpinInfo == null) { if (this.isDebug) { this.nextSpinInfo = GAME_DATA; } else { try { this.nextSpinInfo = await this.nextSpinInfoPromise; } catch (error) { this.isErr = true; let errCode = parseInt(error.message.split("#")[0]); if (isNaN(errCode)) { ErrorManager.instance.reportError( "onIconsDeleted: " + error.message ); this.nextSpinInfo = null; this.nextSpinInfoPromise = null; this.showErrorTip(5, error.message, null); this.handleErrSpin(); } else { this.showErrorTip(errCode, ""); this.handleErrSpin(); } return; } } } this.spinInfo = this.nextSpinInfo; this.nextSpinInfo = null; this.nextSpinInfoPromise = null; this.handleSpinResult(); this.updateGameState(); this.slotGame.createNewIconTop(this.spinData); } onAllRollerIconsCreated() { this.slotGame.IconFallDown(); } async onAllRollerIconsFallen() { if (this.hasEliminate) { this.slotGame.playIconWinAni(this.spinData, this.isFreeSpin); this.slotMsg.showRoundWinMsg(this.spinData.RoundInfo.AllScore); this.slotBar.updateWinMsg(this.spinData.AllScore, false); if (this.isDebug) { this.nextSpinInfo = GAME_DATA; } else { this.nextSpinInfoPromise = this.spinWithRetry(this.slotBar.getBet()); } } else { this.handleRoundEnd(); } } // 处理了这次的数据结果 handleSpinResult() { this.lastSpinInfo = this.spinInfo; this.spinData = this.spinInfo.Data; // this.spinData.AllScore = 7000000000; this.isReceiveMsg = true; if (this.spinInfo.Frb.Ongoing && this.isAutoSpin) this.slotBar.closeAutoSpin(); if (!this.isDebug) GameDataManager.instance.frb = this.spinInfo.Frb; } // 处理当前游戏状态 updateGameState() { this.isFeatureBuySpin = false; this.isFirstFreeSpin = false; this.slotGame.setFastSpin(this.isFastSpin); this.isFreeSpin = this.spinData.FreeSpin != null; if (this.isFreeSpin) { this.slotBar.curFreeSpinScore = 0; this.isFirstFreeSpin = this.spinData.FreeSpin.LeftCount == this.spinData.FreeSpin.MaxCount; } this.hasEliminate = this.spinData.RoundInfo?.Current !== this.spinData.RoundInfo?.Total; } // 处理当前小局结束 handleRoundEnd(isReconnect: boolean = false) { if (this.isFreeSpin) { if (this.isFirstFreeSpin) { // 进入免费前,先给 2 秒展示 scatter 动画并更新信息栏 this.slotBar.updatePlayerMsg(this.spinData, false, null); this.slotGame.upLayer.playScatterWaitSpine(true); AudioManager.instance.playSFX('Wait_Free_Game') this.scheduleOnce(() => { AudioManager.instance.stopSFX('Wait_Free_Game') this.slotGame.upLayer.playScatterWaitSpine(false); this.scheduleOnce(() => { this.updateBg(true, false); this.slotBar.updateIsFreeSpin(true); this.slotBar.setLeftCount(this.spinData.FreeSpin.MaxCount); }, 1) NodePoolManager.instance.getNodeFromPoolDynamic("FreeSpinEnter", "Prefab/FreeSpinEnter", "Game").then((prefab: Node) => { this.node.addChild(prefab); let freeCount = this.spinData.FreeSpin.MaxCount; prefab.getComponent(FreeSpinEnterSpine).showEnterAni(freeCount, () => { AudioManager.instance.playBGM("Free_Bg_Bgm"); AudioManager.instance.playSFX("Free_First_Entry"); NodePoolManager.instance.putNodeToPool("FreeSpinEnter", prefab); this.scheduleOnce(() => { this.handleNextFreeSpin(this.spinData.FreeSpin.LeftCount - 1); }, 1); }); }); }, 2); } else { if (!isReconnect) { this.handleFreeSpinRoundWinMsg(() => { this.handleBigWin(() => { this.handleFreeSpinAgain(() => { this.slotBar.setLeftCount(this.spinData.FreeSpin.LeftCount); if (this.isErr) { this.updateBg(false, false); if ( !this.isAutoSpin && GameDataManager.instance.frb.Finished == null && GameDataManager.instance.frb.Ongoing == null ) { this.slotGame.setFeatureBuyBtnEnable(true); } this.slotBar.updateIsFreeSpin(false); this.checkAutoSpin(this.spinData.AllScore > 0); AudioManager.instance.playBGM("Normal_Bg_Bgm"); return; } if (this.spinData.FreeSpin.LeftCount == 0 && (this.spinData.RoundInfo == null || this.spinData.RoundInfo.Current == this.spinData.RoundInfo.Total)) { this.isFreeSpin = false; let startScore = 0; this.scheduleOnce(() => { this.slotMsg.showTotalWinAnimaiton(startScore, this.spinData.AllScore, () => { NodePoolManager.instance.getNodeFromPoolDynamic("TotalWinSpine", "Prefab/TotalWinSpine", "Game").then((prefab: Node) => { this.node.addChild(prefab); prefab.getComponent(TotalWinSpine).showTotalWinSpine(this.spinData.AllScore, () => { this.slotBar.updatePlayerMsg(this.spinData, false, null); this.updateBg(false, false); if (!this.isAutoSpin && GameDataManager.instance.frb.Finished == null && GameDataManager.instance.frb.Ongoing == null) { this.slotGame.setFeatureBuyBtnEnable(true); } this.slotBar.updateIsFreeSpin(false); this.checkAutoSpin(this.spinData.AllScore > 0); AudioManager.instance.playBGM("Normal_Bg_Bgm"); NodePoolManager.instance.putNodeToPool("TotalWinSpine", prefab); }); }); }); }, 1); } else { this.scheduleOnce(() => { this.handleNextFreeSpin(this.spinData.FreeSpin.LeftCount - 1); }, 1); } }); }); }) } else { if (this.spinData.FreeSpin.LeftCount == 0 && (this.spinData.RoundInfo == null || this.spinData.RoundInfo.Current == this.spinData.RoundInfo.Total)) { this.isFreeSpin = false; // if (this.spinData.RoundInfo && this.spinData.RoundInfo.Mul == 1) { this.slotMsg.showTotalWinMsg(this.spinData.AllScore); // } this.slotBar.updatePlayerMsg(this.spinData, isReconnect, () => { this.updateBg(false, false); this.slotBar.updateIsFreeSpin(false); this.slotBar.resetAllBtn(); if ( GameDataManager.instance.frb.Finished != null || GameDataManager.instance.frb.Ongoing != null ) { this.slotBar.setSystemGiftContinue(); this.slotGame.setFeatureBuyBtnEnable(false); } else { this.slotGame.setFeatureBuyBtnEnable(true); } }); } else { this.slotBar.updateWinMsg(this.spinData.AllScore, isReconnect); this.scheduleOnce(() => { this.handleNextFreeSpin(this.spinData.FreeSpin.LeftCount - 1); }, 1); } } } } else { if (isReconnect) { this.slotBar.updatePlayerMsg(this.spinData, isReconnect, () => { this.updateBg(false, true); this.slotBar.updateIsFreeSpin(false); this.slotBar.resetAllBtn(); if (GameDataManager.instance.frb.Finished != null || GameDataManager.instance.frb.Ongoing != null) { this.slotBar.setSystemGiftContinue(); this.slotGame.setFeatureBuyBtnEnable(false); } else { this.slotGame.setFeatureBuyBtnEnable(true); } this.slotMsg.showTotalWinMsg(this.spinData.AllScore); }); } else { if (this.spinData.RoundInfo && this.spinData.RoundInfo.Mul !== 1) { this.slotMsg.showMultiWinAnimation(this.spinData, () => { this.slotMsg.showTotalWinMsg(this.spinData.AllScore); this.handleBigWin(() => { this.slotBar.updatePlayerMsg(this.spinData, false, () => { this.updateBg(false, false); if ( !this.isAutoSpin && GameDataManager.instance.frb.Finished == null && GameDataManager.instance.frb.Ongoing == null ) { this.slotGame.setFeatureBuyBtnEnable(true); } this.slotBar.updateIsFreeSpin(false); this.checkAutoSpin(this.spinData.AllScore > 0); }); }); }); } else { this.slotMsg.showTotalWinMsg(this.spinData.AllScore); this.handleBigWin(() => { this.slotBar.updatePlayerMsg(this.spinData, false, () => { this.updateBg(false, false); if ( !this.isAutoSpin && GameDataManager.instance.frb.Finished == null && GameDataManager.instance.frb.Ongoing == null ) { this.slotGame.setFeatureBuyBtnEnable(true); } this.slotBar.updateIsFreeSpin(false); this.checkAutoSpin(this.spinData.AllScore > 0); }); }); } } } } handleFreeSpinRoundWinMsg(callBack: () => void) { if (this.spinData.RoundInfo == null) { callBack(); return; } if (this.spinData.RoundInfo.Mul == 1) { this.slotMsg.showTotalWinMsg(this.spinData.RoundInfo.Score); this.slotBar.updateWinMsg(this.spinData.AllScore, false); callBack(); return; } if (this.spinData.RoundInfo.Mul !== 1) { // this.slotMsg.showTotalWinMsg(this.spinData.RoundInfo.AllScoreMul); this.slotMsg.showMultiWinAnimation(this.spinData, callBack); return; } } handleBigWin(callBack: () => void) { if (this.spinData.RoundInfo == null) { callBack(); return } let score = this.spinData.Score; let winType = score ? this.checkWinType(score) : WIN_TYPE.NONE; if (winType >= WIN_TYPE.BIG_WIN) { NodePoolManager.instance.getNodeFromPoolDynamic("BigWin", "Prefab/BigWin", "Game").then((prefab: Node) => { this.node.addChild(prefab); prefab.getComponent(BigWin).open(winType, score, this.slotBar.getBet(), callBack, this.isFreeSpin); }); } else { callBack(); } } handleFreeSpinAgain(callBack: () => void) { if (!this.slotGame.parsedData.hasFreeSpinAgain) { callBack(); return; } NodePoolManager.instance.getNodeFromPoolDynamic("FreeSpinAgain", "Prefab/FreeSpinAgain", "Game").then((prefab: Node) => { this.node.addChild(prefab); prefab.getComponent(FreeSpinAgain).showAgain(callBack); }); } checkWinType(score: number) { let winType = WIN_TYPE.NORMAL_WIN; let bet = this.slotBar.getBet(); let multi = score / bet; if (multi == 0) { winType = WIN_TYPE.NONE; } else if (multi > 0 && multi < 20) { winType = WIN_TYPE.NORMAL_WIN; } else if (multi >= 20 && multi < 35) { winType = WIN_TYPE.BIG_WIN; } else if (multi >= 35 && multi < 50) { winType = WIN_TYPE.MEGA_WIN; } else if (multi >= 50) { winType = WIN_TYPE.SUPER_MEGA_WIN; } return winType; } handleNextFreeSpin(leftCount: number) { this.isFreeSpin = true; this.slotBar.setLeftCount(leftCount); this.onClickSpin(0, false, false); this.slotBar.node.getChildByName("stopBtn").active = true; } /** 扣除金币,如果是购买需要控制buyType */ subBalacne(buyType: number = 0) { let frb = GameDataManager.instance.frb; if (this.spinInfo.Frb && this.spinInfo.Frb.Ongoing != null) { if (!this.isFreeSpin) { let count = this.spinInfo.Frb.Ongoing.Frn; if (count <= 0) { count = 0; } this.sysGift.handleSysInfoFreeCount(count); } } else if (this.spinInfo.Frb && this.spinInfo.Frb.Finished != null) { if (!this.isFreeSpin) { let count = this.spinInfo.Frb.Finished.Frn; if (count <= 0) { count = 0; } this.sysGift.handleSysInfoFreeCount(count); } } else { if (!this.isFreeSpin) { if (!this.isFeatureBuySpin) { let spinCost = this.isDoubleWin ? this.slotBar.getBet() * 1.25 : this.slotBar.getBet(); this.slotBar.setBalance(this.slotBar.getBalance() - spinCost); } else { // if (buyType == 1) { this.slotBar.setBalance(this.slotBar.getBalance() - this.slotBar.getBet() * this.gameInfo.BuyMul) // } else { // this.slotBar.setBalance(this.slotBar.getBalance() - this.slotBar.getBet() * 500) // } } } } } onBtnChooseDiff() { AudioManager.instance.playSFX("Click_Menu"); NodePoolManager.instance.getNodeFromPoolDynamic("ChooseDiff", "Prefab/ChooseDiff", "Game").then((prefab: Node) => { this.node.addChild(prefab); prefab.getComponent(ChooseDiff).open(GameDataManager.instance.chooseDiff, async () => { let gameinfo = await callGameApi('gameinfo', {}); GameDataManager.instance.gameInfo = gameinfo; this.spinInfo = gameinfo; this.spinData = gameinfo.Data; this.resetStateForPreview(); this.isPreviewSpin = true; this.slotGame.startScroll(false); this.handleSpinResult(); this.slotGame.stopScroll(this.spinData); this.slotBar.setGameInfo(gameinfo); this.slotGame.updateDiffBg(true); }, () => { this.slotBar.updateChooseDiff(); }); }); } resetStateForPreview() { this.isFreeSpin = false; this.isFirstFreeSpin = false; this.isFeatureBuySpin = false; this.isDoubleWin = false; this.isAutoSpin = false; this.isReceiveMsg = false; this.isOneRoundEnd = false; this.hasEliminate = false; this.isErr = false; this.nextSpinInfo = null; this.nextSpinInfoPromise = null; } handlePreviewUIEnd() { this.checkAutoSpin(false); this.slotBar.resetAllBtn(); if (this.gameInfo.CloseBuyGame) { this.slotGame.setFeatureBuyBtnEnable(false); } else { this.slotGame.setFeatureBuyBtnEnable(true); } this.isAutoSpin = false; this.slotBar.setLeftAutoCount(0); this.slotBar.updateIsFreeSpin(false); } showErrorTip(errcode: number, errMsg: string, callBack?) { let title = I18nManager.instance.t("AID_ERROR_TITLE"); let msg = ""; if (UIManager.instance.getHasTip()) { return; } switch (errcode) { case 1: msg = `${I18nManager.instance.t( "AID_ERROR_CONTENT_1" )}\n${I18nManager.instance.t("AID_ERROR_CODE_1")}`; UIManager.instance.showTipMessagePanel( title, msg, true, () => { window.close(); }, null, I18nManager.instance.t("AID_QUIT_RIGHT_BUTTON") ); break; case 2: msg = `${I18nManager.instance.t( "AID_ERROR_CONTENT_2" )}\n${I18nManager.instance.t("AID_ERROR_CODE_2")}`; UIManager.instance.showTipMessagePanel( title, msg, true, callBack, null, I18nManager.instance.t("AID_ERROR_OK_BUTTON") ); break; case 3: msg = `${I18nManager.instance.t( "AID_ERROR_CONTENT_3" )}\n${I18nManager.instance.t("AID_ERROR_CODE_3")}`; UIManager.instance.showTipMessagePanel( title, msg, true, null, null, I18nManager.instance.t("AID_ERROR_OK_BUTTON") ); break; case 4: msg = `${I18nManager.instance.t( "AID_ERROR_CONTENT_4" )}\n${I18nManager.instance.t("AID_ERROR_CODE_4")}`; UIManager.instance.showTipMessagePanel( title, msg, true, () => { window.close(); }, null, I18nManager.instance.t("AID_QUIT_RIGHT_BUTTON") ); break; case 5: msg = `${I18nManager.instance.t( "AID_ERROR_CONTENT_4" )}\n${I18nManager.instance.t("AID_ERROR_CODE_4")}`; UIManager.instance.showTipMessagePanel( title, msg, false, null, () => { window.close(); }, I18nManager.instance.t("AID_ERROR_RETRY_BUTTON"), I18nManager.instance.t("AID_QUIT_RIGHT_BUTTON") ); break; } } handleErrSpin() { this.spinInfo = this.lastSpinInfo; this.spinData = this.spinInfo.Data; this.isAutoSpin = false; this.spinData.AllScore = 0; this.spinData.SpinScore = 0; this.slotGame.stopScroll(this.spinData); this.slotBar.setBalance(this.spinInfo.Balance); this.slotBar.closeAutoSpin(); } openFirstChooseDiff() { NodePoolManager.instance.getNodeFromPoolDynamic("ChooseDiff", "Prefab/ChooseDiff", "Game").then((prefab: Node) => { this.node.addChild(prefab); prefab.getComponent(ChooseDiff).open(GameDataManager.instance.chooseDiff, async () => { let gameinfo = await callGameApi('gameinfo', {}); GameDataManager.instance.gameInfo = gameinfo; this.spinInfo = gameinfo; this.spinData = gameinfo.Data; this.resetStateForPreview(); this.isPreviewSpin = true; this.slotGame.startScroll(false); this.handleSpinResult(); this.slotGame.stopScroll(this.spinData); this.slotBar.setGameInfo(gameinfo); this.slotGame.updateDiffBg(true); }, () => { this.slotBar.updateChooseDiff(); }, !localStorage.getItem('HasGamePending')); }); } async spinWithRetry(bet: number, maxTry: number = 5, initialDelay: number = 0.5): Promise { let delay = initialDelay; for (let i = 0; i < maxTry; i++) { if (!this.node || !this.node.isValid) throw new Error("node_invalid"); try { return await callGameApi("spin", { Bet: bet }); } catch (e) { let m = (e as any)?.message ?? ""; let code = parseInt(String(m).split("#")[0]); if (!isNaN(code)) throw e; // 已知业务错误码:不重试 if (i === maxTry - 1) throw e; // 到达上限 await new Promise((resolve) => this.scheduleOnce(() => resolve(), delay) ); delay = Math.min(delay * 2, 2); // 指数退避,上限 2s } } throw new Error("retry_exhausted"); } async spinWithRetryMsg(msg: any, maxTry: number = 5, initialDelay: number = 0.5): Promise { let delay = initialDelay; for (let i = 0; i < maxTry; i++) { if (!this.node || !this.node.isValid) throw new Error("node_invalid"); try { return await callGameApi("spin", msg); } catch (e) { let m = (e as any)?.message ?? ""; let code = parseInt(String(m).split("#")[0]); if (!isNaN(code)) throw e; // 已知业务错误码:不重试 if (i === maxTry - 1) throw e; await new Promise((resolve) => this.scheduleOnce(() => resolve(), delay) ); delay = Math.min(delay * 2, 2); } } throw new Error("retry_exhausted"); } }