pixi-rainman-game-engine 0.3.17 → 0.3.18

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.
@@ -28,8 +28,12 @@
28
28
  .autoplay-settings__title h2 {
29
29
  color: #ec5e27;
30
30
  margin: 0px;
31
- text-decoration: underline;
32
31
  text-transform: uppercase;
32
+ font-weight: bold;
33
+ font-size: 32px;
34
+ @media only screen and (max-width: 600px) {
35
+ font-size: 24px;
36
+ }
33
37
  }
34
38
 
35
39
  .autoplay-settings__sliders {
@@ -71,7 +75,7 @@
71
75
  justify-content: center;
72
76
  width: 40px;
73
77
  border: solid 2px white;
74
- font-size: 20px;
78
+ font-size: 24px;
75
79
  font-weight: bolder;
76
80
  margin: 0px 5px;
77
81
  color: white;
@@ -125,12 +129,16 @@
125
129
 
126
130
  .autoplay-settings__limit.left p {
127
131
  position: relative;
128
- top: -2px;
132
+ font-size: 24px;
133
+ top: -3px;
134
+ right: -1px;
129
135
  }
130
136
 
131
137
  .autoplay-settings__limit.right p {
132
138
  position: relative;
133
- top: -2px;
139
+ font-size: 24px;
140
+ top: -3px;
141
+ left: -1px;
134
142
  }
135
143
 
136
144
  .autoplay-settings__confirmation {
@@ -256,3 +264,9 @@
256
264
  top: 10px;
257
265
  }
258
266
  }
267
+
268
+ .separator {
269
+ width: 100%;
270
+ height: 1px;
271
+ background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.7), transparent);
272
+ }
@@ -84,6 +84,7 @@ export const AutoplaySettings = observer(() => {
84
84
  <p>∞</p>
85
85
  </button>
86
86
  </div>
87
+ <div className="separator"/>
87
88
  <div className="autoplay-settings__title">
88
89
  <h2>{i18next.t("stopAutoPlay")}</h2>
89
90
  </div>
@@ -92,7 +93,7 @@ export const AutoplaySettings = observer(() => {
92
93
  <RichLimitingSlider value={balancedIncreased} setValue={setBalancedIncreased} maxValue={Number(i18next.t("ifBalanceIncreasesBy"))} description={i18next.t("ifBalanceIncreasesByDescription")}/>
93
94
  <RichLimitingSlider value={balancedDecreased} setValue={setBalancedDecreased} maxValue={Number(i18next.t("ifSingleWinExceedsMax"))} description={i18next.t("ifBalanceDecreaseByDescription")}/>
94
95
  </div>
95
-
96
+ <div className="separator"/>
96
97
  <div className="autoplay-settings__switches">
97
98
  <div className="autoplay-settings__switch">
98
99
  <SwitchWithHeader header={i18next.t("onAnyWin")} flag={settingStore.onAnyWin} setFlag={settingStore.setOnAnyWin}/>
@@ -1,26 +1,88 @@
1
1
  import "rc-slider/assets/index.css";
2
2
  import "./richLimitingSlider.css";
3
3
  import { observer } from "mobx-react-lite";
4
- import Slider from "rc-slider";
5
- import React from "react";
4
+ import React, { useEffect, useRef, useState } from "react";
5
+ const clamp = (v, maxValue) => {
6
+ const clamped = Math.min(Math.max(v, 0), maxValue);
7
+ const rounded = Math.round(clamped * 10) / 10;
8
+ return Math.min(rounded, maxValue);
9
+ };
6
10
  export const RichLimitingSlider = observer(({ value, setValue, maxValue, description }) => {
11
+ const valueRef = useRef(value);
12
+ const [rawValue, setRawValue] = useState(String(value));
13
+ useEffect(() => {
14
+ valueRef.current = value;
15
+ setRawValue(String(value));
16
+ console.log("🚀 $$ ~ value:", value);
17
+ }, [value]);
18
+ const holdInterval = useRef(null);
19
+ const isHeldRef = useRef(false);
20
+ const increment = () => {
21
+ setValue(clamp(valueRef.current + 0.2, maxValue));
22
+ };
23
+ const decrement = () => {
24
+ setValue(clamp(valueRef.current - 0.2, maxValue));
25
+ };
26
+ const stopHold = () => {
27
+ isHeldRef.current = false;
28
+ if (holdInterval.current) {
29
+ clearInterval(holdInterval.current);
30
+ holdInterval.current = null;
31
+ }
32
+ window.removeEventListener("mouseup", stopHold);
33
+ window.removeEventListener("touchend", stopHold);
34
+ window.removeEventListener("pointerup", stopHold);
35
+ window.removeEventListener("touchcancel", stopHold);
36
+ };
37
+ const startHold = (action) => {
38
+ isHeldRef.current = true;
39
+ if (holdInterval.current) {
40
+ clearInterval(holdInterval.current);
41
+ holdInterval.current = null;
42
+ }
43
+ holdInterval.current = setTimeout(() => {
44
+ if (isHeldRef.current) {
45
+ holdInterval.current = setInterval(action, 100);
46
+ }
47
+ }, 500);
48
+ window.addEventListener("mouseup", stopHold);
49
+ window.addEventListener("touchend", stopHold, { passive: true });
50
+ window.addEventListener("pointerup", stopHold);
51
+ window.addEventListener("touchcancel", stopHold);
52
+ };
53
+ const onChange = (e) => {
54
+ const v = e.target.value;
55
+ const parsed = Number(v);
56
+ setRawValue(String(clamp(parsed, maxValue)));
57
+ if (v === "")
58
+ return;
59
+ if (!isNaN(parsed)) {
60
+ setValue(clamp(parsed, maxValue));
61
+ }
62
+ };
63
+ useEffect(() => {
64
+ return () => {
65
+ stopHold();
66
+ };
67
+ }, []);
7
68
  return (<div className="rich-slider">
8
- {/* @ts-expect-error type error in library */}
9
- <Slider className="rich-slider__slider" step={1} min={0} max={maxValue} defaultValue={value} value={value} handleStyle={{
10
- backgroundColor: "#fdf425",
11
- borderColor: "#fdf425",
12
- width: "20px",
13
- height: "20px",
14
- bottom: "-4px",
15
- }} railStyle={{
16
- backgroundColor: "#fff",
17
- }} trackStyle={{
18
- backgroundColor: "#fdf425",
19
- }} dotStyle={{
20
- borderColor: "#fdf425",
21
- }} onChange={(value) => setValue(value)}>
22
- <p className="rich-slider__description">{description}</p>
23
- </Slider>
24
- <div className="rich-slider__number">{value}</div>
69
+ <p className="rich-slider__description">{description}</p>
70
+ <div className="rich-slider_button">
71
+ <button onClick={decrement} className="rich-slider_button-left" onMouseDown={() => startHold(decrement)} onMouseUp={stopHold} onMouseLeave={stopHold} onTouchStart={(e) => {
72
+ e.preventDefault();
73
+ startHold(decrement);
74
+ }} onTouchEnd={stopHold} onPointerDown={() => startHold(decrement)} onPointerUp={stopHold}>
75
+ -
76
+ </button>
77
+
78
+ <input className="rich-slider_input" type="number" style={{}} value={rawValue} onClick={() => setRawValue("0")} onChange={onChange}/>
79
+
80
+ <button onClick={increment} className="rich-slider_button-right" onMouseDown={() => startHold(increment)} onMouseUp={stopHold} onMouseLeave={stopHold} onTouchStart={(e) => {
81
+ e.preventDefault();
82
+ startHold(increment);
83
+ }} onTouchEnd={stopHold} onPointerDown={() => startHold(increment)} onPointerUp={stopHold}>
84
+ +
85
+ </button>
86
+ </div>
25
87
  </div>);
26
88
  });
@@ -3,6 +3,7 @@
3
3
  flex-direction: row;
4
4
  align-items: center;
5
5
  padding-inline: 16px;
6
+ justify-content: space-between;
6
7
  }
7
8
 
8
9
  .rich-slider__slider {
@@ -12,9 +13,23 @@
12
13
  align-items: center;
13
14
  }
14
15
 
15
- .rich-slider__number {
16
+ .rich-slider__description {
17
+ text-transform: uppercase;
18
+ @media only screen and (max-width: 650px) {
19
+ width: 50%;
20
+ }
21
+ }
22
+
23
+ @media only screen and (max-width: 650px) {
24
+ .rich-slider__description {
25
+ padding-top: 4px;
26
+ font-size: 9px;
27
+ }
28
+ }
29
+
30
+ .rich-slider_button {
16
31
  margin: 10px 0px 10px 10px;
17
- width: 100px;
32
+ width: 250px;
18
33
  height: 40px;
19
34
  border: solid white 2px;
20
35
  background-color: black;
@@ -25,15 +40,67 @@
25
40
  display: flex;
26
41
  justify-content: center;
27
42
  align-items: center;
43
+ position: relative;
44
+ overflow: hidden;
45
+ @media only screen and (max-width: 650px) {
46
+ width: 50%;
47
+ height: 30px;
48
+ }
28
49
  }
29
50
 
30
- .rich-slider__description {
31
- text-transform: uppercase;
51
+ .rich-slider_button-left,
52
+ .rich-slider_button-right {
53
+ width: 40px;
54
+ border: none;
55
+ color: white;
56
+ display: flex;
57
+ transition: all 0.3s ease;
58
+ justify-content: center;
59
+ padding-bottom: 6px;
60
+ background-color: transparent;
61
+ height: 100%;
62
+ display: flex;
63
+ align-items: center;
64
+ cursor: pointer;
65
+ font-size: 24px;
66
+ }
67
+ .rich-slider_button-left {
68
+ border-right: solid white 2px;
69
+ }
70
+ .rich-slider_button-right {
71
+ border-left: solid white 2px;
32
72
  }
33
73
 
34
- @media only screen and (max-width: 650px) {
35
- .rich-slider__description {
36
- padding-top: 4px;
37
- font-size: 9px;
74
+ .rich-slider_button-left:hover,
75
+ .rich-slider_button-right:hover {
76
+ background-color: #fdf42525;
77
+ color: #fdf425;
78
+ }
79
+
80
+ .rich-slider_input {
81
+ background-color: transparent;
82
+ border: none;
83
+ color: white;
84
+ width: 100%;
85
+ height: 100%;
86
+ text-align: center;
87
+ font-size: 20px;
88
+ @media only screen and (max-width: 650px) {
89
+ font-size: 14px;
38
90
  }
39
91
  }
92
+
93
+ .rich-slider_input:focus-visible {
94
+ outline: none;
95
+ }
96
+
97
+ input[type="number"]::-webkit-inner-spin-button,
98
+ input[type="number"]::-webkit-outer-spin-button {
99
+ -webkit-appearance: none;
100
+ margin: 0;
101
+ }
102
+
103
+ input[type="number"] {
104
+ -moz-appearance: textfield;
105
+ appearance: textfield;
106
+ }
@@ -55,7 +55,7 @@
55
55
  flex-direction: row;
56
56
  width: 36px;
57
57
  justify-content: space-between;
58
- bottom: 10px;
58
+ bottom: 12px;
59
59
  left: 36px;
60
60
  }
61
61
 
@@ -89,7 +89,7 @@
89
89
  .switch__text {
90
90
  margin: 0;
91
91
  position: absolute;
92
- top: 7px;
92
+ top: 5px;
93
93
  right: 9px;
94
94
  }
95
95
 
@@ -22,6 +22,7 @@
22
22
  .speed-settings-popup {
23
23
  display: flex;
24
24
  flex-direction: column;
25
+ gap: 20px;
25
26
  align-items: center;
26
27
  justify-content: space-between;
27
28
  }
@@ -37,6 +38,7 @@
37
38
  display: flex;
38
39
  flex-direction: row;
39
40
  justify-content: space-between;
41
+ gap: 25px;
40
42
  width: 100%;
41
43
  height: 120px;
42
44
  }
@@ -8,6 +8,12 @@
8
8
  text-transform: uppercase;
9
9
  }
10
10
 
11
+ @media only screen and (max-width: 650px) {
12
+ .header-description__title {
13
+ font-size: 14px !important;
14
+ }
15
+ }
16
+
11
17
  .header-description__text {
12
18
  max-width: 170px;
13
19
  margin: 0px;
@@ -18,10 +24,6 @@
18
24
  max-width: 150px;
19
25
  }
20
26
 
21
- .header-description h2 {
22
- font-size: 20px;
23
- }
24
-
25
27
  .header-description h6 {
26
28
  font-size: 10px;
27
29
  }
@@ -1,7 +1,7 @@
1
1
  import i18n from "i18next";
2
2
  import { sample } from "lodash";
3
3
  import { SoundManager, SoundTracks } from "../../application";
4
- import { AutoplayButton, Background, BUTTONS, COMPONENTS, FreeSpinButton, MessageBox, SpeedControlButton, VolumeButton } from "../../components";
4
+ import { AutoplayButton, Background, BUTTONS, COMPONENTS, FreeSpinButton, MessageBox, VolumeButton } from "../../components";
5
5
  import { RainMan } from "../../Rainman";
6
6
  import { allUiItems, hideLayerIfPresent, UI_ITEMS, wait } from "../../utils";
7
7
  import { SPEED_LEVELS } from "../SpeedState";
@@ -47,12 +47,7 @@ export class ButtonsEventManager {
47
47
  * @returns {() => void} function for enabling/disabling buttons
48
48
  */
49
49
  setButtonAvailability = (makeDisabled) => () => {
50
- const isDisabled = RainMan.settingsStore.isFreeSpinsPlayEnabled ||
51
- RainMan.settingsStore.isFreeSpinsBought ||
52
- RainMan.settingsStore.betChangeDisabled;
53
- const buttonsToDisable = isDisabled
54
- ? [SpeedControlButton.registryName]
55
- : [SpeedControlButton.registryName, BUTTONS.neg, BUTTONS.plus];
50
+ const buttonsToDisable = [BUTTONS.neg, BUTTONS.plus];
56
51
  buttonsToDisable.forEach((buttonRegistryName) => RainMan.componentRegistry.get(buttonRegistryName).flipDisabledFlag(makeDisabled));
57
52
  RainMan.componentRegistry.get(VolumeButton.registryName).changeTextureDependOnVolume();
58
53
  };
@@ -276,6 +271,7 @@ export class ButtonsEventManager {
276
271
  RainMan.settingsStore.resetAutoplaySettings();
277
272
  RainMan.componentRegistry.get(MessageBox.registryName).hideAutoSpinText();
278
273
  RainMan.componentRegistry.get(AutoplayButton.registryName).activate(false);
274
+ RainMan.settingsStore.changeBetChangeDisabled(false);
279
275
  if (!RainMan.settingsStore.isPlayingAnyAction) {
280
276
  RainMan.componentRegistry.get(BUTTONS.neg).flipDisabledFlag(false);
281
277
  RainMan.componentRegistry.get(BUTTONS.plus).flipDisabledFlag(false);
@@ -478,6 +478,7 @@ export class AbstractMainContainer extends Container {
478
478
  if (this.bonusWinContainer === null) {
479
479
  return;
480
480
  }
481
+ RainMan.settingsStore.disableKeyboardShortcuts = false;
481
482
  this.removeChild(this.bonusWinContainer);
482
483
  this.bonusWinContainer.destroyAnimations();
483
484
  this.bonusWinContainer.destroy({ children: true });
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "credit": "CREDIT: ",
38
38
  "bet": "BET: ",
39
- "ifBalanceIncreasesBy": "1000",
39
+ "ifBalanceIncreasesBy": "50000",
40
40
  "ifBalanceIncreasesByDescription": "If balance increases by",
41
- "ifSingleWinExceedsMax": "10000",
42
- "ifSingleWinExceedsMaxDescription": "If balance increases by",
43
- "ifBalanceDecreasedBy": "1000",
41
+ "ifSingleWinExceedsMax": "50000",
42
+ "ifSingleWinExceedsMaxDescription": "If single win exceeds",
43
+ "ifBalanceDecreasedBy": "50000",
44
44
  "ifBalanceDecreaseByDescription": "If balance decreases by",
45
45
  "speedButtonHeader": "Quick spin",
46
46
  "speedButtonDescription": "Play faster by reducing total spin time",
@@ -22,7 +22,7 @@ export declare abstract class AbstractSymbolsColumn extends Container implements
22
22
  private velocity;
23
23
  protected velocityMultiplier: number;
24
24
  private previousVelocityMultiplier;
25
- private spritesCount;
25
+ protected spritesCount: number;
26
26
  protected phase: Phase;
27
27
  private ending;
28
28
  private lastEnding;
@@ -258,7 +258,7 @@ export declare abstract class AbstractSymbolsColumn extends Container implements
258
258
  * @private
259
259
  * @returns {void}
260
260
  */
261
- private initSymbolSprites;
261
+ protected initSymbolSprites(): void;
262
262
  /**
263
263
  * This method ensures that top tile is in right place (it might not be due to some FPS issue)
264
264
  * @private
@@ -12,7 +12,7 @@ export class SpinData {
12
12
  this.config = config;
13
13
  this.balance = data.balance;
14
14
  this.balanceAfterSpin = data.future_balance_prediction;
15
- if (data.action !== "spin" && data.action !== "buy") {
15
+ if (data.action !== "spin" && data.action !== "buy" && data.action !== "mini-game") {
16
16
  throw new Error(`Invalid type "${data.action}" provided, "spin" or "buy" expected`);
17
17
  }
18
18
  }
@@ -118,6 +118,7 @@ export class AbstractController {
118
118
  RainMan.componentRegistry.get(AutoplayButton.registryName).activate(true);
119
119
  RainMan.componentRegistry.get(BUTTONS.plus).flipDisabledFlag(true);
120
120
  RainMan.componentRegistry.get(BUTTONS.neg).flipDisabledFlag(true);
121
+ RainMan.settingsStore.changeBetChangeDisabled(true);
121
122
  this.throttledSpin();
122
123
  });
123
124
  SoundManager.setPlayStatus(SoundTracks.music, RainMan.settingsStore.shouldPlayAmbientMusic);
@@ -257,7 +258,9 @@ export class AbstractController {
257
258
  */
258
259
  handleDisablingButtons(disabled) {
259
260
  this.disableBetButtons(disabled ?? this.shouldBetButtonsBeDisabled);
260
- if (RainMan.settingsStore.isFreeSpinsPlayEnabled || RainMan.globals.isSuperBonusGameEnabled) {
261
+ if (RainMan.settingsStore.isFreeSpinsPlayEnabled ||
262
+ RainMan.globals.isSuperBonusGameEnabled ||
263
+ RainMan.settingsStore.isAutoplayEnabled) {
261
264
  this.disableSpeedButton(false);
262
265
  }
263
266
  else {
@@ -835,8 +838,10 @@ export class AbstractController {
835
838
  * @returns {void}
836
839
  */
837
840
  disableAutoplay() {
841
+ this.autoSpinBalance = 0;
838
842
  RainMan.componentRegistry.get(MessageBox.registryName).hideAutoSpinText();
839
843
  RainMan.componentRegistry.get(AutoplayButton.registryName).activate(false);
844
+ RainMan.settingsStore.changeBetChangeDisabled(false);
840
845
  RainMan.componentRegistry.get(BUTTONS.plus).flipDisabledFlag(false);
841
846
  RainMan.componentRegistry.get(BUTTONS.neg).flipDisabledFlag(false);
842
847
  RainMan.settingsStore.resetAutoplaySettings();
@@ -1206,26 +1211,29 @@ export class AbstractController {
1206
1211
  */
1207
1212
  handleAutoplayLogic() {
1208
1213
  RainMan.globals.shouldShowModals = false;
1209
- this.autoSpinBalance += this.uiController.recentWin;
1214
+ RainMan.settingsStore.changeBetChangeDisabled(true);
1215
+ if (this.uiController.recentWin === 0) {
1216
+ this.autoSpinBalance -= RainMan.settingsStore.bet;
1217
+ }
1218
+ else {
1219
+ this.autoSpinBalance += this.uiController.recentWin;
1220
+ }
1210
1221
  const { balancedIncreased, balancedDecreased, singleWinExceeds } = RainMan.settingsStore;
1211
1222
  if (balancedIncreased > 0) {
1212
1223
  if (this.autoSpinBalance >= balancedIncreased) {
1213
1224
  this.disableAutoplay();
1214
- this.autoSpinBalance = 0;
1215
1225
  return;
1216
1226
  }
1217
1227
  }
1218
1228
  if (balancedDecreased > 0) {
1219
1229
  if (this.autoSpinBalance <= -balancedDecreased) {
1220
1230
  this.disableAutoplay();
1221
- this.autoSpinBalance = 0;
1222
1231
  return;
1223
1232
  }
1224
1233
  }
1225
1234
  if (singleWinExceeds > 0) {
1226
1235
  if (this.uiController.recentWin >= singleWinExceeds) {
1227
1236
  this.disableAutoplay();
1228
- this.autoSpinBalance = 0;
1229
1237
  return;
1230
1238
  }
1231
1239
  }
@@ -44,7 +44,7 @@ export class QuickStopController {
44
44
  * @returns {void}
45
45
  */
46
46
  handleSpeedPopupInvocation() {
47
- if (this.shouldInvokeSpeedPopup && !this.speedPopupDisabled) {
47
+ if (this.shouldInvokeSpeedPopup && !this.speedPopupDisabled && !RainMan.settingsStore.isFreeSpinsPlayEnabled) {
48
48
  this.buttonsEventManager?.setSpeedPopupVisibility("flex");
49
49
  RainMan.settingsStore.isSpeedModalShown = true;
50
50
  this.buttonsEventManager.disableButtons();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-rainman-game-engine",
3
- "version": "0.3.17",
3
+ "version": "0.3.18",
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",