|
| 1 | +import { type Snowflake, userMention } from "discord.js"; |
1 | 2 | import type { BotContext } from "@/context.js";
|
2 | 3 |
|
3 | 4 | import * as time from "@/utils/time.js";
|
4 | 5 | import * as lootService from "@/service/loot.js";
|
5 |
| -import { LootAttributeKindId, LootKindId } from "@/service/lootData.js"; |
| 6 | +import { LootAttributeKindId, LootKindId, resolveLootTemplate } from "@/service/lootData.js"; |
6 | 7 | import log from "@log";
|
7 | 8 | import { randomEntry } from "@/service/random.js";
|
8 | 9 |
|
@@ -73,11 +74,78 @@ export async function exposeWithRadiation(context: BotContext) {
|
73 | 74 | await context.textChannels.hauptchat.send({
|
74 | 75 | embeds: [
|
75 | 76 | {
|
76 |
| - description: `:radioactive: ${targetLoot.displayName} von <@${targetLoot.winnerId}> wurde verstrahlt. :radioactive:`, |
| 77 | + description: `:radioactive: ${targetLoot.displayName} von ${userMention(targetLoot.winnerId)} wurde verstrahlt. :radioactive:`, |
77 | 78 | footer: {
|
78 | 79 | text: "Du solltest deinen Müll besser entsorgen",
|
79 | 80 | },
|
80 | 81 | },
|
81 | 82 | ],
|
82 | 83 | });
|
83 | 84 | }
|
| 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