import { EmbedBuilder, AttachmentBuilder } from "discord.js"; import type { ItemUsageData } from "@shared/lib/types"; import { EffectType } from "@shared/lib/constants"; import { resolveAssetUrl, isLocalAssetUrl } from "@shared/lib/assets"; import { join } from "path"; import { existsSync } from "fs"; /** * Inventory entry with item details */ interface InventoryEntry { quantity: bigint | null; item: { id: number; name: string; [key: string]: any; }; } /** * Creates an embed displaying a user's inventory */ export function getInventoryEmbed(items: InventoryEntry[], username: string): EmbedBuilder { const description = items.map(entry => { return `**${entry.item.name}** x${entry.quantity}`; }).join("\n"); return new EmbedBuilder() .setTitle(`📦 ${username}'s Inventory`) .setDescription(description) .setColor(0x3498db); // Blue } /** * Creates an embed showing the results of using an item */ export function getItemUseResultEmbed(results: any[], item?: { name: string, iconUrl: string | null, usageData: any }): { embed: EmbedBuilder, files: AttachmentBuilder[] } { const embed = new EmbedBuilder(); const files: AttachmentBuilder[] = []; const otherMessages: string[] = []; let lootResult: any = null; for (const res of results) { if (typeof res === 'object' && res.type === 'LOOTBOX_RESULT') { lootResult = res; } else { otherMessages.push(typeof res === 'string' ? `• ${res}` : `• ${JSON.stringify(res)}`); } } // Default Configuration const isLootbox = item?.usageData?.effects?.some((e: any) => e.type === EffectType.LOOTBOX); embed.setColor(isLootbox ? 0xFFD700 : 0x2ecc71); // Gold for lootbox, Green otherwise by default embed.setTimestamp(); if (lootResult) { embed.setTitle(`🎁 ${item?.name || "Lootbox"} Opened!`); if (lootResult.rewardType === 'ITEM' && lootResult.item) { const i = lootResult.item; const amountStr = lootResult.amount > 1 ? `x${lootResult.amount}` : ''; // Rarity Colors const rarityColors: Record = { 'C': 0x95A5A6, // Gray 'R': 0x3498DB, // Blue 'SR': 0x9B59B6, // Purple 'SSR': 0xF1C40F // Gold }; const rarityKey = i.rarity || 'C'; if (rarityKey in rarityColors) { embed.setColor(rarityColors[rarityKey] ?? 0x95A5A6); } else { embed.setColor(0x95A5A6); } if (i.image) { if (isLocalAssetUrl(i.image)) { const imagePath = join(process.cwd(), "bot/assets/graphics", i.image.replace(/^\/?assets\//, "")); if (existsSync(imagePath)) { const imageName = defaultName(i.image); if (!files.find(f => f.name === imageName)) { files.push(new AttachmentBuilder(imagePath, { name: imageName })); } embed.setImage(`attachment://${imageName}`); } } else { const imgUrl = resolveAssetUrl(i.image); if (imgUrl) embed.setImage(imgUrl); } } embed.setDescription(`**You found ${i.name} ${amountStr}!**\n${i.description || '_'}`); embed.addFields({ name: 'Rarity', value: rarityKey, inline: true }); } else if (lootResult.rewardType === 'CURRENCY') { embed.setColor(0xF1C40F); embed.setDescription(`**You found ${lootResult.amount.toLocaleString()} 🪙 AU!**`); } else if (lootResult.rewardType === 'XP') { embed.setColor(0x2ECC71); // Green embed.setDescription(`**You gained ${lootResult.amount.toLocaleString()} XP!**`); } else { // Nothing or Message embed.setDescription(lootResult.message); embed.setColor(0x95A5A6); // Gray } } else { // Standard item usage embed.setTitle(item ? `✅ Used ${item.name}` : "✅ Item Used!"); embed.setDescription(otherMessages.join("\n") || "Effect applied."); if (isLootbox && item && item.iconUrl) { if (isLocalAssetUrl(item.iconUrl)) { const iconPath = join(process.cwd(), "bot/assets/graphics", item.iconUrl.replace(/^\/?assets\//, "")); if (existsSync(iconPath)) { const iconName = defaultName(item.iconUrl); if (!files.find(f => f.name === iconName)) { files.push(new AttachmentBuilder(iconPath, { name: iconName })); } embed.setThumbnail(`attachment://${iconName}`); } } else { const resolvedIconUrl = resolveAssetUrl(item.iconUrl); if (resolvedIconUrl) embed.setThumbnail(resolvedIconUrl); } } } if (otherMessages.length > 0 && lootResult) { embed.addFields({ name: "Other Effects", value: otherMessages.join("\n") }); } return { embed, files }; } function defaultName(path: string): string { return path.split("/").pop() || "image.png"; }