Burn: Added card burning for notes and gems

This commit is contained in:
2022-09-26 16:09:23 +02:00
parent bbbcaaaf29
commit 16bb46403b
9 changed files with 183 additions and 30 deletions

62
commands/burn.js Normal file
View File

@@ -0,0 +1,62 @@
const { SlashCommandBuilder, AttachmentBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require("discord.js");
const { Card, User, Band, Character } = require("../models");
const { QUALITY_VALUES, QUALITY_NAMES, CURRENCY_SYMBOLS } = require("../config/constants");
const { UserUtils } = require("../util");
const fs = require("fs");
const edit = require("./edit");
//fetch all cards owned by the user and list them
module.exports = {
data: new SlashCommandBuilder()
.setName("burn")
.setDescription("Burn a specific card")
.addStringOption((option) =>
option
.setName("id")
.setDescription("Card identifier")
.setRequired(true)
.setAutocomplete(true)
),
async execute(interaction) {
await interaction.deferReply();
let card = await Card.findOne({
where: {
identifier: interaction.options.getString("id")
},
include: [
{ model: Character, include: [{ model: Band }] },
{ model: User}
]
});
if (card === null) {
interaction.editReply({ content: "Card not found" });
return;
}
if (card.User.discordId !== interaction.user.id) {
interaction.editReply({ content: "You do not own this card" });
return;
}
if (card.burned) {
interaction.editReply({ content: "This card is already burned" });
return;
}
const embed = new EmbedBuilder()
.setTitle(`${interaction.member.displayName} burned ${card.identifier}`)
.setDescription(`+${QUALITY_VALUES[card.quality].value} ${CURRENCY_SYMBOLS[QUALITY_VALUES[card.quality].type]}`)
.addFields(
{ name: `${card.Character.name}`, value: `${card.Character.Band.name}` },
{ name: 'Print Number', value: `${card.printNr}`, inline: true },
{ name: 'Quality', value: `${QUALITY_NAMES[card.quality]}`, inline: true }
)
.setColor(0xFF0000)
.setFooter({ text: `${card.identifier}`, iconURL: 'https://cdn.discordapp.com/attachments/856904078754971658/1017431187234508820/fp.png' })
.setTimestamp(card.createdAt);
let user = await UserUtils.getUserByDiscordId(interaction.user.id);
await user.addCurrency(QUALITY_VALUES[card.quality].value, QUALITY_VALUES[card.quality].type, `burned ${card.identifier}`);
await card.update({ burned: true });
const message = await interaction.editReply({ embeds: [embed], fetchReply: true });
}
}

View File

@@ -89,7 +89,8 @@ module.exports = {
if (group) { if (group) {
cards = await Card.findAndCountAll({ cards = await Card.findAndCountAll({
where: { where: {
userId: user.id userId: user.id,
burned: false
}, },
group: ["characterId"], group: ["characterId"],
attributes: ["characterId", [Card.sequelize.fn("COUNT", "characterId"), "count"]], attributes: ["characterId", [Card.sequelize.fn("COUNT", "characterId"), "count"]],
@@ -104,7 +105,8 @@ module.exports = {
} else { } else {
cards = await Card.findAndCountAll({ cards = await Card.findAndCountAll({
where: { where: {
userId: user.id userId: user.id,
burned: false
}, },
limit: pageSize, limit: pageSize,
offset: offset, offset: offset,

View File

@@ -51,7 +51,7 @@ module.exports = {
let slots = ['slotOne', 'slotTwo', 'slotThree', 'slotFour']; let slots = ['slotOne', 'slotTwo', 'slotThree', 'slotFour'];
let renderedCards = []; let renderedCards = [];
for (slot of slots) { for (slot of slots) {
let card = await Card.findOne({ where: { id: profile[slot] }}); let card = await Card.findOne({ where: { id: profile[slot], burned: false } });
if (card) { if (card) {
let cardImage = await Rendering.renderCard(card); let cardImage = await Rendering.renderCard(card);
renderedCards.push(cardImage); renderedCards.push(cardImage);

View File

@@ -1,6 +1,6 @@
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
const { UserUtils } = require('../util'); const { UserUtils } = require('../util');
const { QUALITY, QUALITY_NAMES } = require('../config/constants'); const { CURRENCY_SYMBOLS, QUALITY_NAMES } = require('../config/constants');
module.exports = { module.exports = {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName("stats") .setName("stats")
@@ -22,7 +22,15 @@ module.exports = {
let qualityCount = Array(6).fill(0); let qualityCount = Array(6).fill(0);
let qualities = Object.values(QUALITY_NAMES); let qualities = Object.values(QUALITY_NAMES);
let totalCards = 0;
let burnedCards = 0;
for (card of userCards.rows) { for (card of userCards.rows) {
if (card.burned) {
burnedCards++;
continue;
}
totalCards++;
qualityCount[card.quality-1]++; qualityCount[card.quality-1]++;
} }
@@ -33,7 +41,7 @@ module.exports = {
let embed = new EmbedBuilder() let embed = new EmbedBuilder()
.setTitle(`${discordUser.username}'s Stats`) .setTitle(`${discordUser.username}'s Stats`)
.addFields( .addFields(
{ name: "Cards owned", value: `${qualities.join('\n')}\n${userCards.count} total`, inline: true }, { name: "Cards owned", value: `${qualities.join('\n')}\n${totalCards} total - ${burnedCards} burned`, inline: true },
{ name: "Level", value: `${level.currentLevel}`, inline: true }, { name: "Level", value: `${level.currentLevel}`, inline: true },
{ name: "Progress", value: `${level.currentExperience} / ${level.nextLevelExperience}\n${level.remaining} XP remaining`, inline: true }, { name: "Progress", value: `${level.currentExperience} / ${level.nextLevelExperience}\n${level.remaining} XP remaining`, inline: true },
{ name: "Registered since", value: `${registrationDate}`, inline: true } { name: "Registered since", value: `${registrationDate}`, inline: true }

View File

@@ -92,7 +92,10 @@ module.exports = {
.setColor(0x00ff00) .setColor(0x00ff00)
.setFooter({ text: `${card.identifier}`, iconURL: 'https://cdn.discordapp.com/attachments/856904078754971658/1017431187234508820/fp.png' }) .setFooter({ text: `${card.identifier}`, iconURL: 'https://cdn.discordapp.com/attachments/856904078754971658/1017431187234508820/fp.png' })
.setTimestamp(card.createdAt); .setTimestamp(card.createdAt);
if (card.burned) {
embed.setColor(0xff0000);
embed.addFields({ name: "Burned", value: "This card has been burned" });
}
const message = await interaction.editReply({ embeds: [embed], files: [cardImage], fetchReply: true }); const message = await interaction.editReply({ embeds: [embed], files: [cardImage], fetchReply: true });
}, },

View File

@@ -26,7 +26,35 @@ const CURRENCY_NAMES = {
2 : "Gems" 2 : "Gems"
} }
const QUALITY_VALUES = {
1 : {
type: 1,
value: 2
},
2 : {
type: 1,
value: 5
},
3 : {
type: 1,
value: 10
},
4 : {
type: 1,
value: 15
},
5 : {
type: 1,
value: 20
},
6 : {
type: 2,
value: 2
}
}
exports.QUALITY = QUALITY; exports.QUALITY = QUALITY;
exports.QUALITY_NAMES = QUALITY_NAMES; exports.QUALITY_NAMES = QUALITY_NAMES;
exports.CURRENCY_SYMBOLS = CURRENCY_SYMBOLS; exports.CURRENCY_SYMBOLS = CURRENCY_SYMBOLS;
exports.CURRENCY_NAMES = CURRENCY_NAMES; exports.CURRENCY_NAMES = CURRENCY_NAMES;
exports.QUALITY_VALUES = QUALITY_VALUES;

View File

@@ -2,6 +2,8 @@ const { InteractionType } = require('discord.js');
const { UserUtils } = require('../util'); const { UserUtils } = require('../util');
const { Card, Character, User } = require('../models'); const { Card, Character, User } = require('../models');
const Sequelize = require('sequelize'); const Sequelize = require('sequelize');
const { QUALITY_NAMES } = require('../config/constants');
module.exports = { module.exports = {
name: "interactionCreate", name: "interactionCreate",
async execute (interaction) { async execute (interaction) {
@@ -9,30 +11,21 @@ module.exports = {
if (!isRegistered) return; if (!isRegistered) return;
if (interaction.type !== InteractionType.ApplicationCommandAutocomplete) return; if (interaction.type !== InteractionType.ApplicationCommandAutocomplete) return;
console.log(`Autocomplete request from ${interaction.user.tag} (${interaction.user.id}) for ${interaction.commandName} with ${interaction.options.getFocused(true).value}`); console.log(`Autocomplete request from ${interaction.user.tag} (${interaction.user.id}) for ${interaction.commandName} with ${interaction.options.getFocused(true).value}`);
let user = await UserUtils.getUserByDiscordId(interaction.member.id);
let focusedOption = interaction.options.getFocused(true);
let choices = [];
if (interaction.commandName === "burn") {
choices = await this.fetchCards(focusedOption, { user: user, ownedOnly: true });
}
if (interaction.commandName === 'view') { if (interaction.commandName === 'view') {
const viewType = interaction.options.getString('type'); const viewType = interaction.options.getString('type');
let focusedOption = interaction.options.getFocused(true);
let choices = [];
switch (viewType) { switch (viewType) {
case 'card': case 'card':
const cards = await Card.findAll({ choices = await this.fetchCards(focusedOption, { user: user});
where: {
identifier: {
[Sequelize.Op.like]: `%${focusedOption.value}%`
}
},
include: [{ model: Character }, { model: User }],
limit: 10
});
for (let i = 0; i < cards.length; i++) {
choices.push({
name: `${cards[i].identifier} - ${cards[i].Character.name}`,
value: cards[i].identifier
});
}
break;
case 'character': case 'character':
if(focusedOption.value.length < 3) break; if(focusedOption.value.length < 3) break;
const characters = await Character.findAll({ const characters = await Character.findAll({
@@ -53,9 +46,39 @@ module.exports = {
case 'band': case 'band':
break; break;
} }
await interaction.respond(choices);
return;
} }
if (choices.length > 0) {
console.log(choices);
await interaction.respond(choices);
}
return;
},
async fetchCards (focusedOption, options={}) {
let choices = [];
let condition = {
where: {
identifier: {
[Sequelize.Op.like]: `%${focusedOption.value}%`
},
burned: false
},
include: [{ model: Character }, { model: User }],
limit: 10
}
if (options.ownedOnly) {
condition.where.userId = { [Sequelize.Op.eq]: options.user.id };
}
const cards = await Card.findAll(condition);
for (let i = 0; i < cards.length; i++) {
let owned = "";
if (options.user) {
owned = cards[i].userId === options.user.id ? " (owned)" : "";
}
choices.push({
name: `${cards[i].identifier} - ${cards[i].Character.name} (${QUALITY_NAMES[cards[i].quality]})${owned}`,
value: cards[i].identifier
});
}
return choices;
} }
} }

View File

@@ -0,0 +1,26 @@
'use strict';
module.exports = {
async up (queryInterface, Sequelize) {
/**
* Add altering commands here.
*
* Example:
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
await queryInterface.addColumn('Cards', 'burned', {
type: Sequelize.BOOLEAN,
defaultValue: false
});
},
async down (queryInterface, Sequelize) {
/**
* Add reverting commands here.
*
* Example:
* await queryInterface.dropTable('users');
*/
await queryInterface.removeColumn('Cards', 'burned');
}
};

View File

@@ -21,6 +21,7 @@ module.exports = (sequelize, DataTypes) => {
userId: DataTypes.INTEGER, userId: DataTypes.INTEGER,
imageHash: DataTypes.STRING, imageHash: DataTypes.STRING,
enabled: { type: DataTypes.BOOLEAN, defaultValue: true }, enabled: { type: DataTypes.BOOLEAN, defaultValue: true },
burned: { type: DataTypes.BOOLEAN, defaultValue: false },
printNr: DataTypes.INTEGER, printNr: DataTypes.INTEGER,
}, { }, {
sequelize, sequelize,