Skip to content

Commit

Permalink
bug fixes and new options
Browse files Browse the repository at this point in the history
  • Loading branch information
TanvishGG committed Jan 20, 2024
1 parent c289718 commit d1acbbc
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 298 deletions.
1 change: 1 addition & 0 deletions docs/guess-the-number.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const gameOptions = {
max: 20, // Max range of the number, default: 20.
onWin: () => {console.log("win")}, // Function to execute if player wins the game.
onLose: () => {console.log('lose')}, // Function to execute if player loses the game.
onTimeUp: () => {console.log('timeup')}, // Function to execute if game times out.
title: 'Guess The Number', // Embed Title.
startDes: 'Guess the number I\'m Thinking of between 1-20 in 3 tries', // Embed Description when game starts.
retryDes: 'You Guessed {user_option}, but it\'s wrong. You have {tries} tries left! ' // Rety Message
Expand Down
1 change: 1 addition & 0 deletions docs/repeat-the-color.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const gameOptions = {
time: 30000, // timeup duration in milliseconds, default: 30000.
onWin: () => {console.log("win")}, // Function to execute if player wins the game.
onLose: () => {console.log('lose')}, // Function to execute if player loses the game.
onTimeUp: () => {console.log('timeup')}, // Function to execute if game times out.
title: 'Repeat The Color', // Embed Title.
startDes: 'Remember the following color sequence', // Embed Description when game starts and while displaying the sequence.
startDes2: 'Now repeat the sequence', // after the color sequence disappears.
Expand Down
10 changes: 10 additions & 0 deletions docs/rock-paper-scissors.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const gameOptions = {
time: 30000, // timeup duration in milliseconds, default: 30000.
onWin: () => {console.log("win")}, // Function to execute if player wins the game.
onTie: () => {console.log('lose')}, // Function to execute when game ties.
onTimeUp: () => {console.log('timeup')}, // Function to execute when game times out.
title: 'Rock Paper Scissors', // Embed Title.
startDes: 'Choose your option', // Embed Description when game starts.
winDes: null, // Embed Description when player wins the game.
Expand Down Expand Up @@ -56,6 +57,8 @@ The Texts for embed description accepts following formatting.
- **`{loser_choice}`** -> Loser's Choice.
- **tieDes**
- **`{option}`** -> Common Choice of both players.
- **timeUpDes**
- **`{timed_player}`** -> Player who took too long to respond.

## Function Parameters
`onWin` function of multiplayer executes with 2 function parameters to allow winner/loser based actions
Expand All @@ -65,6 +68,13 @@ function onWin(winner,loser) {
console.log(winner.username, "won the game against", loser.username)
}
```
`onTimeUp` function of multiplayer executes with 2 function parameters
```js
function onTimeUp(timed_player,other) {
// Both are User Objects
console.log(timed_player,"didn't respond in time")
}
```

## Starting The Game
```js
Expand Down
13 changes: 12 additions & 1 deletion docs/tic-tac-toe.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const gameOptions = {
time: 30000, // timeup duration in milliseconds, default: 30000.
onWin: () => {console.log("win")}, // Function to execute if player wins the game.
onTie: () => {console.log('lose')}, // Function to execute when game ties.
onTimeUp: () => {console.log('timeup')}, // Function to execute when game times out.
title: 'Rock Paper Scissors', // Embed Title.
startDes: 'Choose your option', // Embed Description when game starts.
opEmoji: "🟢", // Opponent Box Emoji.
Expand All @@ -37,13 +38,23 @@ The Texts for embed description accepts following formatting:
- **winDes**
- **`{winner}`** -> Game Winner.
- **`{emoji}`** -> Winner's Emoji.
- **timeUpDes**
- **`{timed_player}`** -> Player who didn't respond in time.
- **`{emoji}`** -> Emoji of that Player.

## Function Parameters
`onWin` function executes with 2 function parameters to allow winner/loser based actions
```js
function onWin(winner,loser) {
// Both are User Objects
console.log(winner.username, "won the game against", loser.username)
console.log(winner.username, "won the game against", loser.username);
}
```
`onTimeUp` function executes with 2 function parameters
```js
function onTimeUp(timed_player,other) {
// Both are User Objects
console.log(timed_user, "didn't respond in time");
}
```

Expand Down
3 changes: 2 additions & 1 deletion docs/wordle.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const gameOptions = {
time: 180000, // timeup duration in milliseconds, default: 180000.
onWin: () => {console.log("win")}, // Function to execute if player wins the game.
onLose: () => {console.log('lose')}, // Function to execute if player loses the game.
onTimeUp: () => {console.log('timeup')}, // Functuon to execute when game times out.
title: 'CoinFlip', // Embed Title.
startDes: 'Guess the 5 Letter word I\'m thinking of', // Embed Description when game starts
winDes: 'You Won!', // Embed Description when player wins the game.
Expand All @@ -30,7 +31,7 @@ const gameOptions = {
```
## Formatting
The texts for embed descriptions accepts following formatting.
- **winDes** & **loseDes**
- **winDes** & **loseDes** & **timeUpDes**
- **`{word}`** -> Actual Word.

## Starting The Game
Expand Down
2 changes: 2 additions & 0 deletions src/functions/8ball.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ async function EightBall(message,question) {
const answer = ["yes","no","absolutely","absolutely not","maybe","maybe not","probably","i don't know"][Math.floor(Math.random() * 8 + 1)]
const Embed = new discord.EmbedBuilder()
.setTitle('8ball')
.setTimestamp()
.setThumbnail(message.author ? message.author.avatarURL() : message.user.avatarURL())
.addFields({
name:"Question:",
value: question.endsWith('?') ? question : question+'?',
Expand Down
Binary file added src/functions/assets/fts.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 25 additions & 24 deletions src/functions/cf.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ const {EmbedBuilder,ButtonBuilder,ButtonStyle,ActionRowBuilder,ComponentType} =
class CoinFlip{
/**
* Initialises a new instance of CoinFlip Game.
* @param {`Message/Interaction`} message The Message object.
* @param {`Message/Interaction`} message The Message Object.
* @param {`GameOptions-Object`} gameOptions The game Options Object.
* @returns {CoinFlip} Game instance.
*/
constructor(message,gameOptions) {
if(!message) throw new Error("message is not provided");
this.message = message;
if(gameOptions && typeof gameOptions !== 'object') throw new TypeError("gameOptions must be an object");
if(gameOptions && typeof gameOptions !== 'object') throw new TypeError("gameOptions must be an Object");
this.isSlash = gameOptions?.isSlash ?? false;
if(this.isSlash == true) {
if(!(this.message instanceof discord.CommandInteraction)){
Expand All @@ -36,15 +36,15 @@ class CoinFlip{
this.onWin = gameOptions?.onWin ?? null;
this.onLose = gameOptions?.onLose ?? null;
if(typeof this.isSlash !== 'boolean') throw new TypeError('isSlash must be a Boolean');
if(this.onWin && typeof this.onWin !== 'function') throw new TypeError('onWin must be a functon');
if(this.onLose && typeof this.onLose !== 'function') throw new TypeError('onLose must be a funtion');
if(typeof this.time !== 'number') throw new TypeError('time must be a number');
if(this.onWin && typeof this.onWin !== 'function') throw new TypeError('onWin must be a Functon');
if(this.onLose && typeof this.onLose !== 'function') throw new TypeError('onLose must be a Funtion');
if(typeof this.time !== 'number') throw new TypeError('time must be a Number');
if(this.time < 5000) throw new RangeError('time must be greater than 5000');
if(this.options?.title && typeof this.options?.title !== 'string') throw new TypeError('title must be a string');
if(this.options?.startDes && typeof this.options?.startDes !== 'string') throw new TypeError('startDes must be a string');
if(this.options?.winDes && typeof this.options?.winDes !== 'string') throw new TypeError('winDes must be a string');
if(this.options?.loseDes && typeof this.options?.loseDes !== 'string') throw new TypeError('loseDes must be a string');
if(this.options?.timeUpDes && typeof this.options?.timeUpDes !== 'string') throw new TypeError('timeUpDes must be a string');
if(this.options?.title && typeof this.options?.title !== 'string') throw new TypeError('title must be a String');
if(this.options?.startDes && typeof this.options?.startDes !== 'string') throw new TypeError('startDes must be a String');
if(this.options?.winDes && typeof this.options?.winDes !== 'string') throw new TypeError('winDes must be a String');
if(this.options?.loseDes && typeof this.options?.loseDes !== 'string') throw new TypeError('loseDes must be a String');
if(this.options?.timeUpDes && typeof this.options?.timeUpDes !== 'string') throw new TypeError('timeUpDes must be a String');
}
/**
* Starts The Game.
Expand All @@ -60,41 +60,42 @@ async run() {
.setDescription(text)
.setColor(color)
.setThumbnail(game.player.avatarURL())
.setTimestamp()
.setFooter({text:`Requested by ${game.player.username}`})
return embed;
}
function randomN(min,max) {
function random(min,max) {
return Math.floor(Math.random() *(max-min+1) + min);
}
var Row = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('heads').setStyle(ButtonStyle.Secondary).setLabel('Heads'), new ButtonBuilder().setCustomId('tails').setStyle(ButtonStyle.Secondary).setLabel('Tails'))
const msg = await this.edit({embeds:[cfEm(this.options?.startDes?? 'Choose Heads or Tails','Green')],components:[Row]},this.message)
const collector = msg.createMessageComponentCollector({ componentType: ComponentType.Button, time:this.time})
var Row = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('cf_heads').setStyle(ButtonStyle.Secondary).setLabel('Heads'), new ButtonBuilder().setCustomId('cf_tails').setStyle(ButtonStyle.Secondary).setLabel('Tails'))
const msg = await this.edit({embeds:[cfEm(this.options?.startDes?? 'Choose Heads or Tails','Green')],components:[Row]},this.message)
const collector = msg.createMessageComponentCollector({ componentType: ComponentType.Button, idle:this.time})
let played = false;
const choices = ['heads','tails']
const bot = choices[randomN(0,1)]
const bot = choices[random(0,1)]
collector.on('collect', async (i) => {
i.deferUpdate()
if(i.user.id == this.player.id) {
await i.deferUpdate();
if(i.user.id == this.player.id) {
played = true;
collector.stop()
Row.components.find(x => x.data.custom_id == i.customId).setDisabled(true)
if(i.customId == bot) {
await this.edit({embeds:[cfEm(this.options?.winDes?.replace(/{bot_option}/g,bot.toUpperCase())?.replace(/{user_option}/g,i.customId.toUpperCase()) ?? `You won!, it was ${bot.toUpperCase()}`,`Yellow`)],components:[Row]},msg)
if(i.customId.replace('cf_','') == bot) {
await this.edit({embeds:[cfEm(this.options?.winDes?.replace(/{bot_option}/g,bot.toUpperCase())?.replace(/{user_option}/g,i.customId.replace('cf_','').toUpperCase()) ?? `You won!, it was ${bot.toUpperCase()}`,`Yellow`)],components:[Row]},msg)
if(this.onWin) await this.onWin();
}
else {
await this.edit({embeds:[cfEm(this.options.loseDes?.replace(/{bot_option}/g,bot.toUpperCase())?.replace(/{user_option}/g,i.customId.toUpperCase()) ?? `You Lost!, it was ${bot.toUpperCase()}`,`Red`)],components:[Row]},msg)
await this.edit({embeds:[cfEm(this.options.loseDes?.replace(/{bot_option}/g,bot.toUpperCase())?.replace(/{user_option}/g,i.customId.replace('cf_','').toUpperCase()) ?? `You Lost!, it was ${bot.toUpperCase()}`,`Red`)],components:[Row]},msg)
if(this.onLose) await this.onLose();
}
}
})
collector.on('end', async () => {
if(played == false) {
Row.components.forEach(x => x.setDisabled(true))
await this.edit({embeds:[cfEm(this.options?.timeUpDes ?? `Game Ended: Timed Out`,'Red')],components:[Row]},msg);
Row.components.forEach(x => x.setDisabled(true))
await this.edit({embeds:[cfEm(this.options?.timeUpDes ?? `Game Ended: Timed Out`,'Red')],components:[Row]},msg);
}
})
}

}
}

module.exports = CoinFlip;
1 change: 0 additions & 1 deletion src/functions/dare.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
* Fetch a random Dare.
* @returns {Promise<String>} - A promise that resolves to a random Dare.
Expand Down
63 changes: 32 additions & 31 deletions src/functions/fts.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
const discord = require('discord.js');
const file = new discord.AttachmentBuilder().setName('fts.jpg').setFile('./assets/fts.jpg')
const {EmbedBuilder,ButtonBuilder,ButtonStyle,ActionRowBuilder,ComponentType} = require('discord.js')
class FindTheStone {
/**
* Initialises a new instance of Find The Stone Game.
* @param {`Message/Interaction`} message The Message object.
* @param {`Message/Interaction`} message The Message Object.
* @param {`GameOptions-Object`} gameOptions The game Options Object.
* @returns {FindTheStone} Game instance.
*/

constructor(message,gameOptions) {
if(!message) throw new Error("message is not provided");
this.message = message;
if(gameOptions && typeof gameOptions !== 'object') throw new TypeError("gameOptions must be an object");
if(gameOptions && typeof gameOptions !== 'object') throw new TypeError("gameOptions must be an Object");
this.isSlash = gameOptions?.isSlash ?? false;
if(this.isSlash == true){
if(!(this.message instanceof discord.CommandInteraction)){
throw new TypeError("message must be an instance of command interaction")
throw new TypeError("message must be an instance of Command Interaction")
}} else {
if(!(this.message instanceof discord.Message)) {
throw new TypeError("message must be an instance of Discord message")
throw new TypeError("message must be an instance of Discord Message")
}
}
this.player = this.isSlash == true ? this.message?.user : this.message?.author;
this.time = gameOptions?.time ?? 45000;
this.replied = false;
this.randomN = (min,max) => {return Math.floor(Math.random()*max)+min;}
this.edit = async (messageOptions,replyMessage) => {
messageOptions.fetchReply = true;
messageOptions.fetchReply = true;
if(this.replied == false) {
this.replied=true;
if(this.isSlash == true) return await replyMessage.editReply(messageOptions)
Expand All @@ -36,16 +37,16 @@ class FindTheStone {
this.options = gameOptions;
this.onWin = gameOptions?.onWin ?? null;
this.onLose = gameOptions?.onLose ?? null;
if(this.onWin && typeof this.onWin !== 'function') throw new TypeError('onWin must be a functon');
if(this.onLose && typeof this.onLose !== 'function') throw new TypeError('onLose must be a funtion');
if(this.onWin && typeof this.onWin !== 'function') throw new TypeError('onWin must be a Functon');
if(this.onLose && typeof this.onLose !== 'function') throw new TypeError('onLose must be a Funtion');
if(typeof this.isSlash !== 'boolean') throw new TypeError('isSlash must be a Boolean');
if(typeof this.time !== 'number') throw new TypeError('time must be a number');
if(typeof this.time !== 'number') throw new TypeError('time must be a Number');
if(this.time < 5000) throw new RangeError('time must be greater than 5000');
if(this.options?.title && typeof this.options?.title !== 'string') throw new TypeError('title must be a string');
if(this.options?.startDes && typeof this.options?.startDes !== 'string') throw new TypeError('startDes must be a string');
if(this.options?.winDes && typeof this.options?.winDes !== 'string') throw new TypeError('winDes must be a string');
if(this.options?.loseDes && typeof this.options?.loseDes !== 'string') throw new TypeError('loseDes must be a string');
if(this.options?.timeUpDes && typeof this.options?.timeUpDes !== 'string') throw new TypeError('timeUpDes must be a string');
if(this.options?.title && typeof this.options?.title !== 'string') throw new TypeError('title must be a String');
if(this.options?.startDes && typeof this.options?.startDes !== 'string') throw new TypeError('startDes must be a String');
if(this.options?.winDes && typeof this.options?.winDes !== 'string') throw new TypeError('winDes must be a String');
if(this.options?.loseDes && typeof this.options?.loseDes !== 'string') throw new TypeError('loseDes must be a String');
if(this.options?.timeUpDes && typeof this.options?.timeUpDes !== 'string') throw new TypeError('timeUpDes must be a String');

}
/**
Expand All @@ -55,49 +56,49 @@ async run() {
if(this.isSlash == true) {
await this.message.deferReply().catch(() => {});
}
const game = this;
function ftsEm(text,color) {
const embed = new EmbedBuilder()
.setTitle(this.options?.title ??"Find The Stone")
.setImage('https://tanvish.me/assets/images/cups_temp.jpg')
.setTitle(game.options?.title ??"Find The Stone")
.setImage('attachment://fts.jpg')
.setDescription(text)
.setColor(color)
.setTimestamp()
.setThumbnail(game.player.avatarURL())
.setFooter({text:`Requested by ${game.player.username}`})
return embed;
}
function randomN(min,max) {
function random(min,max) {
return Math.floor(Math.random() *(max-min+1) + min);
}
const choices = ['yellow','red','blue']
var Row = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('yellow').setStyle(ButtonStyle.Secondary).setEmoji('🟡'),new ButtonBuilder().setCustomId('red').setStyle(ButtonStyle.Secondary).setEmoji('🔴'),new ButtonBuilder().setCustomId('blue').setEmoji('🔵').setStyle(ButtonStyle.Secondary))
const bot = choices[randomN(0,2)]
const msg = await this.edit({embeds:[ftsEm(this.options?.startDes ?? 'Find the cup which has a stone under it!','Green')],components:[Row]},this.message)
var Row = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('fts_yellow').setStyle(ButtonStyle.Secondary).setEmoji('🟡'),new ButtonBuilder().setCustomId('fts_red').setStyle(ButtonStyle.Secondary).setEmoji('🔴'),new ButtonBuilder().setCustomId('fts_blue').setEmoji('🔵').setStyle(ButtonStyle.Secondary))
const bot = choices[random(0,2)]
const msg = await this.edit({files:[file],embeds:[ftsEm(this.options?.startDes ?? 'Find the Cup which has a Stone under it!','Green')],components:[Row]},this.message)
let played = false;
const collector = msg.createMessageComponentCollector({ componentType: ComponentType.Button,time:15000})
const collector = msg.createMessageComponentCollector({ componentType: ComponentType.Button,idle:this.time})
collector.on('collect', async (i) => {
i.deferUpdate()
await i.deferUpdate()
if(i.user.id == this.player.id) {
played = true;
collector.stop()
Row.components.find(x => x.data.custom_id == i.customId).setDisabled(true)
if(i.customId == bot) {
await this.edit({embeds:[ftsEm(this.options?.winDes?.replace(/{user_option}/g,i.customId.toUpperCase())?.replace(/{bot_option}/g,bot.toUpperCase()) ?? `You Won!, it was ${bot.toUpperCase()} Cup`,'Yellow')],components:[Row]},msg)
if(i.customId.replace('fts_','') == bot) {
await this.edit({files:[file],embeds:[ftsEm(this.options?.winDes?.replace(/{user_option}/g,i.customId.replace('fts_','').toUpperCase())?.replace(/{bot_option}/g,bot.toUpperCase()) ?? `You Won!, it was ${bot.toUpperCase()} Cup`,'Yellow')],components:[Row]},msg)
if(this.onWin) await this.onWin();
}
else {
await this.edit({embeds:[ftsEm(this.options?.loseDes?.replace(/{user_option}/g,i.customId.toUpperCase())?.replace(/{bot_option}/g,bot.toUpperCase()) ?? `You Lost!, it was ${bot.toUpperCase()} Cup`,'Red')],components:[Row]},msg)
await this.edit({files:[file],embeds:[ftsEm(this.options?.loseDes?.replace(/{user_option}/g,i.customId.replace('fts_','').toUpperCase())?.replace(/{bot_option}/g,bot.toUpperCase()) ?? `You Lost!, it was ${bot.toUpperCase()} Cup`,'Red')],components:[Row]},msg)
if(this.onLose) await this.onLose();
}
}
})
collector.on('end', async () => {
if(played == false) {
Row.components.forEach(x => x.setDisabled(true))
await this.edit({embeds:[ftsEm(this.options?.timeUpDes ?? 'Game Ended: Timed Out','Red')],components:[Row]},msg)
Row.components.forEach(x => x.setDisabled(true))
await this.edit({files:[file],embeds:[ftsEm(this.options?.timeUpDes ?? 'Game Ended: Timed Out','Red')],components:[Row]},msg)
}
})

}


}
}}

module.exports = FindTheStone;
Loading

0 comments on commit d1acbbc

Please sign in to comment.