827 lines
27 KiB
TypeScript
827 lines
27 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";
|
|
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;
|
|
|
|
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.slotMsg.showLabelMsgForTween();
|
|
this.updateGameState();
|
|
this.isFreeSpin = this.spinData.Free != null && this.spinData && this.spinData.Free && this.spinData.Free.LeftCount > 0;
|
|
if (this.isFreeSpin) {
|
|
this.slotBar.setLeftCount(this.spinData.Free.LeftCount);
|
|
}
|
|
this.slotBar.updateIsFreeSpin(this.isFreeSpin);
|
|
if (!this.gameInfo.CloseBuyGame) {
|
|
this.slotGame.setFeatureBuyActive(!(this.slotBar.getBet() * this.gameInfo.BuyMul > this.gameInfo.MaxBuyBet));
|
|
}
|
|
this.updateBg(this.isFreeSpin);
|
|
|
|
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");
|
|
}
|
|
|
|
updateBg(isFreeSpin: boolean) {
|
|
this.slotGame.updateGameBg(isFreeSpin);
|
|
}
|
|
|
|
async handleReconnect() {
|
|
if (this.hasEliminate) {
|
|
this.slotBar.manualStop(this.hasEliminate);
|
|
this.slotGame.playIconWinAni(this.spinData);
|
|
this.slotMsg.showWinMsg(this.spinData.AllScore);
|
|
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) {
|
|
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 (!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 {
|
|
this.spinInfo = !this.isDebug ? await this.spinWithRetryMsg(msg) : GAME_DATA;
|
|
this.subBalacne();
|
|
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();
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
onCloseMenu() {
|
|
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.slotBar.onClickSpin();
|
|
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(buyType: number) {
|
|
this.isFeatureBuySpin = true;
|
|
this.slotBar.featureBuySpin();
|
|
this.onClickSpin(buyType);
|
|
}
|
|
|
|
async allRollerStop() {
|
|
this.updateGameState();
|
|
|
|
this.slotBar.manualStop(this.hasEliminate);
|
|
if (this.hasEliminate) this.slotBar.spinBtnSpineEliminate();
|
|
// 如果本次有消除,则进行删除工作。
|
|
if (this.hasEliminate) {
|
|
this.slotGame.playIconWinAni(this.spinData);
|
|
this.slotMsg.showWinMsg(this.spinData.AllScore);
|
|
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.slotMsg.showWinMsg(this.spinData.AllScore);
|
|
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 = 700000;
|
|
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.Free != null;
|
|
if (this.isFreeSpin) {
|
|
this.slotBar.curFreeSpinScore = 0;
|
|
this.isFirstFreeSpin = this.spinData.Free.LeftCount == this.spinData.Free.MaxCount;
|
|
}
|
|
this.hasEliminate = this.spinData.RoundInfo.Current !== this.spinData.RoundInfo.Total;
|
|
}
|
|
|
|
// 处理当前小局结束
|
|
handleRoundEnd(isReconnect: boolean = false) {
|
|
if (this.isFreeSpin) {
|
|
if (this.isFirstFreeSpin) {
|
|
this.updateBg(true);
|
|
this.slotBar.updateIsFreeSpin(true);
|
|
this.slotBar.setLeftCount(this.spinData.Free.MaxCount);
|
|
NodePoolManager.instance.getNodeFromPoolDynamic("FreeSpinEnter", "Prefab/FreeSpinEnter", "Game").then((prefab: Node) => {
|
|
this.node.addChild(prefab);
|
|
let freeCount = this.spinData.Free.MaxCount;
|
|
prefab.getComponent(FreeSpinEnterSpine).showEnterAni(freeCount, () => {
|
|
AudioManager.instance.playBGM("Free_Bg_Bgm");
|
|
NodePoolManager.instance.putNodeToPool("FreeSpinEnter", prefab);
|
|
this.scheduleOnce(() => {
|
|
this.handleNextFreeSpin(this.spinData.Free.LeftCount - 1);
|
|
}, 1);
|
|
});
|
|
});
|
|
} else {
|
|
if (!isReconnect) {
|
|
this.handleBigWin(() => {
|
|
this.handleFreeSpinAgain(() => {
|
|
this.slotBar.setLeftCount(this.spinData.Free.LeftCount);
|
|
if (this.isErr) {
|
|
this.updateBg(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.Free.LeftCount == 0 && this.spinData.RoundInfo.Current == this.spinData.RoundInfo.Total) {
|
|
this.isFreeSpin = false;
|
|
|
|
this.slotBar.updatePlayerMsg(this.spinData, null, true);
|
|
this.scheduleOnce(() => {
|
|
this.slotMsg.showTotalWinAnimaiton(this.spinData.AllScore, this.spinData.AllScore, () => {
|
|
NodePoolManager.instance.getNodeFromPoolDynamic("TotalWinSpine", "Prefab/TotalWinSpine", "Game").then((prefab: Node) => {
|
|
AudioManager.instance.playBGM("Total_Win_Bgm");
|
|
this.node.addChild(prefab);
|
|
prefab.getComponent(TotalWinSpine).showTotalWinSpine(this.spinData.AllScore, () => {
|
|
this.updateBg(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.slotBar.updateWinMsg(this.spinData.AllScore, true);
|
|
this.scheduleOnce(() => {
|
|
this.handleNextFreeSpin(this.spinData.Free.LeftCount - 1);
|
|
}, 1);
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
if (this.spinData.Free.LeftCount == 0 && this.spinData.RoundInfo.Current == this.spinData.RoundInfo.Total) {
|
|
this.isFreeSpin = false;
|
|
this.slotMsg.showTotalWinMsg(this.spinData.AllScore);
|
|
this.slotBar.updatePlayerMsg(this.spinData, () => {
|
|
this.updateBg(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);
|
|
this.scheduleOnce(() => {
|
|
this.handleNextFreeSpin(this.spinData.Free.LeftCount - 1);
|
|
}, 1);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (isReconnect) {
|
|
this.slotBar.updatePlayerMsg(this.spinData, () => {
|
|
this.updateBg(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);
|
|
}
|
|
|
|
this.slotMsg.showTotalWinMsg(this.spinData.AllScore);
|
|
});
|
|
} else {
|
|
this.slotMsg.showTotalWinMsg(this.spinData.AllScore);
|
|
this.handleBigWin(() => {
|
|
this.slotBar.updatePlayerMsg(this.spinData, () => {
|
|
this.updateBg(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);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
handleBigWin(callBack: () => void) {
|
|
let score = this.isFreeSpin
|
|
? this.spinData.SpinScore
|
|
: this.spinData.AllScore;
|
|
// score = 7000000000;
|
|
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();
|
|
this.slotBar.node.getChildByName("stopBtn").active = true;
|
|
}
|
|
|
|
/** 扣除金币 */
|
|
subBalacne() {
|
|
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 {
|
|
this.slotBar.setBalance(
|
|
this.slotBar.getBalance() -
|
|
this.slotBar.getBet() * this.gameInfo.BuyMul
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
testBtn() {
|
|
NodePoolManager.instance
|
|
.getNodeFromPoolDynamic("FreeSpinEnter", "Prefab/FreeSpinEnter", "Game")
|
|
.then((prefab: Node) => {
|
|
this.node.addChild(prefab);
|
|
let freeCount = 10; //this.spinData.FreeSpin.MaxCount;
|
|
freeCount = 10;
|
|
prefab.getComponent(FreeSpinEnterSpine).showEnterAni(freeCount, () => {
|
|
NodePoolManager.instance.putNodeToPool("FreeSpinEnter", prefab);
|
|
});
|
|
});
|
|
}
|
|
|
|
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");
|
|
}
|
|
}
|