74 lines
3.4 KiB
JavaScript
74 lines
3.4 KiB
JavaScript
// This example shows how to tell the bot to place an end crystal
|
|
// Example commands:
|
|
// "place crystal near bot" - find a block near the bot that has a block empty above it, then place a crystal on it
|
|
// "place crystal near ExplodeMe" - find a block near the player with username "ExplodeMe" that has an empty block above it, then place a crystal on it
|
|
|
|
const mineflayer = require('mineflayer')
|
|
const pathfinder = require('mineflayer-pathfinder')
|
|
const { Vec3 } = require('vec3')
|
|
const AABB = require('prismarine-physics/lib/aabb')
|
|
|
|
if (process.argv.length < 4 || process.argv.length > 6) {
|
|
console.log('Usage : node ansi.js <host> <port> [<name>] [<password>]')
|
|
process.exit(1)
|
|
}
|
|
const bot = mineflayer.createBot({
|
|
host: process.argv[2],
|
|
port: parseInt(process.argv[3]),
|
|
username: process.argv[4] ? process.argv[4] : 'crystal_bot',
|
|
password: process.argv[5],
|
|
plugins: [pathfinder.pathfinder]
|
|
})
|
|
|
|
const MAX_DIST_FROM_BLOCK_TO_PLACE = 4
|
|
|
|
bot.on('chat', async (ign, msg) => {
|
|
// solve where the bot will place the crystal near
|
|
let findBlocksNearPoint = null
|
|
if (msg === 'place crystal near bot') {
|
|
findBlocksNearPoint = bot.entity.position
|
|
} else if (msg.startsWith('place crystal near ')) {
|
|
const playerUsername = msg.split(' ').pop()
|
|
const player = bot.players[playerUsername]
|
|
if (!player) return bot.chat(`Couldn't find player with the username: "${playerUsername}"`)
|
|
findBlocksNearPoint = player.entity.position
|
|
} else {
|
|
return // don't do anything
|
|
}
|
|
|
|
// find end crystal(s) in inventory
|
|
const item = bot.inventory.findInventoryItem(bot.registry.itemsByName.end_crystal.id)
|
|
if (!item) bot.chat("I don't have any ender crystals")
|
|
|
|
// find the crystal
|
|
const block = bot.findBlock({
|
|
point: findBlocksNearPoint,
|
|
matching: ['bedrock', 'obsidian'].map(blockName => bot.registry.blocksByName[blockName].id),
|
|
useExtraInfo: block => {
|
|
const hasAirAbove = bot.blockAt(block.position.offset(0, 1, 0)).name === 'air'
|
|
const botNotStandingOnBlock = block.position.xzDistanceTo(bot.entity.position) > 2
|
|
// do no intersecting entity check
|
|
const { x: aboveX, y: aboveY, z: aboveZ } = block.position.offset(0, 1, 0)
|
|
const blockBoundingBox = new AABB(aboveX, aboveY, aboveZ, aboveX + 1, aboveY + 2, aboveZ + 1)
|
|
const entityAABBs = Object.values(bot.entities).map(entity => {
|
|
// taken from taken from https://github.com/PrismarineJS/prismarine-physics/blob/d145e54a4bb8604300258badd7563f59f2101922/index.js#L92
|
|
const w = entity.height / 2
|
|
const { x, y, z } = entity.position
|
|
return new AABB(-w, 0, -w, w, entity.height, w).offset(x, y, z)
|
|
})
|
|
const hasIntersectingEntities = entityAABBs.filter(aabb => aabb.intersects(blockBoundingBox)).length === 0
|
|
return hasAirAbove && botNotStandingOnBlock && !hasIntersectingEntities
|
|
}
|
|
})
|
|
if (!block) return bot.chat("Couldn't find bedrock or obsidian block that has air above it near myself.")
|
|
|
|
// get to the crystal
|
|
if (block.position.xzDistanceTo(bot.entity.position) > MAX_DIST_FROM_BLOCK_TO_PLACE) await bot.pathfinder.goto(new pathfinder.goals.GoalNear(block.position.x, block.position.y, block.position.z, MAX_DIST_FROM_BLOCK_TO_PLACE))
|
|
// get ready to place crystal
|
|
await bot.equip(item, 'hand')
|
|
await bot.lookAt(block.position, true)
|
|
// place crystal
|
|
await bot.placeEntity(block, new Vec3(0, 1, 0))
|
|
bot.chat('I placed an end crystal!')
|
|
})
|