pixi-rainman-game-engine 0.3.33-beta.2 → 0.3.34

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.
@@ -10,8 +10,5 @@ export declare class DescribedPlayableAction<T> {
10
10
  winAmount: Nullable<number>;
11
11
  skipLooping: boolean;
12
12
  isFirstStreak: boolean;
13
- animationTarget: {
14
- isCurrentAnimationPastHalf?: () => boolean;
15
- } | null;
16
13
  constructor(type: T, action: PlayableAction, winAmount?: Nullable<number>, skipLooping?: boolean);
17
14
  }
@@ -9,7 +9,6 @@ export class DescribedPlayableAction {
9
9
  winAmount;
10
10
  skipLooping;
11
11
  isFirstStreak = false;
12
- animationTarget = null;
13
12
  constructor(type, action, winAmount = null, skipLooping = false) {
14
13
  this.type = type;
15
14
  this.action = action;
@@ -81,6 +81,7 @@ export interface Globals {
81
81
  disableSpeedPopup?: (value: boolean) => void;
82
82
  handleDisablingButtons?: (value?: boolean) => void;
83
83
  throttledSpin?: () => void;
84
+ handleSpinLogic?: () => void;
84
85
  prepareBoughtFreeSpins?: () => void;
85
86
  updateFreeSpinShown?: (value: number) => void;
86
87
  backendSymbolMap?: Map<number, never>;
@@ -1,6 +1,5 @@
1
1
  import { autorun } from "mobx";
2
2
  import { useEffect, useState } from "react";
3
- import { RainMan } from "../../../Rainman";
4
3
  /**
5
4
  * Get the available options for buying free spins
6
5
  * @returns {BuyFreeSpinOption[]} the available options for buying free spins
@@ -9,10 +8,7 @@ export const useBuyFreeSpinOptions = () => {
9
8
  const [options, setOptions] = useState([]);
10
9
  useEffect(() => {
11
10
  const disposer = autorun(() => {
12
- setOptions(Object.entries(RainMan.settingsStore.freeSpinBuyTable ?? {}).map(([amount, multiplier]) => ({
13
- amount: parseInt(amount, 10),
14
- price: multiplier
15
- })));
11
+ setOptions([]);
16
12
  });
17
13
  return () => disposer();
18
14
  }, []);
@@ -1,3 +1,4 @@
1
+ import { BuyType } from "connectivity";
1
2
  import { Container, Sprite } from "pixi.js";
2
3
  import { BuyFreeSpinOption } from "SettingsUI/hooks";
3
4
  import { AcceptDeclineButton } from "./AcceptDeclineButton";
@@ -6,6 +7,7 @@ export type BuyFreeSpinConfig = {
6
7
  };
7
8
  export type BuyFreeSpinState = "selection" | "confirmation";
8
9
  export declare abstract class AbstractBuyFreeSpinsPlate extends Container {
10
+ private buyType;
9
11
  private state;
10
12
  protected selectedOption?: BuyFreeSpinOption;
11
13
  protected readonly config: BuyFreeSpinConfig;
@@ -19,7 +21,7 @@ export declare abstract class AbstractBuyFreeSpinsPlate extends Container {
19
21
  private readonly onContinueCallback;
20
22
  private readonly resizeHandler;
21
23
  private handleClose;
22
- protected constructor(onContinue: () => void, config: BuyFreeSpinConfig);
24
+ protected constructor(onContinue: () => void, config: BuyFreeSpinConfig, buyType: BuyType);
23
25
  init(): void;
24
26
  private createElements;
25
27
  resize(): void;
@@ -4,6 +4,7 @@ import { RainMan } from "../../Rainman";
4
4
  import { scaleToParent } from "../../utils";
5
5
  import { AcceptDeclineButton } from "./AcceptDeclineButton";
6
6
  export class AbstractBuyFreeSpinsPlate extends Container {
7
+ buyType;
7
8
  state = "selection";
8
9
  selectedOption;
9
10
  config;
@@ -21,8 +22,9 @@ export class AbstractBuyFreeSpinsPlate extends Container {
21
22
  this.onContinueCallback();
22
23
  RainMan.settingsStore.disableKeyboardShortcuts = false;
23
24
  };
24
- constructor(onContinue, config) {
25
+ constructor(onContinue, config, buyType) {
25
26
  super();
27
+ this.buyType = buyType;
26
28
  RainMan.settingsStore.disableKeyboardShortcuts = true;
27
29
  this.onContinueCallback = onContinue;
28
30
  this.config = config;
@@ -133,29 +135,47 @@ export class AbstractBuyFreeSpinsPlate extends Container {
133
135
  }
134
136
  async onAcceptClick(option) {
135
137
  const roundNumber = RainMan.settingsStore.roundNumber + 1;
136
- try {
137
- const data = await window.connectionWrapper.fetchFreeSpinData(roundNumber, option.amount, option.price);
138
- const code = data.getRawData()?.status?.code;
139
- if (code === 400 || code === 406) {
138
+ switch (this.buyType) {
139
+ case "free-spins":
140
+ try {
141
+ const data = await window.connectionWrapper.fetchFreeSpinData(roundNumber, option.amount, option.price);
142
+ const code = data.getRawData()?.status?.code;
143
+ if (code === 400 || code === 406) {
144
+ return;
145
+ }
146
+ RainMan.settingsStore.setIsFreeSpinBought(true, data);
147
+ RainMan.settingsStore.setFreeSpinNumberBought(option.amount);
148
+ RainMan.globals.updateFreeSpinShown?.(option.amount);
149
+ RainMan.settingsStore.setRoundNumber(roundNumber);
150
+ this.cleanup();
151
+ this.onContinueCallback();
152
+ await RainMan.settingsStore.handleInvokeFreeSpinPlate?.(option.amount, false);
153
+ RainMan.settingsStore.disableKeyboardShortcuts = false;
154
+ RainMan.globals.prepareBoughtFreeSpins?.();
155
+ RainMan.globals.throttledSpin?.();
156
+ }
157
+ catch (err) {
158
+ console.error(err);
159
+ RainMan.settingsStore.setIsFreeSpinBought(false);
160
+ RainMan.settingsStore.disableKeyboardShortcuts = false;
161
+ }
140
162
  return;
141
- }
142
- RainMan.settingsStore.setIsFreeSpinBought(true, data);
143
- RainMan.settingsStore.setFreeSpinNumberBought(option.amount);
144
- RainMan.globals.updateFreeSpinShown?.(option.amount);
145
- RainMan.settingsStore.setRoundNumber(roundNumber);
146
- this.cleanup();
147
- this.onContinueCallback();
148
- await RainMan.settingsStore.handleInvokeFreeSpinPlate?.(option.amount, false);
149
- RainMan.settingsStore.disableKeyboardShortcuts = false;
150
- RainMan.globals.prepareBoughtFreeSpins?.();
151
- setTimeout(() => {
152
- RainMan.globals.throttledSpin?.();
153
- }, 500);
154
- }
155
- catch (err) {
156
- console.error(err);
157
- RainMan.settingsStore.setIsFreeSpinBought(false);
158
- RainMan.settingsStore.disableKeyboardShortcuts = false;
163
+ case "joker":
164
+ try {
165
+ const data = await window.connectionWrapper.fetchJokerData(roundNumber, option.price);
166
+ const code = data.getRawData()?.status?.code;
167
+ if (code === 400 || code === 406) {
168
+ return;
169
+ }
170
+ const r = roundNumber + 1;
171
+ RainMan.settingsStore.setRoundNumber(r);
172
+ this.cleanup();
173
+ this.onContinueCallback();
174
+ setTimeout(() => {
175
+ RainMan.globals.handleSpinLogic?.();
176
+ }, 1000);
177
+ }
178
+ catch (err) { }
159
179
  }
160
180
  }
161
181
  renderState() {
@@ -98,7 +98,6 @@ export declare abstract class AbstractSymbolBase extends Container implements Sp
98
98
  * @returns {Promise<void>} - A promise that resolves when the animation is complete
99
99
  */
100
100
  play(suffix?: string): Promise<void>;
101
- isCurrentAnimationPastHalf(): boolean;
102
101
  /**
103
102
  * Function for stopping the symbol animation.
104
103
  * @public
@@ -214,18 +214,6 @@ export class AbstractSymbolBase extends Container {
214
214
  });
215
215
  });
216
216
  }
217
- isCurrentAnimationPastHalf() {
218
- const entry = this.spine.state.tracks[0];
219
- if (!entry) {
220
- return false;
221
- }
222
- const trackTime = entry.trackTime ?? 0;
223
- const animationEnd = entry.animationEnd ?? 0;
224
- if (animationEnd <= 0) {
225
- return false;
226
- }
227
- return trackTime >= animationEnd / 2;
228
- }
229
217
  /**
230
218
  * Function for stopping the symbol animation.
231
219
  * @public
@@ -64,6 +64,14 @@ export declare class ConnectionWrapper implements SubscribableConnectionWrapper
64
64
  * @returns {SpinData} spin data
65
65
  */
66
66
  fetchFreeSpinData(roundNumber: number, quantity: number, price: number): Promise<SpinData>;
67
+ /**
68
+ * Method for fetching joker data from the server
69
+ * @public
70
+ * @param {number} roundNumber round number
71
+ * @param {number} price price of joker
72
+ * @returns {SpinData} spin data
73
+ */
74
+ fetchJokerData(roundNumber: number, price: number): Promise<SpinData>;
67
75
  /**
68
76
  * Method for fetching spin data from the server
69
77
  * @public
@@ -98,7 +98,9 @@ export class ConnectionWrapper {
98
98
  vendor_id: RainMan.config.gameInitVendorId
99
99
  }));
100
100
  RainMan.globals.currency = Currencies[this._initData.currency];
101
- RainMan.settingsStore.setFreeSpinsPriceTable(this._initData.free_spins_buy_table);
101
+ RainMan.settingsStore.setFreeSpinsBuyOptions(this._initData.buy_table?.["free-spins"] ?? []);
102
+ RainMan.settingsStore.setJokerBuyOptions(this._initData.buy_table?.["joker"] ?? []);
103
+ RainMan.settingsStore.setGameBuyTypes(this._initData.buy_types ?? []);
102
104
  RainMan.settingsStore.setRoundNumber(this._initData.round_number);
103
105
  if (this._initData.status?.code && this._initData.status.code >= 400) {
104
106
  throw new Error(`Init failed with status code: ${this._initData.status?.code}: ${this._initData.status?.message}`);
@@ -126,7 +128,7 @@ export class ConnectionWrapper {
126
128
  }
127
129
  const data = (await this.fetch({
128
130
  action: "buy",
129
- operation: "buy-free-spins",
131
+ operation: "free-spins",
130
132
  buy_price: price,
131
133
  round_number: roundNumber,
132
134
  token: this.config.token,
@@ -139,6 +141,30 @@ export class ConnectionWrapper {
139
141
  RainMan.settingsStore.setRoundNumber(data.round_number);
140
142
  return new SpinData(this.config, data);
141
143
  }
144
+ /**
145
+ * Method for fetching joker data from the server
146
+ * @public
147
+ * @param {number} roundNumber round number
148
+ * @param {number} price price of joker
149
+ * @returns {SpinData} spin data
150
+ */
151
+ async fetchJokerData(roundNumber, price) {
152
+ if (typeof this.config?.token === "undefined") {
153
+ throw new Error("Token was not defined");
154
+ }
155
+ const data = (await this.fetch({
156
+ action: "buy",
157
+ operation: "joker",
158
+ buy_price: price,
159
+ round_number: roundNumber,
160
+ token: this.config.token,
161
+ reference: RainMan.config.gameInitReference,
162
+ bet: RainMan.settingsStore.bet,
163
+ extra_data: {}
164
+ }));
165
+ RainMan.settingsStore.setRoundNumber(data.round_number);
166
+ return new SpinData(this.config, data);
167
+ }
142
168
  /**
143
169
  * Method for fetching spin data from the server
144
170
  * @public
@@ -77,13 +77,24 @@ export type MiniGameRequest = {
77
77
  */
78
78
  export type BuyFreeSpinServerRequest = BaseServerRequest & {
79
79
  action: "buy";
80
- operation: "buy-free-spins";
80
+ operation: "free-spins";
81
81
  bet: number;
82
82
  buy_price: number;
83
83
  extra_data: {
84
84
  free_spins_quantity: number;
85
85
  };
86
86
  };
87
+ /**
88
+ * Request for buying joker spin
89
+ * @typedef {BuyJokerServerRequest}
90
+ */
91
+ export type BuyJokerServerRequest = BaseServerRequest & {
92
+ action: "buy";
93
+ operation: "joker";
94
+ bet: number;
95
+ buy_price: number;
96
+ extra_data: object;
97
+ };
87
98
  /**
88
99
  * Request for gambling
89
100
  * @typedef {GambleServerRequest}
@@ -118,7 +129,7 @@ export interface ExtraDataRequest {
118
129
  * This is the structure of a server request.
119
130
  * @typedef {ServerRequest}
120
131
  */
121
- export type ServerRequest = InitServerRequest | MiniGameRequest | SpinServerRequest | BuyFreeSpinServerRequest | GambleServerRequest | EndServerRequest | TakeServerRequest;
132
+ export type ServerRequest = InitServerRequest | MiniGameRequest | SpinServerRequest | BuyFreeSpinServerRequest | BuyJokerServerRequest | GambleServerRequest | EndServerRequest | TakeServerRequest;
122
133
  /**
123
134
  * This is the structure of a message sent from the server.
124
135
  * @typedef {ServerMessage}
@@ -1,6 +1,22 @@
1
1
  import { PaytableTypes } from "../constants";
2
2
  import { Nullable } from "../utils";
3
3
  import { Point, RawTransformationDetails } from "./transformation";
4
+ export type BuyType = "free-spins" | "joker" | string;
5
+ export interface BaseBuyOption {
6
+ bet_multiplier: number;
7
+ }
8
+ export interface FreeSpinsBuyOption extends BaseBuyOption {
9
+ spin_quantity: number;
10
+ }
11
+ export interface JokerBuyOption extends BaseBuyOption {
12
+ symbol_quantity: number;
13
+ }
14
+ export type BuyTable = Partial<{
15
+ "free-spins": FreeSpinsBuyOption[];
16
+ joker: JokerBuyOption[];
17
+ }> & {
18
+ [key: string]: BaseBuyOption[] | undefined;
19
+ };
4
20
  export interface InitDataInterface {
5
21
  action: string;
6
22
  balance: number;
@@ -20,8 +36,8 @@ export interface InitDataInterface {
20
36
  wins_names: Array<string>;
21
37
  transformations_names: Array<string>;
22
38
  transformations_types: Array<number>;
23
- free_spins_buy_table?: Record<number, number>;
24
- free_spins_prize_table?: Record<number, number>;
39
+ buy_types?: BuyType[];
40
+ buy_table?: BuyTable;
25
41
  paytable: PayTableInterface;
26
42
  reinit_data?: SpinDataInterface[];
27
43
  extra_data: InitExtraData;
@@ -149,6 +165,14 @@ export interface FreeSpinDataInterface {
149
165
  status: Status;
150
166
  symbols_on_reels: number[][];
151
167
  }
168
+ export interface JokerDataInterface {
169
+ action: "buy";
170
+ available_free_spins: number;
171
+ balance: number;
172
+ round_number: number;
173
+ status: Status;
174
+ symbols_on_reels: number[][];
175
+ }
152
176
  export type GambleCardColor = "black" | "red" | "joker";
153
177
  export type GambleCard = "clubs" | "spades" | "hearts" | "diamonds" | "joker";
154
178
  export interface RawWin {
@@ -59,9 +59,6 @@ export declare abstract class AbstractController<T> {
59
59
  shouldStopMobileSpin: boolean;
60
60
  disableMessageBoxChange: boolean;
61
61
  shouldClearQuickReelsStopAfterSpin: boolean;
62
- protected firstAnimationTarget: {
63
- isCurrentAnimationPastHalf?: () => boolean;
64
- } | null;
65
62
  protected resolveBigWin?: () => void;
66
63
  protected resolveMysteryWin?: () => void;
67
64
  protected resolveBonusWin?: () => void;
@@ -59,7 +59,6 @@ export class AbstractController {
59
59
  shouldStopMobileSpin = false;
60
60
  disableMessageBoxChange = false;
61
61
  shouldClearQuickReelsStopAfterSpin = false;
62
- firstAnimationTarget = null;
63
62
  resolveBigWin;
64
63
  resolveMysteryWin;
65
64
  resolveBonusWin;
@@ -105,6 +104,7 @@ export class AbstractController {
105
104
  RainMan.settingsStore.setRoundNumber(this.roundNumber);
106
105
  RainMan.settingsStore.initPaytableMap(initData);
107
106
  RainMan.globals.throttledSpin = this.throttledSpin.bind(this);
107
+ RainMan.globals.handleSpinLogic = this.handleSpinLogic.bind(this);
108
108
  RainMan.globals.prepareBoughtFreeSpins = this.prepareBoughtFreeSpins.bind(this);
109
109
  RainMan.settingsStore.useTakeAction = this.useTakeAction.bind(this);
110
110
  this.connection.subscribeForConfigChanges(this.reinitializeUserBalanceData.bind(this));
@@ -1144,8 +1144,6 @@ export class AbstractController {
1144
1144
  this.uiController.limitWinAmount(spinLogic.winTotalAmount);
1145
1145
  }
1146
1146
  this.composeWinActionsQueue(spinLogic);
1147
- this.firstAnimationTarget =
1148
- this.winActionsQueue.find((action) => action.animationTarget)?.animationTarget ?? null;
1149
1147
  if (spinLogic.winTotalAmount === 0 && this.invokeFreeSpinPlateAfterWin) {
1150
1148
  this.uiController.messageBox.hideCurrentWinText();
1151
1149
  }
@@ -149,6 +149,7 @@ export declare class UiController {
149
149
  updateShownPossibleWin(): void;
150
150
  /**
151
151
  * Shows game pays in a bottom panel, if exists
152
+ * @param amount
152
153
  * @public
153
154
  * @returns {void}
154
155
  */
@@ -216,6 +216,7 @@ export class UiController {
216
216
  }
217
217
  /**
218
218
  * Shows game pays in a bottom panel, if exists
219
+ * @param amount
219
220
  * @public
220
221
  * @returns {void}
221
222
  */
@@ -1,6 +1,6 @@
1
1
  import { SpeedLevel, SymbolId } from "../application";
2
2
  import { ResumableContainer, SpineWithResumableContainer, SpriteWithResumableContainer } from "../components";
3
- import { InitDataInterface, Point, RangeQuantityValue, SpinData, SpinDataInterface } from "../connectivity";
3
+ import { BuyType, FreeSpinsBuyOption, InitDataInterface, JokerBuyOption, Point, RangeQuantityValue, SpinData, SpinDataInterface } from "../connectivity";
4
4
  import { Nullable } from "../utils";
5
5
  import { PaytableData } from "./types";
6
6
  /**
@@ -44,7 +44,9 @@ export declare class SettingsStore {
44
44
  howManyFreeSpinsLeft: number;
45
45
  balanceAfterSpin: number;
46
46
  howManyAutoSpinsLeft: number;
47
- freeSpinBuyTable: Record<number, number>;
47
+ freeSpinsBuyOptions: FreeSpinsBuyOption[];
48
+ jokerBuyOptions: JokerBuyOption[];
49
+ gameBuyTypes: BuyType[];
48
50
  volumeLevel: number;
49
51
  wasVolumeChanged: boolean;
50
52
  popupPaytablePosition?: Point;
@@ -134,10 +136,26 @@ export declare class SettingsStore {
134
136
  /**
135
137
  * Sets the free spins price table.
136
138
  * @public
139
+ * @param freeSpinsBuyOptions
137
140
  * @param {Record<number, number>} freeSpinsPriceTable table with free spins prices
138
141
  * @returns {void}
139
142
  */
140
- setFreeSpinsPriceTable(freeSpinsPriceTable: Record<number, number>): void;
143
+ setFreeSpinsBuyOptions(freeSpinsBuyOptions: FreeSpinsBuyOption[]): void;
144
+ /**
145
+ * Sets the joker win price table.
146
+ * @public
147
+ * @param {Record<number, number>} jokerBuyOption table with joker win prices
148
+ * @returns {void}
149
+ */
150
+ setJokerBuyOptions(jokerBuyOption: JokerBuyOption[]): void;
151
+ /**
152
+ * Sets the free spins price table.
153
+ * @public
154
+ * @param buyTypes
155
+ * @param {Record<number, number>} jokerBuyOption table with free spins prices
156
+ * @returns {void}
157
+ */
158
+ setGameBuyTypes(buyTypes: BuyType[]): void;
141
159
  /**
142
160
  * Sets bet value
143
161
  * @public
@@ -48,7 +48,10 @@ export class SettingsStore {
48
48
  howManyFreeSpinsLeft = 0;
49
49
  balanceAfterSpin = 0;
50
50
  howManyAutoSpinsLeft = INITIAL_AUTO_SPIN_COUNT;
51
- freeSpinBuyTable = {};
51
+ // public freeSpinBuyTable: Record<number, number> = {};
52
+ freeSpinsBuyOptions = [];
53
+ jokerBuyOptions = [];
54
+ gameBuyTypes = [];
52
55
  volumeLevel = Number(getFromLocalStorage(LOCAL_STORAGE.volumeLevel, 100));
53
56
  wasVolumeChanged = false;
54
57
  popupPaytablePosition;
@@ -215,11 +218,31 @@ export class SettingsStore {
215
218
  /**
216
219
  * Sets the free spins price table.
217
220
  * @public
221
+ * @param freeSpinsBuyOptions
218
222
  * @param {Record<number, number>} freeSpinsPriceTable table with free spins prices
219
223
  * @returns {void}
220
224
  */
221
- setFreeSpinsPriceTable(freeSpinsPriceTable) {
222
- this.freeSpinBuyTable = freeSpinsPriceTable;
225
+ setFreeSpinsBuyOptions(freeSpinsBuyOptions) {
226
+ this.freeSpinsBuyOptions = freeSpinsBuyOptions;
227
+ }
228
+ /**
229
+ * Sets the joker win price table.
230
+ * @public
231
+ * @param {Record<number, number>} jokerBuyOption table with joker win prices
232
+ * @returns {void}
233
+ */
234
+ setJokerBuyOptions(jokerBuyOption) {
235
+ this.jokerBuyOptions = jokerBuyOption;
236
+ }
237
+ /**
238
+ * Sets the free spins price table.
239
+ * @public
240
+ * @param buyTypes
241
+ * @param {Record<number, number>} jokerBuyOption table with free spins prices
242
+ * @returns {void}
243
+ */
244
+ setGameBuyTypes(buyTypes) {
245
+ this.gameBuyTypes = buyTypes;
223
246
  }
224
247
  /**
225
248
  * Sets bet value
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.3.33-beta.2",
3
+ "version": "0.3.34",
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",