const assert = require('assert') module.exports = inject function inject (bot) { const Item = require('prismarine-item')(bot.registry) /** * * @param {import('prismarine-block').Block} referenceBlock * @param {import('vec3').Vec3} faceVector * @param {{half?: 'top'|'bottom', delta?: import('vec3').Vec3, forceLook?: boolean | 'ignore', offhand?: boolean, swingArm?: 'right' | 'left', showHand?: boolean}} options */ async function _genericPlace (referenceBlock, faceVector, options) { let handToPlaceWith = 0 if (options.offhand) { if (!bot.inventory.slots[45]) { throw new Error('must be holding an item in the off-hand to place') } handToPlaceWith = 1 } else if (!bot.heldItem) { throw new Error('must be holding an item to place') } // Look at the center of the face let dx = 0.5 + faceVector.x * 0.5 let dy = 0.5 + faceVector.y * 0.5 let dz = 0.5 + faceVector.z * 0.5 if (dy === 0.5) { if (options.half === 'top') dy += 0.25 else if (options.half === 'bottom') dy -= 0.25 } if (options.delta) { dx = options.delta.x dy = options.delta.y dz = options.delta.z } if (options.forceLook !== 'ignore') { await bot.lookAt(referenceBlock.position.offset(dx, dy, dz), options.forceLook) } // TODO: tell the server that we are sneaking while doing this const pos = referenceBlock.position if (options.swingArm) { bot.swingArm(options.swingArm, options.showHand) } if (bot.supportFeature('blockPlaceHasHeldItem')) { const packet = { location: pos, direction: vectorToDirection(faceVector), heldItem: Item.toNotch(bot.heldItem), cursorX: Math.floor(dx * 16), cursorY: Math.floor(dy * 16), cursorZ: Math.floor(dz * 16) } bot._client.write('block_place', packet) } else if (bot.supportFeature('blockPlaceHasHandAndIntCursor')) { bot._client.write('block_place', { location: pos, direction: vectorToDirection(faceVector), hand: handToPlaceWith, cursorX: Math.floor(dx * 16), cursorY: Math.floor(dy * 16), cursorZ: Math.floor(dz * 16) }) } else if (bot.supportFeature('blockPlaceHasHandAndFloatCursor')) { bot._client.write('block_place', { location: pos, direction: vectorToDirection(faceVector), hand: handToPlaceWith, cursorX: dx, cursorY: dy, cursorZ: dz }) } else if (bot.supportFeature('blockPlaceHasInsideBlock')) { bot._client.write('block_place', { location: pos, direction: vectorToDirection(faceVector), hand: handToPlaceWith, cursorX: dx, cursorY: dy, cursorZ: dz, insideBlock: false }) } return pos } bot._genericPlace = _genericPlace } function vectorToDirection (v) { if (v.y < 0) { return 0 } else if (v.y > 0) { return 1 } else if (v.z < 0) { return 2 } else if (v.z > 0) { return 3 } else if (v.x < 0) { return 4 } else if (v.x > 0) { return 5 } assert.ok(false, `invalid direction vector ${v}`) }