pixi-rainman-game-engine 0.3.2 → 0.3.3-b

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.
@@ -81,6 +81,13 @@ export declare class ComponentRegistry {
81
81
  * @returns {void}
82
82
  */
83
83
  updateAllSpeedAdaptable(speedLevel: SpeedLevel): void;
84
+ /**
85
+ * Function that adapt temporary speed to be applied only for reels and not for symbols.
86
+ * @public
87
+ * @param speedLevel
88
+ * @returns {void}
89
+ */
90
+ updateTemporaryReelSpeed(speedLevel: SpeedLevel): void;
84
91
  /**
85
92
  * Getter for components that are in ComponentRegistry
86
93
  * Throws error if component is not present
@@ -1,5 +1,5 @@
1
1
  import { isIncentiveComponentInterface, isSpeedAdapterInterface, SpeedLevelHandler, TimedIncentiveController } from "../application";
2
- import { SpeedControlButton } from "../components";
2
+ import { AbstractSymbolsColumn, SpeedControlButton } from "../components";
3
3
  import { RainMan } from "../Rainman";
4
4
  import { openFullscreen } from "../utils";
5
5
  /**
@@ -28,7 +28,7 @@ export class ComponentRegistry {
28
28
  */
29
29
  setTemporarySpeedLevel(newSpeedLevel) {
30
30
  this.speedLevelHandler.setSpeed(newSpeedLevel);
31
- this.updateAllSpeedAdaptable(newSpeedLevel);
31
+ this.updateTemporaryReelSpeed(newSpeedLevel);
32
32
  }
33
33
  /**
34
34
  * Method for reverting speed level for turbo spin
@@ -37,7 +37,7 @@ export class ComponentRegistry {
37
37
  */
38
38
  revertTemporarySpeedLevel() {
39
39
  this.speedLevelHandler.setSpeed(RainMan.settingsStore.currentSpeed);
40
- this.updateAllSpeedAdaptable(RainMan.settingsStore.currentSpeed);
40
+ this.updateTemporaryReelSpeed(RainMan.settingsStore.currentSpeed);
41
41
  }
42
42
  /**
43
43
  * Setter fo speed level
@@ -142,6 +142,19 @@ export class ComponentRegistry {
142
142
  speedAdaptableComponent.adaptToSpeed(speedLevel);
143
143
  });
144
144
  }
145
+ /**
146
+ * Function that adapt temporary speed to be applied only for reels and not for symbols.
147
+ * @public
148
+ * @param speedLevel
149
+ * @returns {void}
150
+ */
151
+ updateTemporaryReelSpeed(speedLevel) {
152
+ this.speedAdaptableComponents.forEach((speedAdaptableComponent) => {
153
+ if (!(speedAdaptableComponent instanceof AbstractSymbolsColumn)) {
154
+ speedAdaptableComponent.adaptToSpeed(speedLevel);
155
+ }
156
+ });
157
+ }
145
158
  /**
146
159
  * Getter for components that are in ComponentRegistry
147
160
  * Throws error if component is not present
@@ -74,6 +74,7 @@ export class ButtonsEventManager {
74
74
  RainMan.settingsStore.handleModalInvocation = this.handleModalInvocation.bind(this);
75
75
  RainMan.settingsStore.setSpeedPopupVisibility = this.setSpeedPopupVisibility.bind(this);
76
76
  RainMan.settingsStore.enableButtons = this.enableButtons.bind(this);
77
+ RainMan.settingsStore.closeOtherModals = this.closeOtherModals.bind(this);
77
78
  }
78
79
  /**
79
80
  * Method for initializing events in Settings UI
@@ -376,11 +377,9 @@ export class ButtonsEventManager {
376
377
  if (layer !== null) {
377
378
  if (layer.style.display !== "flex") {
378
379
  layer.style.display = "flex";
379
- this.disableButtons();
380
380
  }
381
381
  else {
382
382
  layer.style.display = "none";
383
- this.enableButtons();
384
383
  }
385
384
  }
386
385
  }
@@ -51,6 +51,12 @@ export declare class SoundManagerInstance implements SpeedAdapterInterface<Sound
51
51
  * @returns {void}
52
52
  */
53
53
  play(soundName: SoundTrack): void;
54
+ /**
55
+ * Returns the volume level for a given sound track.
56
+ * @param {SoundTracks} soundName - The name of the sound track.
57
+ * @returns {number} The volume level for the sound track.
58
+ */
59
+ getVolumeLevel(soundName: SoundTrack): number;
54
60
  /**
55
61
  * Function for resuming all sounds in game
56
62
  * If sound is not playing, it will be skipped
@@ -37,13 +37,15 @@ export class SoundManagerInstance {
37
37
  async loadSounds(assets) {
38
38
  const loadingSoundsPromises = [];
39
39
  for (const [soundName, url] of Object.entries(assets)) {
40
- if (!url)
40
+ if (!url) {
41
41
  continue;
42
+ }
42
43
  loadingSoundsPromises.push(new Promise((resolve) => {
43
44
  const sound = Sound.from({
44
45
  url,
45
46
  autoPlay: false,
46
47
  preload: true,
48
+ volume: this.getVolumeLevel(soundName),
47
49
  loaded: () => resolve()
48
50
  });
49
51
  sound.name = soundName;
@@ -59,12 +61,17 @@ export class SoundManagerInstance {
59
61
  * @returns {void}
60
62
  */
61
63
  setVolume(volumeLevel) {
62
- this.musicCatalogue.forEach((sound) => {
63
- if (sound?.name === "music") {
64
- sound.volume = volumeLevel * 0.5;
65
- }
66
- else {
67
- sound.volume = volumeLevel;
64
+ this.musicCatalogue.forEach((sound, soundName) => {
65
+ switch (soundName) {
66
+ case SoundTracks.music:
67
+ sound.volume = volumeLevel * 0.5;
68
+ break;
69
+ case SoundTracks.freeSpinsMusic:
70
+ sound.volume = volumeLevel * 0.95;
71
+ break;
72
+ default:
73
+ sound.volume = volumeLevel;
74
+ break;
68
75
  }
69
76
  });
70
77
  }
@@ -75,8 +82,9 @@ export class SoundManagerInstance {
75
82
  */
76
83
  stopPlayingFxSounds() {
77
84
  for (const [soundName, sound] of this.musicCatalogue.entries()) {
78
- if (soundName === SoundTracks.music)
85
+ if (soundName === SoundTracks.music) {
79
86
  continue;
87
+ }
80
88
  sound.stop();
81
89
  }
82
90
  }
@@ -113,15 +121,33 @@ export class SoundManagerInstance {
113
121
  !RainMan.settingsStore.shouldPlayAmbientMusic) {
114
122
  return;
115
123
  }
116
- const soundLevel = RainMan.settingsStore.volumeLevel / 100;
124
+ if (soundName === "freeSpinsMusic" &&
125
+ sound.isPlaying &&
126
+ RainMan.settingsStore.isFreeSpinsPlayEnabled &&
127
+ !RainMan.settingsStore.shouldPlayAmbientMusic) {
128
+ return;
129
+ }
117
130
  sound.play({
118
- loop: soundsToLoop.includes(soundName),
119
131
  singleInstance: true,
120
- volume: soundName === SoundTracks.music || soundName === SoundTracks.freeSpinsMusic
121
- ? soundLevel * 0.5
122
- : soundLevel
132
+ loop: soundsToLoop.includes(soundName),
133
+ volume: this.getVolumeLevel(soundName)
123
134
  });
124
135
  }
136
+ /**
137
+ * Returns the volume level for a given sound track.
138
+ * @param {SoundTracks} soundName - The name of the sound track.
139
+ * @returns {number} The volume level for the sound track.
140
+ */
141
+ getVolumeLevel(soundName) {
142
+ switch (soundName) {
143
+ case SoundTracks.music:
144
+ return Number((RainMan.settingsStore.volumeLevel / 100) * 0.5);
145
+ case SoundTracks.freeSpinsMusic:
146
+ return Number((RainMan.settingsStore.volumeLevel / 100) * 0.95);
147
+ default:
148
+ return Number(RainMan.settingsStore.volumeLevel / 100);
149
+ }
150
+ }
125
151
  /**
126
152
  * Function for resuming all sounds in game
127
153
  * If sound is not playing, it will be skipped
@@ -58,12 +58,7 @@ export class AbstractMainContainer extends Container {
58
58
  this.name = AbstractMainContainer.registryName;
59
59
  this.buttonsEventManager = new ButtonsEventManager();
60
60
  this.messageBox = new MessageBox();
61
- if (RainMan.settingsStore.isSoundEnabled()) {
62
- SoundManager.resumeAll();
63
- if (RainMan.settingsStore.shouldPlayAmbientMusic) {
64
- SoundManager.setPlayStatus(SoundTracks.music, RainMan.settingsStore.shouldPlayAmbientMusic);
65
- }
66
- }
61
+ SoundManager.setPlayStatus(SoundTracks.music, RainMan.settingsStore.shouldPlayAmbientMusic);
67
62
  RainMan.settingsStore.setHandleInvokeFreeSpinPlate(this.invokeFreeSpinPlate.bind(this));
68
63
  RainMan.app.renderer.on("resize", () => this.resize());
69
64
  }
@@ -1,3 +1,4 @@
1
+ import { RainMan } from "../../../Rainman";
1
2
  import { getTexture } from "../../../utils";
2
3
  import { BaseButton, ButtonStates } from "../BaseButton";
3
4
  const createTextureMap = (speedLevel) => {
@@ -33,6 +34,9 @@ export class SpeedControlButton extends BaseButton {
33
34
  * @returns {void}
34
35
  */
35
36
  adaptToSpeed(speedLevel) {
37
+ if (RainMan.settingsStore.isTemporarySpeed) {
38
+ return;
39
+ }
36
40
  this.setTextureMap(this.speedLevelMapper[speedLevel]);
37
41
  }
38
42
  }
@@ -74,6 +74,7 @@ export class AbstractColumnsContainer extends Container {
74
74
  */
75
75
  enableQuickReelsStop() {
76
76
  this.quickReelsStop = true;
77
+ RainMan.settingsStore.setIsTemporarySpeed(true);
77
78
  RainMan.componentRegistry.setTemporarySpeedLevel(SPEED_LEVELS.fast);
78
79
  this.skipScatterDelay?.();
79
80
  this.resolveMysterySpeedUp();
@@ -47,10 +47,10 @@ export class MessageBox extends Container {
47
47
  this.positioningFrame.drawRect(0, 0, 800, 150);
48
48
  this.addChild(this.positioningFrame);
49
49
  this.parentLayer = UXLayer;
50
- this.freeSpinText = new UpdatableTextComponent(MessageBox.freeSpinTextRegistryName, i18n.t("currentFreeSpins"), UPDATABLE_MODES.int, fontSize, new Color(0xffffff).toHex(), () => this.centerTextOnX(this.freeSpinText));
51
- this.autoSpinText = new UpdatableTextComponent(MessageBox.autoSpinTextRegistryName, i18n.t("autoSpinsLeft"), UPDATABLE_MODES.int, fontSize, new Color(0xffffff).toHex(), () => this.centerTextOnX(this.autoSpinText));
52
- this.currentWinText = new UpdatableTextComponent(MessageBox.currentWinTextRegistryName, i18n.t("currentWin"), UPDATABLE_MODES.money, fontSize, undefined, () => this.centerTextOnX(this.currentWinText));
53
- this.possibleWinText = new UpdatableTextComponent(MessageBox.possibleWinTextRegistryName, i18n.t("possibleWin"), UPDATABLE_MODES.money, fontSize, undefined, () => this.centerTextOnX(this.possibleWinText));
50
+ this.freeSpinText = new UpdatableTextComponent(MessageBox.freeSpinTextRegistryName, i18n.t("currentFreeSpins"), UPDATABLE_MODES.int, fontSize - 5, new Color(0xffffff).toHex(), () => this.centerTextOnX(this.freeSpinText));
51
+ this.autoSpinText = new UpdatableTextComponent(MessageBox.autoSpinTextRegistryName, i18n.t("autoSpinsLeft"), UPDATABLE_MODES.int, fontSize - 5, new Color(0xffffff).toHex(), () => this.centerTextOnX(this.autoSpinText));
52
+ this.currentWinText = new UpdatableTextComponent(MessageBox.currentWinTextRegistryName, i18n.t("currentWin"), UPDATABLE_MODES.money, fontSize + 15, undefined, () => this.centerTextOnX(this.currentWinText));
53
+ this.possibleWinText = new UpdatableTextComponent(MessageBox.possibleWinTextRegistryName, i18n.t("possibleWin"), UPDATABLE_MODES.money, fontSize + 15, undefined, () => this.centerTextOnX(this.possibleWinText));
54
54
  this.incentiveText = new Text(sample(i18n.t("idleMessages", { returnObjects: true })[RainMan.componentRegistry.getSpeedLevel()]), {
55
55
  fontFamily: RainMan.config.fontFace,
56
56
  fontSize,
@@ -286,8 +286,8 @@ export class MessageBox extends Container {
286
286
  this.hideFreeSpinText();
287
287
  this.hideAutoSpinText();
288
288
  const fontSize = getDeviceOrientation().includes("mobile")
289
- ? RainMan.config.mobileFontSize
290
- : RainMan.config.fontSize;
289
+ ? RainMan.config.mobileFontSize - 5
290
+ : RainMan.config.fontSize - 5;
291
291
  const winLineTextStyle = {
292
292
  fontFamily: RainMan.config.fontFace,
293
293
  fontSize,
@@ -3,7 +3,7 @@ import { Spine } from "pixi-spine";
3
3
  import { animationsSpeedLevels, defaultSpeedConfig, SoundManager, SoundTracks } from "../../application";
4
4
  import { AnimationLayer } from "../../layers";
5
5
  import { RainMan } from "../../Rainman";
6
- import { getSpineData, getTexture, logError, togglePaytable } from "../../utils";
6
+ import { getSpineData, getTexture, logError, UI_ITEMS } from "../../utils";
7
7
  /**
8
8
  * Class represents symbol which is displayed in columns
9
9
  * @abstract
@@ -284,7 +284,7 @@ export class AbstractSymbolBase extends Container {
284
284
  const { x, y } = this.getGlobalPosition();
285
285
  RainMan.settingsStore.repositionSymbolPaytablePopup(x, y);
286
286
  });
287
- togglePaytable();
287
+ RainMan.settingsStore.handleModalInvocation?.(UI_ITEMS.symbolPayTable);
288
288
  }
289
289
  /**
290
290
  * Function for setting the symbol.
@@ -27,9 +27,9 @@ export class WinLineIndicator extends Container {
27
27
  current.anchor.set(0);
28
28
  if (previous)
29
29
  current.x += previous.x + previous.width;
30
- current.y -= current.height / 2;
30
+ current.y -= current.height / 2 - 5;
31
31
  }
32
- this.text.y -= this.text.height / 2;
32
+ this.text.y -= this.text.height / 2 - 5;
33
33
  const lastSymbol = last(this.symbols);
34
34
  if (lastSymbol) {
35
35
  this.text.x = lastSymbol.x + lastSymbol.width + WinLineIndicator.OFFSET;
@@ -31,6 +31,7 @@ export declare abstract class AbstractController<T> {
31
31
  protected currentlyPlayedAction: (Promise<void> | Promise<void[]>) | undefined;
32
32
  protected currentlyPlayedActionType: T | undefined;
33
33
  protected isPlayingUnskippableStreak: boolean;
34
+ protected shouldAutoplayFreeSpins: boolean;
34
35
  protected isLoopingWinActionsQueue: boolean;
35
36
  protected gamePhase: GamePhase;
36
37
  protected autoSpinBalance: number;
@@ -78,6 +79,13 @@ export declare abstract class AbstractController<T> {
78
79
  * @returns {void}
79
80
  */
80
81
  private setupSpaceOrEnterListener;
82
+ /**
83
+ * This function sets up a listener for resize event
84
+ * It prevents buttons from being interacted with after a resize
85
+ * @private
86
+ * @returns {void}
87
+ */
88
+ private setupResizeListener;
81
89
  /**
82
90
  * Function for disabling bet buttons
83
91
  * @public
@@ -30,6 +30,7 @@ export class AbstractController {
30
30
  currentlyPlayedAction;
31
31
  currentlyPlayedActionType;
32
32
  isPlayingUnskippableStreak = false;
33
+ shouldAutoplayFreeSpins = true;
33
34
  isLoopingWinActionsQueue = false;
34
35
  gamePhase = gamePhases.IDLE;
35
36
  autoSpinBalance = 0;
@@ -60,6 +61,7 @@ export class AbstractController {
60
61
  this.uiController = new UiController(this.config);
61
62
  this.componentRegistry = RainMan.componentRegistry;
62
63
  this.setupSpaceOrEnterListener();
64
+ this.setupResizeListener();
63
65
  this.roundNumber = initData.round_number;
64
66
  RainMan.settingsStore.setRoundNumber(this.roundNumber);
65
67
  RainMan.globals.handleDisablingButtons = this.handleDisablingButtons.bind(this);
@@ -103,6 +105,7 @@ export class AbstractController {
103
105
  RainMan.componentRegistry.get(BUTTONS.neg).flipDisabledFlag(true);
104
106
  this.throttledSpin();
105
107
  });
108
+ SoundManager.setPlayStatus(SoundTracks.music, RainMan.settingsStore.shouldPlayAmbientMusic);
106
109
  this.changeGamePhase(gamePhases.IDLE);
107
110
  }
108
111
  /**
@@ -151,6 +154,19 @@ export class AbstractController {
151
154
  }
152
155
  });
153
156
  }
157
+ /**
158
+ * This function sets up a listener for resize event
159
+ * It prevents buttons from being interacted with after a resize
160
+ * @private
161
+ * @returns {void}
162
+ */
163
+ setupResizeListener() {
164
+ window.addEventListener("resize", () => {
165
+ if (this.shouldBetButtonsBeDisabled) {
166
+ this.handleDisablingButtons(true);
167
+ }
168
+ });
169
+ }
154
170
  /**
155
171
  * Function for disabling bet buttons
156
172
  * @public
@@ -217,7 +233,12 @@ export class AbstractController {
217
233
  */
218
234
  handleDisablingButtons(disabled) {
219
235
  this.disableBetButtons(disabled ?? this.shouldBetButtonsBeDisabled);
220
- this.disableSpeedButton(disabled ?? this.shouldButtonsBeDisabled);
236
+ if (RainMan.settingsStore.isFreeSpinsPlayEnabled) {
237
+ this.disableSpeedButton(false);
238
+ }
239
+ else {
240
+ this.disableSpeedButton(disabled ?? this.shouldButtonsBeDisabled);
241
+ }
221
242
  this.disableInformationButtons(disabled ?? this.shouldButtonsBeDisabled);
222
243
  }
223
244
  /**
@@ -262,7 +283,7 @@ export class AbstractController {
262
283
  * @returns {void}
263
284
  */
264
285
  initBetButtons() {
265
- const { isFreeSpinsBought, isFreeSpinsPlayEnabled } = RainMan.settingsStore;
286
+ const { isFreeSpinsBought, isFreeSpinsPlayEnabled, betChangeDisabled } = RainMan.settingsStore;
266
287
  this.buttonsEventManager.initBetPlusButtonEvent(this.uiController.updateBet.bind(this.uiController));
267
288
  this.buttonsEventManager.initBetMinusButtonEvent(this.uiController.updateBet.bind(this.uiController));
268
289
  if (RainMan.settingsStore.isAutoplayEnabled) {
@@ -270,21 +291,26 @@ export class AbstractController {
270
291
  }
271
292
  if (getDeviceOrientation().includes("mobile")) {
272
293
  RainMan.componentRegistry.get(BUTTONS.plus).setOnClick(() => {
273
- if (isFreeSpinsBought || isFreeSpinsPlayEnabled)
294
+ if (isFreeSpinsBought || isFreeSpinsPlayEnabled || betChangeDisabled) {
274
295
  return;
296
+ }
275
297
  RainMan.settingsStore.handleModalInvocation?.(UI_ITEMS.bet);
276
298
  });
277
299
  return;
278
300
  }
279
301
  RainMan.componentRegistry.get(BUTTONS.plus).setOnClick(() => {
280
- if (isFreeSpinsBought || isFreeSpinsPlayEnabled)
302
+ if (isFreeSpinsBought || isFreeSpinsPlayEnabled || betChangeDisabled) {
281
303
  return;
304
+ }
282
305
  this.uiController.updateBet("increase");
306
+ RainMan.settingsStore.closeOtherModals?.("");
283
307
  });
284
308
  RainMan.componentRegistry.get(BUTTONS.neg).setOnClick(() => {
285
- if (isFreeSpinsBought || isFreeSpinsPlayEnabled)
309
+ if (isFreeSpinsBought || isFreeSpinsPlayEnabled || betChangeDisabled) {
286
310
  return;
311
+ }
287
312
  this.uiController.updateBet("decrease");
313
+ RainMan.settingsStore.closeOtherModals?.("");
288
314
  });
289
315
  }
290
316
  /**
@@ -459,7 +485,9 @@ export class AbstractController {
459
485
  if (RainMan.settingsStore.isAutoplayEnabled) {
460
486
  const autoSpinText = RainMan.componentRegistry.get(MessageBox.autoSpinTextRegistryName);
461
487
  autoSpinText.setStringValue(RainMan.settingsStore.infinitySpinsEnabled ? "∞" : RainMan.settingsStore.howManyAutoSpinsLeft.toString());
462
- this.uiController.messageBox.showAutoSpinText();
488
+ if (!RainMan.settingsStore.isFreeSpinsPlayEnabled) {
489
+ this.uiController.messageBox.showAutoSpinText();
490
+ }
463
491
  return;
464
492
  }
465
493
  }
@@ -573,6 +601,7 @@ export class AbstractController {
573
601
  * @returns {void}
574
602
  */
575
603
  throttledSpin() {
604
+ this.columnsContainer.setInteractivityForSymbols(false);
576
605
  this.handleDisablingButtons(true);
577
606
  RainMan.globals.shouldShowModals = false;
578
607
  const elementsToSkipHide = [];
@@ -644,7 +673,7 @@ export class AbstractController {
644
673
  if (!RainMan.settingsStore.howManyAutoSpinsLeft) {
645
674
  return;
646
675
  }
647
- if (!RainMan.settingsStore.infinitySpinsEnabled) {
676
+ if (!RainMan.settingsStore.infinitySpinsEnabled || !RainMan.settingsStore.isFreeSpinsPlayEnabled) {
648
677
  RainMan.settingsStore.decreaseAutoSpinsCount();
649
678
  }
650
679
  if (RainMan.settingsStore.howManyAutoSpinsLeft === 0) {
@@ -810,6 +839,7 @@ export class AbstractController {
810
839
  * @returns {Promise<void>}
811
840
  */
812
841
  async spin() {
842
+ this.columnsContainer.setInteractivityForSymbols(false);
813
843
  RainMan.globals.shouldShowModals = false;
814
844
  if (this.uiController.currentBalance < RainMan.settingsStore.bet &&
815
845
  !RainMan.settingsStore.isFreeSpinsPlayEnabled) {
@@ -874,6 +904,12 @@ export class AbstractController {
874
904
  RainMan.settingsStore.isTakeActionAvailable = false;
875
905
  RainMan.settingsStore.isGambleGameAvailable = false;
876
906
  }
907
+ if (RainMan.settingsStore.howManyFreeSpinsLeft === 0 &&
908
+ availableFreeSpinsIncreased &&
909
+ !RainMan.settingsStore.isFreeSpinsPlayEnabled) {
910
+ RainMan.componentRegistry.setSpeedLevel(SPEED_LEVELS.slow);
911
+ this.disableSpeedButton(false);
912
+ }
877
913
  if (!availableFreeSpinsIncreased) {
878
914
  this.uiController.updateShownFreeSpinAmount(availableFreeSpins);
879
915
  }
@@ -953,18 +989,27 @@ export class AbstractController {
953
989
  await this.handleFreeSpinSummaryPlateInvocation();
954
990
  }
955
991
  await this.performActionsAfterSpin();
956
- if (RainMan.settingsStore.isAutoplayEnabled) {
992
+ if (RainMan.settingsStore.isAutoplayEnabled ||
993
+ (RainMan.settingsStore.howManyFreeSpinsLeft !== 0 && this.shouldAutoplayFreeSpins)) {
957
994
  this.handleAutoplayLogic();
958
995
  }
959
996
  RainMan.settingsStore.setRoundNumber(this.roundNumber);
960
997
  this.handleDisablingButtons();
961
998
  if (RainMan.settingsStore.isFreeSpinsPlayEnabled) {
999
+ this.disableAutoplayButton(true);
1000
+ this.uiController.messageBox.hideAutoSpinText();
1001
+ }
1002
+ else {
962
1003
  this.disableAutoplayButton(false);
963
1004
  }
964
1005
  await this.performActionsAfterAllActions();
1006
+ if (RainMan.settingsStore.isTemporarySpeed) {
1007
+ RainMan.settingsStore.setIsTemporarySpeed(false);
1008
+ }
965
1009
  RainMan.settingsStore.setModalsAvailability(true);
966
1010
  RainMan.globals.shouldShowModals = true;
967
1011
  RainMan.settingsStore.setIsPlayingAnyAction(false);
1012
+ this.columnsContainer.setInteractivityForSymbols(true);
968
1013
  }
969
1014
  /**
970
1015
  * Function for invoking free spin plate, invoked in mainContainer
@@ -1054,10 +1099,9 @@ export class AbstractController {
1054
1099
  * @returns {void}
1055
1100
  */
1056
1101
  unlockLogicAfterSpinning() {
1057
- if (RainMan.settingsStore.isAutoplayEnabled) {
1102
+ if (RainMan.settingsStore.isAutoplayEnabled || RainMan.settingsStore.isFreeSpinsPlayEnabled) {
1058
1103
  return;
1059
1104
  }
1060
- this.columnsContainer.setInteractivityForSymbols(true);
1061
1105
  }
1062
1106
  /**
1063
1107
  * Function for stopping playing symbols streak
@@ -1322,7 +1366,9 @@ export class AbstractController {
1322
1366
  * @returns {Promise<void>}
1323
1367
  */
1324
1368
  async handleLoopingWinActionQueue() {
1325
- if (RainMan.settingsStore.isAutoplayEnabled || this.invokeFreeSpinPlateAfterWin) {
1369
+ if (RainMan.settingsStore.isAutoplayEnabled ||
1370
+ this.invokeFreeSpinPlateAfterWin ||
1371
+ RainMan.settingsStore.isFreeSpinsPlayEnabled) {
1326
1372
  return;
1327
1373
  }
1328
1374
  this.isLoopingWinActionsQueue = true;
@@ -45,10 +45,12 @@ export declare class SettingsStore {
45
45
  popupPaytableData?: PaytableData[];
46
46
  currentSpeed: SpeedLevel;
47
47
  isPlayingAnyAction: boolean;
48
+ isTemporarySpeed: boolean;
48
49
  setSpeedPopupVisibility?: (visibility: "flex" | "none") => void;
49
50
  popupPaytableRepositionCallback?: () => void;
50
51
  updateVolumeButtonTexture?: () => void;
51
52
  handleModalInvocation?: (layerId: string) => void;
53
+ closeOtherModals?: (layerId: string) => void;
52
54
  handleInvokeFreeSpinPlate?: (freeSpinAmount: number, isAdditionalFreeSpin: boolean) => Promise<void>;
53
55
  increaseBet?: () => void;
54
56
  decreaseBet?: () => void;
@@ -180,6 +182,13 @@ export declare class SettingsStore {
180
182
  * @returns {void}
181
183
  */
182
184
  setHiResolutionFlag(flag: boolean): void;
185
+ /**
186
+ * Sets the temporary speed flag.
187
+ * @public
188
+ * @param {boolean} flag - New value temporary speed flag.
189
+ * @returns {void}
190
+ */
191
+ setIsTemporarySpeed(flag: boolean): void;
183
192
  /**
184
193
  * Sets the speed level.
185
194
  * @public
@@ -44,15 +44,17 @@ export class SettingsStore {
44
44
  howManyFreeSpinsLeft = 0;
45
45
  howManyAutoSpinsLeft = INITIAL_AUTO_SPIN_COUNT;
46
46
  freeSpinBuyTable = {};
47
- volumeLevel = getFromLocalStorage(LOCAL_STORAGE.volumeLevel, 100);
47
+ volumeLevel = Number(getFromLocalStorage(LOCAL_STORAGE.volumeLevel, 100));
48
48
  popupPaytablePosition;
49
49
  popupPaytableData;
50
50
  currentSpeed = "slow";
51
51
  isPlayingAnyAction = false;
52
+ isTemporarySpeed = false;
52
53
  setSpeedPopupVisibility;
53
54
  popupPaytableRepositionCallback;
54
55
  updateVolumeButtonTexture;
55
56
  handleModalInvocation;
57
+ closeOtherModals;
56
58
  handleInvokeFreeSpinPlate;
57
59
  increaseBet;
58
60
  decreaseBet;
@@ -251,8 +253,9 @@ export class SettingsStore {
251
253
  */
252
254
  setShouldPlayFxSounds(flag, saveToLocalStorage = true) {
253
255
  this.shouldPlayFxSounds = flag;
254
- if (!flag)
256
+ if (!flag) {
255
257
  SoundManager.stopPlayingFxSounds();
258
+ }
256
259
  this.updateVolumeButtonTexture?.();
257
260
  if (saveToLocalStorage) {
258
261
  setToLocalStorage(LOCAL_STORAGE.isSoundFxEnabled, flag);
@@ -290,7 +293,7 @@ export class SettingsStore {
290
293
  * @returns {boolean} True if sound is enabled, false otherwise.
291
294
  */
292
295
  isSoundEnabled() {
293
- return this.shouldPlayFxSounds || this.shouldPlayAmbientMusic;
296
+ return this.shouldPlayAmbientMusic || this.shouldPlayFxSounds;
294
297
  }
295
298
  /**
296
299
  * Sets the full screen flag and enlarges the game container.
@@ -321,6 +324,15 @@ export class SettingsStore {
321
324
  changeResolution(flag);
322
325
  window.dispatchEvent(new Event("resize"));
323
326
  }
327
+ /**
328
+ * Sets the temporary speed flag.
329
+ * @public
330
+ * @param {boolean} flag - New value temporary speed flag.
331
+ * @returns {void}
332
+ */
333
+ setIsTemporarySpeed(flag) {
334
+ this.isTemporarySpeed = flag;
335
+ }
324
336
  /**
325
337
  * Sets the speed level.
326
338
  * @public
@@ -495,7 +507,7 @@ export class SettingsStore {
495
507
  * @returns {void}
496
508
  */
497
509
  decreaseAutoSpinsCount() {
498
- if (this.infinitySpinsEnabled) {
510
+ if (this.infinitySpinsEnabled || this.isFreeSpinsPlayEnabled) {
499
511
  return;
500
512
  }
501
513
  this.howManyAutoSpinsLeft -= 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.3.2",
3
+ "version": "0.3.3b",
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",