All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m17s
1032 lines
34 KiB
TypeScript
1032 lines
34 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, 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<any> = 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.slotBar.getBalance());
|
|
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<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");
|
|
}
|
|
}
|