rp_11009/assets/Game/Scripts/SlotScene.ts
2026-05-15 15:29:37 +08:00

988 lines
33 KiB
TypeScript

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 } 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<any> = null;
UILayer: Node = null;
autoSpinConfig: any = {
count: 0,
delay: {
fast: 0.5,
normal: 1,
},
};
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");
// 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 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.isFreeSpin ? this.spinData.RoundInfo.Score : this.spinData.AllScore;
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,
null,
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);
}
async spinWithRetry(bet: number, maxTry: number = 5, initialDelay: number = 0.5): Promise<any> {
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<void>((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<any> {
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<void>((resolve) =>
this.scheduleOnce(() => resolve(), delay)
);
delay = Math.min(delay * 2, 2);
}
}
throw new Error("retry_exhausted");
}
}