Skip to content

Commit ef3a06e

Browse files
authored
Zerfall von radioaktivem müll (#505)
Resolves #470
1 parent a334647 commit ef3a06e

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

src/service/cron.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { checkBirthdays } from "@/service/birthday.js";
1616
import { handleFadingMessages } from "@/service/fadingMessage.js";
1717
import { checkExpiredShifts } from "@/service/lootRoles.js";
1818
import { getTrichterUnserEmbed } from "@/service/trichterUnser.js";
19-
import { degradeItems, exposeWithRadiation } from "@/service/lootDegradation.js";
19+
import { degradeItems, exposeWithRadiation, runHalfLife } from "@/service/lootDegradation.js";
2020

2121
import * as poll from "@/commands/poll.js";
2222
import * as ehre from "@/storage/ehre.js";
@@ -47,6 +47,7 @@ export async function schedule(context: BotContext) {
4747
cron("0 20 * * FRI", () => getTrichterUnserEmbed(context));
4848
cron("0 * * * *", () => degradeItems(context));
4949
cron("26 18,19 * * *", () => exposeWithRadiation(context));
50+
cron("15 18,19 * * *", () => runHalfLife(context));
5051

5152
const loot = context.commandConfig.loot;
5253
if (loot.enabled) {

src/service/lootDegradation.ts

+70-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { type Snowflake, userMention } from "discord.js";
12
import type { BotContext } from "@/context.js";
23

34
import * as time from "@/utils/time.js";
45
import * as lootService from "@/service/loot.js";
5-
import { LootAttributeKindId, LootKindId } from "@/service/lootData.js";
6+
import { LootAttributeKindId, LootKindId, resolveLootTemplate } from "@/service/lootData.js";
67
import log from "@log";
78
import { randomEntry } from "@/service/random.js";
89

@@ -73,11 +74,78 @@ export async function exposeWithRadiation(context: BotContext) {
7374
await context.textChannels.hauptchat.send({
7475
embeds: [
7576
{
76-
description: `:radioactive: ${targetLoot.displayName} von <@${targetLoot.winnerId}> wurde verstrahlt. :radioactive:`,
77+
description: `:radioactive: ${targetLoot.displayName} von ${userMention(targetLoot.winnerId)} wurde verstrahlt. :radioactive:`,
7778
footer: {
7879
text: "Du solltest deinen Müll besser entsorgen",
7980
},
8081
},
8182
],
8283
});
8384
}
85+
86+
export async function runHalfLife(context: BotContext) {
87+
log.info("Running half life");
88+
89+
const allWaste = await lootService.getLootsByKindId(LootKindId.RADIOACTIVE_WASTE);
90+
91+
// See: https://github.com/NullDev/CSZ-Bot/issues/470
92+
// We don't do /2 straigt away, so we can roll this out more slowly initially. We can increase this to 2 once we got this number down in general
93+
// Also, consider aligning this with the drop rate of radioactive waste, so we have that balanced
94+
const targetWasteCount = Math.ceil(allWaste.length / 1.1);
95+
96+
if (targetWasteCount >= allWaste.length) {
97+
return;
98+
}
99+
100+
const wasteToRemove = allWaste.sort((a, b) => Math.random()).slice(targetWasteCount);
101+
if (wasteToRemove.length === 0) {
102+
return;
103+
}
104+
105+
const leadTemplate = resolveLootTemplate(LootKindId.BLEI);
106+
if (!leadTemplate) {
107+
log.error("Could not resolve loot template for lead.");
108+
return;
109+
}
110+
111+
const replacedStats = new Map<Snowflake, number>();
112+
113+
for (const l of wasteToRemove) {
114+
const replaced = await lootService.replaceLoot(
115+
l.id,
116+
{
117+
displayName: leadTemplate.displayName,
118+
description: leadTemplate.infoDescription ?? leadTemplate.dropDescription,
119+
lootKindId: leadTemplate.id,
120+
usedImage: leadTemplate.asset,
121+
winnerId: l.winnerId,
122+
claimedAt: l.claimedAt,
123+
guildId: l.guildId,
124+
channelId: l.channelId,
125+
messageId: l.messageId,
126+
origin: "replacement",
127+
},
128+
true,
129+
);
130+
131+
replacedStats.set(replaced.winnerId, replacedStats.getOrInsert(replaced.winnerId, 0) + 1);
132+
}
133+
134+
const listFormatter = new Intl.ListFormat("de", {
135+
style: "short",
136+
type: "conjunction",
137+
});
138+
139+
const decayStats = replacedStats
140+
.entries()
141+
.toArray()
142+
.map(([user, count]) => `${count}x von ${userMention(user)}`);
143+
144+
await context.textChannels.hauptchat.send({
145+
embeds: [
146+
{
147+
description: `:radioactive: Der Müll ${decayStats.length === 1 ? "eines Users" : "einiger User"} ist zu einem Stück Blei zerfallen: ${listFormatter.format(decayStats)}. :radioactive:`,
148+
},
149+
],
150+
});
151+
}

0 commit comments

Comments
 (0)