AeThex-Bot-Master/aethex-bot/commands/daily.js
sirpiglr 4a39363dfd Implement a new achievement system for tracking user progress and rewards
Adds a comprehensive achievement system to the bot, including new triggers for various user actions, the ability to create, manage, and view achievements, and integration with existing XP and leveling systems. This also involves updating user statistics tracking to support achievement triggers.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 28bc7e36-c36d-4b62-b518-bcc2c649398e
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
2025-12-08 21:47:11 +00:00

147 lines
5.1 KiB
JavaScript

const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
const { checkAchievements } = require('./achievements');
const { getUserStats, calculateLevel } = require('../listeners/xpTracker');
const DAILY_XP = 50;
const STREAK_BONUS = 10;
const MAX_STREAK_BONUS = 100;
module.exports = {
data: new SlashCommandBuilder()
.setName('daily')
.setDescription('Claim your daily XP bonus'),
async execute(interaction, supabase, client) {
if (!supabase) {
return interaction.reply({ content: 'Database not configured.', ephemeral: true });
}
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 need to link your account first! Use `/verify` to get started.')
]
});
}
const { data: profile } = await supabase
.from('user_profiles')
.select('xp, daily_streak, last_daily, prestige_level, total_xp_earned')
.eq('id', link.user_id)
.single();
const now = new Date();
const lastDaily = profile?.last_daily ? new Date(profile.last_daily) : null;
const currentXp = profile?.xp || 0;
const prestige = profile?.prestige_level || 0;
let streak = profile?.daily_streak || 0;
if (lastDaily) {
const hoursSince = (now - lastDaily) / (1000 * 60 * 60);
if (hoursSince < 20) {
const nextClaim = new Date(lastDaily.getTime() + 20 * 60 * 60 * 1000);
return interaction.editReply({
embeds: [
new EmbedBuilder()
.setColor(0xfbbf24)
.setTitle('Already Claimed!')
.setDescription(`You've already claimed your daily XP.\nNext claim: <t:${Math.floor(nextClaim.getTime() / 1000)}:R>`)
.addFields({ name: 'Current Streak', value: `🔥 ${streak} days` })
]
});
}
if (hoursSince > 48) {
streak = 0;
}
}
streak += 1;
const streakBonus = Math.min(streak * STREAK_BONUS, MAX_STREAK_BONUS);
// Prestige level 4+ gets bonus daily XP (+25)
const prestigeDailyBonus = prestige >= 4 ? 25 : 0;
// Base total before prestige multiplier
let totalXp = DAILY_XP + streakBonus + prestigeDailyBonus;
// Apply prestige XP bonus (+5% per prestige level)
if (prestige > 0) {
const prestigeMultiplier = 1 + (prestige * 0.05);
totalXp = Math.floor(totalXp * prestigeMultiplier);
}
const newXp = currentXp + totalXp;
const totalEarned = (profile?.total_xp_earned || currentXp) + totalXp;
await supabase
.from('user_profiles')
.update({
xp: newXp,
daily_streak: streak,
last_daily: now.toISOString(),
total_xp_earned: totalEarned
})
.eq('id', link.user_id);
const newLevel = Math.floor(Math.sqrt(newXp / 100));
const oldLevel = Math.floor(Math.sqrt(currentXp / 100));
const embed = new EmbedBuilder()
.setColor(prestige > 0 ? getPrestigeColor(prestige) : 0x00ff00)
.setTitle('Daily Reward Claimed!')
.setDescription(`You received **+${totalXp} XP**!${prestige > 0 ? ` *(includes P${prestige} bonus)*` : ''}`)
.addFields(
{ name: 'Base XP', value: `+${DAILY_XP}`, inline: true },
{ name: 'Streak Bonus', value: `+${streakBonus}`, inline: true },
{ name: 'Current Streak', value: `🔥 ${streak} days`, inline: true },
{ name: 'Total XP', value: newXp.toLocaleString(), inline: true },
{ name: 'Level', value: `${newLevel}`, inline: true }
);
if (prestige > 0) {
embed.addFields({ name: 'Prestige Bonus', value: `+${prestige * 5}% XP${prestigeDailyBonus > 0 ? ` + ${prestigeDailyBonus} daily bonus` : ''}`, inline: true });
}
embed.setFooter({ text: 'Come back tomorrow to keep your streak!' })
.setTimestamp();
if (newLevel > oldLevel) {
embed.addFields({ name: '🎉 Level Up!', value: `You reached level ${newLevel}!` });
}
await interaction.editReply({ embeds: [embed] });
// Check achievements with updated stats
const guildId = interaction.guildId;
const stats = await getUserStats(supabase, link.user_id, guildId);
stats.level = newLevel;
stats.prestige = prestige;
stats.totalXp = totalEarned;
stats.dailyStreak = streak;
await checkAchievements(link.user_id, interaction.member, stats, supabase, guildId, client);
} catch (error) {
console.error('Daily error:', error);
await interaction.editReply({ content: 'Failed to claim daily reward.' });
}
},
};
function getPrestigeColor(level) {
const colors = [0x6b7280, 0xcd7f32, 0xc0c0c0, 0xffd700, 0xe5e4e2, 0xb9f2ff, 0xff4500, 0x9400d3, 0xffd700, 0xff69b4, 0x7c3aed];
return colors[Math.min(level, 10)] || 0x00ff00;
}