-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loot Probability Command #483
Closed
Closed
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
05f32d5
Add loot command with probability rate
twobiers 559cbc1
Remove unused imports
twobiers 84da696
One does not need to multiply by 100 when using percent format
twobiers 5a2fb88
filter out undroppable loot
twobiers 5d346df
fix sorting
twobiers 8176c1d
sort desc
twobiers 0d5aff5
fetch personalized loot weights
twobiers 8092cb1
rename function to make its purpose clear
twobiers 494ad53
another rename
twobiers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { | ||
type ChatInputCommandInteraction, | ||
type CommandInteraction, | ||
SlashCommandBuilder, | ||
SlashCommandSubcommandBuilder, | ||
} from "discord.js"; | ||
|
||
import type { BotContext } from "@/context.js"; | ||
import type { ApplicationCommand } from "@/commands/command.js"; | ||
import { ensureChatInputCommand } from "@/utils/interactionUtils.js"; | ||
|
||
import * as lootDataService from "@/service/lootData.js"; | ||
import { adjustLootWithWeightEffectsFromUser } from "@/service/lootDrop.js"; | ||
|
||
export default class LootCommand implements ApplicationCommand { | ||
name = "loot"; | ||
description = "Geht's um Loot?"; | ||
|
||
applicationCommand = new SlashCommandBuilder() | ||
.setName(this.name) | ||
.setDescription(this.description) | ||
.addSubcommand( | ||
new SlashCommandSubcommandBuilder() | ||
.setName("wahrscheinlichkeiten") | ||
.setDescription("Zeige die Wahrscheinlichkeiten für Loot Gegenstände an"), | ||
); | ||
|
||
async handleInteraction(interaction: CommandInteraction, context: BotContext) { | ||
const command = ensureChatInputCommand(interaction); | ||
const subCommand = command.options.getSubcommand(); | ||
switch (subCommand) { | ||
case "wahrscheinlichkeiten": | ||
await this.#showLootProbability(interaction, context); | ||
break; | ||
default: | ||
throw new Error(`Unknown subcommand: "${subCommand}"`); | ||
} | ||
} | ||
|
||
async #showLootProbability(interaction: CommandInteraction, context: BotContext) { | ||
if (!interaction.isChatInputCommand()) { | ||
throw new Error("Interaction is not a chat input command"); | ||
} | ||
if (!interaction.guild || !interaction.channel) { | ||
return; | ||
} | ||
|
||
// TODO: Lowperformer solution. A diagram with graphviz or something would be cooler | ||
const loot = ( | ||
await adjustLootWithWeightEffectsFromUser( | ||
interaction.user, | ||
lootDataService.lootTemplates, | ||
) | ||
).loot.filter(l => l.weight > 0); | ||
const totalWeight = loot.reduce((acc, curr) => acc + curr.weight, 0); | ||
const lootWithProbabilitiy = loot | ||
.map(l => ({ | ||
...l, // Oh no, please optimize for webscale. No need to copy the whole data :cry: | ||
probability: Number(l.weight / totalWeight), | ||
})) | ||
.sort((a, b) => b.probability - a.probability); | ||
|
||
const textRepresentation = lootWithProbabilitiy | ||
.map( | ||
l => | ||
`${l.displayName}: ${l.probability.toLocaleString(undefined, { style: "percent", maximumFractionDigits: 2 })}`, | ||
) | ||
.join("\n"); | ||
|
||
await interaction.reply( | ||
`Deine persönlichen Loot Wahrscheinlichkeiten:\n\n${textRepresentation}`, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
import * as fs from "node:fs/promises"; | ||
|
||
import { | ||
ActionRowBuilder, | ||
ButtonBuilder, | ||
ButtonStyle, | ||
ChannelType, | ||
|
@@ -28,6 +27,7 @@ import { | |
} from "@/service/lootData.js"; | ||
|
||
import log from "@log"; | ||
import type { LootTemplate } from "@/storage/loot.js"; | ||
|
||
const lootTimeoutMs = 60 * 1000; | ||
|
||
|
@@ -152,13 +152,18 @@ export async function postLootDrop( | |
return; | ||
} | ||
|
||
const defaultWeights = lootTemplates.map(t => t.weight); | ||
const { messages, weights } = await getDropWeightAdjustments(interaction.user, defaultWeights); | ||
const { messages, loot } = await adjustLootWithWeightEffectsFromUser( | ||
interaction.user, | ||
lootTemplates, | ||
); | ||
|
||
const rarityWeights = lootAttributeTemplates.map(a => a.initialDropWeight ?? 0); | ||
const initialAttribute = randomEntryWeighted(lootAttributeTemplates, rarityWeights); | ||
|
||
const template = randomEntryWeighted(lootTemplates, weights); | ||
const template = randomEntryWeighted( | ||
lootTemplates, | ||
loot.map(l => l.weight), | ||
); | ||
const claimedLoot = await lootService.createLoot( | ||
template, | ||
interaction.user, | ||
|
@@ -228,12 +233,12 @@ export async function postLootDrop( | |
|
||
type AdjustmentResult = { | ||
messages: string[]; | ||
weights: number[]; | ||
loot: LootTemplate[]; | ||
}; | ||
|
||
async function getDropWeightAdjustments( | ||
export async function adjustLootWithWeightEffectsFromUser( | ||
user: User, | ||
weights: readonly number[], | ||
loot: readonly LootTemplate[], | ||
): Promise<AdjustmentResult> { | ||
const waste = await lootService.getUserLootCountById(user.id, LootKindId.RADIOACTIVE_WASTE); | ||
const messages = []; | ||
|
@@ -254,13 +259,19 @@ async function getDropWeightAdjustments( | |
messages.push("Da du privat versichert bist, hast du die doppelte Chance auf eine AU."); | ||
} | ||
|
||
const newWeights = [...weights]; | ||
newWeights[LootKindId.NICHTS] = Math.ceil(weights[LootKindId.NICHTS] * wasteFactor) | 0; | ||
newWeights[LootKindId.KRANKSCHREIBUNG] = (weights[LootKindId.KRANKSCHREIBUNG] * pkvFactor) | 0; | ||
const weights = loot.map(t => t.weight); | ||
const newLoot = [...loot]; | ||
const updateEntry = (id: LootKindId, newValue: number) => { | ||
const idx = newLoot.findIndex(l => l.id === id); | ||
console.assert(idx !== -1); | ||
newLoot[idx].weight = newValue; | ||
}; | ||
updateEntry(LootKindId.NICHTS, Math.ceil(weights[LootKindId.NICHTS] * wasteFactor) | 0); | ||
updateEntry(LootKindId.KRANKSCHREIBUNG, (weights[LootKindId.KRANKSCHREIBUNG] * pkvFactor) | 0); | ||
|
||
return { | ||
messages, | ||
weights: newWeights, | ||
loot: newLoot, | ||
Comment on lines
-263
to
+274
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Früher war das so und es hatte irgendeinen Grund, warum ich das umgebaut habe. Kann dir nicht genau sagen, welchen |
||
}; | ||
} | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mach mal ephemeral.