Skip to content

Commit 96ff318

Browse files
authored
Add new items category (#208)
* Initial Commit of Items category * Update create-item.js * Moment duration fixes * Update buy/create-item * More items updates * More items updates * More item updates + global-blacklist fixes * Update buy/use with quantity * Create sell-item.js * Change inventory to embed fields * Add stock to items * Update cooldown format
1 parent 65729d9 commit 96ff318

File tree

14 files changed

+1504
-15
lines changed

14 files changed

+1504
-15
lines changed

commands/Bot Support/global-blacklist.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ class GlobalBlacklist extends Command {
99
name: 'global-blacklist',
1010
description: 'Blacklist someone from using the bot',
1111
usage: 'global-blacklist <Add | Remove | Check> <User> <Reason>',
12-
requiredArgs: 1,
12+
examples: ['global-blacklist check bunny', 'global-blacklist add bunny Being naughty'],
13+
requiredArgs: 2,
1314
category: 'Bot Support',
1415
permLevel: 'Bot Support',
1516
aliases: ['gbl', 'g-blacklist', 'gblacklist'],
@@ -26,6 +27,7 @@ class GlobalBlacklist extends Command {
2627
return this.client.util.errorEmbed(msg, msg.settings.prefix + this.help.usage, 'Incorrect Usage');
2728
} else {
2829
type = args[0].toLowerCase();
30+
mem = await this.client.util.getMember(msg, args[1]);
2931
}
3032
} else if (args[0]) {
3133
// Check if the first argument is a user mention
@@ -59,13 +61,15 @@ class GlobalBlacklist extends Command {
5961
if (!mem) {
6062
return this.client.util.errorEmbed(msg, msg.settings.prefix + this.help.usage, 'User not found');
6163
}
64+
mem = mem.user ? mem.user : mem;
6265

6366
args.shift();
6467
args.shift();
6568
const reason = args.join(' ') || false;
6669

6770
const blacklist = await db.get(`users.${mem.id}.blacklist`);
6871

72+
console.log(mem);
6973
const embed = new EmbedBuilder()
7074
.setAuthor({ name: mem.tag, iconURL: mem.displayAvatarURL() })
7175
.setColor(msg.settings.embedColor)
@@ -84,8 +88,8 @@ class GlobalBlacklist extends Command {
8488
await db.set(`users.${mem.id}.blacklistReason`, reason);
8589

8690
embed.setTitle(`${mem.tag} has been added to the global blacklist.`).addFields([
87-
{ name: 'Reason:', value: reason },
8891
{ name: 'User:', value: `${mem.tag} \n(${mem.id})` },
92+
{ name: 'Reason:', value: reason },
8993
]);
9094

9195
msg.channel.send({ embeds: [embed] });
@@ -105,8 +109,8 @@ class GlobalBlacklist extends Command {
105109
await db.set(`users.${mem.id}.blacklistReason`, reason);
106110

107111
embed.setTitle(`${mem.tag} has been removed from the global blacklist.`).addFields([
108-
{ name: 'Reason:', value: reason },
109112
{ name: 'User:', value: `${mem.tag} \n(${mem.id})` },
113+
{ name: 'Reason:', value: reason },
110114
]);
111115

112116
msg.channel.send({ embeds: [embed] });
@@ -117,13 +121,11 @@ class GlobalBlacklist extends Command {
117121
case 'check': {
118122
const reason = (await db.get(`users.${mem.id}.blacklistReason`)) || 'No reason specified';
119123

120-
embed
121-
.setTitle(`${mem.tag} blacklist check`)
122-
.addFields([
123-
{ name: 'User:', value: `${mem.tag} (${mem.id})`, inline: true },
124-
{ name: 'Is Blacklisted?', value: blacklist ? 'True' : 'False', inline: true },
125-
])
126-
.addField('Reason:', reason);
124+
embed.setTitle(`${mem.tag} blacklist check`).addFields([
125+
{ name: 'User:', value: `${mem.tag} (${mem.id})`, inline: true },
126+
{ name: 'Is Blacklisted?', value: blacklist ? 'True' : 'False', inline: true },
127+
{ name: 'Reason', value: reason, inline: true },
128+
]);
127129

128130
msg.channel.send({ embeds: [embed] });
129131
break;

commands/Economy/rob.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ class Rob extends Command {
8383

8484
let totalAmount = Number(memCash + authNet);
8585
if (!Number.isFinite(totalAmount)) {
86-
totalAmount = Number.MAX_SAFE_INTEGER;
86+
totalAmount = Number.MAX_VALUE;
8787
}
8888

8989
let authNetAmount = Number(authNet);
9090
if (!Number.isFinite(authNetAmount)) {
91-
authNetAmount = Number.MAX_SAFE_INTEGER;
91+
authNetAmount = Number.MAX_VALUE;
9292
}
9393

9494
const failRate = Math.floor((authNetAmount / totalAmount) * (maxRate - minRate + 1) + minRate);

commands/General/help.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Help extends Command {
1616
async run(msg, args, level) {
1717
const baseCategories = [
1818
'economy',
19+
'items',
1920
'fun',
2021
'games',
2122
'general',

commands/Items/buy-item.js

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
const Command = require('../../base/Command.js');
2+
const { EmbedBuilder } = require('discord.js');
3+
const { QuickDB } = require('quick.db');
4+
require('moment-duration-format');
5+
const moment = require('moment');
6+
const db = new QuickDB();
7+
8+
class BuyItem extends Command {
9+
constructor(client) {
10+
super(client, {
11+
name: 'buy-item',
12+
category: 'Items',
13+
description: 'Buy an item from the store.',
14+
usage: 'buy-item [quantity] <item>',
15+
examples: ['buy pizza'],
16+
aliases: ['buy'],
17+
requiredArgs: 1,
18+
guildOnly: true,
19+
});
20+
}
21+
22+
async run(msg, args) {
23+
let quantity = 1;
24+
let itemName = args.join(' ').toLowerCase();
25+
if (!isNaN(args[0])) {
26+
quantity = parseInt(args[0]);
27+
if (quantity <= 0) {
28+
return msg.reply('Invalid `[quantity]` argument given. Cannot be less than 1');
29+
}
30+
args.shift();
31+
itemName = args.join(' ').toLowerCase();
32+
if (!itemName) {
33+
return msg.reply('Invalid `<item name>` argument given');
34+
}
35+
}
36+
37+
if (!itemName) return msg.reply('Please specify an item to buy.');
38+
39+
const store = (await db.get(`servers.${msg.guild.id}.economy.store`)) || {};
40+
41+
// Find the item in the store regardless of case
42+
const itemKey = Object.keys(store).find((key) => key.toLowerCase() === itemName);
43+
if (!itemKey) return msg.reply('That item does not exist in the store.');
44+
45+
const item = store[itemKey];
46+
const itemCost = BigInt(item.cost);
47+
let userCash = BigInt(await db.get(`servers.${msg.guild.id}.users.${msg.member.id}.economy.cash`));
48+
if (userCash < itemCost * BigInt(quantity)) return msg.reply('You do not have enough money to buy this item.');
49+
50+
if (item.stock && item.stock < quantity) {
51+
return msg.reply(`The store only has ${item.stock} stock remaining.`);
52+
}
53+
if (item.stock) {
54+
item.stock -= quantity;
55+
if (item.stock === 0) {
56+
await db.delete(`servers.${msg.guild.id}.economy.store.${itemKey}`);
57+
} else {
58+
store[itemKey] = item;
59+
await db.set(`servers.${msg.guild.id}.economy.store`, store);
60+
}
61+
}
62+
63+
if (item.roleRequired) {
64+
const roleRequired = this.client.util.getRole(msg, item.roleRequired);
65+
if (roleRequired) {
66+
// Check if the member has the role
67+
const hasRole = msg.member.roles.cache.has(roleRequired.id);
68+
if (!hasRole) {
69+
return msg.reply(`You do not have the required role **${roleRequired.name}** to purchase this item.`);
70+
}
71+
} else {
72+
return msg.reply('The required role specified does not exist.');
73+
}
74+
}
75+
76+
if (item.roleGiven || item.roleRemoved) {
77+
if (!msg.guild.members.me.permissions.has('ManageRoles'))
78+
return this.client.util.errorEmbed(
79+
msg,
80+
'Manage Roles permission is required on the bot to buy this item.',
81+
'Missing Permission',
82+
);
83+
}
84+
85+
// Deduct the cost from the user's cash
86+
userCash = userCash - itemCost * BigInt(quantity);
87+
await db.set(`servers.${msg.guild.id}.users.${msg.member.id}.economy.cash`, userCash.toString());
88+
89+
if (!item.inventory) {
90+
if (item.roleGiven) {
91+
const role = this.client.util.getRole(msg, item.roleGiven);
92+
await msg.member.roles.add(role).catch((error) => msg.channel.send(error));
93+
}
94+
if (item.roleRemoved) {
95+
const role = this.client.util.getRole(msg, item.roleRemoved);
96+
await msg.member.roles.remove(role).catch((error) => msg.channel.send(error));
97+
}
98+
if (!item.replyMessage) {
99+
return msg.channel.send('👍');
100+
}
101+
102+
// Replace Member
103+
const memberCreatedAt = moment(msg.author.createdAt);
104+
const memberCreated = memberCreatedAt.format('D MM YY');
105+
const memberCreatedDuration = memberCreatedAt.from(moment(), true);
106+
let replyMessage = item.replyMessage
107+
.replace('{member.id}', msg.author.id)
108+
.replace('{member.username}', msg.author.username)
109+
.replace('{member.tag}', msg.author.tag)
110+
.replace('{member.mention}', msg.author)
111+
.replace('{member.created}', memberCreated)
112+
.replace('{member.created.duration}', memberCreatedDuration);
113+
114+
// Replace Server
115+
const guildCreatedAt = moment(msg.guild.createdAt);
116+
const serverCreated = guildCreatedAt.format('D MM YY');
117+
const serverCreatedDuration = guildCreatedAt.from(moment(), true);
118+
119+
replyMessage = replyMessage
120+
.replace('{server.id}', msg.guild.id)
121+
.replace('{server.name}', msg.guild.name)
122+
.replace('{server.members}', msg.guild.memberCount.toLocaleString())
123+
.replace('{server.created}', serverCreated)
124+
.replace('{servers.created.duration', serverCreatedDuration);
125+
126+
const role =
127+
(await this.client.util.getRole(msg, item.roleGiven)) ||
128+
(await this.client.util.getRole(msg, item.roleRemoved)) ||
129+
(await this.client.util.getRole(msg, item.roleRequired));
130+
131+
if (role) {
132+
const roleCreatedAt = moment(role.createdAt);
133+
const roleCreated = roleCreatedAt.format('D MM YY');
134+
const roleCreatedDuration = roleCreatedAt.from(moment(), true);
135+
136+
replyMessage = replyMessage
137+
.replace('{role.id}', role.id)
138+
.replace('{role.name}', role.name)
139+
.replace('{role.mention}', role)
140+
.replace('{role.members}', role.members.size.toLocaleString())
141+
.replace('{role.created}', roleCreated)
142+
.replace('{role.created.duration}', roleCreatedDuration);
143+
}
144+
return msg.channel.send(replyMessage);
145+
}
146+
147+
const userInventory = (await db.get(`servers.${msg.guild.id}.users.${msg.member.id}.economy.inventory`)) || [];
148+
149+
// Find the index of the item in the user's inventory
150+
const itemIndex = userInventory.findIndex((inventoryItem) => inventoryItem?.name?.toLowerCase() === itemName);
151+
if (itemIndex !== -1) {
152+
// If the item is found, increment the quantity
153+
userInventory[itemIndex].quantity += quantity;
154+
userInventory[itemIndex] = {
155+
...userInventory[itemIndex],
156+
replyMessage: item.replyMessage,
157+
roleRequired: item.roleRequired,
158+
roleGiven: item.roleGiven,
159+
roleRemoved: item.roleRemoved,
160+
};
161+
await db.set(`servers.${msg.guild.id}.users.${msg.member.id}.economy.inventory`, userInventory);
162+
} else {
163+
// Add the item to the user's inventory
164+
item.quantity = quantity;
165+
userInventory.push({ name: itemKey, ...item });
166+
167+
await db.set(`servers.${msg.guild.id}.users.${msg.member.id}.economy.inventory`, userInventory);
168+
}
169+
170+
const currencySymbol = (await db.get(`servers.${msg.guild.id}.economy.symbol`)) || '$';
171+
const itemCostQuantity = (itemCost * BigInt(quantity)).toLocaleString();
172+
const csCost =
173+
itemCostQuantity.length > 700
174+
? currencySymbol + itemCostQuantity.slice(0, 700) + '...'
175+
: currencySymbol + itemCostQuantity;
176+
177+
const embed = new EmbedBuilder()
178+
.setTitle('Purchase Successful')
179+
.setDescription(
180+
`You have bought ${quantity} ${itemKey}${
181+
quantity > 1 ? 's' : ''
182+
} for ${csCost}! This is now in your inventory. \nUse this item with the \`use-item\` command.`,
183+
)
184+
.setColor(msg.settings.embedColor)
185+
.setTimestamp();
186+
187+
return msg.channel.send({ embeds: [embed] });
188+
}
189+
}
190+
191+
module.exports = BuyItem;

0 commit comments

Comments
 (0)