xyter/src/commands/credits/subcommands/work/index.ts
Vermium Sifell a816129dd2 feat: ♻️ centralized error classes
I have cleaned up some code by moving some regular used throw new messages to a error class file
2023-10-01 16:10:58 +02:00

128 lines
4.5 KiB
TypeScript

import Chance from "chance";
import { addHours } from "date-fns";
import {
ChatInputCommandInteraction,
EmbedBuilder,
SlashCommandSubcommandBuilder,
} from "discord.js";
import CooldownManager from "../../../../handlers/CooldownManager";
import CreditsManager from "../../../../handlers/CreditsManager";
import prisma from "../../../../handlers/prisma";
import generateCooldownName from "../../../../helpers/generateCooldownName";
import deferReply from "../../../../utils/deferReply";
import { GuildNotFoundError } from "../../../../utils/errors";
import sendResponse from "../../../../utils/sendResponse";
import jobs from "./jobs";
const cooldownManager = new CooldownManager();
const creditsManager = new CreditsManager();
export const builder = (command: SlashCommandSubcommandBuilder) => {
return command
.setName("work")
.setDescription("Put in the hustle and earn some credits!");
};
const fallbackEmoji = "💼"; // Fallback work emoji
export const execute = async (interaction: ChatInputCommandInteraction) => {
const { guild, user } = interaction;
await deferReply(interaction, false);
if (!guild) throw new GuildNotFoundError();
const chance = new Chance();
const getRandomWork = () => {
return chance.pickone(jobs);
};
// Retrieve settings from the GuildSettings model
const guildCreditsSettings = await prisma.guildCreditsSettings.findUnique({
where: { id: guild.id },
});
const baseCreditsRate = getRandomWork().creditsRate; // Get the base rate of credits earned per work action
const bonusChance = guildCreditsSettings?.workBonusChance || 30; // Retrieve bonus chance from guild settings or use default value
const penaltyChance = guildCreditsSettings?.workPenaltyChance || 10; // Retrieve penalty chance from guild settings or use default value
const baseCreditsEarned = chance.integer({ min: 1, max: baseCreditsRate }); // Generate a random base number of credits earned
let bonusCredits = 0; // Initialize bonus credits
let penaltyCredits = 0; // Initialize penalty credits
let creditsEarned = baseCreditsEarned; // Set the initial earned credits to the base amount
let work;
if (chance.bool({ likelihood: bonusChance })) {
// Earn bonus credits
const bonusMultiplier = chance.floating({ min: 1.1, max: 1.5 }); // Get a random multiplier for the bonus credits
bonusCredits = Math.ceil(baseCreditsEarned * bonusMultiplier); // Calculate the bonus credits
creditsEarned = baseCreditsEarned + bonusCredits; // Update the total earned credits
work = getRandomWork(); // Get a random work type
} else if (chance.bool({ likelihood: penaltyChance })) {
// Receive a penalty
const penaltyMultiplier = chance.floating({ min: 0.5, max: 0.8 }); // Get a random multiplier for the penalty credits
penaltyCredits = Math.ceil(baseCreditsEarned * penaltyMultiplier); // Calculate the penalty credits
creditsEarned = baseCreditsEarned - penaltyCredits; // Update the total earned credits
work = getRandomWork(); // Get a random work type
} else {
// Earn base credits
work = getRandomWork(); // Get a random work type
}
// Descriptions
const descriptions = [];
// Work Description
descriptions.push(
`Mission complete! You've earned **${baseCreditsEarned} credits**! 🎉`
);
// Bonus Description
if (bonusCredits > 0) {
descriptions.push(`💰 Bonus: **${bonusCredits} credits**!`);
}
// Penalty Description
if (penaltyCredits !== 0) {
descriptions.push(`😱 Penalty: **${penaltyCredits} credits** deducted.`);
}
// Total Credits Description
descriptions.push(
`Total earnings: **${creditsEarned} credits**. Keep up the hustle!`
);
if (creditsEarned > 0) {
await creditsManager.give(guild, user, creditsEarned); // Give the user the earned credits
}
// User Balance
const userBalance = await creditsManager.balance(guild, user);
const embedSuccess = new EmbedBuilder()
.setColor(process.env.EMBED_COLOR_SUCCESS)
.setAuthor({
name: `${user.username}'s Work Result`,
iconURL: user.displayAvatarURL(),
})
.setTimestamp()
.setDescription(descriptions.join("\n"))
.setFooter({
text: `${user.username} just worked as a ${work.name}! ${
work?.emoji || fallbackEmoji
}`,
})
.addFields({
name: "New Balance",
value: `${userBalance.balance} credits`,
});
await sendResponse(interaction, { embeds: [embedSuccess] });
await cooldownManager.setCooldown(
await generateCooldownName(interaction),
guild,
user,
addHours(new Date(), 1)
);
};