Skip to main content
Glama
swimHelper.ts4.62 kB
import { Bot } from 'mineflayer'; import { Vec3 } from 'vec3'; import { ISkillServiceParams } from '../../types/skillType.js'; import { asyncwrap } from './asyncwrap.js'; // Simple coordinate interface interface ICoordinate { x: number; y: number; z: number; } interface IFindSurfaceOptions { position?: Vec3; getStatsData: ISkillServiceParams['getStatsData']; setStatsData: ISkillServiceParams['setStatsData']; } interface IFindSurfaceDefaultOptions { position: Vec3 | null; } interface IFindLandOptions { startPosition: Vec3; getStatsData: ISkillServiceParams['getStatsData']; setStatsData: ISkillServiceParams['setStatsData']; } /** * Finds the first air block above the specified position or the bot's current position. * * @param {Object} bot - The Mineflayer bot instance. * @param {object} options * @param {Vec3} [options.position = null]: The starting position to search from. If not provided, the bot's current position plus one block up is used. * @param {Function} options.getStatsData - The function to get the stats data from evaluateCode. * @param {Function} options.setStatsData - The function to set the stats data from evaluateCode. * * @returns {Promise<Vec3>} The position of the first air block found, or `null` if no air block is found within the maximum search height. */ export async function findSurface( bot: Bot, options: IFindSurfaceOptions, ): Promise<Vec3 | null> { const defaultOptions: IFindSurfaceDefaultOptions = { position: null, }; const { position, getStatsData, setStatsData } = { ...defaultOptions, ...options, }; let currentPosition = bot.entity.position.offset(0, 1, 0); // Start checking from one block above the bot if (position) { currentPosition = position; } const maxIterations = 400; // Maximum number of blocks to check upward // Linear search to find the first air block, with a limit on the number of iterations for (let i = 0; i < maxIterations; i++) { const block = await asyncwrap({ func: async () => { return bot.world.getBlock(currentPosition); }, getStatsData, setStatsData, }); if (block.name === 'air') { console.log( `Surface found at ${currentPosition.x}, ${currentPosition.y}, ${currentPosition.z}`, ); return currentPosition; // Return the position as soon as the first air block is found } currentPosition = currentPosition.offset(0, 1, 0); // Move up one block to check the next } console.log('Reached the maximum search height without finding surface.'); return null; // Return null if the surface is not found within the limit } export async function findLand( bot: Bot, options: IFindLandOptions, ): Promise<ICoordinate | null> { const { startPosition, getStatsData, setStatsData } = options; const visited = new Set(); const queue = [[Math.floor(startPosition.x), Math.floor(startPosition.z)]]; const directions = [ [1, 0], [-1, 0], [0, 1], [0, -1], ]; const landBlocks = new Set([ 'stone', 'grass_block', 'dirt', 'podzol', 'sand', 'gravel', 'clay', 'bedrock', 'coal_ore', 'iron_ore', 'sandstone', 'mossy_cobblestone', 'obsidian', 'snow', 'ice', 'packed_ice', 'blue_ice', 'red_sand', 'terracotta', 'coarse_dirt', ]); // Defines land blocks considered as solid land while (queue.length > 0) { const [currentX, currentZ] = queue.shift(); for (const [dx, dz] of directions) { const nx = currentX + dx; const nz = currentZ + dz; const hash = `${nx},${nz}`; if (!visited.has(hash)) { visited.add(hash); const position = new Vec3(nx, startPosition.y, nz); const block = await asyncwrap({ func: async () => { return bot.world.getBlock(position); }, getStatsData, setStatsData, }); const blockBelow = await asyncwrap({ func: async () => { return bot.world.getBlock(position.offset(0, -1, 0)); }, getStatsData, setStatsData, }); if (block.name === 'air' && landBlocks.has(blockBelow.name)) { console.log(`Land found at ${nx}, ${startPosition.y}, ${nz}`); return { x: nx, y: startPosition.y, z: nz }; // Coordinates of the land block } queue.push([nx, nz]); // Adds new position to the queue for further exploration } } } console.log('No land found within search range.'); return null; // Returns null if no land is found }

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/leo4life2/minecraft-mcp-http'

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