From 6a1ab4dd91274aafb354e4ebd2e7fb026526aedd Mon Sep 17 00:00:00 2001 From: jay Date: Wed, 17 Feb 2021 09:44:57 +0500 Subject: [PATCH] feat(builder): :construction: add cover plugin for mycellium Work in progress, based on Trend's code. Everything is hardcoded. --- lib/plugins/mycellium.js | 217 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 lib/plugins/mycellium.js diff --git a/lib/plugins/mycellium.js b/lib/plugins/mycellium.js new file mode 100644 index 0000000..5ceefb5 --- /dev/null +++ b/lib/plugins/mycellium.js @@ -0,0 +1,217 @@ + +// const mineflayer = require('mineflayer') +// let pathfinder +// const { pathfinder, Movements, goals } = require('mineflayer-pathfinder') +const { Vec3 } = require('vec3') +// const { GoalFollow, GoalNear } = goals +let GoalFollow, GoalNear +// const mcData = require('minecraft-data')('1.16.5') +let mcData + +// let bot = mineflayer.createBot() +let bot +let cfg = { bot: null } +let timer +let movements + +/* let mcData +bot.once('spawn', () => { + mcData = require('minecraft-data')(bot.version) +}) */ + +function stopCovering(quiet = cfg.quiet, resetGoal = true) { // This is a function to stop the cover() loop when called + if (timer) { + clearTimeout(timer); + timer = null; + } + if (resetGoal) bot.pathfinder.setGoal(null) + bot.stopDigging() + quiet || bot.chat("stopped covering") +} + +function init() { + const { Movements, goals } = require('mineflayer-pathfinder') + GoalFollow = goals.GoalFollow + GoalNear = goals.GoalNear + movements = new Movements(bot, mcData) + movements.canDig = true // Lets the bot dig + bot.pathfinder.setMovements(movements) + + console.info("mycelium start") + stopCovering(true) + bot.waitForChunksToLoad(cover) +} + +function cover(timeInt = 1000) { + if (!Number.isSafeInteger(timeInt)) { + console.log("cover int maybe goal?", timeInt) + switch (timeInt.message) { + case "No path to the goal!": + console.info("Cover: can't reach") + cfg.quiet || bot.chat("can't reach") + break; + + default: + break; + } + if (timeInt) { + timeInt = 5000 + } + } else if (timeInt < 300) { + timeInt = 1000 + } + const wool = "white_wool" + const wool_item = mcData.itemsByName[wool] + const inventoryWool = bot.inventory.findInventoryItem(wool_item.id) + // console.info(wool_item.id, inventoryWool) + // if (!inventoryWool) return + // bot.loadPlugin(pathfinder) + + const myceliumClean = bot.findBlock({ // Const that is a brown_mushroom + maxDistance: 6, + matching: (block) => { + // First check the type + // lol + // const { brown_mushroom, red_mushroom, white_wool } = mcData.blocksByName + // if ([brown_mushroom.id, red_mushroom.id, white_wool.id].includes(block?.type)) { + const { brown_mushroom, red_mushroom, } = mcData.blocksByName + if ([brown_mushroom.id, red_mushroom.id,].includes(block?.type)) { + // If position is defined, you can refine the search + if (block.position) { + const blockBelow = bot.blockAt(block.position.offset(0, -1, 0)) + return blockBelow?.type === mcData.blocksByName.mycelium.id || blockBelow?.type === mcData.blocksByName.spruce_fence.id // Makes sure there is mycelium below + } + return true // otherwise return always true (there is water in the section so it should be checked) + } + return false + } + }) + + function findMycelium(dist = 5) { + return bot.findBlock({ + maxDistance: dist, + matching: (block) => { + // First check the type + if (block?.type === mcData.blocksByName.mycelium.id) { // Const that is a mycelium block + // If position is defined, you can refine the search + if (block.position) { + const blockAbove = bot.blockAt(block.position.offset(0, 1, 0)) + return !blockAbove || blockAbove?.type === mcData.blocksByName.air.id // Makes sure there is nothing above + } + return true // otherwise return always true (there is water in the section so it should be checked) + } + return false + } + }) + } + let mycelium = findMycelium() + + if (myceliumClean) { + // bot.dig(myceliumClean, true) + bot.dig(myceliumClean) + } + + if (mycelium) { + timeInt = 500 + if (bot.heldItem?.type !== wool_item.id) { // Equips wool if not already + if (!inventoryWool || inventoryWool.count < 10) { // Checks if there is less than 10 wool in the bots inventory + timeInt = 5000 + console.warn("no wool") + // const chestLocation = new Vec3(10614, 70, 5350) // Sets chest location + const chestLocation = bot.findBlock({ + maxDistance: 100, + matching: block => block && block.type === mcData.blocksByName.chest.id + })?.position // Sets chest location + const chestGoal = new GoalNear(chestLocation.x, chestLocation.y, chestLocation.z, 6) // Sets goal to chest location + return bot.pathfinder.goto(chestGoal, () => { // Run code below when it gets to the chest + bot.lookAt(chestLocation, true) // Looks at chest + const chest = bot.openChest(bot.blockAt(chestLocation)) // Sets const to for opening chest + chest.once('open', (err) => { // Opens chest + if (err) { + return console.error('Chest error', err) + } + const chest_item = chest.items().filter(item => item.type === wool_item.id) + console.info(chest, chest_item) + if (chest_item.length > 0) { // Checks that there is stuff in chest + try { + // Pulls out a chest (27 stack) of wool + // chest.withdraw(chest_item[0].type, null, 64 * 27) + chest.withdraw(chest_item[0].type, null, 64 * 3) + } catch (error) { + console.error('Chest withdraw error', error) + } + bot.once("close", cover) + } else { + console.log('Chest dont have', wool_item) + cfg.quiet || bot.chat(`Not enough ${wool} in chest`) + stopCovering() + } + setTimeout(chest.close, timeInt) + }) + }) + } else { + bot.equip(wool_item.id, "hand") + } + } else { + const pos = mycelium.position + bot.lookAt(pos, true) + // let tryCount = 0 + const flooredPos = bot.entity.position.floored() + if (flooredPos.offset(0, 1, 0).distanceTo(pos) <= 2) { + bot.setControlState('jump', true) + if (bot.entity.position.y > mycelium.position.y) { + bot.placeBlock(mycelium, new Vec3(0, 1, 0), (err) => { + setTimeout(bot.setControlState, 2000, 'jump', false) + if (err) { + console.error('Place (jumped)', err) + } + }) + } + } else { + bot.placeBlock(mycelium, new Vec3(0, 1, 0), (err) => { + if (err) { + if (err.message !== `No block has been placed : the block is still ${wool}`) { + return console.error('Place (normal)', err) + } else { + return + } + } + }) + } + } + } else { + mycelium = findMycelium(100) + if (mycelium) { + const pos = mycelium.position + const goal = new GoalNear(pos.x, pos.y, pos.z, 3) + stopCovering(true) + timeInt = 2000 + return bot.pathfinder.goto(goal, cover) + } else { + stopCovering(true) + return cfg.quiet || bot.chat("no uncovered mycelium nearby") + } + } + + timer = setTimeout(cover, timeInt, timeInt) +} + +function command(params) { + stopCovering(true) + cover() +} + +const load = (config) => { + cfg = config + bot = cfg.bot + mcData = bot.mcData || (bot.mcData = require('minecraft-data')(bot.version)) + + pathfinder = bot.pathfinder || bot.loadPlugin(require('mineflayer-pathfinder').pathfinder) + init() +} + +const unload = () => { + stopCovering(true) +} + +module.exports = { load, unload, command, cover, stopCovering } \ No newline at end of file