pixi-rainman-game-engine 0.1.9 → 0.1.10

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 (40) hide show
  1. package/dist/DescribedPlayableAction/DescribedPlayableAction.d.ts +2 -1
  2. package/dist/DescribedPlayableAction/DescribedPlayableAction.js +3 -1
  3. package/dist/Rainman/appConfig.js +1 -0
  4. package/dist/Rainman/types.d.ts +2 -0
  5. package/dist/SettingsUI/components/OptionButton/index.jsx +2 -0
  6. package/dist/application/ApiConfig/ApiConfig.js +1 -0
  7. package/dist/application/SpinLogic/SpinLogic.d.ts +3 -1
  8. package/dist/application/SpinLogic/SpinLogic.js +5 -0
  9. package/dist/application/SpinLogic/SpinLogicDTO.d.ts +1 -0
  10. package/dist/application/SpinLogic/SpinLogicDTO.js +3 -0
  11. package/dist/application/SpinLogic/types.d.ts +2 -1
  12. package/dist/components/AbstractMainContainer/AbstractMainContainer.d.ts +5 -3
  13. package/dist/components/AbstractMainContainer/AbstractMainContainer.js +31 -1
  14. package/dist/components/GambleGame/GambleGame.js +6 -5
  15. package/dist/components/buttons/buttonGroups/LeftButtons.d.ts +1 -1
  16. package/dist/components/buttons/buttonGroups/LeftButtons.js +2 -2
  17. package/dist/components/common/AnimatedBackground.js +2 -0
  18. package/dist/components/frame/AbstractColumnsContainer.d.ts +2 -1
  19. package/dist/components/frame/AbstractFrame.d.ts +1 -1
  20. package/dist/components/frame/AbstractFrame.js +1 -0
  21. package/dist/components/symbols/AbstractSymbolBase.d.ts +1 -1
  22. package/dist/components/symbols/AbstractSymbolBase.js +1 -1
  23. package/dist/components/symbols/AbstractSymbolsColumn.d.ts +1 -1
  24. package/dist/components/updatable/GambleUpdatableText.js +1 -1
  25. package/dist/components/updatable/UpdatableValueComponent.d.ts +1 -0
  26. package/dist/components/updatable/UpdatableValueComponent.js +3 -0
  27. package/dist/components/winLineIndicator/WinLineIndicator.js +1 -0
  28. package/dist/connectivity/spinData.js +2 -2
  29. package/dist/connectivity/wins.d.ts +16 -1
  30. package/dist/constants/gamble.d.ts +2 -2
  31. package/dist/constants/gamble.js +3 -3
  32. package/dist/controllers/AbstractController.d.ts +3 -2
  33. package/dist/controllers/AbstractController.js +4 -0
  34. package/dist/utils/common/functions.d.ts +2 -0
  35. package/dist/utils/common/functions.js +3 -0
  36. package/dist/winComponents/UpdatableSpineContainer.d.ts +3 -3
  37. package/dist/winComponents/UpdatableSpineContainer.js +1 -1
  38. package/dist/winComponents/winFactory.d.ts +1 -1
  39. package/dist/winComponents/winFactory.js +3 -3
  40. package/package.json +1 -1
@@ -3,6 +3,7 @@ export declare class DescribedPlayableAction<T> {
3
3
  readonly type: T;
4
4
  action: PlayableAction;
5
5
  winAmount: Nullable<number>;
6
+ skipLooping: boolean;
6
7
  isFirstStreak: boolean;
7
- constructor(type: T, action: PlayableAction, winAmount?: Nullable<number>);
8
+ constructor(type: T, action: PlayableAction, winAmount?: Nullable<number>, skipLooping?: boolean);
8
9
  }
@@ -2,10 +2,12 @@ export class DescribedPlayableAction {
2
2
  type;
3
3
  action;
4
4
  winAmount;
5
+ skipLooping;
5
6
  isFirstStreak = false;
6
- constructor(type, action, winAmount = null) {
7
+ constructor(type, action, winAmount = null, skipLooping = false) {
7
8
  this.type = type;
8
9
  this.action = action;
9
10
  this.winAmount = winAmount;
11
+ this.skipLooping = skipLooping;
10
12
  }
11
13
  }
@@ -43,5 +43,6 @@ export const defaultAppConfig = {
43
43
  },
44
44
  constants: {
45
45
  bigWinMultiplier: 30,
46
+ bigWinTextOffset: 0,
46
47
  },
47
48
  };
@@ -50,9 +50,11 @@ export type OptionalAppConfig = {
50
50
  };
51
51
  constants: {
52
52
  bigWinMultiplier: number;
53
+ bigWinTextOffset: number;
53
54
  };
54
55
  };
55
56
  export type AppConfig = RequiredAppConfig & DeepPartial<OptionalAppConfig>;
56
57
  export interface Globals {
57
58
  currency: Currency;
59
+ throttledSpin?: () => void;
58
60
  }
@@ -1,6 +1,7 @@
1
1
  import i18next from "i18next";
2
2
  import { upperFirst } from "lodash";
3
3
  import React from "react";
4
+ import { RainMan } from "../../../Rainman";
4
5
  import { UI_ITEMS } from "../../../utils";
5
6
  import { useStores } from "../../hooks";
6
7
  import { closeModal } from "../CloseModalButton";
@@ -22,6 +23,7 @@ export const OptionButton = ({ option, currency, setMessage }) => {
22
23
  settingStore.setIsFreeSpinBought(true, data);
23
24
  settingStore.setRoundNumber(data.getRawData().round_number);
24
25
  settingStore.setFreeSpinNumberBought(option.amount);
26
+ RainMan.globals.throttledSpin?.();
25
27
  closeModal(UI_ITEMS.freeSpin);
26
28
  }
27
29
  catch (err) {
@@ -51,6 +51,7 @@ export class ApiConfig {
51
51
  symbolsOnReels: blindsConfiguredByResponse,
52
52
  finalBlindsConfiguration: finalSpinPositionOnReels,
53
53
  winAmountTotal: spinLogicResponse.win_amount_total,
54
+ extraData: spinLogicResponse.extra_data,
54
55
  };
55
56
  }
56
57
  /**
@@ -1,4 +1,4 @@
1
- import { SymbolReels, TransformationDetails } from "../../connectivity";
1
+ import { ExtraData, SymbolReels, TransformationDetails } from "../../connectivity";
2
2
  import { ApiConfig } from "../ApiConfig";
3
3
  import { AdaptedSpinResponse } from "./types";
4
4
  import { WinScenarios } from "./WinScenarios";
@@ -18,6 +18,7 @@ export declare class SpinLogic {
18
18
  private readonly _hasMysteryWin;
19
19
  private readonly _winScenarios;
20
20
  private readonly _standaloneTransformations;
21
+ private readonly _extraData;
21
22
  constructor(spinConfig: AdaptedSpinResponse, gameConfig: ApiConfig);
22
23
  get postSpinBalance(): number;
23
24
  get winTotalAmount(): number;
@@ -28,4 +29,5 @@ export declare class SpinLogic {
28
29
  get hasMysteryWin(): boolean;
29
30
  get winScenarios(): WinScenarios[];
30
31
  get standaloneTransformations(): TransformationDetails[][];
32
+ get extraData(): ExtraData;
31
33
  }
@@ -17,6 +17,7 @@ export class SpinLogic {
17
17
  _hasMysteryWin;
18
18
  _winScenarios;
19
19
  _standaloneTransformations;
20
+ _extraData;
20
21
  constructor(spinConfig, gameConfig) {
21
22
  const spinLogicReader = new SpinLogicDTO(spinConfig, gameConfig);
22
23
  this._postSpinBalance = spinLogicReader.updatedBalance;
@@ -27,6 +28,7 @@ export class SpinLogic {
27
28
  this._hasMysteryWin = spinLogicReader.hasMysteryWin;
28
29
  this._winScenarios = spinLogicReader.winScenarios;
29
30
  this._standaloneTransformations = spinLogicReader.standaloneTransformations;
31
+ this._extraData = spinLogicReader.extraData;
30
32
  logInfo("Spin logic", JSON.parse(JSON.stringify(this)));
31
33
  }
32
34
  get postSpinBalance() {
@@ -57,4 +59,7 @@ export class SpinLogic {
57
59
  get standaloneTransformations() {
58
60
  return this._standaloneTransformations;
59
61
  }
62
+ get extraData() {
63
+ return this._extraData;
64
+ }
60
65
  }
@@ -11,6 +11,7 @@ export declare class SpinLogicDTO {
11
11
  get totalWonAmount(): number;
12
12
  get finalBlindsConfiguration(): SymbolReels;
13
13
  get onStopBlindsConfiguration(): SymbolReels;
14
+ get extraData(): import("../../connectivity").ExtraData;
14
15
  get winScenarios(): WinScenarios[];
15
16
  get standaloneTransformations(): TransformationDetails[][];
16
17
  get hasMysteryWin(): boolean;
@@ -38,6 +38,9 @@ export class SpinLogicDTO {
38
38
  get onStopBlindsConfiguration() {
39
39
  return this.rawData.symbolsOnReels.map((reel) => reel.map((symbol) => this.stringToSymbolId(symbol)));
40
40
  }
41
+ get extraData() {
42
+ return this.rawData.extraData;
43
+ }
41
44
  get winScenarios() {
42
45
  const { results, availableFreeSpins } = this.rawData;
43
46
  if (results === undefined)
@@ -1,4 +1,4 @@
1
- import { SpinDataInterface, SymbolReels, TransformationDetails, WinWithTransformation } from "../../connectivity";
1
+ import { ExtraData, SpinDataInterface, SymbolReels, TransformationDetails, WinWithTransformation } from "../../connectivity";
2
2
  import { ApiConfig } from "../ApiConfig";
3
3
  import { SpinLogic } from "./SpinLogic";
4
4
  export type AdaptedSpinResponse = {
@@ -10,5 +10,6 @@ export type AdaptedSpinResponse = {
10
10
  winAmountTotal: number;
11
11
  results: WinWithTransformation[];
12
12
  standaloneTransformations: TransformationDetails[][];
13
+ extraData: ExtraData;
13
14
  };
14
15
  export type SpinLogicFactory = (spinLogicResponse: SpinDataInterface, gameConfig: ApiConfig) => SpinLogic;
@@ -26,6 +26,8 @@ export declare abstract class AbstractMainContainer extends Container {
26
26
  protected abstract leftButtons: ResponsiveContainer;
27
27
  protected abstract rightButtons: ResponsiveContainer;
28
28
  protected bottomPanel: Nullable<Sprite>;
29
+ private gambleGame;
30
+ protected gambleGameSpineName: Nullable<string>;
29
31
  protected _freeSpinPlate: Nullable<AbstractFreeSpinContainer>;
30
32
  protected _freeSpinSummary: Nullable<AbstractFreeSpinContainer>;
31
33
  private _bigWinInvokedAt;
@@ -36,9 +38,9 @@ export declare abstract class AbstractMainContainer extends Container {
36
38
  protected abstract triggerStoreInitState(): void;
37
39
  get freeSpinPlate(): Nullable<AbstractFreeSpinContainer>;
38
40
  get freeSpinSummary(): Nullable<AbstractFreeSpinContainer>;
39
- protected abstract createFreeSpinPlate(resolver: () => void, freeSpinCount: number, isAdditionalFreeSpin: boolean): AbstractFreeSpinContainer;
41
+ protected createFreeSpinPlate(_resolver: () => void, _freeSpinCount: number, _isAdditionalFreeSpin: boolean): AbstractFreeSpinContainer | null;
40
42
  invokeFreeSpinPlate(freeSpinCount: number, isAdditionalFreeSpin?: boolean): Promise<void>;
41
- protected abstract createFreeSpinSummary(resolver: () => void, freeSpinCount: number, winAmount: number): AbstractFreeSpinContainer;
43
+ protected createFreeSpinSummary(_resolver: () => void, _freeSpinCount: number, _winAmount: number): AbstractFreeSpinContainer | null;
42
44
  invokeFreeSpinSummary(freeSpinCount: number, winAmount: number): Promise<void>;
43
45
  hideFreeSpinSummary(): void;
44
46
  private showOverlay;
@@ -51,7 +53,7 @@ export declare abstract class AbstractMainContainer extends Container {
51
53
  invokeMysteryWin(): void;
52
54
  destroyBigWin(): void;
53
55
  destroyMysteryWin(): void;
54
- invokeGambleGame(): void;
56
+ invokeGambleGame(): Promise<void>;
55
57
  protected createUnderFramePanel(): Graphics | Sprite;
56
58
  enableForMobile(): void;
57
59
  enableForLandscape(): void;
@@ -5,6 +5,7 @@ import { RainMan } from "../../Rainman";
5
5
  import { settingStore } from "../../SettingsUI/hooks";
6
6
  import { getDeviceOrientation, globalMinRatio } from "../../utils";
7
7
  import { BUTTONS, LeftButtons, LeftButtonsLandscape, LeftButtonsMobile, MiddleButtons, RefreshButton, RightButtons, RightButtonsLandscape, RightButtonsMobile, } from "../buttons";
8
+ import { GambleGame } from "../GambleGame";
8
9
  import { MessageBox } from "../messageBox";
9
10
  export class AbstractMainContainer extends Container {
10
11
  static registryName = "mainContainer";
@@ -20,6 +21,8 @@ export class AbstractMainContainer extends Container {
20
21
  portraitPlayButtons = null;
21
22
  landscapePlayButtons = null;
22
23
  bottomPanel = null;
24
+ gambleGame = null;
25
+ gambleGameSpineName = null;
23
26
  _freeSpinPlate = null;
24
27
  _freeSpinSummary = null;
25
28
  _bigWinInvokedAt = null;
@@ -40,11 +43,16 @@ export class AbstractMainContainer extends Container {
40
43
  get freeSpinSummary() {
41
44
  return this._freeSpinSummary;
42
45
  }
46
+ createFreeSpinPlate(_resolver, _freeSpinCount, _isAdditionalFreeSpin) {
47
+ return null;
48
+ }
43
49
  async invokeFreeSpinPlate(freeSpinCount, isAdditionalFreeSpin = false) {
44
50
  const refreshButton = RainMan.componentRegistry.get(RefreshButton.registryName);
45
51
  refreshButton.flipDisabledFlag(true);
46
52
  await new Promise(async (resolve) => {
47
53
  this._freeSpinPlate = this.createFreeSpinPlate(resolve, freeSpinCount, isAdditionalFreeSpin);
54
+ if (this._freeSpinPlate === null)
55
+ return resolve();
48
56
  this._freeSpinPlate.resize();
49
57
  this.showOverlay();
50
58
  this.addChild(this._freeSpinPlate);
@@ -57,11 +65,16 @@ export class AbstractMainContainer extends Container {
57
65
  this.hideOverlay();
58
66
  refreshButton.flipDisabledFlag(false);
59
67
  }
68
+ createFreeSpinSummary(_resolver, _freeSpinCount, _winAmount) {
69
+ return null;
70
+ }
60
71
  async invokeFreeSpinSummary(freeSpinCount, winAmount) {
61
72
  const refreshButton = RainMan.componentRegistry.get(BUTTONS.refresh);
62
73
  refreshButton.flipDisabledFlag(true);
63
74
  await new Promise((resolve) => {
64
75
  this._freeSpinSummary = this.createFreeSpinSummary(resolve, freeSpinCount, winAmount);
76
+ if (this._freeSpinSummary === null)
77
+ return resolve();
65
78
  this._freeSpinSummary.resize();
66
79
  this.showOverlay();
67
80
  this.addChild(this._freeSpinSummary);
@@ -152,7 +165,21 @@ export class AbstractMainContainer extends Container {
152
165
  this.mysteryWinContainer = null;
153
166
  this._mysteryWinInvokedAt = null;
154
167
  }
155
- invokeGambleGame() { }
168
+ async invokeGambleGame() {
169
+ if (!this.gambleGameSpineName)
170
+ return;
171
+ const newBalance = await new Promise((resolve) => {
172
+ this.gambleGame = new GambleGame(this.gambleGameSpineName, resolve, this._controller.lastWinAmount, this._controller.balance);
173
+ this.showOverlay();
174
+ this.addChild(this.gambleGame);
175
+ });
176
+ if (this.gambleGame) {
177
+ this.removeChild(this.gambleGame);
178
+ this.gambleGame = null;
179
+ }
180
+ this._controller.balance = newBalance;
181
+ this.hideOverlay();
182
+ }
156
183
  createUnderFramePanel() {
157
184
  const underFramePanel = new Graphics();
158
185
  underFramePanel.beginFill(0x0, 0.5);
@@ -299,6 +326,9 @@ export class AbstractMainContainer extends Container {
299
326
  this.addChild(this.mysteryWinContainer);
300
327
  this.mysteryWinContainer.resize();
301
328
  }
329
+ if (this.gambleGame) {
330
+ this.gambleGame.resize();
331
+ }
302
332
  if (this.bottomPanel) {
303
333
  this.bottomPanel.scale.set(resizingHelper);
304
334
  this.bottomPanel.width = RainMan.app.screen.width;
@@ -39,25 +39,26 @@ export class GambleGame extends Container {
39
39
  this.resolver = resolver;
40
40
  this.bet = bet;
41
41
  this.balanceValue = balanceValue;
42
- this.interactive = true;
42
+ this.eventMode = "static";
43
43
  this.background = new Sprite(Texture.from("black-bg.png"));
44
44
  this.frame = new Sprite(Texture.from("frame-v2.png"));
45
- this.previousGamblesText = new Text(i18next.t("previousCards"), gamblesTextStyle);
45
+ this.previousGamblesText = new Text(i18next.t("previousCards"), gamblesTextStyle());
46
46
  this.previousGamblesContainer = new Container();
47
47
  this.collectButton = new CollectButton();
48
48
  this.redButton = new RedButton();
49
49
  this.blackButton = new BlackButton();
50
50
  this.collectButton.pivot.x = this.collectButton.width / 2;
51
- this.collectText = new Text(i18next.t("collect"), gamblesTextStyle);
51
+ this.collectText = new Text(i18next.t("collect"), gamblesTextStyle());
52
52
  this.collectText.pivot.x = this.collectText.width / 2;
53
53
  this.collectText.pivot.y = this.collectText.height / 2;
54
54
  this.card = new Spine(getSpineData(cardSpineName));
55
55
  this.card.state.addAnimation(0, "idle", true, 0);
56
56
  this.currentWin = new GambleUpdatableText(GambleGame.gambleCurrentWinRegistryName, i18next.t("currentWinGamble"), this.bet, 1);
57
- this.gambleWin = new GambleUpdatableText(GambleGame.gambleWinRegistryName, i18next.t("currentWinGamble"), this.bet * 2, 2);
57
+ this.gambleWin = new GambleUpdatableText(GambleGame.gambleWinRegistryName, i18next.t("gambleToWin"), this.bet * 2, 2);
58
58
  this.redButton.setOnClick(() => this.handleGamblePlay("red"));
59
59
  this.blackButton.setOnClick(() => this.handleGamblePlay("black"));
60
60
  this.collectButton.setOnClick(() => this.resolver(this.balanceValue));
61
+ this.resize();
61
62
  }
62
63
  showPreviousGambles(previousGambles) {
63
64
  const { width } = RainMan.app.screen;
@@ -138,8 +139,8 @@ export class GambleGame extends Container {
138
139
  this.collectButton.scale.set(globalMinRatio() * 0.8);
139
140
  this.collectButton.x = CENTER;
140
141
  this.collectButton.y = this.collectText.y - this.collectButton.height - 30;
141
- const COLOR_BUTTONS_Y = this.card.y - this.redButton.height / 2;
142
142
  this.redButton.scale.set(globalMinRatio() * COLOR_BUTTONS_SCALE_X);
143
+ const COLOR_BUTTONS_Y = this.card.y - this.redButton.height / 2;
143
144
  this.redButton.x = CENTER - COLOR_BUTTONS_CENTER_OFFSET - this.redButton.width;
144
145
  this.redButton.y = COLOR_BUTTONS_Y;
145
146
  this.blackButton.scale.set(globalMinRatio() * COLOR_BUTTONS_SCALE_X);
@@ -7,7 +7,7 @@ export declare class LeftButtons extends ResponsiveContainer {
7
7
  protected readonly infoButton: InfoButton;
8
8
  protected readonly credit: UpdatableTextComponent;
9
9
  protected readonly bet: UpdatableTextComponent;
10
- constructor();
10
+ constructor(scaleMultiplier?: number);
11
11
  removeChildrenFromRegistry(): void;
12
12
  protected reposition(): void;
13
13
  }
@@ -11,8 +11,8 @@ export class LeftButtons extends ResponsiveContainer {
11
11
  infoButton = new InfoButton();
12
12
  credit = new UpdatableTextComponent(COMPONENTS.creditText, i18next.t("credit"), UPDATABLE_MODES.money);
13
13
  bet = new UpdatableTextComponent(COMPONENTS.betText, i18next.t("bet"), UPDATABLE_MODES.money);
14
- constructor() {
15
- super();
14
+ constructor(scaleMultiplier) {
15
+ super(scaleMultiplier);
16
16
  this.name = REGISTRY.leftButtons;
17
17
  this.parentLayer = UXLayer;
18
18
  this.volumeButton.anchor.set(0, 0);
@@ -1,4 +1,5 @@
1
1
  import { Spine } from "pixi-spine";
2
+ import { BackgroundLayer } from "../../layers";
2
3
  import { RainMan } from "../../Rainman";
3
4
  import { getDeviceOrientation, getSpineData } from "../../utils";
4
5
  import { ResumableContainer } from "./ResumableContainers";
@@ -23,6 +24,7 @@ export class AnimatedBackground extends ResumableContainer {
23
24
  this.animationName = animationName;
24
25
  this.mobileSpineName = mobileSpineName;
25
26
  this.name = AnimatedBackground.registryName;
27
+ this.parentLayer = BackgroundLayer;
26
28
  }
27
29
  resize() {
28
30
  this.changeSpineForOrientation();
@@ -1,6 +1,7 @@
1
1
  import { Container, Graphics } from "pixi.js";
2
2
  import { SoundTrack, SpeedAdapterInterface, SpeedLevel, SymbolId } from "../../application";
3
3
  import { DropTransformationDetails, StreakReelsIndexes, SymbolReels } from "../../connectivity";
4
+ import { PlayableAction } from "../../utils";
4
5
  import { AbstractSymbolsColumn } from "../symbols";
5
6
  /**
6
7
  * Class represents columns container in game
@@ -70,5 +71,5 @@ export declare abstract class AbstractColumnsContainer extends Container impleme
70
71
  handleDestroyTransformations(transformations: DropTransformationDetails[], skipAnimations?: boolean, isStandalone?: boolean): Promise<void>;
71
72
  protected createMask(): Graphics;
72
73
  fixSymbolsColumnsPosition(): void;
73
- private prepareConfiguringReelsEnd;
74
+ protected prepareConfiguringReelsEnd(finalSymbolReels: SymbolReels): PlayableAction[];
74
75
  }
@@ -34,7 +34,7 @@ export declare abstract class AbstractFrame extends ResumableContainer implement
34
34
  get columnsContainer(): AbstractColumnsContainer;
35
35
  adaptToSpeed(speedLevel: SpeedLevel): void;
36
36
  invokeMysteryFx(x: number, y: number): void;
37
- protected abstract repositionMysteryFx(x: number, y: number): void;
37
+ protected repositionMysteryFx(_x: number, _y: number): void;
38
38
  hideMysteryFx(): Promise<void>;
39
39
  destroyMysteryFx(): void;
40
40
  protected createWinLineAnimation(_animationName: string): WinLineAnimation | null;
@@ -49,6 +49,7 @@ export class AbstractFrame extends ResumableContainer {
49
49
  complete: () => this.mysteryFxHighlight?.state.setAnimation(0, this.mysteryFxConfig.loopAnimationName, true),
50
50
  });
51
51
  }
52
+ repositionMysteryFx(_x, _y) { }
52
53
  async hideMysteryFx() {
53
54
  return new Promise((resolve) => {
54
55
  if (!this.mysteryFxConfig)
@@ -14,7 +14,7 @@ import { LoadersSpineData, Nullable } from "../../utils";
14
14
  export declare abstract class AbstractSymbolBase extends Container {
15
15
  private multiplierSpineName;
16
16
  protected symbolImage: Sprite;
17
- protected spine: Spine;
17
+ spine: Spine;
18
18
  protected destroySuffix: string;
19
19
  protected animationSpeedMultiplier: number;
20
20
  private endOfMultiplierAnimationPromise;
@@ -75,7 +75,7 @@ export class AbstractSymbolBase extends Container {
75
75
  return;
76
76
  }
77
77
  async handleMultiplierAnimation(multiplier) {
78
- if (multiplier === 1 || this.multiplierSpineName === null)
78
+ if (multiplier <= 1 || this.multiplierSpineName === null)
79
79
  return;
80
80
  const symbolMultiplier = new Spine(getSpineData(this.multiplierSpineName));
81
81
  this.addChild(symbolMultiplier);
@@ -17,7 +17,7 @@ import { AnimationTimeSettings } from "./types";
17
17
  */
18
18
  export declare abstract class AbstractSymbolsColumn extends Container implements SpeedAdapterInterface<number> {
19
19
  protected columnsContainer: AbstractColumnsContainer;
20
- protected allSymbols: SymbolId[];
20
+ allSymbols: SymbolId[];
21
21
  spinning: boolean;
22
22
  speedLevelMapper: import("../../application").SpeedLevelDirectory<number>;
23
23
  protected symbols: Array<AbstractSymbolBase>;
@@ -7,7 +7,7 @@ export class GambleUpdatableText extends UpdatableValueComponent {
7
7
  frame;
8
8
  icon;
9
9
  constructor(registryName, baseText, initialValue, icon, updateCallback) {
10
- super(registryName, baseText, gamblesTextStyle, gamblesTextStyle, UPDATABLE_MODES.money, updateCallback);
10
+ super(registryName, baseText, gamblesTextStyle(24), gamblesTextStyle(), UPDATABLE_MODES.money, updateCallback);
11
11
  this.name = registryName;
12
12
  this.finalValue = initialValue;
13
13
  this.frame = new Sprite(Texture.from("black-button-n.png"));
@@ -28,4 +28,5 @@ export declare abstract class UpdatableValueComponent extends Container implemen
28
28
  private getFinalValue;
29
29
  private initAnimation;
30
30
  private setResultAndClearTween;
31
+ updateBaseTextStyle(style: Partial<ITextStyle>): void;
31
32
  }
@@ -115,4 +115,7 @@ export class UpdatableValueComponent extends Container {
115
115
  Ticker.shared.remove(() => this.animate());
116
116
  this.changeCurrentWin(finalValue);
117
117
  }
118
+ updateBaseTextStyle(style) {
119
+ this.baseTextComponent.style = { ...this.baseTextComponent.style, ...style };
120
+ }
118
121
  }
@@ -16,6 +16,7 @@ export class WinLineIndicator extends Container {
16
16
  const previous = this.symbols[i - 1];
17
17
  const current = this.symbols[i];
18
18
  current.scale.set(RainMan.config.winLineIndicatorSymbolScale);
19
+ current.anchor.set(0);
19
20
  if (previous)
20
21
  current.x += previous.x + previous.width;
21
22
  current.y -= current.height / 2;
@@ -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") {
10
- throw new Error(`Invalid type "${data.action}" provided, "spin" expected`);
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`);
11
11
  }
12
12
  }
13
13
  getRawData() {
@@ -32,7 +32,22 @@ export type MysteryWin = BaseWin & {
32
32
  export type EggWin = BaseWin & {
33
33
  type: typeof PossibleWins.egg;
34
34
  };
35
- export type Win = StreakWin | FreeSpinWin | GambleWin | MysteryWin | EggWin;
35
+ export type GoldWin = BaseWin & {
36
+ type: typeof PossibleWins.gold;
37
+ };
38
+ export type BigWin = BaseWin & {
39
+ type: typeof PossibleWins.bigWin;
40
+ };
41
+ export type BonusWin = BaseWin & {
42
+ type: typeof PossibleWins.bonus;
43
+ };
44
+ export type SuperBonusWin = BaseWin & {
45
+ type: typeof PossibleWins.superBonus;
46
+ };
47
+ export type ScatterWin = BaseWin & {
48
+ type: typeof PossibleWins.scatter;
49
+ };
50
+ export type Win = StreakWin | FreeSpinWin | GambleWin | MysteryWin | EggWin | GoldWin | BigWin | BonusWin | SuperBonusWin | ScatterWin;
36
51
  /**
37
52
  * Type represents data that come from backend
38
53
  *
@@ -2,8 +2,8 @@ import { TextStyle } from "pixi.js";
2
2
  export declare const BOTTOM_BUTTONS_SCALE_X = 0.3;
3
3
  export declare const BOTTOM_BUTTONS_Y = 800;
4
4
  export declare const BOTTOM_BUTTONS_CENTER_OFFSET = 80;
5
- export declare const COLOR_BUTTONS_SCALE_X = 0.3;
5
+ export declare const COLOR_BUTTONS_SCALE_X = 0.8;
6
6
  export declare const COLOR_BUTTONS_CENTER_OFFSET = 200;
7
7
  export declare const MONEY_Y = 700;
8
8
  export declare const MONEY_CENTER_OFFSET = 300;
9
- export declare const gamblesTextStyle: TextStyle;
9
+ export declare const gamblesTextStyle: (fontSize?: number) => TextStyle;
@@ -2,13 +2,13 @@ import { TextStyle } from "pixi.js";
2
2
  export const BOTTOM_BUTTONS_SCALE_X = 0.3;
3
3
  export const BOTTOM_BUTTONS_Y = 800;
4
4
  export const BOTTOM_BUTTONS_CENTER_OFFSET = 80;
5
- export const COLOR_BUTTONS_SCALE_X = 0.3;
5
+ export const COLOR_BUTTONS_SCALE_X = 0.8;
6
6
  export const COLOR_BUTTONS_CENTER_OFFSET = 200;
7
7
  export const MONEY_Y = 700;
8
8
  export const MONEY_CENTER_OFFSET = 300;
9
- export const gamblesTextStyle = new TextStyle({
9
+ export const gamblesTextStyle = (fontSize = 40) => new TextStyle({
10
10
  fill: "#fff",
11
11
  fontWeight: "bold",
12
12
  align: "center",
13
- fontSize: 40,
13
+ fontSize,
14
14
  });
@@ -57,19 +57,20 @@ export declare abstract class AbstractController<T> {
57
57
  private setRefreshButtonBasedOnPhase;
58
58
  private setMessageBoxBasedOnPhase;
59
59
  private getReelIndexesToShowMysteryFx;
60
- private handleSpinLogic;
60
+ protected handleSpinLogic(): void;
61
61
  protected throttledSpin(): void;
62
62
  private getBoughtNumberOfFreeSpins;
63
63
  private autoplaySpin;
64
64
  protected clearAndDestroyActions(): void;
65
65
  private disableAutoplay;
66
+ protected onDataFetch(_spinData: SpinData, _spinLogic: SpinLogic): void;
66
67
  private fetchAndPrepareSpinData;
67
68
  protected abstract canSkipActions(): boolean;
68
69
  protected onSpinningStart(): Promise<void>;
69
70
  protected onSpinningEnd(_data: SpinData): Promise<void>;
70
71
  private spin;
71
72
  private handleFreeSpinPlateInvocation;
72
- private handleFreeSpinSummaryPlateInvocation;
73
+ protected handleFreeSpinSummaryPlateInvocation(): Promise<void>;
73
74
  private handleAutoplayLogic;
74
75
  private lockLogicWhileSpinning;
75
76
  private unlockLogicAfterSpinning;
@@ -51,6 +51,7 @@ export class AbstractController {
51
51
  const initData = this.connection.initData();
52
52
  this.config = new ApiConfig(initData);
53
53
  RainMan.settingsStore.initPaytableMap(initData);
54
+ RainMan.globals.throttledSpin = this.throttledSpin.bind(this);
54
55
  this.connection.subscribeForConfigChanges(this.reinitializeUserBalanceData.bind(this));
55
56
  this.uiController.updateBet("first");
56
57
  this.uiController.currentBalance = initData.balance;
@@ -74,6 +75,7 @@ export class AbstractController {
74
75
  this.config = new ApiConfig(initData);
75
76
  RainMan.settingsStore.initPaytableMap(initData);
76
77
  this.roundNumber = 0;
78
+ this.uiController.updateBet("first");
77
79
  this.uiController.triggerUiElementsUpdate();
78
80
  }
79
81
  reinitializeAllButtons() {
@@ -354,6 +356,7 @@ export class AbstractController {
354
356
  RainMan.componentRegistry.get(BUTTONS.plus).flipDisabledFlag(false);
355
357
  RainMan.componentRegistry.get(BUTTONS.neg).flipDisabledFlag(false);
356
358
  }
359
+ onDataFetch(_spinData, _spinLogic) { }
357
360
  async fetchAndPrepareSpinData() {
358
361
  this.changeGamePhase(gamePhases.DATA_FETCH);
359
362
  const data = RainMan.settingsStore.buyFreeSpinsData ||
@@ -361,6 +364,7 @@ export class AbstractController {
361
364
  debugSpinData(data);
362
365
  const spinLogic = RainMan.spinLogicFactory(data.getRawData(), this.config);
363
366
  this._lastWinAmount = this.mysteryWinSymbol ? spinLogic.winTotalAmountWithoutMystery : spinLogic.winTotalAmount;
367
+ this.onDataFetch(data, spinLogic);
364
368
  if (spinLogic.winTotalAmount !== 0) {
365
369
  this.uiController.recentWin = ceilToDecimal(spinLogic.winTotalAmount);
366
370
  if (RainMan.settingsStore.onAnyWin) {
@@ -1,4 +1,5 @@
1
1
  import { Spine } from "pixi-spine";
2
+ import { Point } from "../../connectivity";
2
3
  export declare const ceilToDecimal: (value: number, decimalPlaces?: number) => number;
3
4
  export declare const wait: (ms: number) => Promise<void>;
4
5
  export declare const range: (start: number, stop: number, step: number) => number[];
@@ -11,3 +12,4 @@ export declare const waitForAnimationToEnd: (spine: Spine, animationName: string
11
12
  export declare const setTimeScale: (spine: Spine, flag: boolean) => void;
12
13
  export declare const changeResolution: (high: boolean) => void;
13
14
  export declare const notNullish: <T>(x: T | null | undefined) => x is T;
15
+ export declare const areCoordinatesEqual: (firstCoordinates: Point, secondCoordinates: Point) => boolean;
@@ -73,3 +73,6 @@ export const changeResolution = (high) => {
73
73
  export const notNullish = (x) => {
74
74
  return x !== null && x !== undefined;
75
75
  };
76
+ export const areCoordinatesEqual = (firstCoordinates, secondCoordinates) => {
77
+ return firstCoordinates.x === secondCoordinates.x && firstCoordinates.y === secondCoordinates.y;
78
+ };
@@ -12,9 +12,9 @@ import { PositioningFrame } from "./PositioningFrame";
12
12
  * @extends {Container}
13
13
  */
14
14
  export declare class UpdatableSpineContainer extends Container {
15
- private text;
16
- private spine;
17
- private frame;
15
+ protected text: StylefulUpdatableText;
16
+ protected spine: ScalableSpine;
17
+ protected frame: PositioningFrame;
18
18
  private emitters;
19
19
  private spineScale;
20
20
  constructor(text: StylefulUpdatableText, spine: ScalableSpine, frame: PositioningFrame, emitters: AnimableParticlesEmitter[], spineScale?: number);
@@ -35,7 +35,7 @@ export class UpdatableSpineContainer extends Container {
35
35
  Ticker.shared.add(this.animateBox, this);
36
36
  }
37
37
  positionText() {
38
- this.text.y = this.spine.height / 3;
38
+ this.text.y = this.spine.height / 3 + RainMan.config.constants.bigWinTextOffset;
39
39
  this.text.x = 0 - this.text.width / 2;
40
40
  }
41
41
  resize() {
@@ -1,4 +1,4 @@
1
1
  import { ITextStyle } from "pixi.js";
2
2
  import { AnimableParticlesEmitter } from "./AnimableParticlesEmitter";
3
3
  import { UpdatableSpineContainer } from "./UpdatableSpineContainer";
4
- export declare const winFactory: (textRegistryName: string, defaultText: string, spineName: string, animationName: string, emitters?: AnimableParticlesEmitter[], textStyleOverrides?: Partial<ITextStyle>) => UpdatableSpineContainer;
4
+ export declare const winFactory: (textRegistryName: string, defaultText: string, spineName: string, animationName: string, emitters?: AnimableParticlesEmitter[], textStyleOverrides?: Partial<ITextStyle>, spineScale?: number) => UpdatableSpineContainer;
@@ -2,10 +2,10 @@ import { ScalableSpine, StylefulUpdatableText, UPDATABLE_MODES } from "../compon
2
2
  import { RainMan } from "../Rainman";
3
3
  import { PositioningFrame } from "./PositioningFrame";
4
4
  import { UpdatableSpineContainer } from "./UpdatableSpineContainer";
5
- export const winFactory = (textRegistryName, defaultText, spineName, animationName, emitters = [], textStyleOverrides = {}) => {
5
+ export const winFactory = (textRegistryName, defaultText, spineName, animationName, emitters = [], textStyleOverrides = {}, spineScale) => {
6
6
  const textStyle = {
7
7
  fontFamily: RainMan.config.fontFace,
8
- fill: ["#FCD784", "#AE6119", "#FEE391"], // gradient
8
+ fill: ["#FCD784", "#AE6119", "#FEE391"], // gradientnu
9
9
  stroke: "#4a1850",
10
10
  strokeThickness: 5,
11
11
  dropShadow: true,
@@ -20,5 +20,5 @@ export const winFactory = (textRegistryName, defaultText, spineName, animationNa
20
20
  const bigWinSpine = new ScalableSpine(spineName, animationName);
21
21
  const { width, height } = RainMan.app.screen;
22
22
  const bigWinShadow = new PositioningFrame(width, height, 0x000000);
23
- return new UpdatableSpineContainer(bigWinText, bigWinSpine, bigWinShadow, emitters);
23
+ return new UpdatableSpineContainer(bigWinText, bigWinSpine, bigWinShadow, emitters, spineScale);
24
24
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
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",