Skip to main content
Glama
shop.ts4.04 kB
import { CryptoStorage } from '../storage/crypto.js'; import { SHOP_EQUIPMENT, SHOP_ITEMS, getShopEquipmentById, getShopItemById } from '../data/shop.js'; import { cloneEquipment } from '../game/loot.js'; import { cloneItem } from '../data/items.js'; const storage = new CryptoStorage(); export async function buyItem(itemId: string, saveKey: string): Promise<string> { const gameData = await storage.load(saveKey); // 探索中は購入不可 if (gameData.player.state === 'exploring') { return '探索中はショップを利用できません。探索が終了するまでお待ちください。'; } // 装備を探す const shopEquipment = getShopEquipmentById(itemId); if (shopEquipment) { // ゴールドチェック if (gameData.player.gold < shopEquipment.price) { return `ゴールドが足りません。必要: ${shopEquipment.price}G、所持: ${gameData.player.gold}G`; } // 購入処理 gameData.player.gold -= shopEquipment.price; const purchasedEquipment = cloneEquipment(shopEquipment); gameData.player.inventory.push(purchasedEquipment); await storage.save(gameData, saveKey); return `${shopEquipment.name}を${shopEquipment.price}Gで購入しました。残りゴールド: ${gameData.player.gold}G`; } // 持ち物アイテムを探す const shopItem = getShopItemById(itemId); if (shopItem) { // ゴールドチェック if (gameData.player.gold < shopItem.price) { return `ゴールドが足りません。必要: ${shopItem.price}G、所持: ${gameData.player.gold}G`; } // 購入処理 gameData.player.gold -= shopItem.price; const purchasedItem = cloneItem(shopItem); gameData.player.itemInventory.push(purchasedItem); await storage.save(gameData, saveKey); return `${shopItem.name}を${shopItem.price}Gで購入しました。残りゴールド: ${gameData.player.gold}G`; } return `アイテムID "${itemId}" は見つかりませんでした。`; } export async function getShopInventory(saveKey: string): Promise<string> { const gameData = await storage.load(saveKey); // 探索中は閲覧のみ可能(購入は不可) const canBuy = gameData.player.state === 'idle'; const statusMessage = canBuy ? `所持金: ${gameData.player.gold}G\n` : `⚠️ 探索中のため購入できません(閲覧のみ)\n所持金: ${gameData.player.gold}G\n`; let output = '=== 🏪 ショップ ===\n\n' + statusMessage + '\n'; // 装備セクション output += '【装備】\n'; const equipmentByRarity = { common: SHOP_EQUIPMENT.filter(eq => eq.rarity === 'common'), rare: SHOP_EQUIPMENT.filter(eq => eq.rarity === 'rare'), epic: SHOP_EQUIPMENT.filter(eq => eq.rarity === 'epic') }; for (const [rarity, items] of Object.entries(equipmentByRarity)) { if (items.length === 0) continue; const rarityName = rarity === 'common' ? 'コモン' : rarity === 'rare' ? 'レア' : 'エピック'; output += `\n[${rarityName}]\n`; for (const eq of items) { const typeIcon = eq.type === 'weapon' ? '⚔️' : eq.type === 'shield' ? '🛡️' : eq.type === 'armor' ? '🎽' : '💍'; const canAfford = gameData.player.gold >= eq.price ? '✅' : '❌'; output += `${canAfford} ${typeIcon} ${eq.name} - ${eq.price}G\n`; output += ` ID: ${eq.id}\n`; output += ` 攻撃+${eq.stats.attack} 防御+${eq.stats.defense} 速度+${eq.stats.speed} 運+${eq.stats.luck}\n`; } } // 持ち物アイテムセクション output += '\n【持ち物アイテム】\n'; for (const item of SHOP_ITEMS) { const typeIcon = item.type === 'herb' ? '🌿' : '🧿'; const canAfford = gameData.player.gold >= item.price ? '✅' : '❌'; output += `${canAfford} ${typeIcon} ${item.name} - ${item.price}G\n`; output += ` ID: ${item.id}\n`; output += ` ${item.description}\n`; } output += '\n購入方法: buy_item ツールで item_id を指定してください\n'; return output; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bellsanct/mcp-dungeon-game'

If you have feedback or need assistance with the MCP directory API, please join our Discord server