CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PrismarineJS

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: PrismarineJS/mineflayer
Path: blob/master/examples/place_end_crystal/index.js
Views: 789
1
// This example shows how to tell the bot to place an end crystal
2
// Example commands:
3
// "place crystal near bot" - find a block near the bot that has a block empty above it, then place a crystal on it
4
// "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
5
6
const mineflayer = require('mineflayer')
7
const pathfinder = require('mineflayer-pathfinder')
8
const { Vec3 } = require('vec3')
9
const AABB = require('prismarine-physics/lib/aabb')
10
11
if (process.argv.length < 4 || process.argv.length > 6) {
12
console.log('Usage : node ansi.js <host> <port> [<name>] [<password>]')
13
process.exit(1)
14
}
15
const bot = mineflayer.createBot({
16
host: process.argv[2],
17
port: parseInt(process.argv[3]),
18
username: process.argv[4] ? process.argv[4] : 'crystal_bot',
19
password: process.argv[5],
20
plugins: [pathfinder.pathfinder]
21
})
22
23
const MAX_DIST_FROM_BLOCK_TO_PLACE = 4
24
25
bot.on('chat', async (ign, msg) => {
26
// solve where the bot will place the crystal near
27
let findBlocksNearPoint = null
28
if (msg === 'place crystal near bot') {
29
findBlocksNearPoint = bot.entity.position
30
} else if (msg.startsWith('place crystal near ')) {
31
const playerUsername = msg.split(' ').pop()
32
const player = bot.players[playerUsername]
33
if (!player) return bot.chat(`Couldn't find player with the username: "${playerUsername}"`)
34
findBlocksNearPoint = player.entity.position
35
} else {
36
return // don't do anything
37
}
38
39
// find end crystal(s) in inventory
40
const item = bot.inventory.findInventoryItem(bot.registry.itemsByName.end_crystal.id)
41
if (!item) bot.chat("I don't have any ender crystals")
42
43
// find the crystal
44
const block = bot.findBlock({
45
point: findBlocksNearPoint,
46
matching: ['bedrock', 'obsidian'].map(blockName => bot.registry.blocksByName[blockName].id),
47
useExtraInfo: block => {
48
const hasAirAbove = bot.blockAt(block.position.offset(0, 1, 0)).name === 'air'
49
const botNotStandingOnBlock = block.position.xzDistanceTo(bot.entity.position) > 2
50
// do no intersecting entity check
51
const { x: aboveX, y: aboveY, z: aboveZ } = block.position.offset(0, 1, 0)
52
const blockBoundingBox = new AABB(aboveX, aboveY, aboveZ, aboveX + 1, aboveY + 2, aboveZ + 1)
53
const entityAABBs = Object.values(bot.entities).map(entity => {
54
// taken from https://github.com/PrismarineJS/prismarine-physics/blob/d145e54a4bb8604300258badd7563f59f2101922/index.js#L92
55
const w = entity.height / 2
56
const { x, y, z } = entity.position
57
return new AABB(-w, 0, -w, w, entity.height, w).offset(x, y, z)
58
})
59
const hasIntersectingEntities = entityAABBs.filter(aabb => aabb.intersects(blockBoundingBox)).length === 0
60
return hasAirAbove && botNotStandingOnBlock && !hasIntersectingEntities
61
}
62
})
63
if (!block) return bot.chat("Couldn't find bedrock or obsidian block that has air above it near myself.")
64
65
// get to the crystal
66
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))
67
// get ready to place crystal
68
await bot.equip(item, 'hand')
69
await bot.lookAt(block.position, true)
70
// place crystal
71
await bot.placeEntity(block, new Vec3(0, 1, 0))
72
bot.chat('I placed an end crystal!')
73
})
74
75