So I was trying to make a fishing command without a handler, and I ran across a problem- Even if I buy fishing rod from shop, it says I don't have a fishing rod. Here is the code-
client.on("message", async message => {
if(message.content === "$fish") {
const cooldown = db.get(`fishCheck_${message.author.id}`)
const timeout = 900000;
if (cooldown !== null && timeout - (Date.now() - cooldown) > 0) {
const ms = require('pretty-ms')
const timeLeft = ms(timeout - (Date.now() - cooldown))
let manga = new Discord.MessageEmbed()
.setTitle("You cant fish right now")
.setColor("RED")
.setDescription(`You fished just some time ago and need to wait ${timeLeft} for fishing again.`)
.setTimestamp()
message.reply({embeds : [manga]})
} else {
const itemlol = await db.get(`items_fishingrod_${message.author.id}`)
if (itemlol > 0) {
let percenthandle = Math.floor(Math.random() * 100) + 1
if (percenthandle < 101 && percenthandle > 49) {
let fishdom = Math.floor(Math.random() * 10000) + 1000
let balance = db.get(`wallet_${message.author.id}`)
let money = balance + fishdom
db.set(`wallet_${message.author.id}`, money) ;
message.reply(`You went fishing, and were only able to catch very less fish, which you sold and got ${fishdom}`)
}
if (percenthandle < 50 && percenthandle > 5) {
let fishdom = Math.floor(Math.random() * 100000) + 10000
let balance = db.get(`wallet_${message.author.id}`)
let money = balance + fishdom
db.set(`wallet_${message.author.id}`, money) ;
message.reply(`You went fishing, and caught a decent amount of fish, which you sold and got ${fishdom}`)
}
if (percenthandle < 6 && percenthandle > 0) {
let fishdom = Math.floor(Math.random() * 1000000) + 100000
let balance = db.get(`wallet_${message.author.id}`)
let money = balance + fishdom
db.set(`wallet_${message.author.id}`, money) ;
message.reply(`You went fishing, and caught a whole ARMY of fish, which you sold and got ${fishdom}`)
}
db.set(`fishCheck_${message.author.id}`, Date.now())
} else {
let fishEmbedError = new Discord.MessageEmbed()
.setTitle("Item not found")
.setDescription("You do not have a fishing rod to fish! Buy one from the shop and try this command again")
.setColor("RED")
.setFooter("I wanna fish with hand xd")
message.channel.send({embeds :[fishEmbedError]})
}
}
}
})
Can anyone tell where I went wrong?
Dang this code is messy LOL, but shouldn't you check if user has a fishing rod at the start? also I'd suggest using try catch since It's easier to read and It doesn't brick your bot. For example you could do something like:
try{
//code here..
}catch(err){
console.log(err)
}
It also gives you more details about your error, I feel like there's something wrong with your IF & ELSE statements but I just can't see it yet
Related
I'm currently making a Discord bot using JavaScript, the bot features many commands, but I just came across this flaw, the flaw concerns the Math.Random() object, except it sometimes returns negative numbers, does anyone have a solution to this using one of the methods?
Here's the code::
let db = require(`quick.db`)
module.exports = {
name: "rob",
description: "Rob your friends to get money",
category: "economy",
usage: "rob [member]",
timeout: "1 minute",
run: async (client, message, args) => {
let victim = message.mentions.members.first()
if(!victim) {
return message.channel.send(`:x: Please specify a member to rob!`)
}
let victimW = await db.get(`wallet_${victim.id}`)
if(victimW === null) {
message.channel.send(`:x: That user doesn't have money in his wallet, are you sure you want to rob him?`)
}
let random = Math.floor(Math.random() * 100);
if(random < 30) {
let victimWallet = await db.get(`wallet_${victim.id}`)
let userWallet = await db.get(`wallet_${message.author.id}`)
let amount = Math.floor(Math.random() * victimWallet);
const messages = [`POG! You robbed **${victim.username}** and got **${amount}** :coin:!`, `oo seems like you robbed **${victim.displayName}** and got **${amount}** :coin:!`]
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
message.channel.send(randomMessage)
await db.set(`wallet_${victim.id}`, amount - victimWallet)
await db.set(`wallet_${message.author.id}`, userWallet + amount)
} else if(random > 30) {
let authorWallet = await db.get(`wallet_${message.author.id}`)
let wallet1 = await db.get(`wallet_${victim.id}`)
let amountPaid = Math.floor(Math.random() * authorWallet);
const message1 = [`Pfft noob, you got caught and paid **${victim.displayName} ${amountPaid}** :coin: lol!`, `lel ure such a noob, you paid **${victim.displayName} ${amountPaid}** :coin:!`, `u suck and you paid **${amountPaid}** :coin: to **${victim.displayName}**, such a noob lol!`]
const randomMessage1 = message1[Math.floor(Math.random() * message1.length)];
return message.channel.send(randomMessage1)
await db.set(`wallet_${message.author.id}`, (amountPaid - authorWallet));
await db.set(`wallet_${message.author.id}`, (amountPaid + wallet1));
}
}
}
It all works except sometimes it just sends a negative number, can anyone tell me a math method that make sure the number isn't a negative?
Thanks.
You should verify the amount to steal before stealing it
if (random < 30) {
let victimWallet = await db.get(`wallet_${victim.id}`)
let userWallet = await db.get(`wallet_${message.author.id}`)
let amount = Math.floor(Math.random() * victimWallet);
//Check the amount of victim wallet, return if not enough coins to steal
if (amount > victimwallet) {
console.log("Not enough coins to steal") return;
}
const messages = [`POG! You robbed **${victim.username}** and got **${amount}** :coin:!`, `oo seems like you robbed **${victim.displayName}** and got **${amount}** :coin:!`]
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
message.channel.send(randomMessage)
await db.set(`wallet_${victim.id}`, amount - victimWallet)
await db.set(`wallet_${message.author.id}`, userWallet + amount)
}
If the point is just to make the output to always positive, you can try this "if condition"
var x = -10 //change it with any number
if (x < 0){
x = x * -1
}
console.log(x) //it should will always show positive number
alternatively you can always use Match.abs(x)
var x = -10;
console.log(Math.abs(x));
I am trying to make ship command, I have almost everything done but when I use it there are two problems:
It takes first half from both words (I want to take first half from the first word and second half from the second one)
When I mention 2 people then my bot doesn't respond
My code looks like this:
function getRandomIntInclusive() {
return Math.floor(Math.random() * (100 - 1 + 1)) + 1;
}
if (!args[0]) return message.channel.send("Podaj pierwszy argument!")
if (!args[1]) return message.channel.send("Podaj drugi argument!")
if (args[0] || args[1]) {
var FirstUser = args[0]
var SecondUser = args[1]
if (message.mentions.members.first()) {
const FirstUserSliced = FirstUser.user.username.slice(0, FirstUser.user.username.length / 2)
const SecondUserSliced = SecondUser.map(user => { return user.user.username.slice(user.user.username.length / 2) })
const SecondUserName = SecondUser.map(user => { return user.user.username })
} else if (FirstUser || SecondUser) {
const FirstUserSliced = FirstUser.slice(0, FirstUser.length / 2)
const SecondUserSliced = SecondUser.slice (SecondUser.lenght / 2, SecondUser.length / 2)
const SecondUserName = FirstUserSliced + SecondUserSliced
const embed = new MessageEmbed()
.setTitle('Ship')
.setDescription(`${SecondUserName}`)
.addField(`Ocena shipu:`, `${getRandomIntInclusive()}%`)
.setColor(0x0099ff)
.setTimestamp()
.setFooter(`${message.author.username}`);
message.channel.send(embed)
}
}
```
Let me answer your problems:
1.It takes first half from both words (I want to take first half from the first word and second half from the second one)
In your code you have this row slice(SecondUser.lenght / 2, SecondUser.length / 2), let's assume you wrote lenght here(StackOverflow), and what it does is it cuts the first half, otherwise if you had that typo it would notify you.
When I mention 2 people then my bot doesn't respond
Because you have that if statement if (message.mentions.members.first()) where it doesn't get into the MessageEmbed so if you mention someone it goes to the first if statement and can't send a message because there is no message.
I wrote an easier version of your's code so it's easier to understand.
function GetHalfText(first, second) {
return first.substring(0, Math.floor(first.length / 2)) + second.substring(Math.floor(second.length / 2), second.length);
}
function Match(arg){
return arg.match(/<#!?(\d{17,19})>/);
}
const {mentions, guild} = message
if(args.length < 2) return message.channel.send("You must enter two arguments")
const FirstArg = Match(args[0]) ? guild.members.cache.get(Match(args[0])[1]).user.username : args[0];
const SecondArg = Match(args[1])|| guild.members.cache.get(Match(args[1])[1]).user.username || args[1];
const embed = new MessageEmbed()
.setTitle('Ship')
.setDescription(`${GetHalfText(FirstArg, SecondArg)}`)
.addField(`Ocena shipu:`, `${getRandomIntInclusive()}%`)
.setColor(0x0099ff)
.setTimestamp()
.setFooter(`${message.author.username}`);
message.channel.send(embed)
I am creating an event for messageUpdate, and everything is working "perfectly" fine, except when someone sends a message that contains more than 1024 characters, it returns an error as addField has a character limit.
How could I possibly make the bot send an error if the message that has been edited has reached the limit ?
if(oldMessage.cleanContent.length >= 1000) return channel.send("Too long");
if(newMessage.cleanContent.length >= 1000) return channel.send("Too long");
const embed = new Discord.MessageEmbed()
.addField("Old Message", `${oldMessage.cleanContent}`, true)
.addField("New Message", `${newMessage.cleanContent}`, true)
channel.send(embed)
(Posting this message so the question can get answered)
Judging from what you posted in the comments, this should be right. (I'm not the greatest dev so, feel free to yell at me if it's wrong)
const oldMessage = oldMessage.cleanContent
const newMessage = newMessage.cleanContent
if (oldMessageContent.length >= 1000) return channel.send("Too long");
if (newMessageContent.length >= 1000) return channel.send("Too long");
const embed = new Discord.MessageEmbed()
.addField("Old Message", `${oldMessage.cleanContent}`, true)
.addField("New Message", `${newMessage.cleanContent}`, true)
channel.send(embed)
You can also use a loop to add more fields for every 1024 characters
Example:
for (let i = 0; i < oldMessage.cleanContent.length; i += 2000) {
const cont = oldMessage.cleanContent.substring(i, Math.min(oldMessage.cleanContent.length, i + 2000));
embed.addField("Old Message", cont);
}
for (let i = 0; i < newMessage.cleanContent.length; i += 2000) {
const cont = newMessage.cleanContent.substring(i, Math.min(newMessage.cleanContent.length, i + 2000));
embed.addField("New Message", cont);
}
So I made a work command with a cooldown that shows exactly how long you have to wait until you can work again. The cooldown works, but it says time.seconds and time.minutes is undefined. Here is my code:
const Discord = require("discord.js");
const db = require('quick.db')
const ms = require("ms");
module.exports = class economy {
constructor(){
this.name = 'work',
this.alias = ['work'],
this.usage = 's!work',
this.description = 'Work to get paid',
this.runnable = 'true'
}
async run(bot, message, args) {
let timeout = 600000
let amount = Math.floor(Math.random() * 25) + 15;
var jobs = ["Miner", "Bartender", "Cashier", "Cleaner", "Drugdealer", "Assistant", "Nurse", "Cleaner", "Teacher", "Accountants", "Security Guard", "Sheriff", "Lawyer", "Dishwasher", "Electrician", "Singer", "Dancer"];
let work = await db.fetch(`work_${message.author.id}`);
if (work !== null && timeout - (Date.now() - work) > 0) {
let time = ms(timeout - (Date.now() - work));
message.channel.send(`You already worked, try again in **${time.minutes}m ${time.seconds}s**!`)
} else {
var job = jobs[Math.floor(Math.random() * jobs.length)];
message.channel.send(`You worked as a ${job} and earned ${amount} <:shart:646075915293687810>`)
db.add(`money_${message.author.id}`, amount)
db.set(`work_${message.author.id}`, Date.now())
}
}
}
How can I fix this?
According to ms docs, there are no minutes and seconds fields in the result from the ms function. If I understand your use case correctly, instead of **${time.minutes}m ${time.seconds}s** you should provide just **{time}**.
const ms = require("parse-ms")
My 'problem' is more of a feature I am looking to add, I used this guide:
https://anidiots.guide/coding-guides/sqlite-based-points-system
I changed the code a little to mainly give you a random amount of XP, I am looking to edit how much XP is needed to level up.
Right now it is a static amount, being 5000 needed to level up. I am trying to make it increase the amount needed to level up by an extra 5000 each time you level up.
Currently, it works like this:
Level 1 to 2 = 5000 total XP needed
Level 2 to 3 = 10000 total xp needed
Currently, the amount needed to level up is always 5000 between each level.
This is how I want it to work:
Level 1 to 2 = 5000 total XP needed
Level 2 to 3 = 15000 total XP needed
Which will be 5000 to level 2 and then 10000 to level 3 and so on (increasing the amount needed by 5000 each time you level up)
I spent the best part of 2 hours trying different things, and mainly looking at the code being completely out of my depth.
I believed that doing something like this would work, but I have no idea if it's correct
if (score.level == '1') {
nextLevel = 5000
}
if (score.level == '2' {
nextLevel = 10000
}
I highly doubt this is correct, otherwise, my message event would be very long, as I plan to have 100 levels
The code in its entirety:
let score;
if (message.guild) {
score = bot.getScore.get(message.author.id, message.guild.id);
if (!score) {
score = {
id: `${message.guild.id}-${message.author.id}`,
user: message.author.id,
guild: message.guild.id,
points: 0,
level: 1,
};
}
const xpAdd = Math.floor(Math.random() * 10) + 50;
const curxp = score.points;
const curlvl = score.level;
const nxtLvl = score.level * 5000;
score.points = curxp + xpAdd;
if (nxtLvl <= score.points) {
score.level = curlvl + 1;
const lvlup = new MessageEmbed()
.setAuthor(
`Congrats ${message.author.username}`,
message.author.displayAvatarURL()
)
.setTitle('You have leveled up!')
.setThumbnail('https://i.imgur.com/lXeBiMs.png')
.setColor(color)
.addField('New Level', curlvl + 1);
message.channel.send(lvlup).then(msg => {
msg.delete({
timeout: 10000,
});
});
}
bot.setScore.run(score);
}
The code as-is works fine and as expected, but as-is is not very good, as there is no reward from going from level 30-31 as it's the same amount of XP needed to get from level 1-2
Here's a little formula which should do the trick (if I understand your problem correctly):
const nxtLvl = 5000 * (Math.pow(2, score.level) - 1);
This gives the following xp requirements to level up:
1->2: 5000
2->3: 15000
3->4: 35000
4->5: 75000
5->6: 155000
Try something like this:
const levels = [0, 5000, 15000, 30000, 50000, 75000];
....
nextLevel = levels[score.level];
Edit
#Dan you mean like this:
nextLevel = 5000 * Math.round( score.level * (score.level + 1) / 2 );
Here Is Code I'm Using
But Problem Is I Can't Add Or Remove XP
Also I Made It With Scratch So I'm Being Mad Understanding This
let Discord;
let Database;
if (typeof window !== "undefined") {
Discord = DiscordJS;
Database = EasyDatabase;
} else {
Discord = require("discord.js");
Database = require("easy-json-database");
}
const delay = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms));
const s4d = {
Discord,
client: null,
tokenInvalid: false,
reply: null,
joiningMember: null,
database: new Database("./db.json"),
checkMessageExists() {
if (!s4d.client) throw new Error('You cannot perform message operations without a Discord.js client')
if (!s4d.client.readyTimestamp) throw new Error('You cannot perform message operations while the bot is not connected to the Discord API')
}
};
s4d.client = new s4d.Discord.Client({
fetchAllMembers: true
});
s4d.client.on('raw', async (packet) => {
if (['MESSAGE_REACTION_ADD', 'MESSAGE_REACTION_REMOVE'].includes(packet.t)) {
const guild = s4d.client.guilds.cache.get(packet.d.guild_id);
if (!guild) return;
const member = guild.members.cache.get(packet.d.user_id) || guild.members.fetch(d.user_id).catch(() => {});
if (!member) return;
const channel = s4d.client.channels.cache.get(packet.d.channel_id);
if (!channel) return;
const message = channel.messages.cache.get(packet.d.message_id) || await channel.messages.fetch(packet.d.message_id).catch(() => {});
if (!message) return;
s4d.client.emit(packet.t, guild, channel, message, member, packet.d.emoji.name);
}
});
var member_xp, member_level;
s4d.client.login('My Dumb Token').catch((e) => {
s4d.tokenInvalid = true;
s4d.tokenError = e;
});
s4d.client.on('message', async (s4dmessage) => {
if (!((s4dmessage.member).user.bot)) {
member_xp = s4d.database.get(String(('xp-' + String(s4dmessage.author.id))));
member_level = s4d.database.get(String(('level-' + String(s4dmessage.author.id))));
if (!member_xp) {
member_xp = 0;
} else if (!member_level) {
member_level = 0;
}
s4d.database.set(String(('xp-' + String(s4dmessage.author.id))), (member_xp + 1));
member_xp = member_xp + 1;
if (member_xp > 100) {
s4d.database.set(String(('level-' + String(s4dmessage.author.id))), (member_level + 1));
member_level = member_level + 1;
s4dmessage.channel.send(String((['Congratulations, ', s4dmessage.member, 'you jumped to level ', member_level, '!!'].join(''))));
}
if ((s4dmessage.content) == '-level') {
s4dmessage.channel.send(String(([s4dmessage.member, ', you are currently level: ', member_level].join(''))));
} else if ((s4dmessage.content) == '-xp') {
s4dmessage.channel.send(String(([s4dmessage.member, ', you need ', 100 - member_xp, ' to jump to level ', member_level + 1].join(''))));
}
}
});
s4d;