Skip to content

Pathfinding help #3440

@ghost

Description

Hello!! I wanted to write a bot that would run after a specified list of items and pick them up. But I didn’t succeed, the bot runs halfway then stands and turns its head, the movement is very broken

const mineflayer = require('mineflayer');
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder');
const mcData = require('minecraft-data')('1.16.4'); // Replace with your Minecraft version
const readline = require('readline');

// Create the bot
const bot = mineflayer.createBot({
  host: 'funtime.su',
  username: 'PUP52'
});

// Load the pathfinder plugin into the bot
bot.loadPlugin(pathfinder);

// Set up the interface for reading console input
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// List of items to search for
const itemsToCollect = [
  'diamond',
  'iron_ingot',
  'gold_ingot',
  'redstone',
  'lapis_lazuli',
  'coal',
  'st' // Make sure this item name is correct
];

const searchRadius = 25; // Search radius for items

let collectingItem = false; // Flag to check if the bot is currently collecting an item

// Event handler for login
bot.on('login', () => {
  console.log(`Bot ${bot.username} successfully logged into the server!`);
  rl.prompt();
});

// Error handler
bot.on('error', (err) => {
  console.log(`An error occurred: ${err.message}`);
});

// Disconnect handler
bot.on('end', () => {
  console.log('Bot disconnected from the server.');
  rl.close();
});

// Function to search for all items within a radius and pick up the first one found
function findAndPickUpItem() {
  if (collectingItem) return; // Don't search for new items while collecting the current one

  const itemsFound = Object.values(bot.entities).filter(entity => {
    if (entity.name === 'item') {
      const itemId = entity.metadata[8].itemId;
      const itemName = mcData.items[itemId]?.name;
      const distance = bot.entity.position.distanceTo(entity.position);
      return itemsToCollect.includes(itemName) && distance <= searchRadius;
    }
    return false;
  });

  if (itemsFound.length > 0) {
    const targetItem = itemsFound[0]; // First item found
    moveToAndPickUpItem(targetItem);
  } else {
    console.log('No items found within the search radius.');
    setTimeout(findAndPickUpItem, 10000); // Retry after 10 seconds
  }
}

// Function to move to the item and pick it up
function moveToAndPickUpItem(item) {
  collectingItem = true;

  const movements = new Movements(bot, mcData);
  bot.pathfinder.setMovements(movements);

  const goal = new goals.GoalBlock(item.position.x, item.position.y, item.position.z);
  bot.pathfinder.setGoal(goal, true); // Set the movement goal

  bot.once('goal_reached', () => {
    console.log(`Reached the item ${mcData.items[item.metadata[8].itemId]?.name}. Starting to collect.`);

    // Ensure the bot is looking correctly at the item
    bot.lookAt(item.position.offset(0, 1, 0), false); // Look slightly above the item for pickup

    bot.once('entitySpawn', (entity) => {
      if (entity === item) {
        bot.collectBlock.collect(item, (err) => {
          if (err) {
            console.log(`Error while collecting item: ${err}`);
          } else {
            console.log(`Item ${mcData.items[item.metadata[8].itemId]?.name} collected.`);
          }

          collectingItem = false;
          setTimeout(findAndPickUpItem, 5000); // Wait a bit and search for items again
        });
      }
    });
  });

  bot.once('path_update', (results) => {
    if (results.status === 'noPath') {
      console.log('Unable to find a direct path. Retrying.');
      collectingItem = false;
      setTimeout(findAndPickUpItem, 1000); // Restart search in a second
    }
  });

  bot.once('stuck', () => {
    console.log('Bot got stuck or couldn’t reach the item.');
    collectingItem = false;
    setTimeout(findAndPickUpItem, 1000); // Restart search in a second
  });
}

// Handle console input
rl.on('line', (input) => {
  if (input.toLowerCase() === 'stop') {
    console.log('Disconnecting the bot...');
    bot.end();
  } else if (input.toLowerCase() === 'start') {
    findAndPickUpItem(); // Start searching for items
  } else {
    bot.chat(input); // Send a message to the chat
  }
  rl.prompt();
});

// When the console closes, the bot disconnects too
rl.on('close', () => {
  bot.end();
  console.log('Console closed, bot disconnected.');
});

If possible for version 1.16.5 minimum❤️

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stage1just created by someone new to the project, we don't know yet if it deserves an implementation / a fnew feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions