@omnitronix/bonnys-fortune-game-engine 1.7.2 → 1.8.0
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/__tests__/base-game.test.js +17 -10
- package/dist/__tests__/base-game.test.js.map +1 -1
- package/dist/__tests__/bonus-handlers.test.js +15 -21
- package/dist/__tests__/bonus-handlers.test.js.map +1 -1
- package/dist/__tests__/bonus-meters.test.js.map +1 -1
- package/dist/__tests__/collect-feature-handler.test.js +30 -24
- package/dist/__tests__/collect-feature-handler.test.js.map +1 -1
- package/dist/__tests__/comprehensive.test.js.map +1 -1
- package/dist/__tests__/error-paths.test.js +11 -7
- package/dist/__tests__/error-paths.test.js.map +1 -1
- package/dist/__tests__/helpers/test-engine-factory.d.ts +72 -18
- package/dist/__tests__/helpers/test-engine-factory.js +32 -7
- package/dist/__tests__/helpers/test-engine-factory.js.map +1 -1
- package/dist/__tests__/integration-1000-spin.test.js +33 -37
- package/dist/__tests__/integration-1000-spin.test.js.map +1 -1
- package/dist/__tests__/rng-gli19-compliance.test.js.map +1 -1
- package/dist/__tests__/rng-security.test.js +0 -1
- package/dist/__tests__/rng-security.test.js.map +1 -1
- package/dist/__tests__/rtp-simulation.test.js +11 -10
- package/dist/__tests__/rtp-simulation.test.js.map +1 -1
- package/dist/__tests__/state-transitions.test.js +0 -1
- package/dist/__tests__/state-transitions.test.js.map +1 -1
- package/dist/__tests__/steering-fortune-handler.test.js +18 -14
- package/dist/__tests__/steering-fortune-handler.test.js.map +1 -1
- package/dist/__tests__/symbol-distribution.test.js +13 -16
- package/dist/__tests__/symbol-distribution.test.js.map +1 -1
- package/dist/__tests__/treasure-hunt-handler.test.js +23 -16
- package/dist/__tests__/treasure-hunt-handler.test.js.map +1 -1
- package/dist/__tests__/win-calculator.test.js +10 -7
- package/dist/__tests__/win-calculator.test.js.map +1 -1
- package/dist/bonnys-fortune-v1.game-engine.d.ts +3 -3
- package/dist/bonnys-fortune-v1.game-engine.js +8 -5
- package/dist/bonnys-fortune-v1.game-engine.js.map +1 -1
- package/dist/game-engine.interface.d.ts +1 -1
- package/dist/helpers/optional-boolean-mapper.d.ts +1 -1
- package/dist/helpers/validation-helper.d.ts +1 -1
- package/dist/logic/bonnys-fortune.game-logic.js +2 -0
- package/dist/logic/bonnys-fortune.game-logic.js.map +1 -1
- package/dist/logic/bonnys-fortune.types.d.ts +7 -1
- package/dist/logic/handlers/collect-feature-bonus.handler.js.map +1 -1
- package/dist/logic/handlers/steering-to-the-fortune-bonus.handler.js +6 -5
- package/dist/logic/handlers/steering-to-the-fortune-bonus.handler.js.map +1 -1
- package/dist/logic/handlers/treasure-hunt-bonus.handler.js.map +1 -1
- package/dist/rng/rng-client.factory.js +3 -3
- package/dist/rng/rng-client.factory.js.map +1 -1
- package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.js.map +1 -1
- package/dist/validation/custom-decorators/IsNestedIntArray.js.map +1 -1
- package/dist/validation/game-logic-config-validation.service.d.ts +1 -1
- package/dist/validation/game-logic-config-validation.service.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/base-game.test.ts +26 -17
- package/src/__tests__/bonus-handlers.test.ts +16 -21
- package/src/__tests__/bonus-meters.test.ts +13 -8
- package/src/__tests__/collect-feature-handler.test.ts +39 -26
- package/src/__tests__/comprehensive.test.ts +40 -36
- package/src/__tests__/error-paths.test.ts +29 -18
- package/src/__tests__/helpers/test-engine-factory.ts +127 -40
- package/src/__tests__/integration-1000-spin.test.ts +53 -48
- package/src/__tests__/rng-gli19-compliance.test.ts +17 -17
- package/src/__tests__/rng-security.test.ts +11 -8
- package/src/__tests__/rtp-simulation.test.ts +17 -10
- package/src/__tests__/state-transitions.test.ts +8 -4
- package/src/__tests__/steering-fortune-handler.test.ts +30 -18
- package/src/__tests__/symbol-distribution.test.ts +19 -16
- package/src/__tests__/treasure-hunt-handler.test.ts +36 -22
- package/src/__tests__/win-calculator.test.ts +14 -10
- package/src/bonnys-fortune-v1.game-engine.ts +18 -8
- package/src/domain/types/game-symbols.response.dto.ts +1 -1
- package/src/game-engine.interface.ts +1 -1
- package/src/helpers/validation-helper.ts +1 -1
- package/src/logic/bonnys-fortune.game-logic.ts +3 -0
- package/src/logic/bonnys-fortune.types.ts +10 -1
- package/src/logic/handlers/collect-feature-bonus.handler.ts +5 -2
- package/src/logic/handlers/steering-to-the-fortune-bonus.handler.ts +7 -6
- package/src/logic/handlers/treasure-hunt-bonus.handler.ts +2 -2
- package/src/rng/rng-client.factory.ts +3 -3
- package/src/validation/bonnys-fortune/bonnys-fortune-config.dto.ts +72 -72
- package/src/validation/custom-decorators/IsNestedIntArray.ts +1 -1
- package/src/validation/game-logic-config-validation.service.ts +2 -2
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
executeSpin,
|
|
21
21
|
resetCommandIdCounter,
|
|
22
22
|
MockRngClient,
|
|
23
|
+
getOutcome,
|
|
23
24
|
} from './helpers/test-engine-factory';
|
|
24
25
|
|
|
25
26
|
describe('Win Calculator - Bonnys Fortune', () => {
|
|
@@ -766,11 +767,12 @@ describe('Win Calculator - Bonnys Fortune', () => {
|
|
|
766
767
|
|
|
767
768
|
expect(result.success).toBe(true);
|
|
768
769
|
|
|
770
|
+
const outcomeW = getOutcome(result);
|
|
769
771
|
const winResult =
|
|
770
|
-
|
|
772
|
+
outcomeW.result?.winResult ?? outcomeW.winResult;
|
|
771
773
|
if (winResult) {
|
|
772
|
-
expect(winResult.totalWin).toBeGreaterThanOrEqual(0);
|
|
773
|
-
expect(Array.isArray(winResult.winningLines)).toBe(true);
|
|
774
|
+
expect((winResult as { totalWin: number }).totalWin).toBeGreaterThanOrEqual(0);
|
|
775
|
+
expect(Array.isArray((winResult as { winningLines: unknown[] }).winningLines)).toBe(true);
|
|
774
776
|
}
|
|
775
777
|
});
|
|
776
778
|
|
|
@@ -789,14 +791,16 @@ describe('Win Calculator - Bonnys Fortune', () => {
|
|
|
789
791
|
|
|
790
792
|
expect(result.success).toBe(true);
|
|
791
793
|
|
|
794
|
+
const outcomeM = getOutcome(result);
|
|
792
795
|
const screen =
|
|
793
|
-
|
|
794
|
-
|
|
796
|
+
outcomeM.result?.screen ??
|
|
797
|
+
outcomeM.screen ??
|
|
795
798
|
result.privateState.screen;
|
|
796
|
-
const
|
|
797
|
-
|
|
799
|
+
const winResult2 =
|
|
800
|
+
outcomeM.result?.winResult ?? outcomeM.winResult;
|
|
798
801
|
|
|
799
|
-
if (screen &&
|
|
802
|
+
if (screen && winResult2) {
|
|
803
|
+
const wr = winResult2 as { totalWin: number; winningLines: unknown[] };
|
|
800
804
|
// Recalculate using the win calculator directly
|
|
801
805
|
const directResult = BonnysFortuneWinCalculator.calculateWins(
|
|
802
806
|
screen,
|
|
@@ -806,9 +810,9 @@ describe('Win Calculator - Bonnys Fortune', () => {
|
|
|
806
810
|
SpinType.BASE_GAME_SPIN,
|
|
807
811
|
);
|
|
808
812
|
|
|
809
|
-
expect(directResult.totalWin).toBe(
|
|
813
|
+
expect(directResult.totalWin).toBe(wr.totalWin);
|
|
810
814
|
expect(directResult.winningLines.length).toBe(
|
|
811
|
-
|
|
815
|
+
wr.winningLines.length,
|
|
812
816
|
);
|
|
813
817
|
}
|
|
814
818
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BonnysFortunePrivateState,
|
|
3
3
|
BonnysFortunePublicState,
|
|
4
|
+
BonnysFortuneOutcome,
|
|
5
|
+
StartBonusRoundResult,
|
|
4
6
|
SpinResult as LocalSpinResult,
|
|
5
7
|
} from './logic/bonnys-fortune.types';
|
|
6
8
|
import {
|
|
@@ -50,6 +52,7 @@ import { ReelStripsConfig } from './domain/reel-strips-config';
|
|
|
50
52
|
import { ReelStripsConfigLoader } from './config/reel-strips-config/reel-strips-config-loader';
|
|
51
53
|
import { ReelStripsConfigMapper } from './domain/mappers/reel-strips-config.mapper';
|
|
52
54
|
import { ReelStripsConfigValidationService } from './validation/reel-strips-config-validation.service';
|
|
55
|
+
import { RngClientConfig } from '@omnitronix/rng-client-core';
|
|
53
56
|
import { RngClientFactory } from './rng/rng-client.factory';
|
|
54
57
|
import { RngService } from './rng/rng-service';
|
|
55
58
|
import { StartBonusRoundCommand } from './domain/types/start-bonus-round-command';
|
|
@@ -65,7 +68,7 @@ export interface BonnysFortuneV1GameEngineConfig {
|
|
|
65
68
|
export class BonnysFortuneV1GameEngine
|
|
66
69
|
extends SlotGameHandler
|
|
67
70
|
implements
|
|
68
|
-
GameEngine<BonnysFortunePublicState, BonnysFortunePrivateState,
|
|
71
|
+
GameEngine<BonnysFortunePublicState, BonnysFortunePrivateState, BonnysFortuneOutcome>,
|
|
69
72
|
DebugIntrospectable
|
|
70
73
|
{
|
|
71
74
|
/**
|
|
@@ -111,7 +114,7 @@ export class BonnysFortuneV1GameEngine
|
|
|
111
114
|
this.configOutPort = new FileSystemGameLogicConfigLoader();
|
|
112
115
|
this.reelsOutPort = new FileSystemReelStripsConfigLoader();
|
|
113
116
|
|
|
114
|
-
const rngClient = RngClientFactory.create({ metrics: config.metrics });
|
|
117
|
+
const rngClient = RngClientFactory.create({ metrics: config.metrics as RngClientConfig['metrics'] });
|
|
115
118
|
this.rngService = new RngService(rngClient);
|
|
116
119
|
|
|
117
120
|
this.configValidator = new GameLogicConfigValidationService();
|
|
@@ -334,7 +337,7 @@ export class BonnysFortuneV1GameEngine
|
|
|
334
337
|
CommandProcessingResult<
|
|
335
338
|
BonnysFortunePublicState,
|
|
336
339
|
BonnysFortunePrivateState,
|
|
337
|
-
|
|
340
|
+
BonnysFortuneOutcome
|
|
338
341
|
>
|
|
339
342
|
> {
|
|
340
343
|
this.logger.log(`Processing command ${command.type}`);
|
|
@@ -424,15 +427,22 @@ export class BonnysFortuneV1GameEngine
|
|
|
424
427
|
getResultsArray: () => outcome.results ?? [],
|
|
425
428
|
};
|
|
426
429
|
|
|
430
|
+
// The SDK platform expects deliveryStrategy and nextSpinType on the outcome
|
|
431
|
+
// These are SDK-level extensions not part of the game engine's BonnysFortuneOutcome type
|
|
432
|
+
const bonusOutcome: StartBonusRoundResult & {
|
|
433
|
+
nextSpinType: typeof nextSpinType;
|
|
434
|
+
deliveryStrategy: BonusResultDeliveryStrategy;
|
|
435
|
+
} = {
|
|
436
|
+
...outcome,
|
|
437
|
+
nextSpinType, // Required by platform-connect SDK to set CurrentSpinType
|
|
438
|
+
deliveryStrategy,
|
|
439
|
+
};
|
|
440
|
+
|
|
427
441
|
return {
|
|
428
442
|
success: true,
|
|
429
443
|
publicState: outcome.publicState,
|
|
430
444
|
privateState: outcome.privateState,
|
|
431
|
-
outcome:
|
|
432
|
-
...outcome,
|
|
433
|
-
nextSpinType, // Required by platform-connect SDK to set CurrentSpinType
|
|
434
|
-
deliveryStrategy,
|
|
435
|
-
},
|
|
445
|
+
outcome: bonusOutcome as BonnysFortuneOutcome,
|
|
436
446
|
message: 'Bonus round started',
|
|
437
447
|
rngOutcome,
|
|
438
448
|
};
|
|
@@ -11,7 +11,7 @@ export {
|
|
|
11
11
|
} from '@omnitronix/game-engine-contract';
|
|
12
12
|
|
|
13
13
|
// Local types specific to this game engine
|
|
14
|
-
export type GameEngineMetricsHandlers = RngClientConfig['metrics']['handlers'];
|
|
14
|
+
export type GameEngineMetricsHandlers = NonNullable<RngClientConfig['metrics']>['handlers'];
|
|
15
15
|
export interface GameEngineConfig {
|
|
16
16
|
metrics?: {
|
|
17
17
|
handlers: GameEngineMetricsHandlers;
|
|
@@ -21,7 +21,7 @@ export class ValidationHelper {
|
|
|
21
21
|
return validate(dto, ValidationHelper.validationOptionsWithoutForbidden);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
public static isPlainObject(value: unknown): value is Record<string,
|
|
24
|
+
public static isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
25
25
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -218,11 +218,20 @@ export interface GetSymbolsResult {
|
|
|
218
218
|
symbols: GetSymbolsOutcome[];
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/** Outcome returned by the INIT_SESSION_STATE command. */
|
|
222
|
+
export interface InitSessionOutcome {
|
|
223
|
+
publicState: BonnysFortunePublicState;
|
|
224
|
+
privateState: BonnysFortunePrivateState;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Union of all possible outcome types returned by processCommand. */
|
|
221
228
|
export type BonnysFortuneOutcome =
|
|
222
229
|
| BonnysFortuneGameLogicSpinResult
|
|
223
230
|
| BonnysFortuneBonusGameLogicSpinResult
|
|
231
|
+
| StartBonusRoundResult
|
|
232
|
+
| InitSessionOutcome
|
|
224
233
|
| SymbolsCountMatrix
|
|
225
234
|
| DebugTriggerBonusOutcome
|
|
226
235
|
| DebugUpdateBonusMeterProgressOutcome
|
|
227
|
-
|
|
|
236
|
+
| GetSymbolsResult
|
|
228
237
|
| null;
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
SpinType,
|
|
7
7
|
} from '../bonnys-fortune.types';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
BonnysFortuneGameLogicConfigInterface,
|
|
11
|
+
ScatterGameConfig,
|
|
12
|
+
} from '../game-logic-config.interface';
|
|
10
13
|
import { GameSpinInputDto } from '../../domain/types/game-spin-input.dto';
|
|
11
14
|
import { NumberHelper } from '../../helpers/number-helper';
|
|
12
15
|
import { RngService } from '../../rng/rng-service';
|
|
@@ -102,7 +105,7 @@ export class CollectFeatureBonusHandler {
|
|
|
102
105
|
totalMultipliers: number,
|
|
103
106
|
totalWin: number,
|
|
104
107
|
betGame: number,
|
|
105
|
-
scatterConfig:
|
|
108
|
+
scatterConfig: ScatterGameConfig,
|
|
106
109
|
checkpoints: number[],
|
|
107
110
|
publicState: BonnysFortunePublicState,
|
|
108
111
|
privateState: BonnysFortunePrivateState,
|
|
@@ -41,17 +41,18 @@ export class SteeringToTheFortuneBonusHandler {
|
|
|
41
41
|
let triggeredBonus: BonusTrigger | undefined;
|
|
42
42
|
|
|
43
43
|
if (prize.type === PrizeType.MULTIPLIER) {
|
|
44
|
-
playerWinning = NumberHelper.safeMultiply(betStake, prize.value, 2);
|
|
44
|
+
playerWinning = NumberHelper.safeMultiply(betStake, prize.value ?? 0, 2);
|
|
45
45
|
} else if (prize.type === PrizeType.BONUS) {
|
|
46
|
+
const bonusType = prize.bonusType ?? 'bonusGame1';
|
|
46
47
|
triggeredBonus = {
|
|
47
48
|
bonusId: UuidHelper.generateUuid(),
|
|
48
|
-
bonusType
|
|
49
|
+
bonusType,
|
|
49
50
|
betAmount: NumberHelper.toFixedNumber(params.betAmount, 2),
|
|
50
51
|
};
|
|
51
|
-
nextSpinType = getSpinTypeForBonus(
|
|
52
|
+
nextSpinType = getSpinTypeForBonus(bonusType);
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
const results = [
|
|
55
|
+
const results: SpinResultResponse<SteeringToTheFortuneResult>[] = [
|
|
55
56
|
{
|
|
56
57
|
result: {
|
|
57
58
|
spinType: SpinType.BONUS_GAME_3_SPIN,
|
|
@@ -59,9 +60,9 @@ export class SteeringToTheFortuneBonusHandler {
|
|
|
59
60
|
nextSpinType,
|
|
60
61
|
prizeType: prize.type,
|
|
61
62
|
prizeValue:
|
|
62
|
-
prize.type === PrizeType.MULTIPLIER ? prize.value : prize.bonusType,
|
|
63
|
+
prize.type === PrizeType.MULTIPLIER ? (prize.value ?? 0) : (prize.bonusType ?? ''),
|
|
63
64
|
totalMultiplier:
|
|
64
|
-
prize.type === PrizeType.MULTIPLIER ? prize.value : 0,
|
|
65
|
+
prize.type === PrizeType.MULTIPLIER ? (prize.value ?? 0) : 0,
|
|
65
66
|
triggeredBonus,
|
|
66
67
|
// BaseOutcome standardized fields
|
|
67
68
|
actionType: SpinType.BONUS_GAME_3_SPIN,
|
|
@@ -64,14 +64,14 @@ export class TreasureHuntBonusHandler {
|
|
|
64
64
|
// Player only sees the first stepsCount (6) positions
|
|
65
65
|
const playerSelections = selectionsVector.slice(0, stepsCount);
|
|
66
66
|
const selections = playerSelections.map((idx) => jackpotKeys[idx]);
|
|
67
|
-
const multipliers = selections.map((name) => jackpotMultipliers[name]);
|
|
67
|
+
const multipliers = selections.map((name) => (jackpotMultipliers as Record<string, number>)[name]);
|
|
68
68
|
|
|
69
69
|
const results = selections.map((symbol, index) => {
|
|
70
70
|
const isFinalStep = index === stepsCount - 1;
|
|
71
71
|
|
|
72
72
|
const winningMultiplier =
|
|
73
73
|
isFinalStep && winSymbolIndex >= 0
|
|
74
|
-
? jackpotMultipliers[jackpotKeys[winSymbolIndex]]
|
|
74
|
+
? (jackpotMultipliers as Record<string, number>)[jackpotKeys[winSymbolIndex]]
|
|
75
75
|
: 0;
|
|
76
76
|
const playerWinning =
|
|
77
77
|
isFinalStep && winSymbolIndex >= 0
|
|
@@ -15,9 +15,9 @@ export class RngClientFactory {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const rngClientConfig: RngClientConfig = {
|
|
18
|
-
serverUrl: process.env.RNG_CLIENT_URL,
|
|
19
|
-
grpcUrl: process.env.RNG_CLIENT_GRPC_URL,
|
|
20
|
-
clientMethod: process.env.RNG_CLIENT_METHOD as 'grpc' | 'rest',
|
|
18
|
+
serverUrl: process.env.RNG_CLIENT_URL ?? '',
|
|
19
|
+
grpcUrl: process.env.RNG_CLIENT_GRPC_URL ?? '',
|
|
20
|
+
clientMethod: (process.env.RNG_CLIENT_METHOD as 'grpc' | 'rest') ?? 'rest',
|
|
21
21
|
poolingSize: parseInt(process.env.RNG_CLIENT_POOL_SIZE || '2000'),
|
|
22
22
|
metrics: config.metrics,
|
|
23
23
|
};
|
|
@@ -15,109 +15,109 @@ import {
|
|
|
15
15
|
|
|
16
16
|
export class SymbolMultipliersDto {
|
|
17
17
|
@IsInt()
|
|
18
|
-
public symbolId
|
|
18
|
+
public symbolId!: number;
|
|
19
19
|
|
|
20
20
|
@IsString()
|
|
21
|
-
public name
|
|
21
|
+
public name!: string;
|
|
22
22
|
|
|
23
23
|
@IsObject()
|
|
24
|
-
public multipliers
|
|
24
|
+
public multipliers!: Record<'x3' | 'x4' | 'x5', number>;
|
|
25
25
|
|
|
26
26
|
@IsBoolean()
|
|
27
|
-
public isWild
|
|
27
|
+
public isWild!: boolean;
|
|
28
28
|
|
|
29
29
|
@IsBoolean()
|
|
30
|
-
public isScatter
|
|
30
|
+
public isScatter!: boolean;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// --- SymbolDefinitions ---
|
|
34
34
|
|
|
35
35
|
export class CollectFeatureSymbolsDto {
|
|
36
36
|
@IsObject()
|
|
37
|
-
public multipliers
|
|
37
|
+
public multipliers!: Record<string, number>;
|
|
38
38
|
|
|
39
39
|
@IsObject()
|
|
40
|
-
public values
|
|
40
|
+
public values!: Record<string, number>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export class SymbolRangeDto {
|
|
44
44
|
@IsInt()
|
|
45
|
-
public minIndex
|
|
45
|
+
public minIndex!: number;
|
|
46
46
|
|
|
47
47
|
@IsInt()
|
|
48
|
-
public maxIndex
|
|
48
|
+
public maxIndex!: number;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export class SymbolDefinitionsDto {
|
|
52
52
|
@ValidateNested()
|
|
53
53
|
@Type(() => SymbolRangeDto)
|
|
54
|
-
public baseSymbols
|
|
54
|
+
public baseSymbols!: SymbolRangeDto;
|
|
55
55
|
|
|
56
56
|
@IsObject()
|
|
57
|
-
public specialSymbols
|
|
57
|
+
public specialSymbols!: Record<string, number>;
|
|
58
58
|
|
|
59
59
|
@ValidateNested()
|
|
60
60
|
@Type(() => CollectFeatureSymbolsDto)
|
|
61
|
-
public collectFeatureSymbols
|
|
61
|
+
public collectFeatureSymbols!: CollectFeatureSymbolsDto;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// --- BaseGameConfig ---
|
|
65
65
|
|
|
66
66
|
export class LayoutDto {
|
|
67
67
|
@IsInt()
|
|
68
|
-
public rows
|
|
68
|
+
public rows!: number;
|
|
69
69
|
|
|
70
70
|
@IsInt()
|
|
71
|
-
public reels
|
|
71
|
+
public reels!: number;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export class WinConfigDto {
|
|
75
75
|
@IsInt()
|
|
76
|
-
public minLength
|
|
76
|
+
public minLength!: number;
|
|
77
77
|
|
|
78
78
|
@IsInt()
|
|
79
|
-
public maxLength
|
|
79
|
+
public maxLength!: number;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
// --- ReelsOptions ---
|
|
83
83
|
|
|
84
84
|
export class ReelsOptionsDto {
|
|
85
85
|
@IsInt()
|
|
86
|
-
public numberOfOptions
|
|
86
|
+
public numberOfOptions!: number;
|
|
87
87
|
|
|
88
88
|
@IsArray()
|
|
89
89
|
@IsInt({ each: true })
|
|
90
|
-
public optionWeights
|
|
90
|
+
public optionWeights!: number[];
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export class BaseGameConfigDto {
|
|
94
94
|
@ValidateNested()
|
|
95
95
|
@Type(() => LayoutDto)
|
|
96
|
-
public layout
|
|
96
|
+
public layout!: LayoutDto;
|
|
97
97
|
|
|
98
98
|
@ValidateNested()
|
|
99
99
|
@Type(() => WinConfigDto)
|
|
100
|
-
public winConfig
|
|
100
|
+
public winConfig!: WinConfigDto;
|
|
101
101
|
|
|
102
102
|
@IsInt()
|
|
103
|
-
public baseBet
|
|
103
|
+
public baseBet!: number;
|
|
104
104
|
|
|
105
105
|
@ValidateNested()
|
|
106
106
|
@Type(() => ReelsOptionsDto)
|
|
107
|
-
public reelsOptions
|
|
107
|
+
public reelsOptions!: ReelsOptionsDto;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// --- BonusGameMeter ---
|
|
111
111
|
|
|
112
112
|
export class BonusGameMeterDto {
|
|
113
113
|
@IsString()
|
|
114
|
-
public symbol
|
|
114
|
+
public symbol!: string;
|
|
115
115
|
|
|
116
116
|
@IsInt()
|
|
117
|
-
public min
|
|
117
|
+
public min!: number;
|
|
118
118
|
|
|
119
119
|
@IsInt()
|
|
120
|
-
public max
|
|
120
|
+
public max!: number;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
// --- BaseGame ---
|
|
@@ -126,58 +126,58 @@ export class BaseGameDto {
|
|
|
126
126
|
@IsArray()
|
|
127
127
|
@ValidateNested({ each: true })
|
|
128
128
|
@Type(() => SymbolMultipliersDto)
|
|
129
|
-
public symbolMultipliers
|
|
129
|
+
public symbolMultipliers!: SymbolMultipliersDto[];
|
|
130
130
|
|
|
131
131
|
@ValidateNested()
|
|
132
132
|
@Type(() => SymbolDefinitionsDto)
|
|
133
|
-
public symbolDefinitions
|
|
133
|
+
public symbolDefinitions!: SymbolDefinitionsDto;
|
|
134
134
|
|
|
135
135
|
@ValidateNested()
|
|
136
136
|
@Type(() => BaseGameConfigDto)
|
|
137
|
-
public baseGameConfig
|
|
137
|
+
public baseGameConfig!: BaseGameConfigDto;
|
|
138
138
|
|
|
139
139
|
@IsObject()
|
|
140
|
-
public paidHSymbolWeights
|
|
140
|
+
public paidHSymbolWeights!: Record<string, number>;
|
|
141
141
|
|
|
142
142
|
@IsObject()
|
|
143
|
-
public paidHSymbolReelWeights
|
|
143
|
+
public paidHSymbolReelWeights!: Record<string, [number, number]>;
|
|
144
144
|
|
|
145
145
|
@IsObject()
|
|
146
|
-
public paidScatterReelWeights
|
|
146
|
+
public paidScatterReelWeights!: Record<string, [number, number]>;
|
|
147
147
|
|
|
148
148
|
@IsObject()
|
|
149
|
-
public bonusGameMeters
|
|
149
|
+
public bonusGameMeters!: Record<string, BonusGameMeterDto>;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
// --- BonusGame Specific Config DTOs ---
|
|
153
153
|
|
|
154
154
|
export class TreasureHuntBonusConfigDto {
|
|
155
155
|
@IsInt()
|
|
156
|
-
public symbolsCount
|
|
156
|
+
public symbolsCount!: number;
|
|
157
157
|
|
|
158
158
|
@IsInt()
|
|
159
|
-
public stepsCount
|
|
159
|
+
public stepsCount!: number;
|
|
160
160
|
|
|
161
161
|
@IsObject()
|
|
162
|
-
public jackpotMultipliers
|
|
162
|
+
public jackpotMultipliers!: Record<
|
|
163
163
|
'mini' | 'minor' | 'major' | 'grand',
|
|
164
164
|
number
|
|
165
165
|
>;
|
|
166
166
|
|
|
167
167
|
@IsObject()
|
|
168
|
-
public jackpotStartCounts
|
|
168
|
+
public jackpotStartCounts!: Record<
|
|
169
169
|
'mini' | 'minor' | 'major' | 'grand',
|
|
170
170
|
number
|
|
171
171
|
>;
|
|
172
172
|
|
|
173
173
|
@IsObject()
|
|
174
|
-
public jackpotScreenCounts
|
|
174
|
+
public jackpotScreenCounts!: Record<
|
|
175
175
|
'mini' | 'minor' | 'major' | 'grand',
|
|
176
176
|
number
|
|
177
177
|
>;
|
|
178
178
|
|
|
179
179
|
@IsObject()
|
|
180
|
-
public winningWeights
|
|
180
|
+
public winningWeights!: Record<
|
|
181
181
|
'none' | 'mini' | 'minor' | 'major' | 'grand',
|
|
182
182
|
number
|
|
183
183
|
>;
|
|
@@ -187,7 +187,7 @@ export class TreasureHuntBonusConfigDto {
|
|
|
187
187
|
|
|
188
188
|
export class BonusGameEvaluationConfigDto {
|
|
189
189
|
@IsString()
|
|
190
|
-
public defaultConfig
|
|
190
|
+
public defaultConfig!: string;
|
|
191
191
|
|
|
192
192
|
@IsArray()
|
|
193
193
|
@IsString({ each: true })
|
|
@@ -203,57 +203,57 @@ export class BonusGameEvaluationConfigDto {
|
|
|
203
203
|
|
|
204
204
|
export class BaseBonusGameDto {
|
|
205
205
|
@IsString()
|
|
206
|
-
public type
|
|
206
|
+
public type!: string;
|
|
207
207
|
|
|
208
208
|
@IsString()
|
|
209
|
-
public potMeter
|
|
209
|
+
public potMeter!: string;
|
|
210
210
|
|
|
211
211
|
@ValidateNested()
|
|
212
212
|
@Type(() => BonusGameEvaluationConfigDto)
|
|
213
|
-
public evaluationConfig
|
|
213
|
+
public evaluationConfig!: BonusGameEvaluationConfigDto;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
export class TreasureHuntBonusGameDto extends BaseBonusGameDto {
|
|
217
217
|
@ValidateNested()
|
|
218
218
|
@Type(() => TreasureHuntBonusConfigDto)
|
|
219
|
-
public config
|
|
219
|
+
public config!: TreasureHuntBonusConfigDto;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
export class FreeSpinTypeDto {
|
|
223
223
|
@ValidateNested()
|
|
224
224
|
@Type(() => LayoutDto)
|
|
225
|
-
public layout
|
|
225
|
+
public layout!: LayoutDto;
|
|
226
226
|
|
|
227
227
|
@IsInt()
|
|
228
|
-
public spins
|
|
228
|
+
public spins!: number;
|
|
229
229
|
|
|
230
230
|
@IsInt()
|
|
231
|
-
public multiplier
|
|
231
|
+
public multiplier!: number;
|
|
232
232
|
|
|
233
233
|
@IsInt()
|
|
234
|
-
public weight
|
|
234
|
+
public weight!: number;
|
|
235
235
|
|
|
236
236
|
@IsArray()
|
|
237
237
|
@IsInt({ each: true })
|
|
238
|
-
public reelsOptionsWeights
|
|
238
|
+
public reelsOptionsWeights!: number[];
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
export class FreeSpinBonusConfigDto {
|
|
242
242
|
@IsArray()
|
|
243
243
|
@ValidateNested({ each: true })
|
|
244
244
|
@Type(() => FreeSpinTypeDto)
|
|
245
|
-
public spinTypes
|
|
245
|
+
public spinTypes!: FreeSpinTypeDto[];
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
export class FreeSpinBonusGameDto extends BaseBonusGameDto {
|
|
249
249
|
@ValidateNested()
|
|
250
250
|
@Type(() => FreeSpinBonusConfigDto)
|
|
251
|
-
public config
|
|
251
|
+
public config!: FreeSpinBonusConfigDto;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
export class SteeringToTheFortuneWheelResultDto {
|
|
255
255
|
@IsString()
|
|
256
|
-
public type
|
|
256
|
+
public type!: 'MULTIPLIER' | 'BONUS';
|
|
257
257
|
|
|
258
258
|
@IsOptional()
|
|
259
259
|
@IsInt()
|
|
@@ -264,20 +264,20 @@ export class SteeringToTheFortuneWheelResultDto {
|
|
|
264
264
|
public bonusType?: string;
|
|
265
265
|
|
|
266
266
|
@IsInt()
|
|
267
|
-
public weight
|
|
267
|
+
public weight!: number;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
export class SteeringToTheFortuneBonusConfigDto {
|
|
271
271
|
@IsArray()
|
|
272
272
|
@ValidateNested({ each: true })
|
|
273
273
|
@Type(() => SteeringToTheFortuneWheelResultDto)
|
|
274
|
-
public wheelResults
|
|
274
|
+
public wheelResults!: SteeringToTheFortuneWheelResultDto[];
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
export class SteeringToTheFortuneBonusGameDto extends BaseBonusGameDto {
|
|
278
278
|
@ValidateNested()
|
|
279
279
|
@Type(() => SteeringToTheFortuneBonusConfigDto)
|
|
280
|
-
public config
|
|
280
|
+
public config!: SteeringToTheFortuneBonusConfigDto;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
export class BonusGamesDto {
|
|
@@ -301,58 +301,58 @@ export class BonusGamesDto {
|
|
|
301
301
|
|
|
302
302
|
export class ScatterSymbolDto {
|
|
303
303
|
@IsString()
|
|
304
|
-
public symbolId
|
|
304
|
+
public symbolId!: string;
|
|
305
305
|
|
|
306
306
|
@IsInt()
|
|
307
|
-
public value
|
|
307
|
+
public value!: number;
|
|
308
308
|
|
|
309
309
|
@IsInt()
|
|
310
|
-
public weight
|
|
310
|
+
public weight!: number;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
// --- ScatterGameConfigDto ---
|
|
314
314
|
|
|
315
315
|
export class ScatterCheckpointDto {
|
|
316
316
|
@IsInt()
|
|
317
|
-
public spin
|
|
317
|
+
public spin!: number;
|
|
318
318
|
|
|
319
319
|
@IsInt()
|
|
320
|
-
public multiMinValue
|
|
320
|
+
public multiMinValue!: number;
|
|
321
321
|
|
|
322
322
|
@IsInt()
|
|
323
|
-
public valueMinValue
|
|
323
|
+
public valueMinValue!: number;
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
export class ScatterGameConfigDto {
|
|
327
327
|
@IsInt()
|
|
328
|
-
public scatterMinNumber
|
|
328
|
+
public scatterMinNumber!: number;
|
|
329
329
|
|
|
330
330
|
@IsInt()
|
|
331
|
-
public scatterSpins
|
|
331
|
+
public scatterSpins!: number;
|
|
332
332
|
|
|
333
333
|
@IsArray()
|
|
334
334
|
@ValidateNested({ each: true })
|
|
335
335
|
@Type(() => ScatterCheckpointDto)
|
|
336
|
-
public scatterCheckpoints
|
|
336
|
+
public scatterCheckpoints!: ScatterCheckpointDto[];
|
|
337
337
|
|
|
338
338
|
@IsArray()
|
|
339
339
|
@ValidateNested({ each: true })
|
|
340
340
|
@Type(() => ScatterSymbolDto)
|
|
341
|
-
public scatterSymbols
|
|
341
|
+
public scatterSymbols!: ScatterSymbolDto[];
|
|
342
342
|
|
|
343
343
|
@IsArray()
|
|
344
344
|
@IsObject({ each: true })
|
|
345
|
-
public scatterSymbolSpins
|
|
345
|
+
public scatterSymbolSpins!: Record<string, number>[];
|
|
346
346
|
|
|
347
347
|
@IsArray()
|
|
348
348
|
@IsObject({ each: true })
|
|
349
|
-
public scatterSymbolSlash
|
|
349
|
+
public scatterSymbolSlash!: Record<string, number>[];
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
export class ScatterGameConfigWrapperDto {
|
|
353
353
|
@ValidateNested()
|
|
354
354
|
@Type(() => ScatterGameConfigDto)
|
|
355
|
-
public config
|
|
355
|
+
public config!: ScatterGameConfigDto;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
358
|
// --- Root Config DTO ---
|
|
@@ -360,20 +360,20 @@ export class ScatterGameConfigWrapperDto {
|
|
|
360
360
|
export class BonnysFortuneGameLogicConfigDto {
|
|
361
361
|
@ValidateNested()
|
|
362
362
|
@Type(() => BaseGameDto)
|
|
363
|
-
public baseGame
|
|
363
|
+
public baseGame!: BaseGameDto;
|
|
364
364
|
|
|
365
365
|
@ValidateNested()
|
|
366
366
|
@Type(() => BonusGamesDto)
|
|
367
|
-
public bonusGames
|
|
367
|
+
public bonusGames!: BonusGamesDto;
|
|
368
368
|
|
|
369
369
|
@ValidateNested()
|
|
370
370
|
@Type(() => ScatterGameConfigWrapperDto)
|
|
371
|
-
public scatterGame
|
|
371
|
+
public scatterGame!: ScatterGameConfigWrapperDto;
|
|
372
372
|
|
|
373
373
|
@IsArray()
|
|
374
374
|
@IsNumber({}, { each: true })
|
|
375
|
-
public defaultBetAmountThresholds
|
|
375
|
+
public defaultBetAmountThresholds!: number[];
|
|
376
376
|
|
|
377
377
|
@IsNumber()
|
|
378
|
-
public defaultBetAmount
|
|
378
|
+
public defaultBetAmount!: number;
|
|
379
379
|
}
|