UNPKG

@zerospacegg/vynthra

Version:
191 lines • 7.86 kB
const Grell = require("@zerospacegg/iolin/zerospace/faction/grell"); const Legion = require("@zerospacegg/iolin/zerospace/faction/legion"); const Protectorate = require("@zerospacegg/iolin/zerospace/faction/protectorate"); // oo-ascii-tree will be required dynamically inside functions /** * Split a message into chunks that fit within Discord's character limit */ function splitMessage(message, maxLength) { if (message.length <= maxLength) { return [message]; } const chunks = []; let currentChunk = ""; const lines = message.split("\n"); for (const line of lines) { if (currentChunk.length + line.length + 1 > maxLength) { if (currentChunk.trim()) { chunks.push(currentChunk.trim()); currentChunk = ""; } if (line.length > maxLength) { // Split long lines at word boundaries const words = line.split(" "); let currentLine = ""; for (const word of words) { if (currentLine.length + word.length + 1 > maxLength) { if (currentLine.trim()) { chunks.push(currentLine.trim()); currentLine = word; } else { // Single word too long, just truncate it chunks.push(word.substring(0, maxLength - 3) + "..."); currentLine = ""; } } else { currentLine += (currentLine ? " " : "") + word; } } if (currentLine.trim()) { currentChunk = currentLine; } } else { currentChunk = line; } } else { currentChunk += (currentChunk ? "\n" : "") + line; } } if (currentChunk.trim()) { chunks.push(currentChunk.trim()); } return chunks; } /** * Generate tech tree for a faction using the beautiful ASCII tree format */ function generateTechTree(factionName) { try { // Dynamic require for oo-ascii-tree const { AsciiTree } = require("oo-ascii-tree"); // Get the faction instance (handle both ESM and CJS import styles) let faction; switch (factionName.toLowerCase()) { case "grell": const GrellClass = Grell.default || Grell; faction = new GrellClass(); break; case "protectorate": const ProtectorateClass = Protectorate.default || Protectorate; faction = new ProtectorateClass(); break; case "legion": const LegionClass = Legion.default || Legion; faction = new LegionClass(); break; default: return `āŒ ERROR: Faction '${factionName}' not found. Available: grell, protectorate, legion`; } // Get the tech tree data const techTreeData = faction.techTree; if (!techTreeData || !techTreeData.tree) { return `āŒ ERROR: No tech tree data found for faction '${factionName}'`; } // Helper to convert entity name to display format function getDisplayName(node) { if (!node || !node.name) return "Unknown"; return node.name; } // Convert faction tech tree to oo-ascii-tree format function buildAsciiTree(node, visited = new Set()) { if (!node || visited.has(node.id)) { return null; // Avoid infinite loops } const currentVisited = new Set(visited); currentVisited.add(node.id); const asciiNode = new AsciiTree(getDisplayName(node)); if (node.children && node.children.length > 0) { // Use iolin's perfect sorting as-is (upgrades already filtered out at source) for (const child of node.children) { const childNode = buildAsciiTree(child, currentVisited); if (childNode) { asciiNode.add(childNode); } } } return asciiNode; } // Get faction emoji const factionEmojis = { grell: "🧬", protectorate: "šŸŽ–ļø", legion: "šŸ”„", }; const emoji = factionEmojis[factionName.toLowerCase()] || "⚔"; const factionTitle = factionName.toUpperCase(); // Generate the tree with proper markdown structure const factionUrl = `${faction.zsggPath}?tab=techTree`; // Build the ASCII tree from the root const rootTree = buildAsciiTree(techTreeData.tree); let output = `## ${emoji} ${factionTitle} TECH TREE ${emoji}\n\n\`\`\`\n`; if (rootTree) { output += rootTree.toString(); } else { output += "No tech tree structure found."; } output += `\n\`\`\`\n\nšŸ“– **View detailed tech tree on ZeroSpace.gg:** <${factionUrl}>`; return output; } catch (error) { console.error("Tech tree generation error:", error); return `āŒ ERROR: Failed to generate tech tree for ${factionName}. ${error instanceof Error ? error.message : "Unknown error"}`; } } const techTreeSubcommand = { name: "tech-tree", description: "Show tech tree progression for a faction", builder: subcommand => subcommand .setName("tech-tree") .setDescription("Show tech tree progression for a faction") .addStringOption(option => option .setName("faction") .setDescription("Faction to show tech tree for") .setRequired(true) .addChoices({ name: "🧬 Grell", value: "grell" }, { name: "šŸŽ–ļø Protectorate", value: "protectorate" }, { name: "šŸ”„ Legion", value: "legion" })) .addBooleanOption(option => option.setName("public").setDescription("Show results to everyone (default: private)").setRequired(false)), async execute(interaction) { const faction = interaction.options.getString("faction", true); const isPublic = interaction.options.getBoolean("public") ?? false; try { // Defer reply await interaction.deferReply({ ephemeral: !isPublic }); // Generate tech tree const techTreeResult = generateTechTree(faction); // Check if generation failed if (techTreeResult.startsWith("āŒ")) { await interaction.editReply(techTreeResult); return; } // Discord has a 2000 character limit if (techTreeResult.length <= 2000) { await interaction.editReply(techTreeResult); } else { // Split the message const chunks = splitMessage(techTreeResult, 2000); await interaction.editReply(chunks[0]); for (let i = 1; i < chunks.length; i++) { await interaction.followUp({ content: chunks[i], ephemeral: !isPublic, }); } } } catch (error) { console.error("Tech tree command failed:", error); await interaction.editReply({ content: `āŒ Error generating tech tree: ${error instanceof Error ? error.message : "Unknown error"}`, }); } }, }; //# sourceMappingURL=tech-tree.js.map exports.generateTechTree = generateTechTree; exports.techTreeSubcommand = techTreeSubcommand;