feat(game): add area fallback logic for commands and helpers
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { prisma } from '../../../core/database/prisma';
|
import { prisma } from '../../../core/database/prisma';
|
||||||
|
import type { GameArea } from '@prisma/client';
|
||||||
import type { ItemProps } from '../../../game/economy/types';
|
import type { ItemProps } from '../../../game/economy/types';
|
||||||
|
|
||||||
export function parseItemProps(json: unknown): ItemProps {
|
export function parseItemProps(json: unknown): ItemProps {
|
||||||
@@ -11,6 +12,25 @@ export async function resolveArea(guildId: string, areaKey: string) {
|
|||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ResolvedAreaInfo {
|
||||||
|
area: GameArea | null;
|
||||||
|
source: 'guild' | 'global' | 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resolveGuildAreaWithFallback(guildId: string, areaKey: string): Promise<ResolvedAreaInfo> {
|
||||||
|
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<number> {
|
export async function getDefaultLevel(userId: string, guildId: string, areaId: string): Promise<number> {
|
||||||
const prog = await prisma.playerProgress.findUnique({ where: { userId_guildId_areaId: { userId, guildId, areaId } } });
|
const prog = await prisma.playerProgress.findUnique({ where: { userId_guildId_areaId: { userId, guildId, areaId } } });
|
||||||
return Math.max(1, prog?.highestLevel ?? 1);
|
return Math.max(1, prog?.highestLevel ?? 1);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CommandMessage } from '../../../core/types/commands';
|
import type { CommandMessage } from '../../../core/types/commands';
|
||||||
import type Amayo from '../../../core/client';
|
import type Amayo from '../../../core/client';
|
||||||
import { runMinigame } from '../../../game/minigames/service';
|
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 { updateStats } from '../../../game/stats/service';
|
||||||
import { updateQuestProgress } from '../../../game/quests/service';
|
import { updateQuestProgress } from '../../../game/quests/service';
|
||||||
import { checkAchievements } from '../../../game/achievements/service';
|
import { checkAchievements } from '../../../game/achievements/service';
|
||||||
@@ -18,11 +18,14 @@ export const command: CommandMessage = {
|
|||||||
const guildId = message.guild!.id;
|
const guildId = message.guild!.id;
|
||||||
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'mine.cavern');
|
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'mine.cavern');
|
||||||
|
|
||||||
const area = await resolveArea(guildId, areaKey);
|
const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey);
|
||||||
if (!area) {
|
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;
|
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 level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
||||||
const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'pickaxe');
|
const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'pickaxe');
|
||||||
@@ -43,7 +46,8 @@ export const command: CommandMessage = {
|
|||||||
const mobs = result.mobs.length ? result.mobs.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.)`}` : '—';
|
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}
|
Recompensas: ${rewards}
|
||||||
Mobs: ${mobs}
|
Mobs: ${mobs}
|
||||||
Herramienta: ${toolInfo}`;
|
Herramienta: ${toolInfo}`;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CommandMessage } from '../../../core/types/commands';
|
import type { CommandMessage } from '../../../core/types/commands';
|
||||||
import type Amayo from '../../../core/client';
|
import type Amayo from '../../../core/client';
|
||||||
import { runMinigame } from '../../../game/minigames/service';
|
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 { updateStats } from '../../../game/stats/service';
|
||||||
import { updateQuestProgress } from '../../../game/quests/service';
|
import { updateQuestProgress } from '../../../game/quests/service';
|
||||||
import { checkAchievements } from '../../../game/achievements/service';
|
import { checkAchievements } from '../../../game/achievements/service';
|
||||||
@@ -18,11 +18,14 @@ export const command: CommandMessage = {
|
|||||||
const guildId = message.guild!.id;
|
const guildId = message.guild!.id;
|
||||||
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'fight.arena');
|
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'fight.arena');
|
||||||
|
|
||||||
const area = await resolveArea(guildId, areaKey);
|
const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey);
|
||||||
if (!area) {
|
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;
|
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 level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
||||||
const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'sword');
|
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 mobs = result.mobs.length ? result.mobs.join(', ') : '—';
|
||||||
const toolInfo = result.tool?.key ? `🗡️ ${result.tool.key}${result.tool.broken ? ' (rota)' : ` (-${result.tool.durabilityDelta} dur.)`}` : '—';
|
const toolInfo = result.tool?.key ? `🗡️ ${result.tool.key}${result.tool.broken ? ' (rota)' : ` (-${result.tool.durabilityDelta} dur.)`}` : '—';
|
||||||
|
|
||||||
let response = `⚔️ Arena (nivel ${level})
|
let response = globalNotice ? `${globalNotice}\n\n` : '';
|
||||||
Recompensas: ${rewards}
|
response += `⚔️ Arena (nivel ${level})\nRecompensas: ${rewards}\nEnemigos: ${mobs}\nArma: ${toolInfo}`;
|
||||||
Enemigos: ${mobs}
|
|
||||||
Arma: ${toolInfo}`;
|
|
||||||
|
|
||||||
if (newAchievements.length > 0) {
|
if (newAchievements.length > 0) {
|
||||||
response += `\n\n🏆 ¡Logro desbloqueado!`;
|
response += `\n\n🏆 ¡Logro desbloqueado!`;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CommandMessage } from '../../../core/types/commands';
|
import type { CommandMessage } from '../../../core/types/commands';
|
||||||
import type Amayo from '../../../core/client';
|
import type Amayo from '../../../core/client';
|
||||||
import { runMinigame } from '../../../game/minigames/service';
|
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 { updateStats } from '../../../game/stats/service';
|
||||||
import { updateQuestProgress } from '../../../game/quests/service';
|
import { updateQuestProgress } from '../../../game/quests/service';
|
||||||
import { checkAchievements } from '../../../game/achievements/service';
|
import { checkAchievements } from '../../../game/achievements/service';
|
||||||
@@ -18,11 +18,14 @@ export const command: CommandMessage = {
|
|||||||
const guildId = message.guild!.id;
|
const guildId = message.guild!.id;
|
||||||
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'lagoon.shore');
|
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'lagoon.shore');
|
||||||
|
|
||||||
const area = await resolveArea(guildId, areaKey);
|
const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey);
|
||||||
if (!area) {
|
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;
|
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 level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
||||||
const toolKey = providedTool ?? await findBestToolKey(userId, guildId, 'rod');
|
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 mobs = result.mobs.length ? result.mobs.join(', ') : '—';
|
||||||
const toolInfo = result.tool?.key ? `🎣 ${result.tool.key}${result.tool.broken ? ' (rota)' : ` (-${result.tool.durabilityDelta} dur.)`}` : '—';
|
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}
|
Recompensas: ${rewards}
|
||||||
Mobs: ${mobs}
|
Mobs: ${mobs}
|
||||||
Herramienta: ${toolInfo}`;
|
Herramienta: ${toolInfo}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user