Adjusted the `prestigeUp` function in `aethex-bot/commands/prestige.js` to correctly update `total_xp_earned` and display values, preventing duplicate XP accumulation. Replit-Commit-Author: Agent Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: a792080b-bc3a-474f-8aa7-6dcea7ecb128 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/yTaZipL Replit-Helium-Checkpoint-Created: true
323 lines
12 KiB
JavaScript
323 lines
12 KiB
JavaScript
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
|
||
|
||
module.exports = {
|
||
data: new SlashCommandBuilder()
|
||
.setName('prestige')
|
||
.setDescription('Prestige system - reset your level for permanent rewards')
|
||
.addSubcommand(sub =>
|
||
sub.setName('view')
|
||
.setDescription('View your prestige status and rewards')
|
||
.addUserOption(opt =>
|
||
opt.setName('user')
|
||
.setDescription('User to check')
|
||
.setRequired(false)
|
||
)
|
||
)
|
||
.addSubcommand(sub =>
|
||
sub.setName('up')
|
||
.setDescription('Prestige up! Reset your XP for permanent rewards')
|
||
)
|
||
.addSubcommand(sub =>
|
||
sub.setName('rewards')
|
||
.setDescription('View all prestige rewards')
|
||
),
|
||
|
||
async execute(interaction, supabase, client) {
|
||
if (!supabase) {
|
||
return interaction.reply({ content: 'Database not configured.', ephemeral: true });
|
||
}
|
||
|
||
const sub = interaction.options.getSubcommand();
|
||
|
||
if (sub === 'view') {
|
||
return viewPrestige(interaction, supabase);
|
||
} else if (sub === 'up') {
|
||
return prestigeUp(interaction, supabase, client);
|
||
} else if (sub === 'rewards') {
|
||
return viewRewards(interaction);
|
||
}
|
||
},
|
||
};
|
||
|
||
async function viewPrestige(interaction, supabase) {
|
||
const target = interaction.options.getUser('user') || interaction.user;
|
||
await interaction.deferReply();
|
||
|
||
try {
|
||
const { data: link } = await supabase
|
||
.from('discord_links')
|
||
.select('user_id')
|
||
.eq('discord_id', target.id)
|
||
.single();
|
||
|
||
if (!link) {
|
||
return interaction.editReply({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0xff6b6b)
|
||
.setDescription(`${target.id === interaction.user.id ? 'You are' : `${target.tag} is`} not linked to AeThex.`)
|
||
]
|
||
});
|
||
}
|
||
|
||
const { data: profile } = await supabase
|
||
.from('user_profiles')
|
||
.select('username, xp, prestige_level, total_xp_earned')
|
||
.eq('id', link.user_id)
|
||
.single();
|
||
|
||
const prestige = profile?.prestige_level || 0;
|
||
const totalXpEarned = profile?.total_xp_earned || profile?.xp || 0;
|
||
const currentXp = profile?.xp || 0;
|
||
const level = Math.floor(Math.sqrt(currentXp / 100));
|
||
|
||
const prestigeInfo = getPrestigeInfo(prestige);
|
||
const nextPrestigeReq = getPrestigeRequirement(prestige + 1);
|
||
const canPrestige = level >= 50;
|
||
|
||
const embed = new EmbedBuilder()
|
||
.setColor(prestigeInfo.color)
|
||
.setTitle(`${prestigeInfo.icon} ${profile?.username || target.tag}'s Prestige`)
|
||
.setThumbnail(target.displayAvatarURL({ size: 256 }))
|
||
.addFields(
|
||
{ name: 'Prestige Level', value: `**${prestigeInfo.name}** (${prestige})`, inline: true },
|
||
{ name: 'XP Bonus', value: `+${prestige * 5}%`, inline: true },
|
||
{ name: 'Current Level', value: `${level}`, inline: true },
|
||
{ name: 'Total XP Earned', value: totalXpEarned.toLocaleString(), inline: true },
|
||
{ name: 'Current XP', value: currentXp.toLocaleString(), inline: true },
|
||
{ name: 'Can Prestige?', value: canPrestige ? '✅ Yes (Level 50+)' : `❌ Need Level 50 (${level}/50)`, inline: true }
|
||
)
|
||
.setFooter({ text: `Next prestige requirement: Level 50` })
|
||
.setTimestamp();
|
||
|
||
if (prestige > 0) {
|
||
embed.addFields({
|
||
name: '🏆 Prestige Rewards Unlocked',
|
||
value: getUnlockedRewards(prestige).join('\n') || 'None yet',
|
||
inline: false
|
||
});
|
||
}
|
||
|
||
await interaction.editReply({ embeds: [embed] });
|
||
} catch (error) {
|
||
console.error('Prestige view error:', error);
|
||
await interaction.editReply({ content: 'Failed to fetch prestige data.' });
|
||
}
|
||
}
|
||
|
||
async function prestigeUp(interaction, supabase, client) {
|
||
await interaction.deferReply();
|
||
|
||
try {
|
||
const { data: link } = await supabase
|
||
.from('discord_links')
|
||
.select('user_id')
|
||
.eq('discord_id', interaction.user.id)
|
||
.single();
|
||
|
||
if (!link) {
|
||
return interaction.editReply({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0xff6b6b)
|
||
.setDescription('You must link your Discord to AeThex first. Use `/verify` to link.')
|
||
]
|
||
});
|
||
}
|
||
|
||
const { data: profile } = await supabase
|
||
.from('user_profiles')
|
||
.select('username, xp, prestige_level, total_xp_earned')
|
||
.eq('id', link.user_id)
|
||
.single();
|
||
|
||
const currentXp = profile?.xp || 0;
|
||
const level = Math.floor(Math.sqrt(currentXp / 100));
|
||
const prestige = profile?.prestige_level || 0;
|
||
const totalEarned = profile?.total_xp_earned || currentXp;
|
||
|
||
if (level < 50) {
|
||
return interaction.editReply({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0xff6b6b)
|
||
.setTitle('❌ Cannot Prestige')
|
||
.setDescription(`You need to reach **Level 50** to prestige.\nCurrent level: **${level}**/50`)
|
||
]
|
||
});
|
||
}
|
||
|
||
if (prestige >= 10) {
|
||
return interaction.editReply({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0xffd700)
|
||
.setTitle('👑 Maximum Prestige!')
|
||
.setDescription('You have reached the maximum prestige level! You are a true legend.')
|
||
]
|
||
});
|
||
}
|
||
|
||
const newPrestige = prestige + 1;
|
||
const newPrestigeInfo = getPrestigeInfo(newPrestige);
|
||
const xpBonus = newPrestige * 5;
|
||
|
||
const confirmEmbed = new EmbedBuilder()
|
||
.setColor(0xf59e0b)
|
||
.setTitle('⚠️ Confirm Prestige')
|
||
.setDescription(`Are you sure you want to prestige?\n\n**What will happen:**\n• Your XP will reset to **0**\n• Your level will reset to **0**\n• You gain **Prestige ${newPrestige}** (${newPrestigeInfo.name})\n• You get a permanent **+${xpBonus}%** XP bonus\n• You unlock new **prestige rewards**\n\n**Current Stats:**\n• Level: ${level}\n• XP: ${currentXp.toLocaleString()}`)
|
||
.setFooter({ text: 'This action cannot be undone!' });
|
||
|
||
const row = new ActionRowBuilder()
|
||
.addComponents(
|
||
new ButtonBuilder()
|
||
.setCustomId('prestige_confirm')
|
||
.setLabel('✨ Prestige Up!')
|
||
.setStyle(ButtonStyle.Success),
|
||
new ButtonBuilder()
|
||
.setCustomId('prestige_cancel')
|
||
.setLabel('Cancel')
|
||
.setStyle(ButtonStyle.Secondary)
|
||
);
|
||
|
||
const response = await interaction.editReply({ embeds: [confirmEmbed], components: [row] });
|
||
|
||
try {
|
||
const confirmation = await response.awaitMessageComponent({
|
||
filter: i => i.user.id === interaction.user.id,
|
||
time: 60000
|
||
});
|
||
|
||
if (confirmation.customId === 'prestige_confirm') {
|
||
const { error } = await supabase
|
||
.from('user_profiles')
|
||
.update({
|
||
xp: 0,
|
||
prestige_level: newPrestige
|
||
})
|
||
.eq('id', link.user_id);
|
||
|
||
if (error) {
|
||
console.error('Prestige update error:', error);
|
||
return confirmation.update({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0xff0000)
|
||
.setDescription('Failed to prestige. Please try again.')
|
||
],
|
||
components: []
|
||
});
|
||
}
|
||
|
||
const successEmbed = new EmbedBuilder()
|
||
.setColor(newPrestigeInfo.color)
|
||
.setTitle(`${newPrestigeInfo.icon} Prestige ${newPrestige} Achieved!`)
|
||
.setDescription(`Congratulations! You are now **${newPrestigeInfo.name}**!\n\n**Rewards Unlocked:**\n${getNewRewards(newPrestige).join('\n')}`)
|
||
.addFields(
|
||
{ name: 'XP Bonus', value: `+${xpBonus}%`, inline: true },
|
||
{ name: 'Total XP Earned (All Time)', value: totalEarned.toLocaleString(), inline: true }
|
||
)
|
||
.setThumbnail(interaction.user.displayAvatarURL({ size: 256 }))
|
||
.setTimestamp();
|
||
|
||
await confirmation.update({ embeds: [successEmbed], components: [] });
|
||
} else {
|
||
await confirmation.update({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0x6b7280)
|
||
.setDescription('Prestige cancelled.')
|
||
],
|
||
components: []
|
||
});
|
||
}
|
||
} catch (e) {
|
||
await interaction.editReply({
|
||
embeds: [
|
||
new EmbedBuilder()
|
||
.setColor(0x6b7280)
|
||
.setDescription('Prestige request timed out.')
|
||
],
|
||
components: []
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('Prestige up error:', error);
|
||
await interaction.editReply({ content: 'Failed to process prestige.' });
|
||
}
|
||
}
|
||
|
||
async function viewRewards(interaction) {
|
||
const embed = new EmbedBuilder()
|
||
.setColor(0x7c3aed)
|
||
.setTitle('✨ Prestige Rewards')
|
||
.setDescription('Each prestige level grants permanent rewards!\n\n**Requirements:** Level 50 to prestige')
|
||
.addFields(
|
||
{ name: '⭐ Prestige 1 - Bronze', value: '+5% XP bonus\n🏷️ Bronze Prestige badge', inline: true },
|
||
{ name: '⭐ Prestige 2 - Silver', value: '+10% XP bonus\n🏷️ Silver Prestige badge', inline: true },
|
||
{ name: '⭐ Prestige 3 - Gold', value: '+15% XP bonus\n🏷️ Gold Prestige badge', inline: true },
|
||
{ name: '💎 Prestige 4 - Platinum', value: '+20% XP bonus\n🏷️ Platinum badge\n🎁 Bonus daily XP', inline: true },
|
||
{ name: '💎 Prestige 5 - Diamond', value: '+25% XP bonus\n🏷️ Diamond badge\n⏱️ Reduced cooldowns', inline: true },
|
||
{ name: '🔥 Prestige 6 - Master', value: '+30% XP bonus\n🏷️ Master badge\n🎯 XP milestone rewards', inline: true },
|
||
{ name: '🔥 Prestige 7 - Grandmaster', value: '+35% XP bonus\n🏷️ Grandmaster badge\n💫 Special profile effects', inline: true },
|
||
{ name: '👑 Prestige 8 - Champion', value: '+40% XP bonus\n🏷️ Champion badge\n🏆 Leaderboard priority', inline: true },
|
||
{ name: '👑 Prestige 9 - Legend', value: '+45% XP bonus\n🏷️ Legend badge\n✨ Legendary profile aura', inline: true },
|
||
{ name: '🌟 Prestige 10 - Mythic', value: '+50% XP bonus\n🏷️ Mythic badge\n🌈 All prestige perks!', inline: true }
|
||
)
|
||
.setFooter({ text: 'Use /prestige up when you reach Level 50!' })
|
||
.setTimestamp();
|
||
|
||
await interaction.reply({ embeds: [embed] });
|
||
}
|
||
|
||
function getPrestigeInfo(level) {
|
||
const prestiges = [
|
||
{ name: 'Unprestiged', icon: '⚪', color: 0x6b7280 },
|
||
{ name: 'Bronze', icon: '🥉', color: 0xcd7f32 },
|
||
{ name: 'Silver', icon: '🥈', color: 0xc0c0c0 },
|
||
{ name: 'Gold', icon: '🥇', color: 0xffd700 },
|
||
{ name: 'Platinum', icon: '💎', color: 0xe5e4e2 },
|
||
{ name: 'Diamond', icon: '💠', color: 0xb9f2ff },
|
||
{ name: 'Master', icon: '🔥', color: 0xff4500 },
|
||
{ name: 'Grandmaster', icon: '⚔️', color: 0x9400d3 },
|
||
{ name: 'Champion', icon: '👑', color: 0xffd700 },
|
||
{ name: 'Legend', icon: '🌟', color: 0xff69b4 },
|
||
{ name: 'Mythic', icon: '🌈', color: 0x7c3aed }
|
||
];
|
||
return prestiges[Math.min(level, 10)] || prestiges[0];
|
||
}
|
||
|
||
function getPrestigeRequirement(level) {
|
||
return 50;
|
||
}
|
||
|
||
function getUnlockedRewards(prestige) {
|
||
const rewards = [];
|
||
if (prestige >= 1) rewards.push('🥉 Bronze Prestige badge');
|
||
if (prestige >= 2) rewards.push('🥈 Silver Prestige badge');
|
||
if (prestige >= 3) rewards.push('🥇 Gold Prestige badge');
|
||
if (prestige >= 4) rewards.push('💎 Platinum badge + Bonus daily XP');
|
||
if (prestige >= 5) rewards.push('💠 Diamond badge + Reduced cooldowns');
|
||
if (prestige >= 6) rewards.push('🔥 Master badge + XP milestones');
|
||
if (prestige >= 7) rewards.push('⚔️ Grandmaster badge + Profile effects');
|
||
if (prestige >= 8) rewards.push('👑 Champion badge + Leaderboard priority');
|
||
if (prestige >= 9) rewards.push('🌟 Legend badge + Legendary aura');
|
||
if (prestige >= 10) rewards.push('🌈 Mythic badge + All perks unlocked');
|
||
return rewards;
|
||
}
|
||
|
||
function getNewRewards(prestige) {
|
||
const rewardMap = {
|
||
1: ['🥉 Bronze Prestige badge', '+5% XP bonus on all XP gains'],
|
||
2: ['🥈 Silver Prestige badge', '+10% XP bonus on all XP gains'],
|
||
3: ['🥇 Gold Prestige badge', '+15% XP bonus on all XP gains'],
|
||
4: ['💎 Platinum badge', '+20% XP bonus', '🎁 +25 bonus daily XP'],
|
||
5: ['💠 Diamond badge', '+25% XP bonus', '⏱️ 10% reduced XP cooldowns'],
|
||
6: ['🔥 Master badge', '+30% XP bonus', '🎯 XP milestone rewards'],
|
||
7: ['⚔️ Grandmaster badge', '+35% XP bonus', '💫 Special profile effects'],
|
||
8: ['👑 Champion badge', '+40% XP bonus', '🏆 Leaderboard priority display'],
|
||
9: ['🌟 Legend badge', '+45% XP bonus', '✨ Legendary profile aura'],
|
||
10: ['🌈 Mythic badge', '+50% XP bonus', '🌟 All prestige perks unlocked!']
|
||
};
|
||
return rewardMap[prestige] || [];
|
||
}
|