pixi-rainman-game-engine 0.1.20 → 0.1.21

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.
@@ -2,7 +2,9 @@ import i18next from "i18next";
2
2
  import React from "react";
3
3
  import { UI_ITEMS } from "../../utils";
4
4
  import { BetSettings, CloseModalButton, UXSettings } from "../components";
5
+ import { useDeviceOrientations } from "../hooks";
5
6
  export const SystemSettingsComponent = () => {
7
+ const deviceOrientation = useDeviceOrientations();
6
8
  return (<div className="flex w-full max-w-lg flex-col justify-center gap-2 p-4">
7
9
  <div className="flex w-full justify-center">
8
10
  <h2 className="text-2xl font-bold uppercase text-primary-500">{i18next.t("systemSettings")}</h2>
@@ -10,7 +12,7 @@ export const SystemSettingsComponent = () => {
10
12
  <CloseModalButton layerId={UI_ITEMS.settings}/>
11
13
  <div className="flex w-full flex-col justify-center">
12
14
  <UXSettings />
13
- <BetSettings className="hidden w-full justify-center sm:flex"/>
15
+ {!deviceOrientation.includes("mobile") ? <BetSettings className="flex w-full justify-center"/> : null}
14
16
  </div>
15
17
  </div>);
16
18
  };
@@ -5,7 +5,7 @@ import { useStores } from "../../hooks";
5
5
  import { Button } from "../Button";
6
6
  export const BetControls = observer(() => {
7
7
  const { settingStore } = useStores();
8
- return (<div className="my-7 flex w-full flex-col items-center justify-center gap-2">
8
+ return (<div className="flex w-full flex-col items-center justify-center gap-2 p-4">
9
9
  <h2 className="font-bold uppercase text-primary-500 sm:text-2xl">{i18next.t("totalBet")}</h2>
10
10
  <div className="flex w-full items-center justify-center gap-4">
11
11
  <Button className="flex h-10 w-8 items-center justify-center rounded-lg bg-primary-400 p-4 font-bold text-black shadow-md transition duration-300 hover:bg-primary-300" name="bet-minus">
@@ -22,15 +22,17 @@ export const GameRules = observer(() => {
22
22
  }
23
23
  setPageNumber(pageNumber + incrementor);
24
24
  };
25
- return (<div className="flex h-full max-h-[90vh] w-[90%] flex-col items-center gap-4 p-5">
26
- <h2 className="text-pr text-center text-3xl font-bold text-primary-500">{i18next.t("gameRules")}</h2>
25
+ return (<div className="max-w-5/6 flex h-fit max-h-[80vh] flex-col items-center gap-4 p-5">
26
+ <h2 className="text-center text-3xl font-bold text-primary-500">{i18next.t("gameRules")}</h2>
27
27
  <CloseModalButton layerId={UI_ITEMS.gameRules}/>
28
- <div className="custom-scroll mb-5 h-full min-h-[60vh]">
29
- <CustomScroll className="h-[70%]" allowOuterScroll={true}>
30
- <div className="text-md h-full w-[90%] text-justify">{gameRulesContent.pages[pageNumber]}</div>
28
+ <div className="custom-scroll max-w-5/6 h-full min-h-[60vh]">
29
+ <CustomScroll className="h-full w-full overflow-y-auto portrait:max-h-[60vh]" allowOuterScroll={true}>
30
+ <div className="text-md max-w-5/6 w-full overflow-y-auto landscape:max-h-[30vh]">
31
+ {gameRulesContent.pages[pageNumber]}
32
+ </div>
31
33
  </CustomScroll>
32
34
  </div>
33
- <div className="relative bottom-5 left-5 flex h-[50px] items-center justify-center gap-2">
35
+ <div className="flex h-[50px] items-center justify-center gap-2">
34
36
  <div className="flex h-[24px] w-6 items-center bg-[url('/assets/settings/gameRules/left.png')] bg-contain bg-right bg-no-repeat hover:opacity-50" onClick={() => changePage(-1)}/>
35
37
  <div className="flex h-[24px] w-6 items-center bg-[url('/assets/settings/gameRules/cross.png')] bg-contain bg-no-repeat hover:opacity-50" onClick={() => settingStore.handleModalInvocation?.(UI_ITEMS.gameRules)}/>
36
38
  <div className="flex h-[24px] w-6 items-center bg-[url('/assets/settings/gameRules/right.png')] bg-contain bg-no-repeat hover:opacity-50" onClick={() => changePage(1)}/>
@@ -15,7 +15,7 @@ export const Modal = observer(({ layerId, children, className }) => {
15
15
  <div onClick={() => setOpen(!open)} className="fixed inset-0 bg-zinc-800 bg-opacity-75 transition-opacity"/>
16
16
  <div className="fixed inset-0 z-10 w-screen overflow-y-auto p-6">
17
17
  <div className="flex min-h-full w-full items-center justify-center rounded-lg shadow">
18
- <div ref={ref} className={cn("min-w-3/4 relative flex h-5/6 w-full transform flex-col items-center overflow-hidden rounded-lg bg-zinc-900 p-2 text-left shadow-xl transition-all", className)}>
18
+ <div ref={ref} className={cn("relative flex h-5/6 transform flex-col items-center overflow-hidden rounded-lg bg-zinc-900 p-2 text-left shadow-xl transition-all", className)}>
19
19
  {children}
20
20
  </div>
21
21
  </div>
@@ -15,10 +15,10 @@ export const SpeedSettingsPopup = observer(() => {
15
15
  fast: SPEED_LEVELS.fast,
16
16
  };
17
17
  const { settingStore } = useStores();
18
- return (<div className="flex h-full w-[90%] flex-col items-center justify-between gap-2 p-4">
18
+ return (<div className="flex h-full w-fit flex-col items-center justify-between gap-2 p-4 portrait:max-w-72">
19
19
  <CloseModalButton layerId={UI_ITEMS.speedSettings}/>
20
20
  <h1 className="mt-3 font-bold uppercase text-white sm:text-xl">{i18next.t("howDoYouWantToPlay")}</h1>
21
- <div className="flex h-fit w-full flex-wrap justify-between gap-2">
21
+ <div className="flex h-fit w-full flex-wrap justify-between gap-2 portrait:items-center portrait:justify-center">
22
22
  {Object.keys(speedLevelMapper).map((speedLevelKey) => (<div id={`${SPEED_PREFIX}${speedLevelKey}`} key={`${SPEED_PREFIX}${speedLevelKey}`} className={cn("flex h-fit w-[145px] items-center justify-center border-2 border-zinc-400 bg-zinc-800 bg-contain bg-no-repeat p-4", speedLevelKey === settingStore.currentSpeed ? "h-fit border-2 border-primary-500" : "")}>
23
23
  <img className="h-12 w-fit" src={`../../../assets/settings/speedPopup/speed-${speedLevelMapper[speedLevelKey]}.png`}/>
24
24
  </div>))}
@@ -18,7 +18,7 @@ export const SettingsUI = () => {
18
18
  <Modal layerId={UI_ITEMS.autoplay}>
19
19
  <AutoplaySettings />
20
20
  </Modal>
21
- <Modal layerId={UI_ITEMS.speedSettings} className="absolute left-[25wv] top-[40vh] flex h-fit w-fit items-center justify-center rounded-xl bg-zinc-900 p-4 shadow-primary-500/30 landscape:top-[20vh]">
21
+ <Modal layerId={UI_ITEMS.speedSettings} className="absolute flex h-fit items-center justify-center rounded-xl bg-zinc-900 p-4 shadow-primary-500/30 sm:left-auto sm:top-auto portrait:left-auto portrait:top-auto portrait:items-center">
22
22
  <SpeedSettingsPopup />
23
23
  </Modal>
24
24
  <div id={UI_ITEMS.symbolPayTable}>
@@ -628,10 +628,6 @@ video {
628
628
  bottom: 0.5rem;
629
629
  }
630
630
 
631
- .bottom-5 {
632
- bottom: 1.25rem;
633
- }
634
-
635
631
  .bottom-\[5vh\] {
636
632
  bottom: 5vh;
637
633
  }
@@ -648,10 +644,6 @@ video {
648
644
  left: 1rem;
649
645
  }
650
646
 
651
- .left-5 {
652
- left: 1.25rem;
653
- }
654
-
655
647
  .left-9 {
656
648
  left: 2.25rem;
657
649
  }
@@ -660,10 +652,6 @@ video {
660
652
  left: 1vw;
661
653
  }
662
654
 
663
- .left-\[25wv\] {
664
- left: 25wv;
665
- }
666
-
667
655
  .right-0 {
668
656
  right: 0px;
669
657
  }
@@ -680,23 +668,10 @@ video {
680
668
  top: 0.5rem;
681
669
  }
682
670
 
683
- .top-\[40vh\] {
684
- top: 40vh;
685
- }
686
-
687
671
  .z-10 {
688
672
  z-index: 10;
689
673
  }
690
674
 
691
- .my-7 {
692
- margin-top: 1.75rem;
693
- margin-bottom: 1.75rem;
694
- }
695
-
696
- .mb-5 {
697
- margin-bottom: 1.25rem;
698
- }
699
-
700
675
  .ml-4 {
701
676
  margin-left: 1rem;
702
677
  }
@@ -725,10 +700,6 @@ video {
725
700
  display: table;
726
701
  }
727
702
 
728
- .hidden {
729
- display: none;
730
- }
731
-
732
703
  .h-10 {
733
704
  height: 2.5rem;
734
705
  }
@@ -765,10 +736,6 @@ video {
765
736
  height: 50px;
766
737
  }
767
738
 
768
- .h-\[70\%\] {
769
- height: 70%;
770
- }
771
-
772
739
  .h-\[90\%\] {
773
740
  height: 90%;
774
741
  }
@@ -782,8 +749,8 @@ video {
782
749
  height: 100%;
783
750
  }
784
751
 
785
- .max-h-\[90vh\] {
786
- max-height: 90vh;
752
+ .max-h-\[80vh\] {
753
+ max-height: 80vh;
787
754
  }
788
755
 
789
756
  .min-h-\[60vh\] {
@@ -1141,10 +1108,6 @@ video {
1141
1108
  text-align: center;
1142
1109
  }
1143
1110
 
1144
- .text-justify {
1145
- text-align: justify;
1146
- }
1147
-
1148
1111
  .text-2xl {
1149
1112
  font-size: 1.5rem;
1150
1113
  line-height: 2rem;
@@ -1557,6 +1520,10 @@ html.is-locked .ios-scroller-animation {
1557
1520
  }
1558
1521
 
1559
1522
  @media (min-width: 640px) {
1523
+ .sm\:left-auto {
1524
+ left: auto;
1525
+ }
1526
+
1560
1527
  .sm\:right-8 {
1561
1528
  right: 2rem;
1562
1529
  }
@@ -1565,6 +1532,10 @@ html.is-locked .ios-scroller-animation {
1565
1532
  top: 1rem;
1566
1533
  }
1567
1534
 
1535
+ .sm\:top-auto {
1536
+ top: auto;
1537
+ }
1538
+
1568
1539
  .sm\:ml-5 {
1569
1540
  margin-left: 1.25rem;
1570
1541
  }
@@ -1573,10 +1544,6 @@ html.is-locked .ios-scroller-animation {
1573
1544
  margin-top: 1.25rem;
1574
1545
  }
1575
1546
 
1576
- .sm\:flex {
1577
- display: flex;
1578
- }
1579
-
1580
1547
  .sm\:w-full {
1581
1548
  width: 100%;
1582
1549
  }
@@ -1617,8 +1584,34 @@ html.is-locked .ios-scroller-animation {
1617
1584
  }
1618
1585
  }
1619
1586
 
1587
+ @media (orientation: portrait) {
1588
+ .portrait\:left-auto {
1589
+ left: auto;
1590
+ }
1591
+
1592
+ .portrait\:top-auto {
1593
+ top: auto;
1594
+ }
1595
+
1596
+ .portrait\:max-h-\[60vh\] {
1597
+ max-height: 60vh;
1598
+ }
1599
+
1600
+ .portrait\:max-w-72 {
1601
+ max-width: 18rem;
1602
+ }
1603
+
1604
+ .portrait\:items-center {
1605
+ align-items: center;
1606
+ }
1607
+
1608
+ .portrait\:justify-center {
1609
+ justify-content: center;
1610
+ }
1611
+ }
1612
+
1620
1613
  @media (orientation: landscape) {
1621
- .landscape\:top-\[20vh\] {
1622
- top: 20vh;
1614
+ .landscape\:max-h-\[30vh\] {
1615
+ max-height: 30vh;
1623
1616
  }
1624
1617
  }
@@ -189,7 +189,7 @@ export class AbstractMainContainer extends Container {
189
189
  }
190
190
  createUnderFramePanel() {
191
191
  const underFramePanel = new Graphics();
192
- underFramePanel.beginFill(0x0, 0.5);
192
+ underFramePanel.beginFill(0x0, 0.75);
193
193
  underFramePanel.drawRect(0, 0, 800, 100);
194
194
  return underFramePanel;
195
195
  }
@@ -59,6 +59,7 @@ export declare abstract class AbstractController<T> {
59
59
  private setRefreshButtonBasedOnPhase;
60
60
  private setMessageBoxBasedOnPhase;
61
61
  protected getReelIndexesToShowMysteryFx(spinLogic: SpinLogic): number[];
62
+ protected showSuperBonusWin(removeBonusWin: Promise<void>): void;
62
63
  protected handleSpinLogic(): void;
63
64
  protected throttledSpin(): void;
64
65
  private getBoughtNumberOfFreeSpins;
@@ -46,6 +46,7 @@ export class AbstractController {
46
46
  this.uiController = new UiController(this.config);
47
47
  this.componentRegistry = RainMan.componentRegistry;
48
48
  this.setupSpaceOrEnterListener();
49
+ RainMan.settingsStore.showSuperBonusWin = this.showSuperBonusWin.bind(this);
49
50
  }
50
51
  init() {
51
52
  const initData = this.connection.initData();
@@ -259,6 +260,17 @@ export class AbstractController {
259
260
  }
260
261
  return reelsIndexesWithScatter;
261
262
  }
263
+ showSuperBonusWin(removeBonusWin) {
264
+ this.changeGamePhase(gamePhases.BIG_WIN_INVOKED);
265
+ const winAmount = RainMan.settingsStore.cumulativeWinAmount > 0
266
+ ? RainMan.settingsStore.cumulativeWinAmount
267
+ : this.uiController.recentWin;
268
+ this.countWinBigWin(winAmount).then(async () => {
269
+ await removeBonusWin;
270
+ this.changeGamePhase(gamePhases.IDLE);
271
+ });
272
+ RainMan.settingsStore.resetCumulativeWinAmount();
273
+ }
262
274
  handleSpinLogic() {
263
275
  if (this.mainContainer.freeSpinPlate) {
264
276
  if (this.mainContainer.freeSpinPlate.shownAt === null ||
@@ -28,6 +28,7 @@ export declare class SettingsStore {
28
28
  HiResolutionFlag: boolean;
29
29
  batterySaverFlag: boolean;
30
30
  containersWithSpines: (ResumableContainer | SpineWithResumableContainer | SpriteWithResumableContainer)[];
31
+ cumulativeWinAmount: number;
31
32
  progress: number;
32
33
  singleWinExceeds: number;
33
34
  balancedIncreased: number;
@@ -41,6 +42,7 @@ export declare class SettingsStore {
41
42
  popupPaytableRepositionCallback?: () => void;
42
43
  updateVolumeButtonTexture?: () => void;
43
44
  handleModalInvocation?: (layerId: string) => void;
45
+ showSuperBonusWin?: (callback: Promise<void>) => void;
44
46
  private readonly initialAutoplaySettingsState;
45
47
  private modalsAvailable;
46
48
  private paytableMap;
@@ -48,6 +50,8 @@ export declare class SettingsStore {
48
50
  updateBetText(newText: string): void;
49
51
  get indexOfSpeedLevel(): number;
50
52
  get isFreeSpinsPlayEnabled(): boolean;
53
+ addCumulativeWinAmount(amount: number): void;
54
+ resetCumulativeWinAmount(): void;
51
55
  updateBet(newBet: number): void;
52
56
  setBatteryFlag(flag: boolean): void;
53
57
  refreshBatterySaver(): void;
@@ -65,6 +69,7 @@ export declare class SettingsStore {
65
69
  setBalancedDecreased(newValue: number): void;
66
70
  getMinimumPaytableValue(multipliers: RangeQuantityValue[keyof RangeQuantityValue]): number;
67
71
  getMaximumPaytableValue(multipliers: RangeQuantityValue[keyof RangeQuantityValue]): number;
72
+ forceSuperBigWin(removeBonusWin: Promise<void>): void;
68
73
  setDataForSymbolPaytablePopup(symbolId: SymbolId, repositionCallback: () => void): void;
69
74
  resetDataForSymbolPaytablePopup(): void;
70
75
  setUpdateVolumeButtonTexture(fn: () => void): void;
@@ -34,6 +34,7 @@ export class SettingsStore {
34
34
  HiResolutionFlag = getFromLocalStorage(LOCAL_STORAGE.hiResolution, true);
35
35
  batterySaverFlag = getFromLocalStorage(LOCAL_STORAGE.batterySaver, false);
36
36
  containersWithSpines = [];
37
+ cumulativeWinAmount = 0;
37
38
  progress = 0;
38
39
  singleWinExceeds = 0;
39
40
  balancedIncreased = 0;
@@ -47,6 +48,7 @@ export class SettingsStore {
47
48
  popupPaytableRepositionCallback;
48
49
  updateVolumeButtonTexture;
49
50
  handleModalInvocation;
51
+ showSuperBonusWin;
50
52
  initialAutoplaySettingsState = {
51
53
  infinitySpinsEnabled: false,
52
54
  onAnyWin: false,
@@ -105,6 +107,12 @@ export class SettingsStore {
105
107
  get isFreeSpinsPlayEnabled() {
106
108
  return this.howManyFreeSpinsLeft > 0 || this.isLastFreeSpin;
107
109
  }
110
+ addCumulativeWinAmount(amount) {
111
+ this.cumulativeWinAmount = this.cumulativeWinAmount + amount;
112
+ }
113
+ resetCumulativeWinAmount() {
114
+ this.cumulativeWinAmount = 0;
115
+ }
108
116
  updateBet(newBet) {
109
117
  this.bet = newBet;
110
118
  }
@@ -205,6 +213,9 @@ export class SettingsStore {
205
213
  return last(multipliers) || 0;
206
214
  return 0;
207
215
  }
216
+ forceSuperBigWin(removeBonusWin) {
217
+ this.showSuperBonusWin?.(removeBonusWin);
218
+ }
208
219
  setDataForSymbolPaytablePopup(symbolId, repositionCallback) {
209
220
  this.popupPaytableRepositionCallback = repositionCallback;
210
221
  this.popupPaytableRepositionCallback();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
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",