forked from syntaxbullet/aurorabot
141 lines
5.3 KiB
TypeScript
141 lines
5.3 KiB
TypeScript
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<string, number> = {
|
|
'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";
|
|
}
|