feat: Enhance offer editing command with interactive selection and improved error handling
- Added interactive selection for offers in the `offerEdit` command, allowing users to choose an offer to edit. - Improved permission checks with detailed error messages. - Refactored editor display and components for better readability and user experience. - Updated modal handling for various editing options (base, price, window, limits, metadata) to ensure consistent UI updates. - Enhanced feedback messages for successful updates and cancellations. - Integrated item fetching and formatting for better display of rewards in `pelear`, `pescar`, `plantar`, and `racha` commands. - Improved item display in the shop command with consistent formatting and icons.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
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 } from './_helpers';
|
||||
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 MINING_ACCENT = 0xC27C0E;
|
||||
|
||||
export const command: CommandMessage = {
|
||||
name: 'mina',
|
||||
@@ -41,6 +44,12 @@ export const command: CommandMessage = {
|
||||
|
||||
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
|
||||
await updateStats(userId, guildId, { minesCompleted: 1 });
|
||||
@@ -51,25 +60,44 @@ export const command: CommandMessage = {
|
||||
// Verificar logros
|
||||
const newAchievements = await checkAchievements(userId, guildId, 'mine_count');
|
||||
|
||||
const rewards = result.rewards.map(r => r.type === 'coins' ? `🪙 +${r.amount}` : `📦 ${r.itemKey} x${r.qty}`).join(' · ') || '—';
|
||||
const mobs = result.mobs.length ? result.mobs.join(', ') : '—';
|
||||
const toolInfo = result.tool?.key ? `🔧 ${result.tool.key}${result.tool.broken ? ' (rota)' : ` (-${result.tool.durabilityDelta} dur.)`}` : '—';
|
||||
|
||||
let response = globalNotice ? `${globalNotice}\n\n` : '';
|
||||
response += `⛏️ Mina (nivel ${level})
|
||||
Recompensas: ${rewards}
|
||||
Mobs: ${mobs}
|
||||
Herramienta: ${toolInfo}`;
|
||||
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.)`}`
|
||||
: '—';
|
||||
|
||||
// Notificar logros desbloqueados
|
||||
if (newAchievements.length > 0) {
|
||||
response += `\n\n🏆 ¡Logro desbloqueado!`;
|
||||
for (const ach of newAchievements) {
|
||||
response += `\n✨ **${ach.name}** - ${ach.description}`;
|
||||
}
|
||||
const blocks = [textBlock('# ⛏️ Mina')];
|
||||
|
||||
if (globalNotice) {
|
||||
blocks.push(dividerBlock({ divider: false, spacing: 1 }));
|
||||
blocks.push(textBlock(globalNotice));
|
||||
}
|
||||
|
||||
await message.reply(response);
|
||||
|
||||
blocks.push(dividerBlock());
|
||||
const areaScope = source === 'global' ? '🌐 Configuración global' : '📍 Configuración local';
|
||||
blocks.push(textBlock(`**Área:** \`${area.key}\` • ${areaScope}\n**Nivel:** ${level}\n**Herramienta:** ${toolInfo}`));
|
||||
blocks.push(dividerBlock({ divider: false, spacing: 1 }));
|
||||
blocks.push(textBlock(`**Recompensas**\n${rewardLines}`));
|
||||
blocks.push(dividerBlock({ divider: false, spacing: 1 }));
|
||||
blocks.push(textBlock(`**Mobs**\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(MINING_ACCENT, blocks);
|
||||
await sendDisplayReply(message, display);
|
||||
} catch (e: any) {
|
||||
await message.reply(`❌ No se pudo minar: ${e?.message ?? e}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user