diff --git a/src/agent/commands/queries.js b/src/agent/commands/queries.js index 3419d0f..b4dc74a 100644 --- a/src/agent/commands/queries.js +++ b/src/agent/commands/queries.js @@ -17,6 +17,7 @@ export const queryList = [ 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`; @@ -31,6 +32,9 @@ export const queryList = [ // 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'; @@ -107,6 +111,11 @@ export const queryList = [ } 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); } diff --git a/src/agent/library/world.js b/src/agent/library/world.js index 6fc9460..0253b41 100644 --- a/src/agent/library/world.js +++ b/src/agent/library/world.js @@ -39,6 +39,82 @@ export function getNearestFreeSpace(bot, size=1, distance=8) { } +export function getBlockAtPosition(bot, x=0, y=0, z=0) { + /** + * Get a block from the bot's relative position + * @param {Bot} bot - The bot to get the block for. + * @param {number} x - The relative x offset to serach, default 0. + * @param {number} y - The relative y offset to serach, default 0. + * @param {number} y - The relative z offset to serach, default 0. + * @returns {Block} - The nearest block. + * @example + * let blockBelow = world.getBlockAtPosition(bot, 0, -1, 0); + * let blockAbove = world.getBlockAtPosition(bot, 0, 2, 0); since minecraft position is at the feet + **/ + let block = bot.blockAt(bot.entity.position.offset(x, y, z)); + if (!block) block = {name: 'air'}; + + return block; +} + + +export function getSurroundingBlocks(bot) { + /** + * Get the surrounding blocks from the bot's environment. + * @param {Bot} bot - The bot to get the block for. + * @returns {string[]} - A list of block results as strings. + * @example + **/ + // Create a list of block position results that can be unpacked. + let res = []; + res.push(`Block Below: ${getBlockAtPosition(bot, 0, -1, 0).name}`); + res.push(`Block at Legs: ${getBlockAtPosition(bot, 0, 0, 0).name}`); + res.push(`Block at Head: ${getBlockAtPosition(bot, 0, 1, 0).name}`); + + return res; +} + + +export function getFirstBlockAboveHead(bot, ignore_types=null, distance=32) { + /** + * Searches a column from the bot's position for the first solid block above its head + * @param {Bot} bot - The bot to get the block for. + * @param {string[]} ignore_types - The names of the blocks to ignore. + * @param {number} distance - The maximum distance to search, default 32. + * @returns {string} - The fist block above head. + * @example + * let firstBlockAboveHead = world.getFirstBlockAboveHead(bot, null, 32); + **/ + // if ignore_types is not a list, make it a list. + let ignore_blocks = []; + if (ignore_types === null) ignore_blocks = ['air', 'cave_air']; + else { + if (!Array.isArray(ignore_types)) + ignore_types = [ignore_types]; + for(let ignore_type of ignore_types) { + if (mc.getBlockId(ignore_type)) ignore_blocks.push(ignore_type); + } + } + // The block above, stops when it finds a solid block . + let block_above = {name: 'air'}; + let height = 0 + for (let i = 0; i < distance; i++) { + let block = bot.blockAt(bot.entity.position.offset(0, i+2, 0)); + if (!block) block = {name: 'air'}; + // Ignore and continue + if (ignore_blocks.includes(block.name)) continue; + // Defaults to any block + block_above = block; + height = i; + break; + } + + if (ignore_blocks.includes(block_above.name)) return 'none'; + + return `${block_above.name} (${height} blocks up)`; +} + + export function getNearestBlocks(bot, block_types=null, distance=16, count=10000) { /** * Get a list of the nearest blocks of the given types. diff --git a/src/utils/mcdata.js b/src/utils/mcdata.js index 4df8b2a..58cfbdb 100644 --- a/src/utils/mcdata.js +++ b/src/utils/mcdata.js @@ -18,7 +18,7 @@ const Item = prismarine_items(mc_version); * @typedef {string} BlockName */ -export const WOOD_TYPES = ['oak', 'spruce', 'birch', 'jungle', 'acacia', 'dark_oak']; +export const WOOD_TYPES = ['oak', 'spruce', 'birch', 'jungle', 'acacia', 'dark_oak', 'mangrove', 'cherry']; export const MATCHING_WOOD_BLOCKS = [ 'log', 'planks', @@ -202,7 +202,7 @@ export function isSmeltable(itemName) { } export function getSmeltingFuel(bot) { - let fuel = bot.inventory.items().find(i => i.name === 'coal' || i.name === 'charcoal') + let fuel = bot.inventory.items().find(i => i.name === 'coal' || i.name === 'charcoal' || i.name === 'blaze_rod') if (fuel) return fuel; fuel = bot.inventory.items().find(i => i.name.includes('log') || i.name.includes('planks')) @@ -214,6 +214,8 @@ export function getSmeltingFuel(bot) { export function getFuelSmeltOutput(fuelName) { if (fuelName === 'coal' || fuelName === 'charcoal') return 8; + if (fuelName === 'blaze_rod') + return 12; if (fuelName.includes('log') || fuelName.includes('planks')) return 1.5 if (fuelName === 'coal_block')