diff --git a/src/cbclient.ts b/src/cbclient.ts index 7247c65..a41d16d 100644 --- a/src/cbclient.ts +++ b/src/cbclient.ts @@ -1,4 +1,4 @@ -import { ClientOptions, Collection, EmbedBuilder, Message, Snowflake } from "discord.js"; +import { ClientOptions, Collection, EmbedBuilder, GuildMember, Message, Snowflake, User } from "discord.js"; import Elo from "arpad"; import { Sequelize } from "sequelize"; import { Battle, BattleState } from "./battle"; @@ -25,15 +25,19 @@ export class Challenge { } export class Trade { - constructor (player1: Player, player2: Player, message: Message) { - this.player1 = player1; - this.player2 = player2; + constructor (origin: User, tradeguy: User, unit1: Unit, unit2: Unit, message: Message) { + this.origin = origin; + this.tradeguy = tradeguy; + this.unit1 = unit1; + this.unit2 = unit2; this.message = message - this.id = player1.user_id + player2.user_id; + this.id = 't' + unit1.user_id + unit2.user_id; } - player1: Player - player2: Player + origin: User + tradeguy: User + unit1: Unit + unit2: Unit message: Message id: string created = Date.now() @@ -122,74 +126,115 @@ export class CBClient extends CommandClient { this.on('interactionCreate', async (int) => { if (!int.isButton() || !int.channel || int.channel.isDMBased()) return; - const defaultUnit = await Unit.findOne({ where: { id: 0 } }) as Unit; - - const challenge = this.CHALLENGES.get(int.customId); - if (!challenge || challenge.created+60_000 < Date.now()) { - int.reply({ - content: "That challenge has expired!", - ephemeral: true - }); - return; - } - - if (int.user.id != challenge.player2.user_id) { - int.reply({ - content: "You can't accept someone else's challenge!", - ephemeral: true - }); - return; - } - - if (this.ACTIVE_BATTLES.find(e => { - return [challenge.player1.user_id, challenge.player2.user_id].includes(e.battle.player1.user_id) - || [challenge.player1.user_id, challenge.player2.user_id].includes(e.battle.player2.user_id); - })) { - int.reply({ - content: "A participant is already in a battle!", - ephemeral: true - }); - return; - } - - await challenge.message.delete(); - this.CHALLENGES.delete(challenge.id); - - const team1: [Unit, Unit, Unit] = [ - await Unit.findOne({ where: { id: challenge.player1.slot1 || -1 } }) || defaultUnit, - await Unit.findOne({ where: { id: challenge.player1.slot2 || -1 } }) || defaultUnit, - await Unit.findOne({ where: { id: challenge.player1.slot3 || -1 } }) || defaultUnit - ] - const team2: [Unit, Unit, Unit] = [ - await Unit.findOne({ where: { id: challenge.player2.slot1 || -1 } }) || defaultUnit, - await Unit.findOne({ where: { id: challenge.player2.slot2 || -1 } }) || defaultUnit, - await Unit.findOne({ where: { id: challenge.player2.slot3 || -1 } }) || defaultUnit - ] - - if (challenge.message.channel.isDMBased()) return; - const player1 = challenge.message.channel.guild.members.resolve(challenge.player1.user_id); - const player2 = challenge.message.channel.guild.members.resolve(challenge.player2.user_id); - - const battle = new Battle(this, int.channel, challenge.player1, challenge.player2, team1, team2); - const activeBattle = new ActiveBattle(battle, - await int.channel.send({ - embeds: [ - new EmbedBuilder() - .addFields([ - { name: player1?.user.username || '████████', value: `${battle.team1[0].character.name} [${battle.team1[0].health}]\n${battle.team1[1].character.name} [${battle.team1[1].health}]\n${battle.team1[2].character.name} [${battle.team1[2].health}]`, inline: true }, - { name: player2?.user.username || '████████', value: `${battle.team2[0].character.name} [${battle.team2[0].health}]\n${battle.team2[1].character.name} [${battle.team2[1].health}]\n${battle.team2[2].character.name} [${battle.team2[2].health}]`, inline: true }, - { name: 'Log', value: 'Starting...' } - ]) - .setColor(0x8c110b) - .setThumbnail('https://i.imgur.com/sMrWQWO.png') - ] + if (int.customId.startsWith('t')){ + const trade = this.TRADES.get(int.customId); + if (!trade || trade.created+60_000 < Date.now()) { + int.reply({ + content: "That trade has expired!", + ephemeral: true + }); + return; } - )); - this.ACTIVE_BATTLES.push(activeBattle); + + if (int.user.id != trade.tradeguy.id) { + int.reply({ + content: "You can't accept someone else's trade!", + ephemeral: true + }); + return; + } + + const player1 = await Player.findOne({ where: { user_id: trade.unit1.user_id } }); + const player2 = await Player.findOne({ where: { user_id: trade.unit2.user_id } }); + + if (!player1 || !player2) return; + + if (player1.slot1 === trade.unit1.id) player1.set({slot1:null}); + if (player1.slot2 === trade.unit1.id) player1.set({slot2:null}); + if (player1.slot3 === trade.unit1.id) player1.set({slot3:null}); + if (player2.slot1 === trade.unit2.id) player2.set({slot1:null}); + if (player2.slot2 === trade.unit2.id) player2.set({slot2:null}); + if (player2.slot3 === trade.unit2.id) player2.set({slot3:null}); + + await trade.unit1.update({ user_id: trade.tradeguy.id }); + await trade.unit2.update({ user_id: trade.origin.id }); + await player1.save(); + await player2.save(); + + int.reply('Trade accepted!'); + return; + } + else { + const defaultUnit = await Unit.findOne({ where: { id: 0 } }) as Unit; + + const challenge = this.CHALLENGES.get(int.customId); + if (!challenge || challenge.created+60_000 < Date.now()) { + int.reply({ + content: "That challenge has expired!", + ephemeral: true + }); + return; + } + + if (int.user.id != challenge.player2.user_id) { + int.reply({ + content: "You can't accept someone else's challenge!", + ephemeral: true + }); + return; + } + + if (this.ACTIVE_BATTLES.find(e => { + return [challenge.player1.user_id, challenge.player2.user_id].includes(e.battle.player1.user_id) + || [challenge.player1.user_id, challenge.player2.user_id].includes(e.battle.player2.user_id); + })) { + int.reply({ + content: "A participant is already in a battle!", + ephemeral: true + }); + return; + } + + await challenge.message.delete(); + this.CHALLENGES.delete(challenge.id); + + const team1: [Unit, Unit, Unit] = [ + await Unit.findOne({ where: { id: challenge.player1.slot1 || -1 } }) || defaultUnit, + await Unit.findOne({ where: { id: challenge.player1.slot2 || -1 } }) || defaultUnit, + await Unit.findOne({ where: { id: challenge.player1.slot3 || -1 } }) || defaultUnit + ] + const team2: [Unit, Unit, Unit] = [ + await Unit.findOne({ where: { id: challenge.player2.slot1 || -1 } }) || defaultUnit, + await Unit.findOne({ where: { id: challenge.player2.slot2 || -1 } }) || defaultUnit, + await Unit.findOne({ where: { id: challenge.player2.slot3 || -1 } }) || defaultUnit + ] + + if (challenge.message.channel.isDMBased()) return; + const player1 = challenge.message.channel.guild.members.resolve(challenge.player1.user_id); + const player2 = challenge.message.channel.guild.members.resolve(challenge.player2.user_id); + + const battle = new Battle(this, int.channel, challenge.player1, challenge.player2, team1, team2); + const activeBattle = new ActiveBattle(battle, + await int.channel.send({ + embeds: [ + new EmbedBuilder() + .addFields([ + { name: player1?.user.username || '████████', value: `${battle.team1[0].character.name} [${battle.team1[0].health}]\n${battle.team1[1].character.name} [${battle.team1[1].health}]\n${battle.team1[2].character.name} [${battle.team1[2].health}]`, inline: true }, + { name: player2?.user.username || '████████', value: `${battle.team2[0].character.name} [${battle.team2[0].health}]\n${battle.team2[1].character.name} [${battle.team2[1].health}]\n${battle.team2[2].character.name} [${battle.team2[2].health}]`, inline: true }, + { name: 'Log', value: 'Starting...' } + ]) + .setColor(0x8c110b) + .setThumbnail('https://i.imgur.com/sMrWQWO.png') + ] + } + )); + this.ACTIVE_BATTLES.push(activeBattle); + } }); } readonly CHALLENGES: Collection = new Collection() + readonly TRADES: Collection = new Collection() readonly ACTIVE_BATTLES: ActiveBattle[] = [] static async createPlayer(user_id: Snowflake) { diff --git a/src/commands/deployslash.ts b/src/commands/deployslash.ts index e43b541..17999bd 100644 --- a/src/commands/deployslash.ts +++ b/src/commands/deployslash.ts @@ -15,7 +15,7 @@ export class DeploySlashCommand implements Command{ async execute(msg: Message) { const client = msg.client as CommandClient; - await client.application!.commands.set([]); + //await client.application!.commands.set([]); client.slashCommands.forEach(async (command) => { console.log(command); diff --git a/src/slash/trade.ts b/src/slash/trade.ts new file mode 100644 index 0000000..bb36f05 --- /dev/null +++ b/src/slash/trade.ts @@ -0,0 +1,72 @@ +import { ActionRowBuilder, ApplicationCommandOptionData, ApplicationCommandOptionType, ButtonBuilder, ButtonStyle, CommandInteraction, PermissionFlagsBits } from "discord.js" +import { CBClient, Trade } from "../cbclient" +import { CHARACTERS } from "../characters" +import { Unit } from "../models/unit" +import { SlashCommand, createArgumentsObject } from "./slash" + +interface TradeArguments { + your_character: number + their_character: number +} + +export class TradeCommand implements SlashCommand { + name = 'trade' + description = 'Trade a character with someone' + permission = [PermissionFlagsBits.Administrator] + ownerOnly = false + guildOnly = true + //guildID = "739645806100873328" //for testing + args: ApplicationCommandOptionData[] = [ + { + name: 'your_character', + type: ApplicationCommandOptionType.Integer, + description: "The character you want to give", + required: true + }, + { + name: 'their_character', + type: ApplicationCommandOptionType.Integer, + description: "The character you want to get", + required: true + } + ] + + async execute(int: CommandInteraction) { + const args = createArgumentsObject(int.options.data); + const client = int.client as CBClient; + + const unit1 = await Unit.findOne( { where: { user_id: int.user.id, id: args.your_character } } ); + const unit2 = await Unit.findOne( { where: { id: args.their_character } } ); + + if (!unit1) return int.reply({ + content: `You don't own that unit!`, + ephemeral: true + }); + if (!unit2) return int.reply({ + content: `You can't trade for a unit that doesn't exist!`, + ephemeral: true + }); + + const tradeguy = int.guild!.members.resolve(unit2.user_id); + if (!tradeguy) return int.reply({ + content: `Either something went wrong or you're trading with a ghost (something went wrong)`, + ephemeral: true + }); + + const character1 = CHARACTERS.get(unit1.character_id)!; + const character2 = CHARACTERS.get(unit2.character_id)!; + + const trade = new Trade(int.user, tradeguy.user, unit1, unit2, await int.reply({ + content: `${tradeguy}, ${int.user} wants to trade ${character1.name} for your ${character2.name}!\n**THIS IS A TRADE PLEASE DON'T MINDLESSLY CLICK THE BUTTON**`, + fetchReply: true, + components: [new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('t'+int.user.id+tradeguy.user.id) + .setLabel('Yes, accept trade!') + .setStyle(ButtonStyle.Primary) + )] + })); + return client.TRADES.set(trade.id, trade); + } +};