pixi-rainman-game-engine 0.1.8 → 0.1.9

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 (54) hide show
  1. package/dist/DescribedPlayableAction/DescribedPlayableAction.d.ts +1 -1
  2. package/dist/Money/MoneyText.js +2 -2
  3. package/dist/Rainman/Rainman.d.ts +2 -3
  4. package/dist/Rainman/Rainman.js +4 -2
  5. package/dist/Rainman/appConfig.js +1 -1
  6. package/dist/Rainman/types.d.ts +9 -1
  7. package/dist/SettingsUI/index.css +1 -1
  8. package/dist/application/ApiConfig/ApiConfig.d.ts +14 -4
  9. package/dist/application/ApiConfig/ApiConfig.js +29 -7
  10. package/dist/application/SoundManager/types.d.ts +1 -1
  11. package/dist/application/SpinLogic/SpinLogic.d.ts +1 -0
  12. package/dist/application/SpinLogic/SpinLogic.js +5 -0
  13. package/dist/application/SpinLogic/SpinLogicDTO.js +1 -1
  14. package/dist/application/SpinLogic/util.d.ts +2 -3
  15. package/dist/application/SpinLogic/util.js +5 -8
  16. package/dist/components/AbstractFreeSpinContainer/AbstractFreeSpinContainer.d.ts +3 -2
  17. package/dist/components/AbstractFreeSpinContainer/AbstractFreeSpinContainer.js +1 -0
  18. package/dist/components/AbstractMainContainer/AbstractMainContainer.d.ts +4 -3
  19. package/dist/components/AbstractMainContainer/AbstractMainContainer.js +11 -4
  20. package/dist/components/buttons/buttonGroups/LeftButtons.js +1 -1
  21. package/dist/components/buttons/default/AutoplayButton.js +4 -1
  22. package/dist/components/common/FreeSpinBox.js +2 -1
  23. package/dist/components/common/Logo.d.ts +7 -1
  24. package/dist/components/common/Logo.js +27 -13
  25. package/dist/components/common/LogoStatic.d.ts +2 -1
  26. package/dist/components/common/LogoStatic.js +4 -2
  27. package/dist/components/dictionary/locales/en.json +1 -1
  28. package/dist/components/frame/AbstractColumnsContainer.d.ts +2 -1
  29. package/dist/components/frame/AbstractColumnsContainer.js +6 -3
  30. package/dist/components/frame/AbstractFrame.d.ts +3 -2
  31. package/dist/components/frame/AbstractFrame.js +15 -3
  32. package/dist/components/frame/WinLineAnimation.js +3 -0
  33. package/dist/components/messageBox/MessageBox.js +1 -0
  34. package/dist/components/symbols/AbstractSymbolBase.d.ts +1 -1
  35. package/dist/components/symbols/AbstractSymbolsColumn.d.ts +2 -2
  36. package/dist/components/symbols/AbstractSymbolsColumn.js +5 -2
  37. package/dist/components/updatable/UpdatableTextComponent.js +11 -2
  38. package/dist/components/winLineIndicator/WinLineIndicator.js +2 -1
  39. package/dist/connectivity/ConnectionWrapper.d.ts +3 -1
  40. package/dist/connectivity/ConnectionWrapper.js +9 -4
  41. package/dist/connectivity/LocalConnectionWrapper.d.ts +1 -0
  42. package/dist/connectivity/LocalConnectionWrapper.js +5 -1
  43. package/dist/connectivity/serverConnection.d.ts +1 -0
  44. package/dist/connectivity/serverData.d.ts +4 -1
  45. package/dist/connectivity/transformation.d.ts +2 -2
  46. package/dist/connectivity/wins.d.ts +2 -1
  47. package/dist/controllers/AbstractController.d.ts +7 -4
  48. package/dist/controllers/AbstractController.js +22 -10
  49. package/dist/loading/AbstractLoadingContainer.d.ts +1 -1
  50. package/dist/loading/AbstractLoadingContainer.js +7 -0
  51. package/dist/stores/SettingsStore.js +9 -4
  52. package/dist/utils/common/functions.d.ts +1 -0
  53. package/dist/utils/common/functions.js +3 -0
  54. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { Nullable, PlayableAction } from "../utils";
2
- export declare class DescribedPlayableAction<T = number> {
2
+ export declare class DescribedPlayableAction<T> {
3
3
  readonly type: T;
4
4
  action: PlayableAction;
5
5
  winAmount: Nullable<number>;
@@ -10,9 +10,9 @@ import { RainMan } from "../Rainman";
10
10
  export class MoneyText {
11
11
  money;
12
12
  constructor(amount) {
13
- this.money = Money.fromDecimal(amount, RainMan.currency, Math.round);
13
+ this.money = Money.fromDecimal(amount, RainMan.globals.currency, Math.round);
14
14
  }
15
15
  toString() {
16
- return `${this.money} ${RainMan.currency.symbol_native}`;
16
+ return `${this.money} ${RainMan.globals.currency.symbol_native}`;
17
17
  }
18
18
  }
@@ -1,10 +1,9 @@
1
1
  import "../components/dictionary/i18n";
2
2
  import { Application } from "pixi.js";
3
- import { Currency } from "ts-money";
4
3
  import { SpinLogicFactory, SymbolIds, WinTypeIds } from "../application";
5
4
  import { ComponentRegistry } from "../ComponentRegistry";
6
5
  import { SettingsStore } from "../stores";
7
- import { AppConfig, OptionalAppConfig, RequiredAppConfig } from "./types";
6
+ import { AppConfig, Globals, OptionalAppConfig, RequiredAppConfig } from "./types";
8
7
  export declare class RainMan {
9
8
  static app: Application;
10
9
  static config: RequiredAppConfig & OptionalAppConfig;
@@ -13,6 +12,6 @@ export declare class RainMan {
13
12
  static settingsStore: SettingsStore;
14
13
  static componentRegistry: ComponentRegistry;
15
14
  static spinLogicFactory: SpinLogicFactory;
16
- static currency: Currency;
15
+ static globals: Globals;
17
16
  constructor(app: Application, config: AppConfig, symbolIds: SymbolIds, winTypeIds: WinTypeIds, spinLogicFactory: SpinLogicFactory);
18
17
  }
@@ -12,7 +12,7 @@ export class RainMan {
12
12
  static settingsStore;
13
13
  static componentRegistry;
14
14
  static spinLogicFactory;
15
- static currency;
15
+ static globals;
16
16
  constructor(app, config, symbolIds, winTypeIds, spinLogicFactory) {
17
17
  RainMan.app = app;
18
18
  RainMan.config = merge(defaultAppConfig, config);
@@ -21,6 +21,8 @@ export class RainMan {
21
21
  RainMan.settingsStore = settingStore;
22
22
  RainMan.componentRegistry = new ComponentRegistry(app);
23
23
  RainMan.spinLogicFactory = spinLogicFactory;
24
- RainMan.currency = Currencies["USD"];
24
+ RainMan.globals = {
25
+ currency: Currencies["USD"],
26
+ };
25
27
  }
26
28
  }
@@ -12,9 +12,9 @@ export const defaultAppConfig = {
12
12
  fontSize: 35,
13
13
  mobileFontSize: 45,
14
14
  updatableSpineContainerFontSize: 50,
15
- fontColor: new Color(0xfbd400).toHex(),
16
15
  updatableTextValueColor: new Color(0xffffff).toHex(),
17
16
  fontFace: ["HelveticaNeueLTStd"],
17
+ winLineIndicatorSymbolScale: 0.75,
18
18
  durationOfActions: {
19
19
  eachColumnsSpinDelay: [0, 200, 700, 1200, 1800],
20
20
  spinBaseTime: 800,
@@ -1,3 +1,4 @@
1
+ import { Currency } from "ts-money";
1
2
  import { DeepPartial } from "../utils";
2
3
  export type RequiredAppConfig = {
3
4
  websocketUrl: string;
@@ -6,6 +7,8 @@ export type RequiredAppConfig = {
6
7
  gameInitReference: string;
7
8
  numberOfColumns: number;
8
9
  numberOfRows: number;
10
+ fontColor: string;
11
+ autoplayGlowColor: number;
9
12
  };
10
13
  export type OptionalAppConfig = {
11
14
  gameWidth: number;
@@ -14,9 +17,11 @@ export type OptionalAppConfig = {
14
17
  fontSize: number;
15
18
  updatableSpineContainerFontSize: number;
16
19
  mobileFontSize: number;
17
- fontColor: string;
20
+ mobileFontColor?: string;
18
21
  updatableTextValueColor: string;
19
22
  fontFace: string[];
23
+ mobileFontFace?: string[];
24
+ winLineIndicatorSymbolScale: number;
20
25
  durationOfActions: {
21
26
  eachColumnsSpinDelay: number[];
22
27
  spinBaseTime: number;
@@ -48,3 +53,6 @@ export type OptionalAppConfig = {
48
53
  };
49
54
  };
50
55
  export type AppConfig = RequiredAppConfig & DeepPartial<OptionalAppConfig>;
56
+ export interface Globals {
57
+ currency: Currency;
58
+ }
@@ -131,7 +131,7 @@ body {
131
131
  position: fixed;
132
132
  width: 100%;
133
133
  height: 100%;
134
- background: url("../assets/images/swipe-up.png") no-repeat 50% 50%;
134
+ background: url("../assets/images/materials/swipe-up.png") no-repeat 50% 50%;
135
135
  background-size: 150px;
136
136
  animation: iosAnimMove 1.5s ease-out infinite;
137
137
  }
@@ -1,4 +1,5 @@
1
- import { InitDataInterface } from "../../connectivity";
1
+ import { InitDataInterface, SpinDataInterface } from "../../connectivity";
2
+ import { AdaptedSpinResponse } from "../SpinLogic";
2
3
  import { SymbolId } from "./SymbolId";
3
4
  import { TransformationTypeId } from "./TransformationTypesId";
4
5
  import { WinTypeId } from "./WinTypeId";
@@ -22,14 +23,23 @@ export declare class ApiConfig {
22
23
  * @param {InitDataInterface} data
23
24
  */
24
25
  constructor(data: InitDataInterface);
26
+ /**
27
+ * Function to generate metadata for a particular spin
28
+ *
29
+ * @public
30
+ * @param {SpinDataInterface} spinLogicResponse
31
+ * @returns AdaptedSpinResponse without results and standalone results, these should be created in each game
32
+ */
33
+ generateMetadata(spinLogicResponse: SpinDataInterface): Omit<AdaptedSpinResponse, "results" | "standaloneTransformations">;
25
34
  /**
26
35
  * Getter for win line number
27
36
  *
28
37
  * @public
29
38
  * @param winLineAnimationName
39
+ * @param defaultNumber
30
40
  * @returns {string | number}
31
41
  */
32
- getWinLineNumber(winLineAnimationName: string): number | string;
42
+ getWinLineNumber(winLineAnimationName: string, defaultNumber?: string): number | string;
33
43
  /**
34
44
  * Function for getting next bet from config
35
45
  *
@@ -91,9 +101,9 @@ export declare class ApiConfig {
91
101
  *
92
102
  * @public
93
103
  * @param {number[][]} symbols_on_reels
94
- * @returns {SymbolId[]}
104
+ * @returns {SymbolId[][]}
95
105
  */
96
- mapSymbolIdsToSymbolNames(symbols_on_reels: number[][]): SymbolId[];
106
+ mapSymbolIdsToSymbolNames(symbols_on_reels: number[][]): SymbolId[][];
97
107
  /**
98
108
  * Getter for bet that placed in current position
99
109
  *
@@ -1,5 +1,6 @@
1
1
  import { RainMan } from "../../Rainman";
2
2
  import { logError } from "../../utils";
3
+ import { isBlindsConfiguredByTransformations } from "../SpinLogic";
3
4
  /**
4
5
  * Class representing config for connection to API
5
6
  *
@@ -30,15 +31,38 @@ export class ApiConfig {
30
31
  this.initStreakMap(data);
31
32
  this.initTransformationMap(data);
32
33
  }
34
+ /**
35
+ * Function to generate metadata for a particular spin
36
+ *
37
+ * @public
38
+ * @param {SpinDataInterface} spinLogicResponse
39
+ * @returns AdaptedSpinResponse without results and standalone results, these should be created in each game
40
+ */
41
+ generateMetadata(spinLogicResponse) {
42
+ const blindsConfiguredByResponse = this.mapSymbolIdsToSymbolNames(spinLogicResponse.symbols_on_reels);
43
+ const blindsConfiguredByTransformation = isBlindsConfiguredByTransformations(spinLogicResponse.results);
44
+ const finalSpinPositionOnReels = blindsConfiguredByTransformation !== null
45
+ ? this.mapSymbolIdsToSymbolNames(blindsConfiguredByTransformation)
46
+ : blindsConfiguredByResponse;
47
+ return {
48
+ action: spinLogicResponse.action,
49
+ balance: spinLogicResponse.balance,
50
+ availableFreeSpins: spinLogicResponse.available_free_spins,
51
+ symbolsOnReels: blindsConfiguredByResponse,
52
+ finalBlindsConfiguration: finalSpinPositionOnReels,
53
+ winAmountTotal: spinLogicResponse.win_amount_total,
54
+ };
55
+ }
33
56
  /**
34
57
  * Getter for win line number
35
58
  *
36
59
  * @public
37
60
  * @param winLineAnimationName
61
+ * @param defaultNumber
38
62
  * @returns {string | number}
39
63
  */
40
- getWinLineNumber(winLineAnimationName) {
41
- return this.streakMap.get(winLineAnimationName) ?? "unknown";
64
+ getWinLineNumber(winLineAnimationName, defaultNumber = "unknown") {
65
+ return this.streakMap.get(winLineAnimationName) ?? defaultNumber;
42
66
  }
43
67
  /**
44
68
  * Function for getting next bet from config
@@ -129,14 +153,12 @@ export class ApiConfig {
129
153
  *
130
154
  * @public
131
155
  * @param {number[][]} symbols_on_reels
132
- * @returns {SymbolId[]}
156
+ * @returns {SymbolId[][]}
133
157
  */
134
158
  mapSymbolIdsToSymbolNames(symbols_on_reels) {
135
- return symbols_on_reels
136
- .map((reel) => {
159
+ return symbols_on_reels.map((reel) => {
137
160
  return reel.map((symbolId) => this.getSymbolId(symbolId));
138
- })
139
- .flat();
161
+ });
140
162
  }
141
163
  /**
142
164
  * Getter for bet that placed in current position
@@ -42,5 +42,5 @@ export type SoundTrack = SoundTracks[keyof SoundTracks];
42
42
  * @property {string} start - on start spinning
43
43
  * @property {string} symbol - on symbol click and show paytable popup
44
44
  */
45
- export type GameSoundAssets = Record<SoundTrack, string> & Record<string, string>;
45
+ export type GameSoundAssets = Record<SoundTrack, string>;
46
46
  export type SoundOverrides = Partial<Record<SoundTrack, SoundTrack>>;
@@ -21,6 +21,7 @@ export declare class SpinLogic {
21
21
  constructor(spinConfig: AdaptedSpinResponse, gameConfig: ApiConfig);
22
22
  get postSpinBalance(): number;
23
23
  get winTotalAmount(): number;
24
+ get winTotalAmountWithoutMystery(): number;
24
25
  get onStopBlindsConfiguration(): SymbolReels;
25
26
  get finalBlindsConfiguration(): SymbolReels;
26
27
  get availableFreeSpins(): number;
@@ -1,3 +1,4 @@
1
+ import { PossibleWins } from "../../constants";
1
2
  import { logInfo } from "../../utils";
2
3
  import { SpinLogicDTO } from "./SpinLogicDTO";
3
4
  /**
@@ -34,6 +35,10 @@ export class SpinLogic {
34
35
  get winTotalAmount() {
35
36
  return this._winTotalAmount;
36
37
  }
38
+ get winTotalAmountWithoutMystery() {
39
+ return this._winScenarios.reduce((accumulator, scenario) => accumulator +
40
+ scenario.wins.reduce((winAccumulator, currentWin) => currentWin.type === PossibleWins.mystery ? winAccumulator : winAccumulator + currentWin.amount, 0), 0);
41
+ }
37
42
  get onStopBlindsConfiguration() {
38
43
  return this._onStopBlindsConfiguration;
39
44
  }
@@ -65,8 +65,8 @@ export class SpinLogicDTO {
65
65
  symbolId: this.gameConfig.getSymbolId(singleWin.symbolId),
66
66
  positionOnReels: singleWin.positionOnReels,
67
67
  quantity: singleWin.quantity,
68
- spinId: singleWin.spinId,
69
68
  multiplier: singleWin.multiplier,
69
+ winIndex: singleWin.winIndex,
70
70
  typeId: singleWin.typeId,
71
71
  };
72
72
  if (rawWin.type === PossibleWins.freeSpins) {
@@ -1,8 +1,7 @@
1
1
  import { DropTransformationDetails, FreezeTransformationDetails, RawFreezeTransformationDetails, RawWin, Result, SpinAndFreezeTransformationDetails, SpinDataInterface, SymbolReels, TransformationDetails, WinWithTransformation } from "../../connectivity";
2
2
  import { ApiConfig } from "../ApiConfig";
3
3
  export declare const concatenateDestroyAndSetTransformations: (spinLogicResponse: SpinDataInterface, currentIndexOfRootTransformation: number, gameConfig: ApiConfig) => [DropTransformationDetails[], number];
4
- export declare const mapSymbolIdsToSymbolNames: (symbols_on_reels: number[][], gameConfig: ApiConfig) => never[][];
5
4
  export declare const getFreezeTransformationFromRawResponse: (transformations: RawFreezeTransformationDetails[]) => FreezeTransformationDetails[];
6
5
  export declare const concatenateFreezeAndSpinTransformations: (freezeTransformations: FreezeTransformationDetails[], onStopBlindsConfiguration: SymbolReels) => SpinAndFreezeTransformationDetails;
7
- export declare const isBlindsConfiguredByTransformations: (results: Result[]) => number[][] | null;
8
- export declare const collectWinDetailsWithTransformation: (winIndex: string | null, winsDetails: RawWin | null, transformations: TransformationDetails[]) => WinWithTransformation;
6
+ export declare const isBlindsConfiguredByTransformations: (results: Result[], transformationTypeId?: number) => number[][] | null;
7
+ export declare const collectWinDetailsWithTransformation: (winsDetails: RawWin | null, transformations: TransformationDetails[], winIndex?: string | null) => WinWithTransformation;
@@ -5,10 +5,10 @@ const getWinFromRawResponse = (rawWin, winIndex) => {
5
5
  multiplier: rawWin.multiplier,
6
6
  positionOnReels: rawWin.position_on_reels,
7
7
  quantity: rawWin.quantity,
8
- spinId: winIndex,
9
8
  symbolId: rawWin.symbol_id,
10
9
  typeId: rawWin.type_id,
11
10
  amount: rawWin.amount,
11
+ winIndex,
12
12
  };
13
13
  };
14
14
  const joinTransformationsIntoDropTransformation = (destroyTransformations, symbolsOnReel, gameConfig) => {
@@ -62,9 +62,6 @@ export const concatenateDestroyAndSetTransformations = (spinLogicResponse, curre
62
62
  const parsedDropTransformations = joinTransformationsIntoDropTransformation(destroyTransformations, symbolsIdsOnReelsAfterSet, gameConfig);
63
63
  return [parsedDropTransformations, setTransformationsIndex];
64
64
  };
65
- export const mapSymbolIdsToSymbolNames = (symbols_on_reels, gameConfig) => {
66
- return symbols_on_reels.map((reel) => reel.map((symbolId) => gameConfig.getSymbolId(symbolId)));
67
- };
68
65
  export const getFreezeTransformationFromRawResponse = (transformations) => {
69
66
  return transformations.map((freezeTransformation) => {
70
67
  return {
@@ -81,17 +78,17 @@ export const concatenateFreezeAndSpinTransformations = (freezeTransformations, o
81
78
  symbolsOnReels: onStopBlindsConfiguration,
82
79
  };
83
80
  };
84
- export const isBlindsConfiguredByTransformations = (results) => {
85
- // make copy of results because reverse is made in place
81
+ export const isBlindsConfiguredByTransformations = (results, transformationTypeId = 16) => {
86
82
  const reversedResults = [...results].reverse();
87
83
  for (const rawTransformation of reversedResults) {
88
- if (rawTransformation.transformation_type === 16 && rawTransformation.symbols_on_reels !== null) {
84
+ if (rawTransformation.transformation_type === transformationTypeId &&
85
+ rawTransformation.symbols_on_reels !== null) {
89
86
  return rawTransformation.symbols_on_reels;
90
87
  }
91
88
  }
92
89
  return null;
93
90
  };
94
- export const collectWinDetailsWithTransformation = (winIndex, winsDetails, transformations) => {
91
+ export const collectWinDetailsWithTransformation = (winsDetails, transformations, winIndex = "") => {
95
92
  const wins = winsDetails ? [getWinFromRawResponse(winsDetails, winIndex ?? "")] : [];
96
93
  return {
97
94
  wins,
@@ -11,12 +11,13 @@ import { Spine } from "pixi-spine";
11
11
  */
12
12
  export declare abstract class AbstractFreeSpinContainer extends Container {
13
13
  protected abstract freeSpinPlate: Sprite | Spine;
14
- shownAt: number;
14
+ shownAt: number | null;
15
15
  protected scaleMultiplier: number;
16
16
  protected constructor();
17
17
  abstract get onClick(): () => void;
18
+ onStart(): Promise<void>;
18
19
  resize(): void;
19
- private reposition;
20
+ protected reposition(): void;
20
21
  protected centerComponent(component: Text | Container): void;
21
22
  protected abstract initChildPositions(): void;
22
23
  }
@@ -20,6 +20,7 @@ export class AbstractFreeSpinContainer extends Container {
20
20
  this.shownAt = performance.now();
21
21
  this.parentLayer = UXLayer;
22
22
  }
23
+ async onStart() { }
23
24
  resize() {
24
25
  this.scale.set(globalMinRatio() * this.scaleMultiplier);
25
26
  this.reposition();
@@ -19,8 +19,8 @@ export declare abstract class AbstractMainContainer extends Container {
19
19
  protected logo: Nullable<Logo>;
20
20
  protected abstract background: IResizableContainer;
21
21
  protected animatedFront: Nullable<IResizableContainer>;
22
- protected abstract freeSpinBox: Nullable<FreeSpinBox>;
23
- protected underFramePanel: Nullable<Graphics>;
22
+ protected freeSpinBox: Nullable<FreeSpinBox>;
23
+ protected underFramePanel: Nullable<Graphics | Sprite>;
24
24
  protected portraitPlayButtons: Nullable<MiddleButtons>;
25
25
  protected landscapePlayButtons: Nullable<MiddleButtons>;
26
26
  protected abstract leftButtons: ResponsiveContainer;
@@ -31,7 +31,7 @@ export declare abstract class AbstractMainContainer extends Container {
31
31
  private _bigWinInvokedAt;
32
32
  private _mysteryWinInvokedAt;
33
33
  protected abstract _frame: AbstractFrame;
34
- protected _controller: Nullable<AbstractController>;
34
+ protected _controller: Nullable<AbstractController<unknown>>;
35
35
  protected constructor();
36
36
  protected abstract triggerStoreInitState(): void;
37
37
  get freeSpinPlate(): Nullable<AbstractFreeSpinContainer>;
@@ -52,6 +52,7 @@ export declare abstract class AbstractMainContainer extends Container {
52
52
  destroyBigWin(): void;
53
53
  destroyMysteryWin(): void;
54
54
  invokeGambleGame(): void;
55
+ protected createUnderFramePanel(): Graphics | Sprite;
55
56
  enableForMobile(): void;
56
57
  enableForLandscape(): void;
57
58
  disableForMobile(): void;
@@ -15,6 +15,7 @@ export class AbstractMainContainer extends Container {
15
15
  buttonsEventManager;
16
16
  logo = null;
17
17
  animatedFront = null;
18
+ freeSpinBox = null;
18
19
  underFramePanel = null;
19
20
  portraitPlayButtons = null;
20
21
  landscapePlayButtons = null;
@@ -42,11 +43,12 @@ export class AbstractMainContainer extends Container {
42
43
  async invokeFreeSpinPlate(freeSpinCount, isAdditionalFreeSpin = false) {
43
44
  const refreshButton = RainMan.componentRegistry.get(RefreshButton.registryName);
44
45
  refreshButton.flipDisabledFlag(true);
45
- await new Promise((resolve) => {
46
+ await new Promise(async (resolve) => {
46
47
  this._freeSpinPlate = this.createFreeSpinPlate(resolve, freeSpinCount, isAdditionalFreeSpin);
47
48
  this._freeSpinPlate.resize();
48
49
  this.showOverlay();
49
50
  this.addChild(this._freeSpinPlate);
51
+ await this._freeSpinPlate.onStart();
50
52
  });
51
53
  if (this._freeSpinPlate !== null) {
52
54
  this.removeChild(this._freeSpinPlate);
@@ -151,12 +153,16 @@ export class AbstractMainContainer extends Container {
151
153
  this._mysteryWinInvokedAt = null;
152
154
  }
153
155
  invokeGambleGame() { }
156
+ createUnderFramePanel() {
157
+ const underFramePanel = new Graphics();
158
+ underFramePanel.beginFill(0x0, 0.5);
159
+ underFramePanel.drawRect(0, 0, 800, 100);
160
+ return underFramePanel;
161
+ }
154
162
  enableForMobile() {
155
163
  if (this.logo)
156
164
  this.logo.renderable = true;
157
- this.underFramePanel = new Graphics();
158
- this.underFramePanel.beginFill(0x0, 0.5);
159
- this.underFramePanel.drawRect(0, 0, 800, 100);
165
+ this.underFramePanel = this.createUnderFramePanel();
160
166
  this.underFramePanel.name = "underFramePanel";
161
167
  this.underFramePanel.parentLayer = UXLayer;
162
168
  this.addChild(this.underFramePanel);
@@ -269,6 +275,7 @@ export class AbstractMainContainer extends Container {
269
275
  resizeDependentComponents() {
270
276
  const resizingHelper = globalMinRatio();
271
277
  this._frame.resize();
278
+ this.logo?.resize();
272
279
  this.leftButtons.resize();
273
280
  this.rightButtons.resize();
274
281
  if (this.landscapePlayButtons !== null)
@@ -34,7 +34,7 @@ export class LeftButtons extends ResponsiveContainer {
34
34
  const margin = 15;
35
35
  this.y = RainMan.app.screen.height - this.height;
36
36
  this.credit.x = this.infoButton.x + this.infoButton.width + margin;
37
- this.bet.x = this.credit.x + 62;
37
+ this.bet.x = this.credit.x + this.credit.width / 2 - this.bet.width / 2;
38
38
  this.credit.y = 20;
39
39
  this.bet.y = this.credit.y + this.credit.height;
40
40
  }
@@ -1,5 +1,6 @@
1
1
  import { GlowFilter } from "@pixi/filter-glow";
2
2
  import { SoundTracks } from "../../../application";
3
+ import { RainMan } from "../../../Rainman";
3
4
  import { getTexture, getTextureSafely } from "../../../utils";
4
5
  import { BaseButton, ButtonStates } from "../BaseButton";
5
6
  export class AutoplayButton extends BaseButton {
@@ -30,7 +31,9 @@ export class AutoplayButton extends BaseButton {
30
31
  if (state === ButtonStates.ACTIVE ||
31
32
  state === ButtonStates.ACTIVE_OVER ||
32
33
  state === ButtonStates.ACTIVE_CLICKED) {
33
- this.filters = [new GlowFilter({ distance: 20, outerStrength: 2, color: 0xffb401 })];
34
+ this.filters = [
35
+ new GlowFilter({ distance: 20, outerStrength: 2, color: RainMan.config.autoplayGlowColor }),
36
+ ];
34
37
  }
35
38
  else {
36
39
  this.filters = [];
@@ -1,3 +1,4 @@
1
+ import { Color } from "pixi.js";
1
2
  import { Spine } from "pixi-spine";
2
3
  import { TINT_DISABLED, TINT_ENABLED } from "../../constants";
3
4
  import { UXLayer } from "../../layers";
@@ -38,7 +39,7 @@ export class FreeSpinBox extends ResumableContainer {
38
39
  }
39
40
  setInteractivity(newValue) {
40
41
  this.eventMode = newValue ? "static" : "auto";
41
- this.spine.tint = Number(newValue ? TINT_ENABLED : TINT_DISABLED);
42
+ this.spine.tint = new Color(newValue ? TINT_ENABLED : TINT_DISABLED).toNumber();
42
43
  }
43
44
  resize() {
44
45
  this.changeSpineForOrientation();
@@ -9,8 +9,14 @@ import { ResumableContainer } from "./ResumableContainers";
9
9
  * @extends {ResumableContainer}
10
10
  */
11
11
  export declare class Logo extends ResumableContainer {
12
+ private desktopSpineName;
13
+ private animationName;
14
+ private mobileSpineName;
15
+ static readonly registryName = "logo";
12
16
  protected spine: Spine;
13
- constructor(spineName: string, animationName: string);
17
+ constructor(desktopSpineName: string, animationName: string, mobileSpineName?: string);
14
18
  resize(): void;
15
19
  private reposition;
20
+ private setSpine;
21
+ private changeSpineForOrientation;
16
22
  }
@@ -1,7 +1,7 @@
1
1
  import { Spine } from "pixi-spine";
2
2
  import { UXLayer } from "../../layers";
3
3
  import { RainMan } from "../../Rainman";
4
- import { getSpineData, globalMinRatio } from "../../utils";
4
+ import { getDeviceOrientation, getSpineData, globalMinRatio } from "../../utils";
5
5
  import { ResumableContainer } from "./ResumableContainers";
6
6
  /**
7
7
  * This logo is animated logo that will display after loading the game
@@ -12,23 +12,23 @@ import { ResumableContainer } from "./ResumableContainers";
12
12
  * @extends {ResumableContainer}
13
13
  */
14
14
  export class Logo extends ResumableContainer {
15
+ desktopSpineName;
16
+ animationName;
17
+ mobileSpineName;
18
+ static registryName = "logo";
15
19
  spine;
16
- constructor(spineName, animationName) {
20
+ constructor(desktopSpineName, animationName, mobileSpineName = desktopSpineName) {
17
21
  super();
18
- this.name = "logo";
19
- this.spine = new Spine(getSpineData(spineName));
20
- this.addChild(this.spine);
21
- this.allSpines.push(this.spine);
22
- this.spine.x = 0;
23
- this.spine.y = 0;
22
+ this.desktopSpineName = desktopSpineName;
23
+ this.animationName = animationName;
24
+ this.mobileSpineName = mobileSpineName;
25
+ this.name = Logo.registryName;
24
26
  this.parentLayer = UXLayer;
25
- this.spine.visible = true;
26
- this.spine.state.addAnimation(0, animationName, true, 0);
27
- this.spine.state.timeScale = 1;
28
- this.spine.pivot.x = 0;
29
- this.spine.pivot.y = 0;
27
+ this.setSpine(this.desktopSpineName);
28
+ this.resize();
30
29
  }
31
30
  resize() {
31
+ this.changeSpineForOrientation();
32
32
  this.y = 0; // reset position
33
33
  this.x = 0; // reset position
34
34
  this.scale.set(Math.min(1.5, globalMinRatio()));
@@ -38,4 +38,18 @@ export class Logo extends ResumableContainer {
38
38
  this.y = this.spine.getBounds().height / 2;
39
39
  this.x = RainMan.app.screen.width / 2;
40
40
  }
41
+ setSpine(spineName) {
42
+ this.spine = new Spine(getSpineData(spineName));
43
+ this.spine.state.setAnimation(0, this.animationName, true);
44
+ this.spine.visible = true;
45
+ }
46
+ changeSpineForOrientation() {
47
+ this.removeChildren();
48
+ getDeviceOrientation() === "mobile-portrait"
49
+ ? this.setSpine(this.mobileSpineName)
50
+ : this.setSpine(this.desktopSpineName);
51
+ this.addChild(this.spine);
52
+ this.allSpines = [this.spine];
53
+ RainMan.settingsStore.refreshBatterySaver();
54
+ }
41
55
  }
@@ -8,7 +8,8 @@ import { Sprite } from "pixi.js";
8
8
  * @extends {Sprite}
9
9
  */
10
10
  export declare class LogoStatic extends Sprite {
11
- constructor(textureName: string);
11
+ private maxScale;
12
+ constructor(textureName: string, maxScale?: number);
12
13
  resize(): void;
13
14
  private reposition;
14
15
  }
@@ -10,15 +10,17 @@ import { getTexture, globalMinRatio } from "../../utils";
10
10
  * @extends {Sprite}
11
11
  */
12
12
  export class LogoStatic extends Sprite {
13
- constructor(textureName) {
13
+ maxScale;
14
+ constructor(textureName, maxScale = 1.5) {
14
15
  super(getTexture(textureName));
16
+ this.maxScale = maxScale;
15
17
  this.x = 0;
16
18
  this.y = 30;
17
19
  this.name = "logo";
18
20
  this.anchor.x = 0.5;
19
21
  }
20
22
  resize() {
21
- this.scale.set(Math.min(1.5, globalMinRatio())); // limit to 1.5
23
+ this.scale.set(Math.min(this.maxScale, globalMinRatio()));
22
24
  this.reposition();
23
25
  }
24
26
  reposition() {
@@ -20,7 +20,7 @@
20
20
  "freeSpinsSummaryTextShort": "In {{amount}}",
21
21
  "pressToContinue": "\"Press ME to continue...\"",
22
22
  "freeSpinsLeft": "FREE SPIN LEFT {{amount}}",
23
- "freeSpinsDescription": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolor placeat sit iusto, possimus quia vero, porro asperiores distinctio eaque maxime, nulla eligendi! Iure esse, voluptate impedit illo ut unde quas.",
23
+ "freeSpinsDescription": "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
24
24
  "numberWithCurrency": "{{amount}}{{currency}}",
25
25
  "currentWin": "WIN: ",
26
26
  "currentFreeSpins": "FREE SPINS: ",
@@ -58,9 +58,10 @@ export declare abstract class AbstractColumnsContainer extends Container impleme
58
58
  * @param {StreakReelsIndexes} streak
59
59
  * @param {number} reelsQuantity
60
60
  * @param {number} [multiplier=1]
61
+ * @param {string} [suffix=""]
61
62
  * @returns {Promise<void>}
62
63
  */
63
- playStreak(streak: StreakReelsIndexes, reelsQuantity: number, multiplier?: number): Promise<void>;
64
+ playStreak(streak: StreakReelsIndexes, reelsQuantity: number, multiplier?: number, suffix?: string): Promise<void>;
64
65
  abstract doResize(): void;
65
66
  animate(delta: number): void;
66
67
  abstract getColumnAtPosition(column: number): AbstractSymbolsColumn;
@@ -48,6 +48,8 @@ export class AbstractColumnsContainer extends Container {
48
48
  this.quickReelsStop = true;
49
49
  this.skipScatterDelay?.();
50
50
  this.skipScatterDelay = null;
51
+ if (this.currentColumn)
52
+ this.currentColumn.skipHidingMysteryFx = true;
51
53
  }
52
54
  clearQuickReelsStop() {
53
55
  this.quickReelsStop = false;
@@ -83,7 +85,7 @@ export class AbstractColumnsContainer extends Container {
83
85
  if (configureSpinAction !== undefined) {
84
86
  if (indexesOfReelsToExtendSpinningTime.includes(index)) {
85
87
  this.currentColumn = this.allColumns[index];
86
- await frame.invokeMysteryFx(this.currentColumn.x, this.currentColumn.y);
88
+ frame.invokeMysteryFx(this.currentColumn.x, this.currentColumn.y);
87
89
  this.skipScatterDelay = configureSpinAction;
88
90
  setTimeout(() => {
89
91
  this.skipScatterDelay?.();
@@ -148,9 +150,10 @@ export class AbstractColumnsContainer extends Container {
148
150
  * @param {StreakReelsIndexes} streak
149
151
  * @param {number} reelsQuantity
150
152
  * @param {number} [multiplier=1]
153
+ * @param {string} [suffix=""]
151
154
  * @returns {Promise<void>}
152
155
  */
153
- async playStreak(streak, reelsQuantity, multiplier = 1) {
156
+ async playStreak(streak, reelsQuantity, multiplier = 1, suffix = "") {
154
157
  const promises = [];
155
158
  let reelIndex = 0;
156
159
  let playSymbolAnimation = true;
@@ -163,7 +166,7 @@ export class AbstractColumnsContainer extends Container {
163
166
  const column = this.getColumnAtPosition(reelIndex);
164
167
  if (playSymbolAnimation)
165
168
  streakSymbols.push(column.getSymbolAtPosition(symbolIndex).id);
166
- promises.push(column.playSymbolAtPosition(symbolIndex, playSymbolAnimation, multiplier));
169
+ promises.push(column.playSymbolAtPosition(symbolIndex, playSymbolAnimation, multiplier, suffix));
167
170
  if (reelIndex >= reelsQuantity - 1) {
168
171
  playSymbolAnimation = false;
169
172
  }