I'm trying to make a levelling system configured for my server that gives XP to users when admins use >givexp, sends a message when a user reaches a new level, resets a user's XP & levels when admins use >resetxp, and displays the user's level & XP (current XP on the current level over XP to the next level) on using >level.
However, users aren't receiving XP from the first time being awarded XP (if I use >givexp @user#1234 50, then use >givexp @user#1234 20, their total XP would be 20).
A user on Level 0 reaching 100 XP or more after the last awarding won't be given Level 1 until being awarded more XP.
givexp.js:
const Discord = require("discord.js");
const db = require("quick.db")
const adm = " "; //ids here
module.exports = {
name: "givexp"
}
module.exports.ex = async(message, args) => {
let { guild } = message;
const user = message.mentions.users.first();
if (message.author.id === adm) {
if (!user) {
message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setTitle("Invalid Syntax").setDescription(`The format for [givexp] is \`>givexp @user#1234 [amount]\``));
} else {
// xp requirements for each level
const levels = {
0: 100,
1: 125,
2: 150,
3: 175,
4: 200,
5: 225
};
// total xp requirements
const xpreqs = {
0: 100,
1: 225,
2: 350,
3: 475,
4: 600,
5: 725
}
const giveAmount = args.slice(1).join(" ");
let xp = db.get(`xp_${message.guild.id}_${user.id}`);
let level = db.get(`level_${message.guild.id}_${user.id}`);
let totalxp = db.get(`totalxp_${message.guild.id}_${user.id}`);
if (xp === null) db.set(`xp_${message.guild.id}_${user.id}`, 0);
if (totalxp === null) db.set(`totalxp_${message.guild.id}_${user.id}`, 0);
if (level === null) db.set(`level_${message.guild.id}_${user.id}`, 0);
if (giveAmount) {
await db.add(`totalxp_${message.guild.id}_${user.id}`, parseInt(giveAmount));
user.send(new Discord.MessageEmbed().setColor("D9B3FF").setDescription(`You were awarded **${giveAmount}XP** by ${message.author.tag}`));
await message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setDescription(`${user.tag} has been awarded **${giveAmount}XP** by ${message.author.tag}`));
console.log(`${message.author.tag} awarded ${user.tag} ${giveAmount}XP.`);
if (totalxp >= xpreqs[level]) {
await db.set(`xp_${message.guild.id}_${user.id}`, totalxp - xpreqs[level]);
await db.add(`level_${message.guild.id}_${user.id}`, 1);
level = db.get(`level_${message.guild.id}_${user.id}`);
await message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setTitle("Level Up!").setDescription(`<@${user.id}> has reached Level ${level}!`))
} else if (totalxp < xpreqs[level]) {
await db.add(`xp_${message.guild.id}_${user.id}`, parseInt(giveAmount));
}
} else {
message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setTitle("Invalid Syntax").setDescription(`The format for [givexp] is \`>givexp @user#1234 [amount]\``));
}
}
} else {
message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setDescription(`<@${message.author.id}>, you do not have permission to give users XP.`));
}
};
level.js
const Discord = require("discord.js");
const db = require("quick.db")
module.exports = {
name: "level"
}
module.exports.ex = async(message, args) => {
let { guild } = message;
const user = message.mentions.members.first() || message.author;
const levels = {
0: 100,
1: 125,
2: 150,
3: 175,
4: 200,
5: 225
};
let xp = db.get(`xp_${message.guild.id}_${user.id}`);
let level = db.get(`level_${message.guild.id}_${user.id}`);
let xpreq = levels[level];
if (xp === null) {
xp = 0;
}
if (level === null) {
level = 0;
}
message.channel.send(new Discord.MessageEmbed().setColor("D9B3FF").setAuthor(user.username, message.guild.iconURL()).setThumbnail(user.avatarURL()).setDescription(`**LEVEL: **${level}\n**XP: **${xp}/${xpreq}`));
console.log(`${message.author.tag} used [level] in ${guild.name}`);
};
It is because if the value is null, like you check it. You never redefine the value of level
variable. You just set the level to 0 on your quick.db, but not the actual variable.
if (level === null) db.set(`level_${message.guild.id}_${user.id}`, 0);
// this is the issue, "if level is null, set db level_${message.guild.id} to 0"
You need to set the value to the level
variable as well so once you check the leveling requirement later on your code
if (totalxp >= xpreqs[level])
// You are basically checking if (totalxp >= xpreqs[null])
That is why your users get the level they need after the second XP addition because then there is value for your level
variable already.