import type { CommandMessage } from '../../../core/types/commands'; import type Amayo from '../../../core/client'; import { runMinigame } from '../../../game/minigames/service'; import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback, resolveAreaByType, sendDisplayReply, fetchItemBasics, formatItemLabel } from './_helpers'; import { updateStats } from '../../../game/stats/service'; import { updateQuestProgress } from '../../../game/quests/service'; import { checkAchievements } from '../../../game/achievements/service'; import { buildDisplay, dividerBlock, textBlock } from '../../../core/lib/componentsV2'; const FIGHT_ACCENT = 0x992D22; export const command: CommandMessage = { name: 'pelear', type: 'message', aliases: ['fight','arena'], cooldown: 8, description: 'Entra a la arena y pelea (usa espada si está disponible).', usage: 'pelear [nivel] [toolKey] [area:clave] (ej: pelear 1 weapon.sword.iron)', run: async (message, args, _client: Amayo) => { const userId = message.author.id; const guildId = message.guild!.id; const { levelArg, providedTool, areaOverride } = parseGameArgs(args); const areaInfo = areaOverride ? await resolveGuildAreaWithFallback(guildId, areaOverride) : await resolveAreaByType(guildId, 'FIGHT'); if (!areaInfo.area) { if (areaOverride) { await message.reply(`⚠️ No existe un área con key \`${areaOverride}\` para este servidor.`); } else { await message.reply('⚠️ No hay un área de tipo **FIGHT** configurada. Crea una con `!area-crear` o especifica `area:`.'); } return; } const { area, source } = areaInfo; const globalNotice = source === 'global' ? `ℹ️ Usando configuración global para \`${area.key}\`. Puedes crear \`gameArea\` tipo **FIGHT** para personalizarla en este servidor.` : null; const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id); const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'sword'); try { const result = await runMinigame(userId, guildId, area.key, level, { toolKey: toolKey ?? undefined }); const rewardKeys = result.rewards .filter((r): r is { type: 'item'; itemKey: string; qty?: number } => r.type === 'item' && Boolean(r.itemKey)) .map((r) => r.itemKey!); if (result.tool?.key) rewardKeys.push(result.tool.key); const rewardItems = await fetchItemBasics(guildId, rewardKeys); // Actualizar stats y misiones await updateStats(userId, guildId, { fightsCompleted: 1 }); await updateQuestProgress(userId, guildId, 'fight_count', 1); // Contar mobs derrotados const mobsCount = result.mobs.length; if (mobsCount > 0) { await updateStats(userId, guildId, { mobsDefeated: mobsCount }); await updateQuestProgress(userId, guildId, 'mob_defeat_count', mobsCount); } const newAchievements = await checkAchievements(userId, guildId, 'fight_count'); const rewardLines = result.rewards.length ? result.rewards.map((r) => { if (r.type === 'coins') return `• 🪙 +${r.amount}`; const info = rewardItems.get(r.itemKey!); const label = formatItemLabel(info ?? { key: r.itemKey!, name: null, icon: null }); return `• ${label} x${r.qty ?? 1}`; }).join('\n') : '• —'; const mobsLines = result.mobs.length ? result.mobs.map(m => `• ${m}`).join('\n') : '• —'; const toolInfo = result.tool?.key ? `${formatItemLabel(rewardItems.get(result.tool.key) ?? { key: result.tool.key, name: null, icon: null }, { fallbackIcon: '🗡️' })}${result.tool.broken ? ' (rota)' : ` (-${result.tool.durabilityDelta ?? 0} dur.)`}` : '—'; const blocks = [textBlock('# ⚔️ Arena')]; if (globalNotice) { blocks.push(dividerBlock({ divider: false, spacing: 1 })); blocks.push(textBlock(globalNotice)); } blocks.push(dividerBlock()); const areaScope = source === 'global' ? '🌐 Configuración global' : '📍 Configuración local'; blocks.push(textBlock(`**Área:** \`${area.key}\` • ${areaScope}\n**Nivel:** ${level}\n**Arma:** ${toolInfo}`)); blocks.push(dividerBlock({ divider: false, spacing: 1 })); blocks.push(textBlock(`**Recompensas**\n${rewardLines}`)); blocks.push(dividerBlock({ divider: false, spacing: 1 })); blocks.push(textBlock(`**Enemigos**\n${mobsLines}`)); if (newAchievements.length > 0) { blocks.push(dividerBlock({ divider: false, spacing: 2 })); const achLines = newAchievements.map(ach => `✨ **${ach.name}** — ${ach.description}`).join('\n'); blocks.push(textBlock(`🏆 ¡Logro desbloqueado!\n${achLines}`)); } const display = buildDisplay(FIGHT_ACCENT, blocks); await sendDisplayReply(message, display); } catch (e: any) { await message.reply(`❌ No se pudo pelear: ${e?.message ?? e}`); } } };