import * as world from '../library/world.js'; import * as mc from '../../utils/mcdata.js'; import { getCommandDocs } from './index.js'; import convoManager from '../conversation.js'; const pad = (str) => { return '\n' + str + '\n'; } // queries are commands that just return strings and don't affect anything in the world export const queryList = [ { name: "!stats", description: "Get your bot's location, health, hunger, and time of day.", perform: function (agent) { let bot = agent.bot; let res = 'STATS'; let pos = bot.entity.position; // display position to 2 decimal places res += `\n- Position: x: ${pos.x.toFixed(2)}, y: ${pos.y.toFixed(2)}, z: ${pos.z.toFixed(2)}`; // Gameplay res += `\n- Gamemode: ${bot.game.gameMode}`; res += `\n- Health: ${Math.round(bot.health)} / 20`; res += `\n- Hunger: ${Math.round(bot.food)} / 20`; res += `\n- Biome: ${world.getBiomeName(bot)}`; let weather = "Clear"; if (bot.rainState > 0) weather = "Rain"; if (bot.thunderState > 0) weather = "Thunderstorm"; res += `\n- Weather: ${weather}`; // let block = bot.blockAt(pos); // res += `\n- Artficial light: ${block.skyLight}`; // res += `\n- Sky light: ${block.light}`; // light properties are bugged, they are not accurate res += '\n- ' + world.getSurroundingBlocks(bot).join('\n- ') res += `\n- First Solid Block Above Head: ${world.getFirstBlockAboveHead(bot, null, 32)}`; if (bot.time.timeOfDay < 6000) { res += '\n- Time: Morning'; } else if (bot.time.timeOfDay < 12000) { res += '\n- Time: Afternoon'; } else { res += '\n- Time: Night'; } // get the bot's current action let action = agent.actions.currentActionLabel; if (agent.isIdle()) action = 'Idle'; res += `\- Current Action: ${action}`; let players = world.getNearbyPlayerNames(bot); let bots = convoManager.getInGameAgents().filter(b => b !== agent.name); players = players.filter(p => !bots.includes(p)); res += '\n- Nearby Human Players: ' + (players.length > 0 ? players.join(', ') : 'None.'); res += '\n- Nearby Bot Players: ' + (bots.length > 0 ? bots.join(', ') : 'None.'); res += '\n' + agent.bot.modes.getMiniDocs() + '\n'; return pad(res); } }, { name: "!inventory", description: "Get your bot's inventory.", perform: function (agent) { let bot = agent.bot; let inventory = world.getInventoryCounts(bot); let res = 'INVENTORY'; for (const item in inventory) { if (inventory[item] && inventory[item] > 0) res += `\n- ${item}: ${inventory[item]}`; } if (res === 'INVENTORY') { res += ': Nothing'; } else if (agent.bot.game.gameMode === 'creative') { res += '\n(You have infinite items in creative mode. You do not need to gather resources!!)'; } let helmet = bot.inventory.slots[5]; let chestplate = bot.inventory.slots[6]; let leggings = bot.inventory.slots[7]; let boots = bot.inventory.slots[8]; res += '\nWEARING: '; if (helmet) res += `\nHead: ${helmet.name}`; if (chestplate) res += `\nTorso: ${chestplate.name}`; if (leggings) res += `\nLegs: ${leggings.name}`; if (boots) res += `\nFeet: ${boots.name}`; if (!helmet && !chestplate && !leggings && !boots) res += 'Nothing'; return pad(res); } }, { name: "!nearbyBlocks", description: "Get the blocks near the bot.", perform: function (agent) { let bot = agent.bot; let res = 'NEARBY_BLOCKS'; let blocks = world.getNearbyBlockTypes(bot); for (let i = 0; i < blocks.length; i++) { res += `\n- ${blocks[i]}`; } if (blocks.length == 0) { res += ': none'; } else { // Environmental Awareness res += '\n- ' + world.getSurroundingBlocks(bot).join('\n- ') res += `\n- First Solid Block Above Head: ${world.getFirstBlockAboveHead(bot, null, 32)}`; } return pad(res); } }, { name: "!craftable", description: "Get the craftable items with the bot's inventory.", perform: function (agent) { let craftable = world.getCraftableItems(agent.bot); let res = 'CRAFTABLE_ITEMS'; for (const item of craftable) { res += `\n- ${item}`; } if (res == 'CRAFTABLE_ITEMS') { res += ': none'; } return pad(res); } }, { name: "!entities", description: "Get the nearby players and entities.", perform: function (agent) { let bot = agent.bot; let res = 'NEARBY_ENTITIES'; let players = world.getNearbyPlayerNames(bot); let bots = convoManager.getInGameAgents().filter(b => b !== agent.name); players = players.filter(p => !bots.includes(p)); for (const player of players) { res += `\n- Human player: ${player}`; } for (const bot of bots) { res += `\n- Bot player: ${bot}`; } for (const entity of world.getNearbyEntityTypes(bot)) { if (entity === 'player' || entity === 'item') continue; res += `\n- entities: ${entity}`; } if (res == 'NEARBY_ENTITIES') { res += ': none'; } return pad(res); } }, { name: "!modes", description: "Get all available modes and their docs and see which are on/off.", perform: function (agent) { return agent.bot.modes.getDocs(); } }, { name: '!savedPlaces', description: 'List all saved locations.', perform: async function (agent) { return "Saved place names: " + agent.memory_bank.getKeys(); } }, { name: '!getCraftingPlan', description: "Provides a comprehensive crafting plan for a specified item. This includes a breakdown of required ingredients, the exact quantities needed, and an analysis of missing ingredients or extra items needed based on the bot's current inventory.", params: { targetItem: { type: 'string', description: 'The item that we are trying to craft' }, quantity: { type: 'int', description: 'The quantity of the item that we are trying to craft', optional: true, domain: [1, Infinity, '[)'], // Quantity must be at least 1, default: 1 } }, perform: function (agent, targetItem, quantity = 1) { let bot = agent.bot; // Fetch the bot's inventory const curr_inventory = world.getInventoryCounts(bot); const target_item = targetItem; let existingCount = curr_inventory[target_item] || 0; let prefixMessage = ''; if (existingCount > 0) { curr_inventory[target_item] -= existingCount; prefixMessage = `You already have ${existingCount} ${target_item} in your inventory. If you need to craft more,\n`; } // Generate crafting plan let craftingPlan = mc.getDetailedCraftingPlan(target_item, quantity, curr_inventory); craftingPlan = prefixMessage + craftingPlan; console.log(craftingPlan); return pad(craftingPlan); }, }, { name: '!help', description: 'Lists all available commands and their descriptions.', perform: async function (agent) { return getCommandDocs(); } }, ];