pixi-rainman-game-engine 0.2.25 → 0.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/ComponentRegistry/ComponentRegistry.js +1 -2
  2. package/dist/ComponentRegistry/types.js +1 -1
  3. package/dist/Rainman/Rainman.js +2 -2
  4. package/dist/Rainman/appConfig.js +3 -3
  5. package/dist/Rainman/types.d.ts +2 -0
  6. package/dist/SettingsUI/components/AutoplaySettings/index.jsx +2 -2
  7. package/dist/SettingsUI/components/BuyFreeSpins/index.jsx +2 -1
  8. package/dist/SettingsUI/components/OptionButton/index.jsx +3 -2
  9. package/dist/SettingsUI/hooks/useBuyFreeSpins/useBuyFreeSpins.js +14 -10
  10. package/dist/application/SpinLogic/util.js +5 -5
  11. package/dist/application/setup.js +1 -1
  12. package/dist/components/AbstractMainContainer/AbstractMainContainer.d.ts +4 -4
  13. package/dist/components/AbstractMainContainer/AbstractMainContainer.js +16 -4
  14. package/dist/components/buttons/BaseButton/ButtonState.js +1 -1
  15. package/dist/components/symbols/AbstractSymbolsColumn.d.ts +2 -2
  16. package/dist/connectivity/ConnectionWrapper.d.ts +56 -3
  17. package/dist/connectivity/ConnectionWrapper.js +83 -18
  18. package/dist/connectivity/LocalConnectionWrapper.d.ts +1 -0
  19. package/dist/connectivity/LocalConnectionWrapper.js +10 -0
  20. package/dist/connectivity/serverConnection.d.ts +14 -6
  21. package/dist/connectivity/serverData.d.ts +15 -2
  22. package/dist/connectivity/spinData.js +2 -2
  23. package/dist/constants/gamePhase.js +1 -1
  24. package/dist/constants/transformation.js +1 -1
  25. package/dist/constants/wins.js +1 -1
  26. package/dist/controllers/AbstractController.js +16 -11
  27. package/dist/controllers/UiController.js +1 -0
  28. package/dist/loading/AbstractLoadingContainer.js +1 -1
  29. package/dist/stores/SettingsStore.d.ts +6 -2
  30. package/dist/stores/SettingsStore.js +10 -0
  31. package/dist/utils/common/functions.js +1 -1
  32. package/dist/utils/common/placementHelpers.js +1 -1
  33. package/dist/utils/common/types.d.ts +2 -1
  34. package/package.json +1 -1
@@ -9,10 +9,9 @@ import { openFullscreen } from "../utils";
9
9
  export class ComponentRegistry {
10
10
  registry = new Map();
11
11
  speedAdaptableComponents = new Set();
12
- incentiveJobsManager;
12
+ incentiveJobsManager = new TimedIncentiveController();
13
13
  speedLevelHandler = SpeedLevelHandler.initWithDefaultSpeedLevels();
14
14
  constructor(app) {
15
- this.incentiveJobsManager = new TimedIncentiveController();
16
15
  app.renderer.addListener("pointerdown", () => {
17
16
  this.setUserActivityTime();
18
17
  openFullscreen();
@@ -1 +1 @@
1
- import { AbstractColumnsContainer, AbstractFrame, AbstractInnerFrame, AutoplayButton, Background, BUTTONS, COMPONENTS, FreeSpinButton, InfoButton, MessageBox, MoreButton, NegButton, PlusButton, RefreshButton, SpeedControlButton, VolumeButton, } from "../components";
1
+ import { AbstractColumnsContainer, AbstractFrame, AbstractInnerFrame, AutoplayButton, Background, BUTTONS, COMPONENTS, FreeSpinButton, InfoButton, MessageBox, MoreButton, NegButton, PlusButton, RefreshButton, SpeedControlButton, VolumeButton } from "../components";
@@ -28,8 +28,8 @@ export class RainMan {
28
28
  RainMan.settingsStore = settingStore;
29
29
  RainMan.componentRegistry = new ComponentRegistry(app);
30
30
  RainMan.globals = {
31
- shouldShowModals: false,
32
- currency: Currencies["USD"]
31
+ currency: Currencies["USD"],
32
+ shouldShowModals: false
33
33
  };
34
34
  }
35
35
  }
@@ -47,10 +47,10 @@ export const defaultAppConfig = {
47
47
  superBonusWinMinimumTime: 2000,
48
48
  superBonusWinPhaseTimeout: 2600,
49
49
  speedPopupVisibleTime: 2000,
50
- minAnimationTime: 1000,
50
+ minAnimationTime: 1000
51
51
  },
52
52
  constants: {
53
53
  bigWinMultiplier: 30,
54
- bigWinTextOffset: 0,
55
- },
54
+ bigWinTextOffset: 0
55
+ }
56
56
  };
@@ -68,8 +68,10 @@ export type AppConfig = RequiredAppConfig & DeepPartial<OptionalAppConfig>;
68
68
  export interface Globals {
69
69
  currency: Currency;
70
70
  shouldShowModals: boolean;
71
+ getWebSocketConnection?: () => WebSocket;
71
72
  actionsAfterClosureWebSocket?: () => void;
72
73
  disableSpeedPopup?: (value: boolean) => void;
73
74
  handleDisablingButtons?: (value?: boolean) => void;
74
75
  throttledSpin?: () => void;
76
+ updateFreeSpinShown?: (value: number) => void;
75
77
  }
@@ -25,7 +25,7 @@ export const AutoplaySettings = observer(() => {
25
25
  }
26
26
  return {
27
27
  bottomLimitIndex,
28
- topLimitIndex,
28
+ topLimitIndex
29
29
  };
30
30
  };
31
31
  const updateLimitsBounds = (newLimit) => {
@@ -49,7 +49,7 @@ export const AutoplaySettings = observer(() => {
49
49
  useEffect(() => {
50
50
  updateLimitsBounds(initialAutoSpinCount);
51
51
  }, []);
52
- const { singleWinExceeds, balancedIncreased, balancedDecreased, howManyAutoSpinsLeft, infinitySpinsEnabled, setSingleWinExceeds, setBalancedIncreased, setBalancedDecreased, setAutoSpinsCount, flipInfinitySpinsFlag, resetAutoplaySettings, } = settingStore;
52
+ const { singleWinExceeds, balancedIncreased, balancedDecreased, howManyAutoSpinsLeft, infinitySpinsEnabled, setSingleWinExceeds, setBalancedIncreased, setBalancedDecreased, setAutoSpinsCount, flipInfinitySpinsFlag, resetAutoplaySettings } = settingStore;
53
53
  return (<div className="autoplay-settings">
54
54
  <CloseModalButton layerId={UI_ITEMS.autoplay}/>
55
55
  <div className="autoplay-settings__title">
@@ -1,4 +1,5 @@
1
1
  import "./buyFreeSpin.css";
2
+ import i18next from "i18next";
2
3
  import React, { useState } from "react";
3
4
  import { Currencies } from "ts-money";
4
5
  import { UI_ITEMS } from "../../../utils";
@@ -13,7 +14,7 @@ export const BuyFreeSpinModal = () => {
13
14
  return (<div className="buyFreeSpins__container">
14
15
  <CloseModalButton layerId={UI_ITEMS.freeSpin} afterClose={clearErrorMessage}/>
15
16
  <div className="buyFreeSpins__title-container">
16
- <h1>Buy Free Spins</h1>
17
+ <h1>{i18next.t("buyFreeSpins")}</h1>
17
18
  </div>
18
19
  <div className="buyFreeSpins__buttons-container">
19
20
  {freeSpinOptions.map((option) => (<OptionButton key={option.amount} setMessage={setErrorMessage} option={option} currency={currency}/>))}
@@ -20,10 +20,11 @@ export const OptionButton = ({ option, currency, setMessage }) => {
20
20
  return;
21
21
  }
22
22
  settingStore.setIsFreeSpinBought(true, data);
23
- settingStore.setRoundNumber(data.getRawData().round_number);
24
23
  settingStore.setFreeSpinNumberBought(option.amount);
25
- RainMan.globals.throttledSpin?.();
26
24
  settingStore.handleModalInvocation?.(UI_ITEMS.freeSpin);
25
+ settingStore.handleInvokeFreeSpinPlate?.(option.amount, false);
26
+ RainMan.globals.updateFreeSpinShown?.(option.amount);
27
+ settingStore.setRoundNumber(roundNumber);
27
28
  }
28
29
  catch (err) {
29
30
  setMessage(err.message);
@@ -1,12 +1,16 @@
1
+ import { autorun } from "mobx";
2
+ import { useEffect, useState } from "react";
3
+ import { RainMan } from "../../../Rainman";
1
4
  export const useBuyFreeSpinOptions = () => {
2
- return [
3
- {
4
- amount: 10,
5
- price: 35,
6
- },
7
- {
8
- amount: 30,
9
- price: 100,
10
- },
11
- ];
5
+ const [options, setOptions] = useState([]);
6
+ useEffect(() => {
7
+ const disposer = autorun(() => {
8
+ setOptions(Object.entries(RainMan.settingsStore.freeSpinBuyTable).map(([amount, multiplier]) => ({
9
+ amount: parseInt(amount, 10),
10
+ price: multiplier
11
+ })));
12
+ });
13
+ return () => disposer();
14
+ }, []);
15
+ return options;
12
16
  };
@@ -14,7 +14,7 @@ const getWinFromRawResponse = (rawWin, winIndex) => {
14
14
  symbolId: rawWin.symbol_id,
15
15
  typeId: rawWin.type_id,
16
16
  amount: rawWin.amount,
17
- winIndex,
17
+ winIndex
18
18
  };
19
19
  };
20
20
  /**
@@ -50,7 +50,7 @@ const joinTransformationsIntoDropTransformation = (destroyTransformations, symbo
50
50
  preparedDropTransformations.push({
51
51
  type: transformationTypes.drop,
52
52
  coordinates: destroyPlace,
53
- symbolId: gameConfig.getSymbolId(symbolsToDrop[index]),
53
+ symbolId: gameConfig.getSymbolId(symbolsToDrop[index])
54
54
  });
55
55
  });
56
56
  });
@@ -91,7 +91,7 @@ export const getFreezeTransformationFromRawResponse = (transformations) => {
91
91
  return transformations.map((freezeTransformation) => {
92
92
  return {
93
93
  type: transformationTypes.freeze,
94
- coordinates: freezeTransformation.coordinates,
94
+ coordinates: freezeTransformation.coordinates
95
95
  };
96
96
  });
97
97
  };
@@ -106,7 +106,7 @@ export const concatenateFreezeAndSpinTransformations = (freezeTransformations, o
106
106
  return {
107
107
  type: transformationTypes.spinAndFreeze,
108
108
  coordinates: allCoordinatesToFreeze,
109
- symbolsOnReels: onStopBlindsConfiguration,
109
+ symbolsOnReels: onStopBlindsConfiguration
110
110
  };
111
111
  };
112
112
  /**
@@ -136,6 +136,6 @@ export const collectWinDetailsWithTransformation = (winsDetails, transformations
136
136
  const wins = winsDetails ? [getWinFromRawResponse(winsDetails, winIndex ?? "")] : [];
137
137
  return {
138
138
  wins,
139
- transformations,
139
+ transformations
140
140
  };
141
141
  };
@@ -1,7 +1,7 @@
1
1
  import { createRoot } from "react-dom/client";
2
2
  import { RainMan } from "../Rainman";
3
3
  import { SettingsUI } from "../SettingsUI";
4
- import { changeResolution, disableMagnifyingGlassOnIOS, getDeviceOrientation, invokeStatsBoard, loadSoundsOnTabChange, resizeCanvas, setupFullscreenForIOS, } from "../utils";
4
+ import { changeResolution, disableMagnifyingGlassOnIOS, getDeviceOrientation, invokeStatsBoard, loadSoundsOnTabChange, resizeCanvas, setupFullscreenForIOS } from "../utils";
5
5
  /**
6
6
  * This function is for setup the whole games
7
7
  *
@@ -2,7 +2,7 @@ import { Container, Graphics, Sprite } from "pixi.js";
2
2
  import { ButtonsEventManager, WinTypeId } from "../../application";
3
3
  import { AbstractController } from "../../controllers";
4
4
  import { RainMan } from "../../Rainman";
5
- import { Nullable } from "../../utils";
5
+ import { Nullable, PromiseResolverType } from "../../utils";
6
6
  import { BigWinContainer, MysteryWinContainer, UpdatableSpineContainer } from "../../winComponents";
7
7
  import { AbstractFreeSpinContainer } from "../AbstractFreeSpinContainer";
8
8
  import { LeftButtons, LeftButtonsLandscape, LeftButtonsMobile, MiddleButtons, RightButtons, RightButtonsLandscape, RightButtonsMobile } from "../buttons";
@@ -49,9 +49,9 @@ export declare abstract class AbstractMainContainer extends Container {
49
49
  protected bottomPanel: Nullable<Sprite>;
50
50
  protected gambleGameSpineName: Nullable<string>;
51
51
  private gambleGame;
52
- private rouletteWinContainer;
53
- private mysteryBonusContainer;
54
- protected resolveMysteryBonusContainer?: (value?: void | PromiseLike<void>) => void;
52
+ protected rouletteWinContainer: Nullable<UpdatableSpineContainer>;
53
+ protected mysteryBonusContainer: Nullable<UpdatableSpineContainer>;
54
+ protected resolveMysteryBonusContainer?: PromiseResolverType;
55
55
  protected _freeSpinPlate: Nullable<AbstractFreeSpinContainer>;
56
56
  protected _freeSpinSummary: Nullable<AbstractFreeSpinContainer>;
57
57
  private _bigWinInvokedAt;
@@ -44,7 +44,7 @@ export class AbstractMainContainer extends Container {
44
44
  gambleGame = null;
45
45
  rouletteWinContainer = null;
46
46
  mysteryBonusContainer = null;
47
- resolveMysteryBonusContainer;
47
+ resolveMysteryBonusContainer = undefined;
48
48
  _freeSpinPlate = null;
49
49
  _freeSpinSummary = null;
50
50
  _bigWinInvokedAt = null;
@@ -63,6 +63,7 @@ export class AbstractMainContainer extends Container {
63
63
  SoundManager.setPlayStatus(SoundTracks.music, RainMan.settingsStore.shouldPlayAmbientMusic);
64
64
  }
65
65
  }
66
+ RainMan.settingsStore.setHandleInvokeFreeSpinPlate(this.invokeFreeSpinPlate.bind(this));
66
67
  RainMan.app.renderer.on("resize", () => this.resize());
67
68
  }
68
69
  /**
@@ -283,8 +284,9 @@ export class AbstractMainContainer extends Container {
283
284
  * This function removes the overlay from the main container and sets it to null.
284
285
  */
285
286
  hideOverlay() {
286
- if (this.overlay)
287
+ if (this.overlay) {
287
288
  this.removeChild(this.overlay);
289
+ }
288
290
  this.overlay = null;
289
291
  }
290
292
  /**
@@ -563,8 +565,9 @@ export class AbstractMainContainer extends Container {
563
565
  * Function for disabling components for mobile portrait orientation.
564
566
  */
565
567
  disableForMobile() {
566
- if (this.logo)
568
+ if (this.logo) {
567
569
  this.logo.renderable = false;
570
+ }
568
571
  if (this.underFramePanel !== null) {
569
572
  this.removeChild(this.underFramePanel);
570
573
  this.underFramePanel = null;
@@ -604,11 +607,15 @@ export class AbstractMainContainer extends Container {
604
607
  if (this.bonusWinContainer) {
605
608
  this.removeChild(this.bonusWinContainer);
606
609
  }
610
+ if (this.mysteryBonusContainer) {
611
+ this.removeChild(this.mysteryBonusContainer);
612
+ }
607
613
  this.messageBox.resize();
608
614
  this.background.resize();
609
615
  this.animatedFront?.resize();
610
- if (this.freeSpinButton)
616
+ if (this.freeSpinButton) {
611
617
  this.freeSpinButton.resize();
618
+ }
612
619
  this.addChild(this._frame);
613
620
  this._frame.resize();
614
621
  this.initComponentsForScreenRatio();
@@ -770,6 +777,11 @@ export class AbstractMainContainer extends Container {
770
777
  this.addChild(this.mysteryWinContainer);
771
778
  this.mysteryWinContainer.resize();
772
779
  }
780
+ if (this.mysteryBonusContainer) {
781
+ this.removeChild(this.mysteryBonusContainer);
782
+ this.mysteryBonusContainer.resize();
783
+ this.addChild(this.mysteryBonusContainer);
784
+ }
773
785
  if (this.gambleGame) {
774
786
  this.gambleGame.resize();
775
787
  }
@@ -15,5 +15,5 @@ export const ButtonStates = {
15
15
  CLICKED: "CLICKED",
16
16
  ACTIVE: "ACTIVE",
17
17
  ACTIVE_OVER: "ACTIVE_OVER",
18
- ACTIVE_CLICKED: "ACTIVE_CLICKED",
18
+ ACTIVE_CLICKED: "ACTIVE_CLICKED"
19
19
  };
@@ -1,7 +1,7 @@
1
1
  import { Container } from "pixi.js";
2
2
  import { SpeedAdapterInterface, SpeedLevel, SymbolId } from "../../application";
3
3
  import { DropTransformationDetails, SymbolReel } from "../../connectivity";
4
- import { Nullable, VoidPromiseResolver } from "../../utils";
4
+ import { Nullable, PromiseResolverType } from "../../utils";
5
5
  import { AbstractColumnsContainer, AbstractFrame } from "../frame";
6
6
  import { AbstractSymbolBase } from "./AbstractSymbolBase";
7
7
  import { AnimationTimeSettings, Phase } from "./types";
@@ -28,7 +28,7 @@ export declare abstract class AbstractSymbolsColumn extends Container implements
28
28
  private lastEnding;
29
29
  private tween;
30
30
  private wiggleTween;
31
- resolveMysterySpeedUp: Nullable<VoidPromiseResolver>;
31
+ resolveMysterySpeedUp: Nullable<PromiseResolverType<void>>;
32
32
  private resolver;
33
33
  private shouldMoveToTop;
34
34
  private droppingTweens;
@@ -1,10 +1,12 @@
1
1
  import { ExtraDataRequest, GambleCardColor, GambleDataInterface, InitDataInterface, ServerMessage, SpinData, SubscribableConnectionWrapper } from "../connectivity";
2
2
  /**
3
3
  * Class for managing connection to the server via websockets
4
+ * This class handles communication with the server, including fetching initial data, spin data, free spin data, and gamble data.
5
+ * @implements {SubscribableConnectionWrapper}
4
6
  */
5
7
  export declare class ConnectionWrapper implements SubscribableConnectionWrapper {
6
8
  private webSocketConnection;
7
- private config;
9
+ private config?;
8
10
  private fetchInProgress;
9
11
  private lastFetchResponse;
10
12
  private lastGambleResponse;
@@ -15,18 +17,43 @@ export declare class ConnectionWrapper implements SubscribableConnectionWrapper
15
17
  */
16
18
  private handleMessage;
17
19
  private _messageHistory;
18
- private _initData;
20
+ private _initData?;
19
21
  constructor();
22
+ /**
23
+ * Method for opening a websocket connection
24
+ * @returns {Promise<void>} resolves when the connection is opened
25
+ */
20
26
  private openConnection;
21
27
  /**
22
28
  * Method for initializing communication with the server
23
29
  */
24
30
  initCommunication(): Promise<void>;
31
+ /**
32
+ * Method for subscribing to configuration changes
33
+ * @param {() => void} subscriberFn - function to be called when configuration changes
34
+ * @returns {void}
35
+ * @memberof ConnectionWrapper
36
+ */
25
37
  subscribeForConfigChanges(subscriberFn: () => void): void;
38
+ /**
39
+ * Method for fetching initial data from the server
40
+ * @returns {Promise<void>} resolves when the data is fetched
41
+ * @memberof ConnectionWrapper
42
+ */
26
43
  fetchInitData(): Promise<void>;
44
+ /**
45
+ * Method for getting initial data from the server
46
+ * @returns {InitDataInterface} initial data from the server
47
+ */
27
48
  initData(): InitDataInterface;
49
+ /**
50
+ * Method for fetching free spin data from the server
51
+ * @param {number} roundNumber round number
52
+ * @param {number} quantity quantity of free spins
53
+ * @param {number} price price of free spins
54
+ * @returns {SpinData} spin data
55
+ */
28
56
  fetchFreeSpinData(roundNumber: number, quantity: number, price: number): Promise<SpinData>;
29
- private transformFreeSpinData;
30
57
  /**
31
58
  * Method for fetching spin data from the server
32
59
  * @param {number} roundNumber round number
@@ -35,7 +62,25 @@ export declare class ConnectionWrapper implements SubscribableConnectionWrapper
35
62
  * @returns {SpinData} spin data
36
63
  */
37
64
  fetchSpinData(roundNumber: number, bet: number, extra_data?: ExtraDataRequest): Promise<SpinData>;
65
+ /**
66
+ * Sends end of round data to the server
67
+ * This method is used to notify the server that the round has ended and to update the server state accordingly.
68
+ * @param {number} roundNumber - the round number to send data from
69
+ * @returns {Promise<ServerMessage>} - server message with end of round data
70
+ */
71
+ sendEndOfRoundData(roundNumber: number): Promise<ServerMessage>;
72
+ /**
73
+ * Method for fetching gamble data from the server
74
+ * @param {number} roundNumber round number
75
+ * @param {number} bet bet amount
76
+ * @param {GambleCardColor} choice gamble card color choice
77
+ * @returns {Promise<GambleDataInterface>} gamble data
78
+ */
38
79
  fetchGambleData(roundNumber: number, bet: number, choice: GambleCardColor): Promise<GambleDataInterface>;
80
+ /**
81
+ * Method for getting a fresh websocket instance
82
+ * @returns {WebSocket} fresh websocket instance
83
+ */
39
84
  private getFreshWsInstance;
40
85
  /**
41
86
  * Method for fetching data from the server
@@ -43,6 +88,14 @@ export declare class ConnectionWrapper implements SubscribableConnectionWrapper
43
88
  * @returns {ServerMessage} server response
44
89
  */
45
90
  private fetch;
91
+ /**
92
+ * Method for getting message history
93
+ * @returns {ServerMessage[]} message history
94
+ */
46
95
  getMessageHistory(): ServerMessage[];
96
+ /**
97
+ * Method for getting the last gamble response
98
+ * @returns {GambleDataInterface | null} last gamble response
99
+ */
47
100
  getLastGambleResponse(): typeof this.lastGambleResponse;
48
101
  }
@@ -7,6 +7,8 @@ import { logError, logInfo, logWarn } from "../utils";
7
7
  const overrideMap = new Map();
8
8
  /**
9
9
  * Class for managing connection to the server via websockets
10
+ * This class handles communication with the server, including fetching initial data, spin data, free spin data, and gamble data.
11
+ * @implements {SubscribableConnectionWrapper}
10
12
  */
11
13
  export class ConnectionWrapper {
12
14
  webSocketConnection;
@@ -40,35 +42,43 @@ export class ConnectionWrapper {
40
42
  constructor() {
41
43
  this.webSocketConnection = this.getFreshWsInstance();
42
44
  }
45
+ /**
46
+ * Method for opening a websocket connection
47
+ * @returns {Promise<void>} resolves when the connection is opened
48
+ */
43
49
  async openConnection() {
44
- return new Promise((resolve) => {
45
- this.webSocketConnection.addEventListener("open", resolve);
46
- });
50
+ return new Promise((resolve) => this.webSocketConnection.addEventListener("open", resolve));
47
51
  }
48
52
  /**
49
53
  * Method for initializing communication with the server
50
54
  */
51
55
  async initCommunication() {
52
- this.webSocketConnection.addEventListener("error", (event) => {
53
- logError(`Error in webSocket connection: ${event}`);
54
- });
56
+ this.webSocketConnection.addEventListener("error", (event) => logError(`Error in webSocket connection: ${event}`));
55
57
  await this.openConnection();
56
58
  this.webSocketConnection.addEventListener("close", async (event) => {
57
59
  logWarn(`Reiniting communications after connection was closed. Reason: ${event.reason}`);
58
60
  this.webSocketConnection = this.getFreshWsInstance();
59
61
  await this.initCommunication();
60
62
  await this.fetchInitData();
61
- this.subscribers.forEach((subscriberFn) => {
62
- subscriberFn();
63
- });
64
- RainMan.globals.actionsAfterClosureWebSocket?.();
63
+ this.subscribers.forEach((subscriberFn) => subscriberFn());
65
64
  });
66
65
  this.webSocketConnection.addEventListener("message", (event) => this.handleMessage(JSON.parse(event.data)));
67
66
  logInfo("connection established, listener set");
68
67
  }
68
+ /**
69
+ * Method for subscribing to configuration changes
70
+ * @param {() => void} subscriberFn - function to be called when configuration changes
71
+ * @returns {void}
72
+ * @memberof ConnectionWrapper
73
+ */
69
74
  subscribeForConfigChanges(subscriberFn) {
70
75
  this.subscribers.push(subscriberFn);
71
76
  }
77
+ /**
78
+ * Method for fetching initial data from the server
79
+ * @returns {Promise<void>} resolves when the data is fetched
80
+ * @memberof ConnectionWrapper
81
+ */
72
82
  async fetchInitData() {
73
83
  this._initData = (await this.fetch({
74
84
  action: "init",
@@ -85,26 +95,40 @@ export class ConnectionWrapper {
85
95
  vendor_id: RainMan.config.gameInitVendorId
86
96
  }));
87
97
  RainMan.globals.currency = Currencies[this._initData.currency];
98
+ RainMan.settingsStore.setFreeSpinsPriceTable(this._initData.free_spins_buy_table);
88
99
  }
100
+ /**
101
+ * Method for getting initial data from the server
102
+ * @returns {InitDataInterface} initial data from the server
103
+ */
89
104
  initData() {
90
105
  return this._initData;
91
106
  }
107
+ /**
108
+ * Method for fetching free spin data from the server
109
+ * @param {number} roundNumber round number
110
+ * @param {number} quantity quantity of free spins
111
+ * @param {number} price price of free spins
112
+ * @returns {SpinData} spin data
113
+ */
92
114
  async fetchFreeSpinData(roundNumber, quantity, price) {
93
115
  if (typeof this.config?.token === "undefined") {
94
116
  throw new Error("Token was not defined");
95
117
  }
96
118
  const data = (await this.fetch({
97
- action: "buy-free-spins",
119
+ action: "buy",
120
+ operation: "buy-free-spins",
121
+ buy_price: price,
98
122
  round_number: roundNumber,
99
- free_spins_quantity: quantity,
100
- free_spins_price: price,
101
123
  token: this.config.token,
102
- reference: RainMan.config.gameInitReference
124
+ reference: RainMan.config.gameInitReference,
125
+ bet: RainMan.settingsStore.bet,
126
+ extra_data: {
127
+ free_spins_quantity: quantity
128
+ }
103
129
  }));
104
- return new SpinData(this.config, this.transformFreeSpinData(data));
105
- }
106
- transformFreeSpinData(data) {
107
- return { ...data, previous_gambles: [], results: [], win_amount_total: 0, wins: {}, extra_data: {} };
130
+ RainMan.settingsStore.setRoundNumber(data.round_number);
131
+ return new SpinData(this.config, data);
108
132
  }
109
133
  /**
110
134
  * Method for fetching spin data from the server
@@ -126,8 +150,35 @@ export class ConnectionWrapper {
126
150
  extra_data
127
151
  });
128
152
  this._messageHistory.push(data);
153
+ this.sendEndOfRoundData(roundNumber - 1);
129
154
  return new SpinData(this.config, data);
130
155
  }
156
+ /**
157
+ * Sends end of round data to the server
158
+ * This method is used to notify the server that the round has ended and to update the server state accordingly.
159
+ * @param {number} roundNumber - the round number to send data from
160
+ * @returns {Promise<ServerMessage>} - server message with end of round data
161
+ */
162
+ async sendEndOfRoundData(roundNumber) {
163
+ if (typeof this.config?.token === "undefined") {
164
+ throw new Error("Token was not defined");
165
+ }
166
+ const data = await this.fetch({
167
+ action: "end",
168
+ round_number: roundNumber,
169
+ reference: RainMan.config.gameInitReference,
170
+ token: this.config.token
171
+ });
172
+ this._messageHistory.push(data);
173
+ return data;
174
+ }
175
+ /**
176
+ * Method for fetching gamble data from the server
177
+ * @param {number} roundNumber round number
178
+ * @param {number} bet bet amount
179
+ * @param {GambleCardColor} choice gamble card color choice
180
+ * @returns {Promise<GambleDataInterface>} gamble data
181
+ */
131
182
  async fetchGambleData(roundNumber, bet, choice) {
132
183
  if (typeof this.config?.token === "undefined") {
133
184
  throw new Error("Token was not defined");
@@ -140,8 +191,14 @@ export class ConnectionWrapper {
140
191
  bet,
141
192
  choice
142
193
  }));
194
+ this._messageHistory.push(this.lastGambleResponse);
195
+ this.sendEndOfRoundData(roundNumber - 1);
143
196
  return this.lastGambleResponse;
144
197
  }
198
+ /**
199
+ * Method for getting a fresh websocket instance
200
+ * @returns {WebSocket} fresh websocket instance
201
+ */
145
202
  getFreshWsInstance() {
146
203
  return new WebSocket(RainMan.config.websocketUrl);
147
204
  }
@@ -171,9 +228,17 @@ export class ConnectionWrapper {
171
228
  waitForData();
172
229
  });
173
230
  }
231
+ /**
232
+ * Method for getting message history
233
+ * @returns {ServerMessage[]} message history
234
+ */
174
235
  getMessageHistory() {
175
236
  return this._messageHistory;
176
237
  }
238
+ /**
239
+ * Method for getting the last gamble response
240
+ * @returns {GambleDataInterface | null} last gamble response
241
+ */
177
242
  getLastGambleResponse() {
178
243
  return this.lastGambleResponse;
179
244
  }
@@ -18,6 +18,7 @@ export declare class LocalConnectionWrapper implements SubscribableConnectionWra
18
18
  initData(): InitDataInterface;
19
19
  fetchSpinData(): Promise<SpinData>;
20
20
  subscribeForConfigChanges(subscriberFn: () => void): void;
21
+ sendEndOfRoundData(roundNumber: number): Promise<ServerMessage>;
21
22
  fetchFreeSpinData(roundNumber: number, quantity: number): Promise<SpinData>;
22
23
  getMessageHistory(): ServerMessage[];
23
24
  }
@@ -41,6 +41,16 @@ export class LocalConnectionWrapper {
41
41
  subscribeForConfigChanges(subscriberFn) {
42
42
  this.subscribers.push(subscriberFn);
43
43
  }
44
+ sendEndOfRoundData(roundNumber) {
45
+ const data = {
46
+ action: "end",
47
+ balance: 1000,
48
+ round_number: roundNumber,
49
+ status: { code: 200, message: "OK" }
50
+ };
51
+ this.subscribers.forEach((subscriber) => subscriber());
52
+ return Promise.resolve(data);
53
+ }
44
54
  fetchFreeSpinData(roundNumber, quantity) {
45
55
  const data = {
46
56
  action: "buy-free-spins",
@@ -1,4 +1,4 @@
1
- import { GambleCardColor, GambleDataInterface, InitDataInterface, SpinDataInterface } from "./serverData";
1
+ import { EndDataInterface, GambleCardColor, GambleDataInterface, InitDataInterface, SpinDataInterface } from "./serverData";
2
2
  import { SpinData } from "./spinData";
3
3
  export interface ServerCommunication {
4
4
  initCommunication(): Promise<void>;
@@ -6,6 +6,7 @@ export interface ServerCommunication {
6
6
  initData(): InitDataInterface;
7
7
  fetchSpinData(roundNumber: number, bet: number, extraData?: ExtraDataRequest): Promise<SpinData>;
8
8
  fetchFreeSpinData(roundNumber: number, amount: number, price: number): Promise<SpinData>;
9
+ sendEndOfRoundData(roundNumber: number): Promise<ServerMessage>;
9
10
  getMessageHistory(): ServerMessage[];
10
11
  }
11
12
  export interface Subscribable {
@@ -34,17 +35,24 @@ export type SpinServerRequest = BaseServerRequest & {
34
35
  extra_data: ExtraDataRequest;
35
36
  };
36
37
  export type BuyFreeSpinServerRequest = BaseServerRequest & {
37
- action: "buy-free-spins";
38
- free_spins_quantity: number;
39
- free_spins_price: number;
38
+ action: "buy";
39
+ operation: "buy-free-spins";
40
+ bet: number;
41
+ buy_price: number;
42
+ extra_data: {
43
+ free_spins_quantity: number;
44
+ };
40
45
  };
41
46
  export type GambleServerRequest = BaseServerRequest & {
42
47
  action: "gamble";
43
48
  bet: number;
44
49
  choice: GambleCardColor;
45
50
  };
51
+ export type EndServerRequest = BaseServerRequest & {
52
+ action: "end";
53
+ };
46
54
  export interface ExtraDataRequest {
47
55
  }
48
- export type ServerRequest = InitServerRequest | SpinServerRequest | BuyFreeSpinServerRequest | GambleServerRequest;
49
- export type ServerMessage = InitDataInterface | SpinDataInterface | GambleDataInterface;
56
+ export type ServerRequest = InitServerRequest | SpinServerRequest | BuyFreeSpinServerRequest | GambleServerRequest | EndServerRequest;
57
+ export type ServerMessage = InitDataInterface | SpinDataInterface | GambleDataInterface | EndDataInterface;
50
58
  export {};
@@ -1,4 +1,5 @@
1
1
  import { PaytableTypes } from "../constants";
2
+ import { Nullable } from "../utils";
2
3
  import { Point, RawTransformationDetails } from "./transformation";
3
4
  export interface InitDataInterface {
4
5
  action: string;
@@ -14,10 +15,21 @@ export interface InitDataInterface {
14
15
  wins_names: Array<string>;
15
16
  transformations_names: Array<string>;
16
17
  transformations_types: Array<number>;
18
+ free_spins_buy_table?: Record<number, number>;
19
+ free_spins_prize_table?: Record<number, number>;
17
20
  paytable: PayTableInterface;
18
21
  extra_data: InitExtraData;
19
22
  jackpot_wins?: JackpotWins;
20
23
  }
24
+ export interface EndDataInterface {
25
+ action: "end";
26
+ balance: number;
27
+ round_number: number;
28
+ status: {
29
+ code: number;
30
+ message: string;
31
+ };
32
+ }
21
33
  export type JackpotType = "jackpot-mini" | "jackpot-minor" | "jackpot-major" | "jackpot-grand";
22
34
  export type JackpotWins = {
23
35
  "jackpot-grand": {
@@ -76,9 +88,10 @@ export interface SpinDataInterface {
76
88
  symbols_on_reels: number[][];
77
89
  win_amount_total: number;
78
90
  wins: Record<string, RawWin>;
79
- extra_data: ExtraData | null;
91
+ extra_data: Nullable<ExtraData>;
80
92
  }
81
93
  export interface ExtraData {
94
+ available_free_spins?: number;
82
95
  }
83
96
  export interface GambleDataInterface {
84
97
  action: "gamble";
@@ -90,7 +103,7 @@ export interface GambleDataInterface {
90
103
  winning_card: GambleCard;
91
104
  }
92
105
  export interface FreeSpinDataInterface {
93
- action: "buy-free-spins";
106
+ action: "buy";
94
107
  available_free_spins: number;
95
108
  balance: number;
96
109
  round_number: number;
@@ -6,8 +6,8 @@ export class SpinData {
6
6
  this.rawData = data;
7
7
  this.config = config;
8
8
  this.balance = data.balance;
9
- if (data.action !== "spin" && data.action !== "buy-free-spins") {
10
- throw new Error(`Invalid type "${data.action}" provided, "spin" or "buy-free-spins" expected`);
9
+ if (data.action !== "spin" && data.action !== "buy") {
10
+ throw new Error(`Invalid type "${data.action}" provided, "spin" or "buy" expected`);
11
11
  }
12
12
  }
13
13
  getRawData() {
@@ -12,5 +12,5 @@ export const gamePhases = {
12
12
  BIG_WIN_INVOKED: "bigWinInvoked",
13
13
  SUPER_BONUS_WIN_INVOKED: "superBonusWinInvoked",
14
14
  BONUS_WIN_INVOKED: "bonusWinInvoked",
15
- GAME_SUMMARY: "gameSummary",
15
+ GAME_SUMMARY: "gameSummary"
16
16
  };
@@ -10,5 +10,5 @@ export const transformationTypes = {
10
10
  swap: "swap",
11
11
  replace: "replace",
12
12
  spinAndFreeze: "spinAndFreeze",
13
- verticalExpand: "vertical-expand",
13
+ verticalExpand: "vertical-expand"
14
14
  };
@@ -19,5 +19,5 @@ export const PossibleWins = {
19
19
  bonus: "bonus",
20
20
  superBonus: "super-bonus",
21
21
  joker: "joker",
22
- multi: "multi",
22
+ multi: "multi"
23
23
  };
@@ -531,8 +531,7 @@ export class AbstractController {
531
531
  if (RainMan.settingsStore.isFreeSpinsBought) {
532
532
  this.uiController.totalNumberOfFreeSpins += this.getBoughtNumberOfFreeSpins();
533
533
  RainMan.componentRegistry.getIfExists(FreeSpinButton.registryName)?.setInteractivity(false);
534
- this.changeGamePhase(gamePhases.IDLE);
535
- this.spin().then(() => RainMan.settingsStore.setIsFreeSpinBought(false));
534
+ RainMan.settingsStore.setIsFreeSpinBought(false);
536
535
  return;
537
536
  }
538
537
  if (RainMan.settingsStore.isAutoplayEnabled && !this.spinning) {
@@ -560,7 +559,7 @@ export class AbstractController {
560
559
  * @returns {number} - number of free spins bought
561
560
  */
562
561
  getBoughtNumberOfFreeSpins() {
563
- return RainMan.settingsStore.buyFreeSpinsData?.getRawData().available_free_spins || 0;
562
+ return RainMan.settingsStore.buyFreeSpinsData?.getRawData().extra_data.available_free_spins || 0;
564
563
  }
565
564
  /**
566
565
  * Function for autoplay spin
@@ -619,8 +618,7 @@ export class AbstractController {
619
618
  async fetchAndPrepareSpinData() {
620
619
  this.changeGamePhase(gamePhases.DATA_FETCH);
621
620
  this.handleDisablingButtons(true);
622
- const data = RainMan.settingsStore.buyFreeSpinsData ||
623
- (await this.connection.fetchSpinData(this.roundNumber, RainMan.settingsStore.bet, this.getExtraData()));
621
+ const data = await this.connection.fetchSpinData(this.roundNumber, RainMan.settingsStore.bet, this.getExtraData());
624
622
  debugSpinData(data);
625
623
  const spinLogic = this.spinLogicFactory(data.getRawData(), this.config);
626
624
  this._lastWinAmount = this.mysteryWinSymbol ? spinLogic.winTotalAmountWithoutMystery : spinLogic.winTotalAmount;
@@ -633,6 +631,8 @@ export class AbstractController {
633
631
  }
634
632
  this.changeGamePhase(gamePhases.CONFIGURING_SPIN);
635
633
  this.uiController.currentBalance = data.balance;
634
+ this.roundNumber = data.getRawData().round_number;
635
+ RainMan.settingsStore.setRoundNumber(data.getRawData().round_number);
636
636
  return {
637
637
  data,
638
638
  spinLogic
@@ -704,8 +704,9 @@ export class AbstractController {
704
704
  case gamePhases.IDLE:
705
705
  break;
706
706
  case gamePhases.HANDLING_ACTIONS:
707
- if (!this.canSkipActions())
707
+ if (!this.canSkipActions()) {
708
708
  return;
709
+ }
709
710
  this.changeGamePhase(gamePhases.STOPPING_HANDLING_ACTIONS);
710
711
  if (this.currentlyPlayedAction !== undefined) {
711
712
  this.stopPlayingSymbolsStreak();
@@ -736,10 +737,12 @@ export class AbstractController {
736
737
  const availableFreeSpins = spinLogic.availableFreeSpins;
737
738
  const availableFreeSpinsIncreased = availableFreeSpins > RainMan.settingsStore.howManyFreeSpinsLeft;
738
739
  this.hideFreeSpinsMessageBox = availableFreeSpinsIncreased;
739
- if (!availableFreeSpinsIncreased)
740
+ if (!availableFreeSpinsIncreased) {
740
741
  this.uiController.updateShownFreeSpinAmount(availableFreeSpins);
741
- else
742
+ }
743
+ else {
742
744
  this.uiController.updateShownFreeSpinAmount(RainMan.settingsStore.howManyFreeSpinsLeft - 1);
745
+ }
743
746
  if (availableFreeSpins > 0) {
744
747
  RainMan.settingsStore.setTotalNumberOfFreeSpins(availableFreeSpins + RainMan.settingsStore.freeSpinNumberBought);
745
748
  }
@@ -764,8 +767,9 @@ export class AbstractController {
764
767
  this.uiController.limitWinAmount(spinLogic.winTotalAmount);
765
768
  }
766
769
  this.composeWinActionsQueue(spinLogic);
767
- if (spinLogic.winTotalAmount === 0 && this.invokeFreeSpinPlateAfterWin)
770
+ if (spinLogic.winTotalAmount === 0 && this.invokeFreeSpinPlateAfterWin) {
768
771
  this.uiController.messageBox.hideCurrentWinText();
772
+ }
769
773
  RainMan.settingsStore.setIsPlayingAnyAction(true);
770
774
  await this.playWinActionQueue();
771
775
  await this.countBigWin();
@@ -788,7 +792,7 @@ export class AbstractController {
788
792
  RainMan.settingsStore.resetIsLastFreeSpin();
789
793
  this.mainContainer.destroyBigWin();
790
794
  this.columnsContainer.resetPlayedSounds();
791
- if (this.invokeFreeSpinPlateAfterWin || RainMan.settingsStore.isFreeSpinsBought) {
795
+ if (this.invokeFreeSpinPlateAfterWin) {
792
796
  this.uiController.messageBox.hideCurrentWinText();
793
797
  this.mainContainer.messageBox.hideFreeSpinText();
794
798
  hideLayerIfPresent();
@@ -804,8 +808,9 @@ export class AbstractController {
804
808
  this.uiController.triggerUiElementsUpdate();
805
809
  this.uiController.messageBox.showFreeSpinText();
806
810
  }
807
- if (availableFreeSpinsIncreased)
811
+ if (availableFreeSpinsIncreased) {
808
812
  this.uiController.updateShownFreeSpinAmount(availableFreeSpins);
813
+ }
809
814
  if (this.invokeFreeSpinSummaryPlateAfterWin && !this.skipFreeSpinSummary) {
810
815
  hideLayerIfPresent();
811
816
  await this.handleFreeSpinSummaryPlateInvocation();
@@ -17,6 +17,7 @@ export class UiController {
17
17
  constructor(config) {
18
18
  this.config = config;
19
19
  this._messageBox = RainMan.componentRegistry.get(MessageBox.registryName);
20
+ RainMan.globals.updateFreeSpinShown = this.updateShownFreeSpinAmount.bind(this);
20
21
  }
21
22
  get messageBox() {
22
23
  return this._messageBox;
@@ -19,7 +19,7 @@ export class AbstractLoadingContainer extends Container {
19
19
  this.loaderContainer = new SpriteLoadingContainer("./assets/images/materials/texture.png", {
20
20
  fill: ["#FCD784", "#AE6119", "#FEE391"], // gradient
21
21
  stroke: "#4a1850",
22
- dropShadowColor: "#000000",
22
+ dropShadowColor: "#000000"
23
23
  });
24
24
  RainMan.app.renderer.on("resize", () => this.resize()); // arrow fn to pass this context to resize
25
25
  }
@@ -20,7 +20,7 @@ export declare class SettingsStore {
20
20
  totalNumberOfFreeSpins: number;
21
21
  isFreeSpinsBought: boolean;
22
22
  freeSpinNumberBought: number;
23
- buyFreeSpinsData: SpinData | null;
23
+ buyFreeSpinsData: Nullable<SpinData>;
24
24
  isAutoplayEnabled: boolean;
25
25
  isLastFreeSpin: boolean;
26
26
  infinitySpinsEnabled: boolean;
@@ -38,6 +38,7 @@ export declare class SettingsStore {
38
38
  balancedDecreased: number;
39
39
  howManyFreeSpinsLeft: number;
40
40
  howManyAutoSpinsLeft: number;
41
+ freeSpinBuyTable: Record<number, number>;
41
42
  volumeLevel: number;
42
43
  popupPaytablePosition?: Point;
43
44
  popupPaytableData?: PaytableData[];
@@ -47,6 +48,7 @@ export declare class SettingsStore {
47
48
  popupPaytableRepositionCallback?: () => void;
48
49
  updateVolumeButtonTexture?: () => void;
49
50
  handleModalInvocation?: (layerId: string) => void;
51
+ handleInvokeFreeSpinPlate?: (freeSpinAmount: number, isAdditionalFreeSpin: boolean) => Promise<void>;
50
52
  increaseBet?: () => void;
51
53
  decreaseBet?: () => void;
52
54
  enableButtons?: () => void;
@@ -61,6 +63,7 @@ export declare class SettingsStore {
61
63
  changeBetChangeDisabled(flag: boolean): void;
62
64
  isIosScrollerInteractive(flag: boolean): void;
63
65
  resetCumulativeWinAmount(): void;
66
+ setFreeSpinsPriceTable(freeSpinsPriceTable: Record<number, number>): void;
64
67
  /**
65
68
  * Sets bet value
66
69
  * @param {number} newBet updated bet value
@@ -113,8 +116,9 @@ export declare class SettingsStore {
113
116
  resetIsLastFreeSpin(): void;
114
117
  setTotalNumberOfFreeSpins(newValue: number): void;
115
118
  resetTotalNumberOfFreeSpins(): void;
116
- setIsFreeSpinBought(newValue: boolean, data?: SpinData | null): void;
119
+ setIsFreeSpinBought(newValue: boolean, data?: Nullable<SpinData>): void;
117
120
  setFreeSpinNumberBought(newValue: number): void;
121
+ setHandleInvokeFreeSpinPlate(callback: (freeSpinAmount: number, isAdditionalFreeSpin: boolean) => Promise<void>): void;
118
122
  resetFreeSpinNumberBought(): void;
119
123
  setRoundNumber(newValue: number): void;
120
124
  setModalsAvailability(flag: boolean): void;
@@ -41,6 +41,7 @@ export class SettingsStore {
41
41
  balancedDecreased = 0;
42
42
  howManyFreeSpinsLeft = 0;
43
43
  howManyAutoSpinsLeft = INITIAL_AUTO_SPIN_COUNT;
44
+ freeSpinBuyTable = {};
44
45
  volumeLevel = getFromLocalStorage(LOCAL_STORAGE.volumeLevel, 100);
45
46
  popupPaytablePosition;
46
47
  popupPaytableData;
@@ -50,6 +51,7 @@ export class SettingsStore {
50
51
  popupPaytableRepositionCallback;
51
52
  updateVolumeButtonTexture;
52
53
  handleModalInvocation;
54
+ handleInvokeFreeSpinPlate;
53
55
  increaseBet;
54
56
  decreaseBet;
55
57
  enableButtons;
@@ -129,6 +131,9 @@ export class SettingsStore {
129
131
  resetCumulativeWinAmount() {
130
132
  this.cumulativeWinAmount = 0;
131
133
  }
134
+ setFreeSpinsPriceTable(freeSpinsPriceTable) {
135
+ this.freeSpinBuyTable = freeSpinsPriceTable;
136
+ }
132
137
  /**
133
138
  * Sets bet value
134
139
  * @param {number} newBet updated bet value
@@ -333,6 +338,11 @@ export class SettingsStore {
333
338
  }
334
339
  setFreeSpinNumberBought(newValue) {
335
340
  this.freeSpinNumberBought = newValue;
341
+ this.howManyFreeSpinsLeft = newValue;
342
+ this.totalNumberOfFreeSpins = newValue;
343
+ }
344
+ setHandleInvokeFreeSpinPlate(callback) {
345
+ this.handleInvokeFreeSpinPlate = callback;
336
346
  }
337
347
  resetFreeSpinNumberBought() {
338
348
  this.freeSpinNumberBought = 0;
@@ -72,7 +72,7 @@ export const waitForAnimationToEnd = async (spine, animationName, loopAnimationN
72
72
  if (loopAnimationName)
73
73
  spine.state.setAnimation(0, loopAnimationName, true);
74
74
  resolve();
75
- },
75
+ }
76
76
  });
77
77
  });
78
78
  };
@@ -8,7 +8,7 @@ export const scaleToParent = (width, height, parentWidth, parentHeight) => {
8
8
  // some dependent size. image, figure etc.
9
9
  target: new Size(width, height),
10
10
  // policy is optional. default is null
11
- policy: POLICY.ShowAll, // null | ExactFit | NoBorder | FullHeight | FullWidth | ShowAll
11
+ policy: POLICY.ShowAll // null | ExactFit | NoBorder | FullHeight | FullWidth | ShowAll
12
12
  });
13
13
  };
14
14
  const getMobileScreenRatio = () => {
@@ -1,7 +1,8 @@
1
1
  export type Nullable<T> = T | null;
2
2
  export type PlayableAction = () => Promise<void> | Promise<void[]>;
3
- export type VoidPromiseResolver = (value: void | PromiseLike<void>) => void;
4
3
  export type DeviceOrientation = "pc" | "mobile-portrait" | "mobile-landscape";
5
4
  export type DeepPartial<T> = T extends object ? {
6
5
  [P in keyof T]?: DeepPartial<T[P]>;
7
6
  } : T;
7
+ export type VoidFunction = () => void;
8
+ export type PromiseResolverType<T = void> = (value: T | PromiseLike<T>) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "This repository contains all of the mechanics that used in rainman games.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",