Skip to content

Commit 9f50aab

Browse files
authored
Add time-based loot drop weight multipliers (#568)
Resolves #485
1 parent b2ed96b commit 9f50aab

3 files changed

Lines changed: 54 additions & 2 deletions

File tree

src/service/lootData.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
137137
[LootKind.DOENER]: {
138138
id: LootKind.DOENER,
139139
weight: 5,
140+
timeBasedWeight: {
141+
evening: 10,
142+
},
140143
displayName: "Döner",
141144
titleText: "Einen Döner",
142145
dropDescription: "Bewahre ihn gut als Geldanlage auf!",
@@ -156,6 +159,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
156159
[LootKind.KRANKSCHREIBUNG]: {
157160
id: LootKind.KRANKSCHREIBUNG,
158161
weight: 0.5,
162+
timeBasedWeight: {
163+
morning: 1,
164+
},
159165
displayName: "Arbeitsunfähigkeitsbescheinigung",
160166
titleText: "Einen gelben Urlaubsschein",
161167
dropDescription: "Benutze ihn weise!",
@@ -222,6 +228,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
222228
[LootKind.AYRAN]: {
223229
id: LootKind.AYRAN,
224230
weight: 1,
231+
timeBasedWeight: {
232+
evening: 2,
233+
},
225234
displayName: "Ayran",
226235
titleText: "Einen Ayran",
227236
dropDescription: "Der gute von Müller",
@@ -242,6 +251,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
242251
[LootKind.TRICHTER]: {
243252
id: LootKind.TRICHTER,
244253
weight: 1,
254+
timeBasedWeight: {
255+
evening: 2,
256+
},
245257
displayName: "Trichter",
246258
titleText: "Einen Trichter",
247259
dropDescription: "Für die ganz großen Schlücke",
@@ -313,6 +325,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
313325
[LootKind.OETTINGER]: {
314326
id: LootKind.OETTINGER,
315327
weight: 1,
328+
timeBasedWeight: {
329+
morning: 2,
330+
},
316331
displayName: "Oettinger",
317332
titleText: "Ein warmes Oettinger",
318333
dropDescription: "Ja dann Prost ne!",
@@ -370,6 +385,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
370385
[LootKind.SAHNE]: {
371386
id: LootKind.SAHNE,
372387
weight: 1,
388+
timeBasedWeight: {
389+
evening: 2,
390+
},
373391
displayName: "Sprühsahne",
374392
titleText: "Sprühsahne",
375393
dropDescription: "Fürs Frühstück oder so",
@@ -414,6 +432,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
414432
[LootKind.GAULOISES_BLAU]: {
415433
id: LootKind.GAULOISES_BLAU,
416434
weight: 1,
435+
timeBasedWeight: {
436+
evening: 2,
437+
},
417438
displayName: "Gauloises Blau",
418439
titleText: "Eine Schachtel Gauloises Blau",
419440
dropDescription:
@@ -496,6 +517,9 @@ export const lootTemplateMap: Record<LootKindId, LootTemplate> = {
496517
[LootKind.KAFFEEMUEHLE]: {
497518
id: LootKind.KAFFEEMUEHLE,
498519
weight: 1,
520+
timeBasedWeight: {
521+
morning: 2,
522+
},
499523
displayName: "Kaffeemühle",
500524
titleText: "Eine Kaffeemühle für 400€",
501525
dropDescription: "Kann Kaffee mühlen. Und das gut. Mit Gold.",

src/service/lootDrop.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ import * as sentry from "@sentry/node";
2222

2323
import type { BotContext } from "#context.ts";
2424
import type { Loot, LootId } from "#storage/db/model.ts";
25-
import type { LootTemplate } from "#storage/loot.ts";
25+
import type { LootTemplate, TimeBasedWeightConfig } from "#storage/loot.ts";
2626
import { randomBoolean, randomEntry, randomEntryWeighted } from "#service/random.ts";
2727
import * as timeUtils from "#utils/time.ts";
28+
import { zonedNow } from "#utils/dateUtils.ts";
2829

2930
import * as lootService from "#service/loot.ts";
3031
import {
@@ -154,7 +155,12 @@ export async function postLootDrop(
154155
return;
155156
}
156157

157-
const defaultWeights = lootTemplates.map(t => t.weight);
158+
const timeBasedWeightKey = getCurrentTimeBasedKey();
159+
160+
const defaultWeights = timeBasedWeightKey
161+
? lootTemplates.map(t => t.timeBasedWeight?.[timeBasedWeightKey] ?? t.weight)
162+
: lootTemplates.map(t => t.weight);
163+
158164
const { messages, weights } = await getDropWeightAdjustments(interaction.user, defaultWeights);
159165

160166
const template = randomEntryWeighted(lootTemplates, weights);
@@ -358,6 +364,22 @@ export async function createDropTakenContent(
358364
};
359365
}
360366

367+
function getCurrentTimeBasedKey(): keyof TimeBasedWeightConfig | undefined {
368+
// Caution: using a ZonedDateTime and comparing the hour to the raw values breaks when daylight-saving-time happens (an hour can happen multiple times)
369+
// We disregard these edge-cases, but keep it in mind
370+
const hour = zonedNow().hour;
371+
372+
// :shibakek:
373+
switch (true) {
374+
case 6 <= hour && hour <= 12:
375+
return "morning";
376+
case 18 <= hour && hour <= 24:
377+
return "evening";
378+
default:
379+
return undefined;
380+
}
381+
}
382+
361383
type AdjustmentResult = {
362384
messages: string[];
363385
weights: number[];

src/storage/loot.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,15 @@ export type LootUseCommandInteraction = ChatInputCommandInteraction & {
3232
channel: GuildTextBasedChannel;
3333
};
3434

35+
export interface TimeBasedWeightConfig {
36+
morning?: number;
37+
evening?: number;
38+
}
39+
3540
export interface LootTemplate {
3641
id: LootKindId;
3742
weight: number;
43+
timeBasedWeight?: TimeBasedWeightConfig;
3844
displayName: string;
3945
titleText: string;
4046
dropDescription: string;

0 commit comments

Comments
 (0)