From 0b7ec0ee3286cd2211b08f77a3ba24c16b094e20 Mon Sep 17 00:00:00 2001 From: shni Date: Sun, 5 Oct 2025 19:44:54 -0500 Subject: [PATCH] feat(game): add area fallback logic for commands and helpers --- src/commands/messages/game/_helpers.ts | 20 ++++++++++++++++++++ src/commands/messages/game/mina.ts | 18 +++++++++++------- src/commands/messages/game/pelear.ts | 15 ++++++++------- src/commands/messages/game/pescar.ts | 12 ++++++++---- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/commands/messages/game/_helpers.ts b/src/commands/messages/game/_helpers.ts index 955e059..2c16359 100644 --- a/src/commands/messages/game/_helpers.ts +++ b/src/commands/messages/game/_helpers.ts @@ -1,4 +1,5 @@ import { prisma } from '../../../core/database/prisma'; +import type { GameArea } from '@prisma/client'; import type { ItemProps } from '../../../game/economy/types'; export function parseItemProps(json: unknown): ItemProps { @@ -11,6 +12,25 @@ export async function resolveArea(guildId: string, areaKey: string) { return area; } +export interface ResolvedAreaInfo { + area: GameArea | null; + source: 'guild' | 'global' | 'none'; +} + +export async function resolveGuildAreaWithFallback(guildId: string, areaKey: string): Promise { + const guildArea = await prisma.gameArea.findFirst({ where: { key: areaKey, guildId } }); + if (guildArea) { + return { area: guildArea, source: 'guild' }; + } + + const globalArea = await prisma.gameArea.findFirst({ where: { key: areaKey, guildId: null } }); + if (globalArea) { + return { area: globalArea, source: 'global' }; + } + + return { area: null, source: 'none' }; +} + export async function getDefaultLevel(userId: string, guildId: string, areaId: string): Promise { const prog = await prisma.playerProgress.findUnique({ where: { userId_guildId_areaId: { userId, guildId, areaId } } }); return Math.max(1, prog?.highestLevel ?? 1); diff --git a/src/commands/messages/game/mina.ts b/src/commands/messages/game/mina.ts index 485b42a..6f3cbdd 100644 --- a/src/commands/messages/game/mina.ts +++ b/src/commands/messages/game/mina.ts @@ -1,7 +1,7 @@ import type { CommandMessage } from '../../../core/types/commands'; import type Amayo from '../../../core/client'; import { runMinigame } from '../../../game/minigames/service'; -import { resolveArea, getDefaultLevel, findBestToolKey, parseGameArgs } from './_helpers'; +import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback } from './_helpers'; import { updateStats } from '../../../game/stats/service'; import { updateQuestProgress } from '../../../game/quests/service'; import { checkAchievements } from '../../../game/achievements/service'; @@ -18,11 +18,14 @@ export const command: CommandMessage = { const guildId = message.guild!.id; const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'mine.cavern'); - const area = await resolveArea(guildId, areaKey); + const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey); if (!area) { - await message.reply(`⚠️ Área de mina no configurada. Pide a un admin crear \`gameArea\` con key \`${areaKey}\`.`); + await message.reply(`⚠️ Área de mina no configurada. Pide a un admin crear \`gameArea\` con key \`${areaKey}\` en este servidor.`); return; } + const globalNotice = source === 'global' + ? `ℹ️ Usando configuración global para \`${areaKey}\`. Puedes crear \`gameArea\` para personalizarla en este servidor.` + : null; const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id); const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'pickaxe'); @@ -32,9 +35,9 @@ export const command: CommandMessage = { // Actualizar stats await updateStats(userId, guildId, { minesCompleted: 1 }); - - // Actualizar progreso de misiones - await updateQuestProgress(userId, guildId, 'mine_count', 1); + + // Actualizar progreso de misiones + await updateQuestProgress(userId, guildId, 'mine_count', 1); // Verificar logros const newAchievements = await checkAchievements(userId, guildId, 'mine_count'); @@ -43,7 +46,8 @@ export const command: CommandMessage = { 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 = `⛏️ Mina (nivel ${level}) + let response = globalNotice ? `${globalNotice}\n\n` : ''; + response += `⛏️ Mina (nivel ${level}) Recompensas: ${rewards} Mobs: ${mobs} Herramienta: ${toolInfo}`; diff --git a/src/commands/messages/game/pelear.ts b/src/commands/messages/game/pelear.ts index ce53d7d..d165717 100644 --- a/src/commands/messages/game/pelear.ts +++ b/src/commands/messages/game/pelear.ts @@ -1,7 +1,7 @@ import type { CommandMessage } from '../../../core/types/commands'; import type Amayo from '../../../core/client'; import { runMinigame } from '../../../game/minigames/service'; -import { resolveArea, getDefaultLevel, findBestToolKey, parseGameArgs } from './_helpers'; +import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback } from './_helpers'; import { updateStats } from '../../../game/stats/service'; import { updateQuestProgress } from '../../../game/quests/service'; import { checkAchievements } from '../../../game/achievements/service'; @@ -18,11 +18,14 @@ export const command: CommandMessage = { const guildId = message.guild!.id; const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'fight.arena'); - const area = await resolveArea(guildId, areaKey); + const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey); if (!area) { - await message.reply(`⚠️ Área de arena no configurada. Crea \`gameArea\` con key \`${areaKey}\`.`); + await message.reply(`⚠️ Área de arena no configurada. Crea \`gameArea\` con key \`${areaKey}\` en este servidor.`); return; } + const globalNotice = source === 'global' + ? `ℹ️ Usando configuración global para \`${areaKey}\`. Puedes crear \`gameArea\` para personalizarla en este servidor.` + : null; const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id); const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'sword'); @@ -47,10 +50,8 @@ export const command: CommandMessage = { 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 = `⚔️ Arena (nivel ${level}) -Recompensas: ${rewards} -Enemigos: ${mobs} -Arma: ${toolInfo}`; + let response = globalNotice ? `${globalNotice}\n\n` : ''; + response += `⚔️ Arena (nivel ${level})\nRecompensas: ${rewards}\nEnemigos: ${mobs}\nArma: ${toolInfo}`; if (newAchievements.length > 0) { response += `\n\n🏆 ¡Logro desbloqueado!`; diff --git a/src/commands/messages/game/pescar.ts b/src/commands/messages/game/pescar.ts index 7104e55..d77f7db 100644 --- a/src/commands/messages/game/pescar.ts +++ b/src/commands/messages/game/pescar.ts @@ -1,7 +1,7 @@ import type { CommandMessage } from '../../../core/types/commands'; import type Amayo from '../../../core/client'; import { runMinigame } from '../../../game/minigames/service'; -import { resolveArea, getDefaultLevel, findBestToolKey, parseGameArgs } from './_helpers'; +import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback } from './_helpers'; import { updateStats } from '../../../game/stats/service'; import { updateQuestProgress } from '../../../game/quests/service'; import { checkAchievements } from '../../../game/achievements/service'; @@ -18,11 +18,14 @@ export const command: CommandMessage = { const guildId = message.guild!.id; const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'lagoon.shore'); - const area = await resolveArea(guildId, areaKey); + const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey); if (!area) { - await message.reply(`⚠️ Área de laguna no configurada. Crea \`gameArea\` con key \`${areaKey}\`.`); + await message.reply(`⚠️ Área de laguna no configurada. Crea \`gameArea\` con key \`${areaKey}\` en este servidor.`); return; } + const globalNotice = source === 'global' + ? `ℹ️ Usando configuración global para \`${areaKey}\`. Puedes crear \`gameArea\` para personalizarla en este servidor.` + : null; const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id); const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'rod'); @@ -39,7 +42,8 @@ export const command: CommandMessage = { 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 = `🎣 Pesca (nivel ${level}) + let response = globalNotice ? `${globalNotice}\n\n` : ''; + response += `🎣 Pesca (nivel ${level}) Recompensas: ${rewards} Mobs: ${mobs} Herramienta: ${toolInfo}`;