Skip to content

Commit

Permalink
add: jackpot percentage parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
pirak committed Apr 20, 2021
1 parent 5f6ca84 commit 165c806
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## Unreleased
- Add: parameter to define the percentage of points that should be added to the
jackpot. Also enables disabling of the jackpot.
-

## v0.1.1
Expand Down
29 changes: 21 additions & 8 deletions src/gamble-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,26 @@ type Logger = {
export class GambleHandler {
private readonly gamblingMode: GambleMode;
private readonly minimumEntry: number;
private readonly jackpotPercent: number;
private readonly jackpotEnabled: boolean;
private readonly logger: Logger;

constructor(mode: GambleMode, logger: Logger, minimumEntry: number) {
constructor(mode: GambleMode, logger: Logger, minimumEntry: number, jackpotPercent: number) {
this.gamblingMode = mode;
this.logger = logger;
this.minimumEntry = Math.floor(minimumEntry);

if (jackpotPercent <= 0) {
this.jackpotPercent = 0;
this.jackpotEnabled = false;
} else {
this.jackpotPercent = jackpotPercent / 100;
this.jackpotEnabled = true;
}
}

handle(params: Params, entry: GambleEntry): Effect[] {
const gambleResult = this.gamblingMode.winnings(entry.userPointsEntered);
const gambleResult = this.gamblingMode.winnings(entry.userPointsEntered, this.jackpotEnabled);
this.logger.info(`${gambleResult}`);
return this.gambleResultEffects(params, entry.user, gambleResult);
}
Expand Down Expand Up @@ -55,12 +65,15 @@ export class GambleHandler {
const pointsRemove = new CurrencyEffect(params.currencyId, CurrencyAction.Remove, username, result.amount);
effects.push(pointsRemove);

const resetJackpot = new UpdateCounterEffect(
params.jackpotCounterId,
UpdateCounterEffectMode.Increment,
result.amount,
);
effects.push(resetJackpot);
const jackpotAddAmount = Math.floor(result.amount * this.jackpotPercent);
if (jackpotAddAmount > 0) {
const addToJackpot = new UpdateCounterEffect(
params.jackpotCounterId,
UpdateCounterEffectMode.Increment,
jackpotAddAmount,
);
effects.push(addToJackpot);
}

const message = GambleHandler.replaceMessagePlaceholders(params, result, params.messageLost);
effects.push(new ChatMessageEffect(message));
Expand Down
10 changes: 10 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Params {
jackpotCounterId: string;
currentJackpotAmount: string;
minimumEntry: number;
jackpotPercent: number;

messageJackpotWon: string;
messageWon: string;
Expand All @@ -38,6 +39,7 @@ export function defaultParams(): Params {
jackpotCounterId: '71dd1e86-178d-491d-8f61-9c5851faf8a8',
currentJackpotAmount: '$counter[jackpot]',
minimumEntry: 100,
jackpotPercent: 100,
userCurrentPoints: '$currency[points, $user]',

messageJackpotWon: 'Rolled %roll. $user won the jackpot of %amount points and now has a total of %newTotal.',
Expand Down Expand Up @@ -89,6 +91,13 @@ export class GamblingScript implements Firebot.CustomScript<Params> {
description: 'Minimum Entry',
secondaryDescription: 'The minimum amount of points users can gamble.',
},
jackpotPercent: {
type: 'number',
default: params.jackpotPercent,
description: 'Jackpot Percent',
secondaryDescription:
'Defines which percentage of the lost points should go into the jackpot. Should be >= 0. Values < 0 will be used as 0 and disables the jackpot. E.g. ‘50’ means that 50% of the lost points are added to the jackpot.',
},
messageJackpotWon: {
type: 'string',
default: params.messageJackpotWon,
Expand Down Expand Up @@ -139,6 +148,7 @@ export class GamblingScript implements Firebot.CustomScript<Params> {
new GambleModePercentage(),
logger,
runRequest.parameters.minimumEntry,
runRequest.parameters.jackpotPercent,
);
}

Expand Down
5 changes: 4 additions & 1 deletion src/model/gamble-mode-percentage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export class GambleModePercentage implements GambleMode {
* - Roll 0: `gamblingAmount` is lost.
*
* @param gamblingAmount the amount the user entered into the bet.
* @param jackpotEnabled unused.
*/
winnings(gamblingAmount: number): GambleResult {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
winnings(gamblingAmount: number, jackpotEnabled: boolean = true): GambleResult {
const roll = GambleModePercentage.randIntInclusive(this.maxRoll);

if (roll === this.neutralValue) {
Expand All @@ -39,6 +41,7 @@ export class GambleModePercentage implements GambleMode {
* @private
*/
private static randIntInclusive(max: number): number {
// Node crypto module for proper randomness is not available in Firebot
return Math.floor(Math.random() * (max + 1));
}
}
2 changes: 1 addition & 1 deletion src/model/gamble-mode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GambleResult } from './gamble-result';

export interface GambleMode {
winnings: (gamblingAmount: number) => GambleResult;
winnings: (gamblingAmount: number, jackpotEnabled: boolean) => GambleResult;
}
71 changes: 67 additions & 4 deletions tests/gamble-hander.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { GambleHandler } from '../src/gamble-handler';
import { GambleModePercentage } from '../src/model/gamble-mode-percentage';
import { ArgumentsOf, replaceMessageParams, mockExpectedRoll } from './helpers';
import { ArgumentsOf, mockExpectedRoll, replaceMessageParams } from './helpers';
import { ScriptModules } from 'firebot-custom-scripts-types';
import { defaultParams, Params } from '../src/main';
import { GambleResult, GambleResultType } from '../src/model/gamble-result';
import { ChatMessageEffect } from '../src/helpers/effects/chat-message-effect';
import { CurrencyEffect, CurrencyAction } from '../src/helpers/effects/currency-effect';
import { CurrencyAction, CurrencyEffect } from '../src/helpers/effects/currency-effect';
import { UpdateCounterEffect, UpdateCounterEffectMode } from '../src/helpers/effects/update-counter-effect';
import { GambleEntry } from '../src/model/gamble-entry';

Expand All @@ -16,8 +16,6 @@ const mockLogger = {
error: jest.fn<void, ArgumentsOf<ScriptModules['logger']['error']>>(),
};

const gambleHandler = new GambleHandler(new GambleModePercentage(), mockLogger, 100);

const params = defaultParams();
params.currentJackpotAmount = '1000';
params.userCurrentPoints = '10000';
Expand Down Expand Up @@ -61,6 +59,8 @@ describe('The Gambling Handler Message Replacer', () => {
});

describe('The Gambling Handler Effect Creator', () => {
const gambleHandler = new GambleHandler(new GambleModePercentage(), mockLogger, 100, 100);

const effectCreator = (params: Params, result: GambleResult) =>
// @ts-ignore
gambleHandler.gambleResultEffects(params, 'pirak__', result);
Expand Down Expand Up @@ -106,6 +106,8 @@ describe('The Gambling Handler Effect Creator', () => {
});

describe('The Gambling Handler', () => {
const gambleHandler = new GambleHandler(new GambleModePercentage(), mockLogger, 100, 100);

it('should for neutral results only create a chat message', async () => {
const entry = new GambleEntry('pirak__', 10000, 1000);
mockExpectedRoll(50);
Expand Down Expand Up @@ -148,4 +150,65 @@ describe('The Gambling Handler', () => {

expect(gambleHandler.handle(params, entry)).toEqual(expectedEffects);
});

it('should disable the jackpot for jackpotPercents <= 0', async () => {
const mode = new GambleModePercentage();
const mockFn = jest
.spyOn(mode, 'winnings')
.mockImplementation(() => new GambleResult(GambleResultType.Lost, 40, 120));

const entry = new GambleEntry('pirak__', 10000, 1000);
const gambleHandler = new GambleHandler(mode, mockLogger, 100, 0);

const expectedEffects = [
new CurrencyEffect(defaultParams().currencyId, CurrencyAction.Remove, 'pirak__', 120),
new ChatMessageEffect(replaceMessageParams(defaultParams().messageLost, 40, 120, 10000 - 120)),
];

expect(gambleHandler.handle(params, entry)).toEqual(expectedEffects);
expect(mockFn).toHaveBeenCalledWith(1000, false);

// jackpotPercent -1 should be used as 0
const gambleHandler2 = new GambleHandler(mode, mockLogger, 100, -1);
expect(gambleHandler2.handle(params, entry)).toEqual(expectedEffects);
expect(mockFn).toHaveBeenCalledWith(1000, false);
});

it('should take the jackpot percent into account for values > 0', async () => {
const mode = new GambleModePercentage();
const mockFn = jest
.spyOn(mode, 'winnings')
.mockImplementationOnce(() => new GambleResult(GambleResultType.Lost, 40, 120));

const entry = new GambleEntry('pirak__', 10000, 1000);
const gambleHandler = new GambleHandler(mode, mockLogger, 100, 50);

const expectedEffects = [
new CurrencyEffect(defaultParams().currencyId, CurrencyAction.Remove, 'pirak__', 120),
new UpdateCounterEffect(params.jackpotCounterId, UpdateCounterEffectMode.Increment, 60),
new ChatMessageEffect(replaceMessageParams(defaultParams().messageLost, 40, 120, 10000 - 120)),
];

expect(gambleHandler.handle(params, entry)).toEqual(expectedEffects);
expect(mockFn).toHaveBeenCalledWith(1000, true);
});

it('should round down the amount added to the jackpot', async () => {
const mode = new GambleModePercentage();
const mockFn = jest
.spyOn(mode, 'winnings')
.mockImplementationOnce(() => new GambleResult(GambleResultType.Lost, 40, 49));

const entry = new GambleEntry('pirak__', 10000, 1000);
const gambleHandler = new GambleHandler(mode, mockLogger, 100, 50);

const expectedEffects = [
new CurrencyEffect(defaultParams().currencyId, CurrencyAction.Remove, 'pirak__', 49),
new UpdateCounterEffect(params.jackpotCounterId, UpdateCounterEffectMode.Increment, 24),
new ChatMessageEffect(replaceMessageParams(defaultParams().messageLost, 40, 49, 10000 - 49)),
];

expect(gambleHandler.handle(params, entry)).toEqual(expectedEffects);
expect(mockFn).toHaveBeenCalledWith(1000, true);
});
});

0 comments on commit 165c806

Please sign in to comment.