pixi-rainman-game-engine 0.1.47 → 0.1.48
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.
- package/dist/ComponentRegistry/ComponentRegistry.js +1 -4
- package/dist/SettingsUI/components/AutoplaySettings/index.jsx +3 -3
- package/dist/application/ButtonsEventManager/ButtonsEventManager.d.ts +2 -0
- package/dist/application/ButtonsEventManager/ButtonsEventManager.js +10 -0
- package/dist/application/SoundManager/SoundManager.d.ts +12 -0
- package/dist/application/SoundManager/SoundManager.js +16 -0
- package/dist/application/SpeedState/SpeedLevelHandler.d.ts +0 -1
- package/dist/application/SpeedState/SpeedLevelHandler.js +0 -1
- package/dist/components/frame/AbstractColumnsContainer.d.ts +3 -2
- package/dist/components/frame/AbstractColumnsContainer.js +6 -3
- package/dist/components/frame/AbstractFrame.d.ts +3 -0
- package/dist/components/frame/AbstractFrame.js +15 -4
- package/dist/components/frame/types.d.ts +4 -0
- package/dist/components/frame/types.js +1 -0
- package/dist/components/symbols/AbstractSymbolBase.d.ts +6 -0
- package/dist/components/symbols/AbstractSymbolBase.js +36 -0
- package/dist/components/symbols/AbstractSymbolsColumn.d.ts +1 -0
- package/dist/components/symbols/AbstractSymbolsColumn.js +5 -3
- package/dist/constants/gamePhase.d.ts +2 -0
- package/dist/constants/gamePhase.js +3 -1
- package/dist/controllers/AbstractController.d.ts +1 -0
- package/dist/controllers/AbstractController.js +14 -3
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isIncentiveComponentInterface, isSpeedAdapterInterface,
|
|
1
|
+
import { isIncentiveComponentInterface, isSpeedAdapterInterface, SpeedLevelHandler, TimedIncentiveController, } from "../application";
|
|
2
2
|
import { SpeedControlButton } from "../components";
|
|
3
3
|
import { RainMan } from "../Rainman";
|
|
4
4
|
import { openFullscreen } from "../utils";
|
|
@@ -58,9 +58,6 @@ export class ComponentRegistry {
|
|
|
58
58
|
*/
|
|
59
59
|
nextSpeedLevel() {
|
|
60
60
|
this.speedLevelHandler.nextSpeed();
|
|
61
|
-
if (this.speedLevelHandler.currentSpeed !== SPEED_LEVELS.slow) {
|
|
62
|
-
RainMan.globals.disableSpeedPopup?.(false);
|
|
63
|
-
}
|
|
64
61
|
RainMan.settingsStore.setSpeedLevel(this.speedLevelHandler.currentSpeed);
|
|
65
62
|
this.updateAllSpeedAdaptable(RainMan.settingsStore.currentSpeed);
|
|
66
63
|
this.get(SpeedControlButton.registryName).forceTextureUpdate();
|
|
@@ -10,7 +10,7 @@ import { CloseModalButton } from "../CloseModalButton";
|
|
|
10
10
|
import { RichLimitingSlider } from "../RichLimitingSlider";
|
|
11
11
|
import { SpeedButtonWithHeader, SwitchWithHeader } from "../SwitchWithHeader";
|
|
12
12
|
export const AutoplaySettings = observer(() => {
|
|
13
|
-
const [
|
|
13
|
+
const [limitNumbers, setLimitNumbers] = useState([0]);
|
|
14
14
|
const initialAutoSpinCount = 50;
|
|
15
15
|
const availableAutoSpinLimits = [10, 20, 50, 100, 150, 200, 250, 300, 350, 400, 500, 600, 700, 800, 900, 1000];
|
|
16
16
|
const { settingStore } = useStores();
|
|
@@ -66,7 +66,7 @@ export const AutoplaySettings = observer(() => {
|
|
|
66
66
|
}}>
|
|
67
67
|
<p>-</p>
|
|
68
68
|
</button>
|
|
69
|
-
{
|
|
69
|
+
{limitNumbers.map((limiter, index) => (<button key={`${limiter}${index}`} value={limiter} className={`autoplay-settings__limit ${limiter === howManyAutoSpinsLeft ? "autoplay-settings__limit--active" : ""} middle ${infinitySpinsEnabled ? "autoplay-settings__limit--infinity" : ""}`} disabled={settingStore.infinitySpinsEnabled} onClick={(event) => updateLimitsBounds(Number(event.currentTarget.value))}>
|
|
70
70
|
<p>{limiter}</p>
|
|
71
71
|
</button>))}
|
|
72
72
|
<button className={`autoplay-settings__limit right ${infinitySpinsEnabled ? "autoplay-settings__limit--infinity" : ""}`} onClick={() => {
|
|
@@ -110,7 +110,7 @@ export const AutoplaySettings = observer(() => {
|
|
|
110
110
|
}}>
|
|
111
111
|
<p>{i18next.t("cancel")}</p>
|
|
112
112
|
</button>
|
|
113
|
-
<button id={COMPONENTS.autoSpinConfirm} className="autoplay-settings__confirmation-button">
|
|
113
|
+
<button id={COMPONENTS.autoSpinConfirm} onClick={() => settingStore.decreaseAutoSpinsCount()} className="autoplay-settings__confirmation-button">
|
|
114
114
|
<p>{i18next.t("confirm")}</p>
|
|
115
115
|
</button>
|
|
116
116
|
</div>
|
|
@@ -82,6 +82,8 @@ export declare class ButtonsEventManager {
|
|
|
82
82
|
initFreeSpinModal(): void;
|
|
83
83
|
/**
|
|
84
84
|
* Method for initializing volume button
|
|
85
|
+
* This method changes texture of Volume button based on volume level
|
|
86
|
+
* If music was muted, it will be resumed
|
|
85
87
|
*
|
|
86
88
|
* @public
|
|
87
89
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import i18n from "i18next";
|
|
2
2
|
import { sample } from "lodash";
|
|
3
|
+
import { SoundManager, SoundTracks } from "../../application";
|
|
3
4
|
import { AutoplayButton, Background, BUTTONS, COMPONENTS, FreeSpinButton, MessageBox, SpeedControlButton, VolumeButton, } from "../../components";
|
|
4
5
|
import { RainMan } from "../../Rainman";
|
|
5
6
|
import { allUiItems, hideLayerIfPresent, UI_ITEMS } from "../../utils";
|
|
@@ -74,6 +75,10 @@ export class ButtonsEventManager {
|
|
|
74
75
|
if (this.settingsSpeedButton) {
|
|
75
76
|
this.settingsSpeedButton.addEventListener("click", () => {
|
|
76
77
|
RainMan.componentRegistry.nextSpeedLevel();
|
|
78
|
+
if (RainMan.settingsStore.currentSpeed === SPEED_LEVELS.fast ||
|
|
79
|
+
RainMan.settingsStore.currentSpeed === SPEED_LEVELS.normal) {
|
|
80
|
+
RainMan.globals.disableSpeedPopup?.(true);
|
|
81
|
+
}
|
|
77
82
|
messageBox.updateIncentiveText(sample(i18n.t("idleMessages", { returnObjects: true })[RainMan.componentRegistry.getSpeedLevel()]));
|
|
78
83
|
});
|
|
79
84
|
}
|
|
@@ -179,6 +184,8 @@ export class ButtonsEventManager {
|
|
|
179
184
|
}
|
|
180
185
|
/**
|
|
181
186
|
* Method for initializing volume button
|
|
187
|
+
* This method changes texture of Volume button based on volume level
|
|
188
|
+
* If music was muted, it will be resumed
|
|
182
189
|
*
|
|
183
190
|
* @public
|
|
184
191
|
*/
|
|
@@ -186,6 +193,9 @@ export class ButtonsEventManager {
|
|
|
186
193
|
RainMan.settingsStore.setUpdateVolumeButtonTexture(() => RainMan.componentRegistry.get(VolumeButton.registryName).changeTextureDependOnVolume());
|
|
187
194
|
RainMan.componentRegistry.get(VolumeButton.registryName).setOnClick(() => {
|
|
188
195
|
RainMan.settingsStore.flipSoundsEnabled();
|
|
196
|
+
if (RainMan.settingsStore.ambientMusicFlag && RainMan.settingsStore.isSoundEnabled()) {
|
|
197
|
+
SoundManager.resume(SoundTracks.music);
|
|
198
|
+
}
|
|
189
199
|
RainMan.componentRegistry.get(VolumeButton.registryName).changeTextureDependOnVolume();
|
|
190
200
|
this.handleModalInvocation(UI_ITEMS.volume);
|
|
191
201
|
});
|
|
@@ -61,11 +61,23 @@ export declare class SoundManagerInstance implements SpeedAdapterInterface<Sound
|
|
|
61
61
|
* @param {SoundTrack} soundName
|
|
62
62
|
*/
|
|
63
63
|
pause(soundName: SoundTrack): void;
|
|
64
|
+
/**
|
|
65
|
+
* Function for resuming sound with given name
|
|
66
|
+
*
|
|
67
|
+
* @param {SoundTrack} soundName
|
|
68
|
+
*/
|
|
69
|
+
resume(soundName: SoundTrack): void;
|
|
64
70
|
/**
|
|
65
71
|
* Function for adapting sound into the speed of animations
|
|
66
72
|
*
|
|
67
73
|
* @param {SpeedLevel} speedLevel
|
|
68
74
|
*/
|
|
69
75
|
adaptToSpeed(speedLevel: SpeedLevel): void;
|
|
76
|
+
/**
|
|
77
|
+
* Function for stopping sound with given name
|
|
78
|
+
*
|
|
79
|
+
* @param {SoundTrack} soundName - name of the sound
|
|
80
|
+
*/
|
|
81
|
+
stop(soundName: SoundTrack): void;
|
|
70
82
|
}
|
|
71
83
|
export declare const SoundManager: SoundManagerInstance;
|
|
@@ -123,6 +123,14 @@ export class SoundManagerInstance {
|
|
|
123
123
|
pause(soundName) {
|
|
124
124
|
this.musicCatalogue.get(soundName)?.pause();
|
|
125
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Function for resuming sound with given name
|
|
128
|
+
*
|
|
129
|
+
* @param {SoundTrack} soundName
|
|
130
|
+
*/
|
|
131
|
+
resume(soundName) {
|
|
132
|
+
this.musicCatalogue.get(soundName)?.resume();
|
|
133
|
+
}
|
|
126
134
|
/**
|
|
127
135
|
* Function for adapting sound into the speed of animations
|
|
128
136
|
*
|
|
@@ -131,5 +139,13 @@ export class SoundManagerInstance {
|
|
|
131
139
|
adaptToSpeed(speedLevel) {
|
|
132
140
|
this.overrides = this.speedLevelMapper[speedLevel];
|
|
133
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Function for stopping sound with given name
|
|
144
|
+
*
|
|
145
|
+
* @param {SoundTrack} soundName - name of the sound
|
|
146
|
+
*/
|
|
147
|
+
stop(soundName) {
|
|
148
|
+
this.musicCatalogue.get(soundName)?.stop();
|
|
149
|
+
}
|
|
134
150
|
}
|
|
135
151
|
export const SoundManager = SoundManagerInstance.getInstance();
|
|
@@ -48,9 +48,9 @@ export declare abstract class AbstractColumnsContainer extends Container impleme
|
|
|
48
48
|
* @returns {Promise<void>}
|
|
49
49
|
*/
|
|
50
50
|
configBlindSpin(finalSymbolReels: SymbolReels, afterSpinResolver: (value: void | PromiseLike<void>) => void, indexesOfReelsToExtendSpinningTime: number[]): Promise<void>;
|
|
51
|
-
playAllStreaks(streaks: StreakReelsIndexes[], amount: number): Promise<void>;
|
|
51
|
+
playAllStreaks(streaks: StreakReelsIndexes[], amount: number, allSymbols?: SymbolId[]): Promise<void>;
|
|
52
52
|
resetPlayedSounds(): void;
|
|
53
|
-
protected playSoundDependingOnAmount(amount: number): void;
|
|
53
|
+
protected playSoundDependingOnAmount(amount: number, _allSymbols?: SymbolId[]): void;
|
|
54
54
|
protected playStreakSound(symbols: SymbolId[]): void;
|
|
55
55
|
/**
|
|
56
56
|
* Function for playing animation of streak
|
|
@@ -68,6 +68,7 @@ export declare abstract class AbstractColumnsContainer extends Container impleme
|
|
|
68
68
|
animate(delta: number): void;
|
|
69
69
|
abstract getColumnAtPosition(column: number): AbstractSymbolsColumn;
|
|
70
70
|
stopPlayingSymbolsInColumns(): void;
|
|
71
|
+
stopPlayingSymbolsTransformationInColumns(): void;
|
|
71
72
|
setInteractivityForSymbols(flag: boolean): void;
|
|
72
73
|
handleDestroyTransformations(transformations: DropTransformationDetails[], skipAnimations?: boolean, isStandalone?: boolean, allowSoundInSymbolsColumn?: boolean): Promise<void>;
|
|
73
74
|
protected createMask(): Graphics;
|
|
@@ -105,7 +105,7 @@ export class AbstractColumnsContainer extends Container {
|
|
|
105
105
|
resolve();
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
|
-
async playAllStreaks(streaks, amount) {
|
|
108
|
+
async playAllStreaks(streaks, amount, allSymbols = []) {
|
|
109
109
|
const columnsToPlay = [];
|
|
110
110
|
streaks.forEach((streak) => {
|
|
111
111
|
streak.forEach((symbolIndex, index) => {
|
|
@@ -121,13 +121,13 @@ export class AbstractColumnsContainer extends Container {
|
|
|
121
121
|
columnsToPlay.forEach((column, index) => {
|
|
122
122
|
column.forEach((symbolIndex) => promises.push(this.getColumnAtPosition(index).playSymbolAtPosition(symbolIndex, true)));
|
|
123
123
|
});
|
|
124
|
-
this.playSoundDependingOnAmount(amount);
|
|
124
|
+
this.playSoundDependingOnAmount(amount, allSymbols);
|
|
125
125
|
await Promise.allSettled(promises);
|
|
126
126
|
}
|
|
127
127
|
resetPlayedSounds() {
|
|
128
128
|
this.playedSounds = [];
|
|
129
129
|
}
|
|
130
|
-
playSoundDependingOnAmount(amount) {
|
|
130
|
+
playSoundDependingOnAmount(amount, _allSymbols = []) {
|
|
131
131
|
const bet = RainMan.settingsStore.bet;
|
|
132
132
|
if (amount < WIN_MULTIPLIER_VALUES.LOW_WIN * bet) {
|
|
133
133
|
SoundManager.play(SoundTracks.lowWin);
|
|
@@ -202,6 +202,9 @@ export class AbstractColumnsContainer extends Container {
|
|
|
202
202
|
stopPlayingSymbolsInColumns() {
|
|
203
203
|
this.allColumns.forEach((column) => column.stopAllPlayingSymbols());
|
|
204
204
|
}
|
|
205
|
+
stopPlayingSymbolsTransformationInColumns() {
|
|
206
|
+
this.allColumns.forEach((column) => column.stopTransformationPlayingSymbols());
|
|
207
|
+
}
|
|
205
208
|
setInteractivityForSymbols(flag) {
|
|
206
209
|
this.allColumns.forEach((column) => column.setAllSymbolsInteractiveFlag(flag));
|
|
207
210
|
}
|
|
@@ -4,6 +4,7 @@ import { Nullable } from "../../utils";
|
|
|
4
4
|
import { ResumableContainer } from "../common";
|
|
5
5
|
import { AbstractColumnsContainer } from "./AbstractColumnsContainer";
|
|
6
6
|
import { AbstractInnerFrame } from "./AbstractInnerFrame";
|
|
7
|
+
import { MysteryFxCoordinates } from "./types";
|
|
7
8
|
import { WinLineAnimation } from "./WinLineAnimation";
|
|
8
9
|
/**
|
|
9
10
|
* This class is representing all of elements in center frame like Columns Container, frame animation
|
|
@@ -30,12 +31,14 @@ export declare abstract class AbstractFrame extends ResumableContainer implement
|
|
|
30
31
|
}>;
|
|
31
32
|
protected abstract innerFrame: AbstractInnerFrame;
|
|
32
33
|
protected winLineAnimations: WinLineAnimation[];
|
|
34
|
+
protected mysteryFxCoordinates: MysteryFxCoordinates;
|
|
33
35
|
protected constructor(spineName: string);
|
|
34
36
|
get columnsContainer(): AbstractColumnsContainer;
|
|
35
37
|
adaptToSpeed(speedLevel: SpeedLevel): void;
|
|
36
38
|
invokeMysteryFx(x: number, y: number): void;
|
|
37
39
|
protected repositionMysteryFx(_x: number, _y: number): void;
|
|
38
40
|
hideMysteryFx(): Promise<void>;
|
|
41
|
+
private resetMysteryFxCoordinates;
|
|
39
42
|
destroyMysteryFx(): void;
|
|
40
43
|
protected createWinLineAnimation(_animationName: string): WinLineAnimation | null;
|
|
41
44
|
playAllWinLineAnimations(animationNames: string[]): Promise<void>;
|
|
@@ -22,6 +22,7 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
22
22
|
mysteryFxHighlight = null;
|
|
23
23
|
mysteryFxConfig = null;
|
|
24
24
|
winLineAnimations = [];
|
|
25
|
+
mysteryFxCoordinates = { x: 0, y: 0 };
|
|
25
26
|
constructor(spineName) {
|
|
26
27
|
super();
|
|
27
28
|
this.name = AbstractFrame.registryName;
|
|
@@ -37,17 +38,20 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
37
38
|
invokeMysteryFx(x, y) {
|
|
38
39
|
if (!this.mysteryFxConfig)
|
|
39
40
|
return;
|
|
41
|
+
if (this.mysteryFxHighlight)
|
|
42
|
+
this.removeChild(this.mysteryFxHighlight);
|
|
43
|
+
this.mysteryFxCoordinates = { x, y };
|
|
40
44
|
const spineName = this.mysteryFxConfig.mobileSpineName && getDeviceOrientation() === "mobile-portrait"
|
|
41
45
|
? this.mysteryFxConfig.mobileSpineName
|
|
42
46
|
: this.mysteryFxConfig.spineName;
|
|
43
47
|
this.mysteryFxHighlight = new Spine(getSpineData(spineName));
|
|
44
48
|
this.repositionMysteryFx(x, y);
|
|
45
|
-
this.addChild(this.mysteryFxHighlight);
|
|
46
49
|
SoundManager.play(SoundTracks.mysteryFxLoop);
|
|
47
50
|
this.mysteryFxHighlight.state.setAnimation(0, this.mysteryFxConfig.startAnimationName || this.mysteryFxConfig.loopAnimationName, false);
|
|
48
51
|
this.mysteryFxHighlight.state.addListener({
|
|
49
52
|
complete: () => this.mysteryFxHighlight?.state.setAnimation(0, this.mysteryFxConfig.loopAnimationName, true),
|
|
50
53
|
});
|
|
54
|
+
this.addChild(this.mysteryFxHighlight);
|
|
51
55
|
}
|
|
52
56
|
repositionMysteryFx(_x, _y) { }
|
|
53
57
|
async hideMysteryFx() {
|
|
@@ -59,8 +63,9 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
59
63
|
return resolve();
|
|
60
64
|
}
|
|
61
65
|
if (this.mysteryFxHighlight) {
|
|
62
|
-
SoundManager.
|
|
66
|
+
SoundManager.stop(SoundTracks.mysteryFxLoop);
|
|
63
67
|
SoundManager.play(SoundTracks.mysteryFxEnd);
|
|
68
|
+
this.resetMysteryFxCoordinates();
|
|
64
69
|
this.mysteryFxHighlight.state.setAnimation(0, this.mysteryFxConfig.endAnimationName, false);
|
|
65
70
|
this.mysteryFxHighlight.state.addListener({
|
|
66
71
|
complete: () => resolve(),
|
|
@@ -68,6 +73,9 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
68
73
|
}
|
|
69
74
|
});
|
|
70
75
|
}
|
|
76
|
+
resetMysteryFxCoordinates() {
|
|
77
|
+
this.mysteryFxCoordinates = { x: 0, y: 0 };
|
|
78
|
+
}
|
|
71
79
|
destroyMysteryFx() {
|
|
72
80
|
if (this.mysteryFxHighlight) {
|
|
73
81
|
SoundManager.pause(SoundTracks.mysteryFxLoop);
|
|
@@ -80,12 +88,12 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
80
88
|
return null;
|
|
81
89
|
}
|
|
82
90
|
async playAllWinLineAnimations(animationNames) {
|
|
83
|
-
await Promise.
|
|
91
|
+
await Promise.allSettled(animationNames.map((animationName) => this.playWinLineAnimation(animationName)));
|
|
84
92
|
}
|
|
85
93
|
async playWinLineAnimation(animationName) {
|
|
86
94
|
const winLineAnimation = this.createWinLineAnimation(animationName);
|
|
87
95
|
if (winLineAnimation === null) {
|
|
88
|
-
logError(
|
|
96
|
+
logError("Function createWinLineAnimation in Frame is not implemented!");
|
|
89
97
|
return;
|
|
90
98
|
}
|
|
91
99
|
this.winLineAnimations.push(winLineAnimation);
|
|
@@ -112,6 +120,8 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
112
120
|
this.addChild(this.innerFrame);
|
|
113
121
|
}
|
|
114
122
|
resize() {
|
|
123
|
+
if (this.mysteryFxHighlight)
|
|
124
|
+
this.removeChild(this.mysteryFxHighlight);
|
|
115
125
|
this.changeFrameForOrientation();
|
|
116
126
|
const expectedScreenDimensions = {
|
|
117
127
|
width: this.transformedWidth(),
|
|
@@ -122,6 +132,7 @@ export class AbstractFrame extends ResumableContainer {
|
|
|
122
132
|
this.height = dimensions.height;
|
|
123
133
|
this.width = dimensions.width;
|
|
124
134
|
this.addChild(this.innerFrame);
|
|
135
|
+
this.repositionMysteryFx(this.mysteryFxCoordinates.x, this.mysteryFxCoordinates.y);
|
|
125
136
|
if (this.mysteryFxHighlight)
|
|
126
137
|
this.addChild(this.mysteryFxHighlight);
|
|
127
138
|
this.winLineAnimations.forEach((winLineAnimation) => this.addChild(winLineAnimation));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -18,6 +18,7 @@ export declare abstract class AbstractSymbolBase extends Container {
|
|
|
18
18
|
protected animationSpeedMultiplier: number;
|
|
19
19
|
private endOfMultiplierAnimationPromise;
|
|
20
20
|
protected endOfSymbolAnimationPromise: ((value: void | PromiseLike<void>) => void) | undefined;
|
|
21
|
+
protected endOfSwapAnimationPromise: ((value: void | PromiseLike<void>) => void) | undefined;
|
|
21
22
|
protected popSymbolAnimationPromise: ((value: void | PromiseLike<void>) => void) | undefined;
|
|
22
23
|
protected abstract paytableIgnoredSymbols: SymbolId[];
|
|
23
24
|
private _id;
|
|
@@ -25,6 +26,9 @@ export declare abstract class AbstractSymbolBase extends Container {
|
|
|
25
26
|
get id(): SymbolId;
|
|
26
27
|
setInteractiveFlag(flag: boolean): void;
|
|
27
28
|
updateTimeScaleOfSpine(scale?: number): void;
|
|
29
|
+
protected changeSpecialFaceForSymbol(symbolId: SymbolId): string;
|
|
30
|
+
swapSymbolsToSpecials(symbolId: SymbolId, specialResourceName: string, spineScale: number): () => Promise<void>;
|
|
31
|
+
protected animateForSpecialSwap(animationName: string, specialResourceName: string, symbolId: SymbolId, spineScale: number): () => Promise<void>;
|
|
28
32
|
switchSymbolBaseDisplayedObject(option: "sprite" | "spine", suffix?: string): void;
|
|
29
33
|
handleMultiplierAnimation(multiplier: number): Promise<void>;
|
|
30
34
|
play(suffix?: string): Promise<void>;
|
|
@@ -34,6 +38,8 @@ export declare abstract class AbstractSymbolBase extends Container {
|
|
|
34
38
|
swapSymbol(symbolId: SymbolId): void;
|
|
35
39
|
private setupClickListener;
|
|
36
40
|
protected setSymbol(symbolId: SymbolId, shouldSwitchSprite?: boolean): void;
|
|
41
|
+
stopTransformationPlaying(): void;
|
|
42
|
+
protected resolveTransformationsPromise(): void;
|
|
37
43
|
protected resolveAndDestroyPlayingPromise(): void;
|
|
38
44
|
protected abstract getResourceForSymbolId(symbolId: SymbolId): LoadersSpineData;
|
|
39
45
|
protected abstract getAnimationNameForSymbol(symbolId: SymbolId, suffix?: string): string;
|
|
@@ -20,6 +20,7 @@ export class AbstractSymbolBase extends Container {
|
|
|
20
20
|
animationSpeedMultiplier = defaultSpeedConfig.animationDefaultSpeedScale;
|
|
21
21
|
endOfMultiplierAnimationPromise;
|
|
22
22
|
endOfSymbolAnimationPromise;
|
|
23
|
+
endOfSwapAnimationPromise;
|
|
23
24
|
popSymbolAnimationPromise;
|
|
24
25
|
_id;
|
|
25
26
|
constructor(parent, symbolId, multiplierSpineName = null) {
|
|
@@ -48,6 +49,31 @@ export class AbstractSymbolBase extends Container {
|
|
|
48
49
|
updateTimeScaleOfSpine(scale = 0) {
|
|
49
50
|
this.animationSpeedMultiplier = scale;
|
|
50
51
|
}
|
|
52
|
+
changeSpecialFaceForSymbol(symbolId) {
|
|
53
|
+
return `efx_${symbolId.toLowerCase()}`;
|
|
54
|
+
}
|
|
55
|
+
swapSymbolsToSpecials(symbolId, specialResourceName, spineScale) {
|
|
56
|
+
const animation = this.changeSpecialFaceForSymbol(symbolId);
|
|
57
|
+
return this.animateForSpecialSwap(animation, specialResourceName, symbolId, spineScale);
|
|
58
|
+
}
|
|
59
|
+
animateForSpecialSwap(animationName, specialResourceName, symbolId, spineScale) {
|
|
60
|
+
return () => {
|
|
61
|
+
this.swapSymbol(symbolId);
|
|
62
|
+
return new Promise((resolve) => {
|
|
63
|
+
this.spine = new Spine(getSpineData(specialResourceName));
|
|
64
|
+
this.endOfSwapAnimationPromise = resolve;
|
|
65
|
+
this.spine.state.timeScale = (this.animationSpeedMultiplier = 1) ? 1.5 : this.animationSpeedMultiplier;
|
|
66
|
+
this.spine.state.setAnimation(0, animationName, false);
|
|
67
|
+
this.spine.scale.set(spineScale);
|
|
68
|
+
this.addChild(this.spine);
|
|
69
|
+
this.spine.state.addListener({
|
|
70
|
+
complete: () => {
|
|
71
|
+
resolve();
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
}
|
|
51
77
|
switchSymbolBaseDisplayedObject(option, suffix = "") {
|
|
52
78
|
if (option === "spine") {
|
|
53
79
|
this.removeChild(this.spine);
|
|
@@ -145,6 +171,16 @@ export class AbstractSymbolBase extends Container {
|
|
|
145
171
|
if (shouldSwitchSprite)
|
|
146
172
|
this.switchSymbolBaseDisplayedObject("sprite");
|
|
147
173
|
}
|
|
174
|
+
stopTransformationPlaying() {
|
|
175
|
+
this.setSymbol(this._id);
|
|
176
|
+
this.resolveTransformationsPromise();
|
|
177
|
+
}
|
|
178
|
+
resolveTransformationsPromise() {
|
|
179
|
+
if (this.endOfSwapAnimationPromise) {
|
|
180
|
+
this.endOfSwapAnimationPromise();
|
|
181
|
+
this.endOfSwapAnimationPromise = undefined;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
148
184
|
resolveAndDestroyPlayingPromise() {
|
|
149
185
|
if (this.endOfMultiplierAnimationPromise) {
|
|
150
186
|
this.endOfMultiplierAnimationPromise();
|
|
@@ -60,6 +60,7 @@ export declare abstract class AbstractSymbolsColumn extends Container implements
|
|
|
60
60
|
getTriggersPromise(): Promise<void>;
|
|
61
61
|
getStopPromise(): Promise<void>;
|
|
62
62
|
stopAllPlayingSymbols(): void;
|
|
63
|
+
stopTransformationPlayingSymbols(): void;
|
|
63
64
|
getSymbolAtPosition(position: number): AbstractSymbolBase;
|
|
64
65
|
findSymbols(symbolId: SymbolId): Array<AbstractSymbolBase>;
|
|
65
66
|
playSymbolAtPosition(position: number, playSymbol: boolean, multiplier?: number, suffix?: string): Promise<void>;
|
|
@@ -81,7 +81,7 @@ export class AbstractSymbolsColumn extends Container {
|
|
|
81
81
|
}
|
|
82
82
|
async changeVelocity(velocity, duration, frame) {
|
|
83
83
|
await new Promise((resolve) => {
|
|
84
|
-
this.tween = new TWEEN.Tween({ velocity:
|
|
84
|
+
this.tween = new TWEEN.Tween({ velocity: velocity })
|
|
85
85
|
.onUpdate((value) => {
|
|
86
86
|
this.velocity = value.velocity;
|
|
87
87
|
})
|
|
@@ -91,8 +91,7 @@ export class AbstractSymbolsColumn extends Container {
|
|
|
91
91
|
.onStop(async () => {
|
|
92
92
|
this.tween = null;
|
|
93
93
|
if (frame) {
|
|
94
|
-
|
|
95
|
-
await frame.hideMysteryFx();
|
|
94
|
+
await frame.hideMysteryFx();
|
|
96
95
|
frame.destroyMysteryFx();
|
|
97
96
|
}
|
|
98
97
|
this.skipHidingMysteryFx = false;
|
|
@@ -181,6 +180,9 @@ export class AbstractSymbolsColumn extends Container {
|
|
|
181
180
|
stopAllPlayingSymbols() {
|
|
182
181
|
this.symbols.forEach((symbol) => symbol.stopPlaying());
|
|
183
182
|
}
|
|
183
|
+
stopTransformationPlayingSymbols() {
|
|
184
|
+
this.symbols.forEach((symbol) => symbol.stopTransformationPlaying());
|
|
185
|
+
}
|
|
184
186
|
getSymbolAtPosition(position) {
|
|
185
187
|
return this.symbols[position];
|
|
186
188
|
}
|
|
@@ -10,6 +10,8 @@ export declare const gamePhases: {
|
|
|
10
10
|
readonly STOPPING_HANDLING_ACTIONS: "stoppingHandlingActions";
|
|
11
11
|
readonly DATA_FETCH: "dataFetch";
|
|
12
12
|
readonly BIG_WIN_INVOKED: "bigWinInvoked";
|
|
13
|
+
readonly SUPER_BONUS_WIN_INVOKED: "superBonusWinInvoked";
|
|
14
|
+
readonly BONUS_WIN_INVOKED: "bonusWinInvoked";
|
|
13
15
|
readonly GAME_SUMMARY: "gameSummary";
|
|
14
16
|
};
|
|
15
17
|
export type GamePhase = (typeof gamePhases)[keyof typeof gamePhases];
|
|
@@ -10,5 +10,7 @@ export const gamePhases = {
|
|
|
10
10
|
STOPPING_HANDLING_ACTIONS: "stoppingHandlingActions",
|
|
11
11
|
DATA_FETCH: "dataFetch",
|
|
12
12
|
BIG_WIN_INVOKED: "bigWinInvoked",
|
|
13
|
-
|
|
13
|
+
SUPER_BONUS_WIN_INVOKED: "superBonusWinInvoked",
|
|
14
|
+
BONUS_WIN_INVOKED: "bonusWinInvoked",
|
|
15
|
+
GAME_SUMMARY: "gameSummary",
|
|
14
16
|
};
|
|
@@ -154,6 +154,7 @@ export declare abstract class AbstractController<T> {
|
|
|
154
154
|
private lockLogicWhileSpinning;
|
|
155
155
|
private unlockLogicAfterSpinning;
|
|
156
156
|
protected stopPlayingSymbolsStreak(): void;
|
|
157
|
+
protected stopPlayingSymbolsTransformation(): void;
|
|
157
158
|
protected countBigWin(customAmount?: number): Promise<void>;
|
|
158
159
|
protected countBonusWin(winAmount?: number): Promise<void>;
|
|
159
160
|
protected countSuperBonusWin(winAmount?: number): Promise<void>;
|
|
@@ -437,7 +437,7 @@ export class AbstractController {
|
|
|
437
437
|
autoplaySpin() {
|
|
438
438
|
if (!RainMan.settingsStore.howManyAutoSpinsLeft)
|
|
439
439
|
return;
|
|
440
|
-
if (!RainMan.settingsStore.infinitySpinsEnabled) {
|
|
440
|
+
if (!RainMan.settingsStore.infinitySpinsEnabled || RainMan.settingsStore.howManyAutoSpinsLeft > 0) {
|
|
441
441
|
RainMan.settingsStore.decreaseAutoSpinsCount();
|
|
442
442
|
}
|
|
443
443
|
if (RainMan.settingsStore.howManyAutoSpinsLeft === 0) {
|
|
@@ -592,7 +592,7 @@ export class AbstractController {
|
|
|
592
592
|
this.unlockLogicAfterSpinning();
|
|
593
593
|
if (RainMan.settingsStore.isFreeSpinsPlayEnabled) {
|
|
594
594
|
this.uiController.increaseTotalFreeSpinWinAmount(spinLogic.winTotalAmountWithoutMystery);
|
|
595
|
-
this.uiController.limitWinAmount(
|
|
595
|
+
this.uiController.limitWinAmount(spinLogic.winTotalAmount);
|
|
596
596
|
}
|
|
597
597
|
else {
|
|
598
598
|
this.uiController.limitWinAmount(spinLogic.winTotalAmount);
|
|
@@ -702,6 +702,9 @@ export class AbstractController {
|
|
|
702
702
|
this.columnsContainer.stopPlayingSymbolsInColumns();
|
|
703
703
|
this.frame.stopPlayingWinLineAnimations();
|
|
704
704
|
}
|
|
705
|
+
stopPlayingSymbolsTransformation() {
|
|
706
|
+
this.columnsContainer.stopPlayingSymbolsTransformationInColumns();
|
|
707
|
+
}
|
|
705
708
|
async countBigWin(customAmount) {
|
|
706
709
|
if (RainMan.config.disableBigWinOnBonus)
|
|
707
710
|
return;
|
|
@@ -710,10 +713,12 @@ export class AbstractController {
|
|
|
710
713
|
return;
|
|
711
714
|
const amount = customAmount || this.uiController.recentWin;
|
|
712
715
|
this.mainContainer.invokeBigWin();
|
|
716
|
+
this.changeGamePhase(gamePhases.BIG_WIN_INVOKED);
|
|
713
717
|
const animationTimeDivider = RainMan.settingsStore.currentSpeed === SPEED_LEVELS.fast ? 3 : 1;
|
|
714
718
|
await RainMan.componentRegistry
|
|
715
719
|
.get(COMPONENTS.bigWin)
|
|
716
720
|
.update(amount, RainMan.config.durationOfActions.updatableTextCountingDuration / animationTimeDivider);
|
|
721
|
+
this.changeGamePhase(gamePhases.STOPPING_HANDLING_ACTIONS);
|
|
717
722
|
await new Promise((resolve) => {
|
|
718
723
|
this.resolveBigWin = resolve;
|
|
719
724
|
setTimeout(() => {
|
|
@@ -722,6 +727,7 @@ export class AbstractController {
|
|
|
722
727
|
this.mainContainer.destroyBigWin();
|
|
723
728
|
this.resolveBigWin();
|
|
724
729
|
this.resolveBigWin = undefined;
|
|
730
|
+
this.changeGamePhase(gamePhases.IDLE);
|
|
725
731
|
}, RainMan.config.durationOfActions.bigWinPhaseTimeout / animationTimeDivider);
|
|
726
732
|
});
|
|
727
733
|
}
|
|
@@ -730,11 +736,12 @@ export class AbstractController {
|
|
|
730
736
|
return;
|
|
731
737
|
const amount = winAmount || this.uiController.recentWin;
|
|
732
738
|
this.mainContainer.invokeBonusWin();
|
|
733
|
-
this.changeGamePhase(gamePhases.
|
|
739
|
+
this.changeGamePhase(gamePhases.BONUS_WIN_INVOKED);
|
|
734
740
|
const animationTimeDivider = RainMan.settingsStore.currentSpeed === SPEED_LEVELS.fast ? 3 : 1;
|
|
735
741
|
await RainMan.componentRegistry
|
|
736
742
|
.get(COMPONENTS.bonusWin)
|
|
737
743
|
.update(amount, RainMan.config.durationOfActions.updatableTextCountingDuration / animationTimeDivider);
|
|
744
|
+
this.changeGamePhase(gamePhases.STOPPING_HANDLING_ACTIONS);
|
|
738
745
|
await new Promise((resolve) => {
|
|
739
746
|
this.resolveBonusWin = resolve;
|
|
740
747
|
setTimeout(() => {
|
|
@@ -743,6 +750,7 @@ export class AbstractController {
|
|
|
743
750
|
this.mainContainer.destroyBonusWin();
|
|
744
751
|
this.resolveBonusWin();
|
|
745
752
|
this.resolveBonusWin = undefined;
|
|
753
|
+
this.changeGamePhase(gamePhases.IDLE);
|
|
746
754
|
}, RainMan.config.durationOfActions.bonusWinPhaseTimeout / animationTimeDivider);
|
|
747
755
|
});
|
|
748
756
|
}
|
|
@@ -751,10 +759,12 @@ export class AbstractController {
|
|
|
751
759
|
return;
|
|
752
760
|
const amount = winAmount || RainMan.settingsStore.cumulativeWinAmount;
|
|
753
761
|
this.mainContainer.invokeSuperBonusWin();
|
|
762
|
+
this.changeGamePhase(gamePhases.SUPER_BONUS_WIN_INVOKED);
|
|
754
763
|
const animationTimeDivider = RainMan.settingsStore.currentSpeed === SPEED_LEVELS.fast ? 3 : 1;
|
|
755
764
|
await RainMan.componentRegistry
|
|
756
765
|
.get(COMPONENTS.superBonusWin)
|
|
757
766
|
.update(amount, RainMan.config.durationOfActions.updatableTextCountingDuration / animationTimeDivider);
|
|
767
|
+
this.changeGamePhase(gamePhases.STOPPING_HANDLING_ACTIONS);
|
|
758
768
|
await new Promise((resolve) => {
|
|
759
769
|
this.resolveSuperBonusWin = resolve;
|
|
760
770
|
setTimeout(() => {
|
|
@@ -763,6 +773,7 @@ export class AbstractController {
|
|
|
763
773
|
this.mainContainer.destroySuperBonusWin();
|
|
764
774
|
this.resolveSuperBonusWin();
|
|
765
775
|
this.resolveSuperBonusWin = undefined;
|
|
776
|
+
this.changeGamePhase(gamePhases.IDLE);
|
|
766
777
|
}, RainMan.config.durationOfActions.superBonusWinPhaseTimeout / animationTimeDivider);
|
|
767
778
|
});
|
|
768
779
|
}
|
package/package.json
CHANGED