From b3b9a26288652c4b60cac9fd81ffb1c8cd6b0681 Mon Sep 17 00:00:00 2001
From: Daenges <57369924+Daenges@users.noreply.github.com>
Date: Tue, 3 Aug 2021 07:25:43 +0200
Subject: [PATCH] Add script for excavating cubes (#1677)
* Add MineCube.cs
* Clear unused comments and using directives
* Move the command to a chatbot class
* Set a maximum sleep time for block mining
* Add tool selection function
* Improve the block - tool detection
* Improve naming and comments
* Add missing blocktypes
* Add block-tool assertion and tool switching in hotbar
* Remove unused using declaratives and improve coordinate handling
* Move Material2Tool in the Mapping folder
* Add function to let the bot mine up to 5 blocks above its head
* Remove obsolete function to detect breakability
* Implement mineup command
Users can dig out a 2 high square manually. The client will walk through it
mining everything that is reachable above, while avoiding falling blocks and liquids.
* Refactor big parts of the code
Move the function for obtaining cubes to a seperate file.
Sort Unbreakables alphabetically.
Change the distance to wait in the mine function back to 2.
* Fix suggestions from review
Change several parts of the code according to the review
Add credits
* Convert the bot into a script file and move it to config folder
Adjust the script to be loadable with /script
Remove unnecessary code
Add public modifier to material2tool
* Add checking for lava and water for normal mining
* Remove MineCube.cs from chatbots
* Code re-format
Rename variables
Fix indentation
Co-authored-by: ReinforceZwei <39955851+ReinforceZwei@users.noreply.github.com>
---
MinecraftClient/Mapping/CubeFromWorld.cs | 165 +++++
MinecraftClient/Mapping/Material2Tool.cs | 705 ++++++++++++++++++++
MinecraftClient/MinecraftClient.csproj | 2 +
MinecraftClient/config/ChatBots/MineCube.cs | 315 +++++++++
4 files changed, 1187 insertions(+)
create mode 100644 MinecraftClient/Mapping/CubeFromWorld.cs
create mode 100644 MinecraftClient/Mapping/Material2Tool.cs
create mode 100644 MinecraftClient/config/ChatBots/MineCube.cs
diff --git a/MinecraftClient/Mapping/CubeFromWorld.cs b/MinecraftClient/Mapping/CubeFromWorld.cs
new file mode 100644
index 00000000..94ee39ee
--- /dev/null
+++ b/MinecraftClient/Mapping/CubeFromWorld.cs
@@ -0,0 +1,165 @@
+using System;
+using System.Collections.Generic;
+
+namespace MinecraftClient.Mapping
+{
+ ///
+ /// A row of blocks that will be mined
+ ///
+ public class Row
+ {
+ public readonly List BlocksInRow;
+
+ ///
+ /// Initialize a row of blocks
+ ///
+ /// Enter a list of blocks
+ public Row(List blocksInRow = null)
+ {
+ BlocksInRow = blocksInRow ?? new List();
+ }
+ }
+
+ ///
+ /// Several rows are summarized in a layer
+ ///
+ public class Layer
+ {
+ public readonly List RowsInLayer;
+
+ ///
+ /// Add a new row to this layer
+ ///
+ /// enter a row that should be added
+ /// Index of the last row
+ public void AddRow(Row givenRow = null)
+ {
+ RowsInLayer.Add(givenRow ?? new Row());
+ }
+
+ ///
+ /// Initialize a layer
+ ///
+ /// Enter a list of rows
+ public Layer(List rowInLayer = null)
+ {
+ RowsInLayer = rowInLayer ?? new List();
+ }
+ }
+
+ ///
+ /// Several layers result in a cube
+ ///
+ public class Cube
+ {
+ public readonly List LayersInCube;
+
+ ///
+ /// Add a new layer to the cube
+ ///
+ /// Enter a layer that should be added
+ /// Index of the last layer
+ public void AddLayer(Layer givenLayer = null)
+ {
+ LayersInCube.Add(givenLayer ?? new Layer());
+ }
+
+ ///
+ /// Initialize a cube
+ ///
+ /// Enter a list of layers
+ public Cube(List layerInCube = null)
+ {
+ LayersInCube = layerInCube ?? new List();
+ }
+ }
+
+ public static class CubeFromWorld
+ {
+ ///
+ /// Creates a cube of blocks out of two coordinates.
+ ///
+ /// Start Location
+ /// Stop Location
+ /// A cube of blocks consisting of Layers, Rows and single blocks
+ public static Cube GetBlocksAsCube(World currentWorld, Location startBlock, Location stopBlock, List materialList = null, bool isBlacklist = true)
+ {
+ // Initialize cube to mine.
+ Cube cubeToMine = new Cube();
+
+ // Get the distance between start and finish as Vector.
+ Location vectorToStopPosition = stopBlock - startBlock;
+
+ // Initialize Iteration process
+ int[] iterateX = GetNumbersFromTo(0, Convert.ToInt32(Math.Round(vectorToStopPosition.X))).ToArray();
+ int[] iterateY = GetNumbersFromTo(0, Convert.ToInt32(Math.Round(vectorToStopPosition.Y))).ToArray();
+ int[] iterateZ = GetNumbersFromTo(0, Convert.ToInt32(Math.Round(vectorToStopPosition.Z))).ToArray();
+
+ // Iterate through all coordinates relative to the start block.
+ foreach (int y in iterateY)
+ {
+ Layer tempLayer = new Layer();
+ foreach (int x in iterateX)
+ {
+ Row tempRow = new Row();
+ foreach (int z in iterateZ)
+ {
+ if (materialList != null && materialList.Count > 0)
+ {
+ Location tempLocation = new Location(Math.Round(startBlock.X + x), Math.Round(startBlock.Y + y), Math.Round(startBlock.Z + z));
+ Material tempLocationMaterial = currentWorld.GetBlock(tempLocation).Type;
+
+ // XOR
+ // If blacklist == true and it does not contain the material (false); Add it.
+ // If blacklist == false (whitelist) and it contains the item (true); Add it.
+ if (isBlacklist ^ materialList.Contains(tempLocationMaterial))
+ {
+ tempRow.BlocksInRow.Add(tempLocation);
+ }
+ }
+ else
+ {
+ tempRow.BlocksInRow.Add(new Location(Math.Round(startBlock.X + x), Math.Round(startBlock.Y + y), Math.Round(startBlock.Z + z)));
+ }
+ }
+ if (tempRow.BlocksInRow.Count > 0)
+ {
+ tempLayer.AddRow(tempRow);
+ }
+ }
+ if (tempLayer.RowsInLayer.Count > 0)
+ {
+ cubeToMine.AddLayer(tempLayer);
+ }
+ }
+
+ return cubeToMine;
+ }
+
+ ///
+ /// Get all numbers between from and to.
+ ///
+ /// Number to start
+ /// Number to stop
+ /// All numbers between the start and stop number, including the stop number
+ private static List GetNumbersFromTo(int start, int stop)
+ {
+ List tempList = new List();
+ if (start <= stop)
+ {
+ for (int i = start; i <= stop; i++)
+ {
+ tempList.Add(i);
+ }
+ }
+ else
+ {
+ for (int i = start; i >= stop; i--)
+ {
+ tempList.Add(i);
+ }
+ }
+ return tempList;
+ }
+ }
+}
diff --git a/MinecraftClient/Mapping/Material2Tool.cs b/MinecraftClient/Mapping/Material2Tool.cs
new file mode 100644
index 00000000..0a3fe8db
--- /dev/null
+++ b/MinecraftClient/Mapping/Material2Tool.cs
@@ -0,0 +1,705 @@
+using MinecraftClient.Inventory;
+using System.Collections.Generic;
+
+namespace MinecraftClient.Mapping
+{
+ public static class Material2Tool
+ {
+ // Made with the following ressources: https://minecraft.fandom.com/wiki/Breaking
+ // Sorted in alphabetical order.
+ // Minable by Any Pickaxe.
+ private static readonly List pickaxeTier0 = new List()
+ {
+ Material.ActivatorRail,
+ Material.Andesite,
+ Material.AndesiteSlab,
+ Material.AndesiteStairs,
+ Material.AndesiteWall,
+ Material.Anvil,
+ Material.Basalt,
+ Material.Bell,
+ Material.BlackConcrete,
+ Material.BlackGlazedTerracotta,
+ Material.BlackShulkerBox,
+ Material.BlackTerracotta,
+ Material.Blackstone,
+ Material.BlackstoneSlab,
+ Material.BlackstoneStairs,
+ Material.BlackstoneWall,
+ Material.BlastFurnace,
+ Material.BlueConcrete,
+ Material.BlueGlazedTerracotta,
+ Material.BlueIce,
+ Material.BlueShulkerBox,
+ Material.BlueTerracotta,
+ Material.BoneBlock,
+ Material.BrewingStand,
+ Material.BrickSlab,
+ Material.BrickStairs,
+ Material.BrickWall,
+ Material.Bricks,
+ Material.BrownConcrete,
+ Material.BrownGlazedTerracotta,
+ Material.BrownShulkerBox,
+ Material.BrownTerracotta,
+ Material.Cauldron,
+ Material.Chain,
+ Material.ChippedAnvil,
+ Material.ChiseledNetherBricks,
+ Material.ChiseledPolishedBlackstone,
+ Material.ChiseledQuartzBlock,
+ Material.ChiseledRedSandstone,
+ Material.ChiseledSandstone,
+ Material.ChiseledStoneBricks,
+ Material.CoalBlock,
+ Material.CoalOre,
+ Material.Cobblestone,
+ Material.CobblestoneSlab,
+ Material.CobblestoneStairs,
+ Material.CobblestoneWall,
+ Material.Conduit,
+ Material.CrackedNetherBricks,
+ Material.CrackedPolishedBlackstoneBricks,
+ Material.CrackedStoneBricks,
+ Material.CrimsonNylium,
+ Material.CutRedSandstone,
+ Material.CutRedSandstoneSlab,
+ Material.CutSandstone,
+ Material.CutSandstoneSlab,
+ Material.CyanConcrete,
+ Material.CyanGlazedTerracotta,
+ Material.CyanShulkerBox,
+ Material.CyanTerracotta,
+ Material.DamagedAnvil,
+ Material.DarkPrismarine,
+ Material.DarkPrismarineSlab,
+ Material.DarkPrismarineStairs,
+ Material.DetectorRail,
+ Material.Diorite,
+ Material.DioriteSlab,
+ Material.DioriteStairs,
+ Material.DioriteWall,
+ Material.Dispenser,
+ Material.Dropper,
+ Material.EnchantingTable,
+ Material.EndRod,
+ Material.EndStone,
+ Material.EndStoneBrickSlab,
+ Material.EndStoneBrickStairs,
+ Material.EndStoneBrickWall,
+ Material.EndStoneBricks,
+ Material.EnderChest,
+ Material.FrostedIce,
+ Material.Furnace,
+ Material.GildedBlackstone,
+ Material.Glowstone,
+ Material.Granite,
+ Material.GraniteSlab,
+ Material.GraniteStairs,
+ Material.GraniteWall,
+ Material.GrayConcrete,
+ Material.GrayGlazedTerracotta,
+ Material.GrayShulkerBox,
+ Material.GrayTerracotta,
+ Material.GreenConcrete,
+ Material.GreenGlazedTerracotta,
+ Material.GreenShulkerBox,
+ Material.GreenTerracotta,
+ Material.Grindstone,
+ Material.HeavyWeightedPressurePlate,
+ Material.Hopper,
+ Material.Ice,
+ Material.IronBars,
+ Material.IronDoor,
+ Material.IronTrapdoor,
+ Material.Lantern,
+ Material.LightBlueConcrete,
+ Material.LightBlueGlazedTerracotta,
+ Material.LightBlueShulkerBox,
+ Material.LightBlueTerracotta,
+ Material.LightGrayConcrete,
+ Material.LightGrayGlazedTerracotta,
+ Material.LightGrayShulkerBox,
+ Material.LightGrayTerracotta,
+ Material.LightWeightedPressurePlate,
+ Material.LimeConcrete,
+ Material.LimeGlazedTerracotta,
+ Material.LimeShulkerBox,
+ Material.LimeTerracotta,
+ Material.Lodestone,
+ Material.MagentaConcrete,
+ Material.MagentaGlazedTerracotta,
+ Material.MagentaShulkerBox,
+ Material.MagentaTerracotta,
+ Material.MagmaBlock,
+ Material.MossyCobblestone,
+ Material.MossyCobblestoneSlab,
+ Material.MossyCobblestoneStairs,
+ Material.MossyCobblestoneWall,
+ Material.MossyStoneBrickSlab,
+ Material.MossyStoneBrickStairs,
+ Material.MossyStoneBrickWall,
+ Material.MossyStoneBricks,
+ Material.NetherBrickFence,
+ Material.NetherBrickSlab,
+ Material.NetherBrickStairs,
+ Material.NetherBrickWall,
+ Material.NetherBricks,
+ Material.NetherGoldOre,
+ Material.NetherQuartzOre,
+ Material.Netherrack,
+ Material.Observer,
+ Material.OrangeConcrete,
+ Material.OrangeGlazedTerracotta,
+ Material.OrangeShulkerBox,
+ Material.OrangeTerracotta,
+ Material.PackedIce,
+ Material.PetrifiedOakSlab,
+ Material.PinkConcrete,
+ Material.PinkGlazedTerracotta,
+ Material.PinkShulkerBox,
+ Material.PinkTerracotta,
+ Material.Piston,
+ Material.PolishedAndesite,
+ Material.PolishedAndesiteSlab,
+ Material.PolishedAndesiteStairs,
+ Material.PolishedBasalt,
+ Material.PolishedBlackstone,
+ Material.PolishedBlackstoneBrickSlab,
+ Material.PolishedBlackstoneBrickStairs,
+ Material.PolishedBlackstoneBrickWall,
+ Material.PolishedBlackstoneBricks,
+ Material.PolishedBlackstoneButton,
+ Material.PolishedBlackstonePressurePlate,
+ Material.PolishedBlackstoneSlab,
+ Material.PolishedBlackstoneStairs,
+ Material.PolishedBlackstoneWall,
+ Material.PolishedDiorite,
+ Material.PolishedDioriteSlab,
+ Material.PolishedDioriteStairs,
+ Material.PolishedGranite,
+ Material.PolishedGraniteSlab,
+ Material.PolishedGraniteStairs,
+ Material.PoweredRail,
+ Material.Prismarine,
+ Material.PrismarineBrickSlab,
+ Material.PrismarineBrickStairs,
+ Material.PrismarineBricks,
+ Material.PrismarineSlab,
+ Material.PrismarineStairs,
+ Material.PrismarineWall,
+ Material.PurpleConcrete,
+ Material.PurpleGlazedTerracotta,
+ Material.PurpleShulkerBox,
+ Material.PurpleTerracotta,
+ Material.PurpurBlock,
+ Material.PurpurPillar,
+ Material.PurpurSlab,
+ Material.PurpurStairs,
+ Material.QuartzBlock,
+ Material.QuartzBricks,
+ Material.QuartzPillar,
+ Material.QuartzSlab,
+ Material.QuartzStairs,
+ Material.Rail,
+ Material.RedConcrete,
+ Material.RedGlazedTerracotta,
+ Material.RedNetherBrickSlab,
+ Material.RedNetherBrickStairs,
+ Material.RedNetherBrickWall,
+ Material.RedNetherBricks,
+ Material.RedSandstone,
+ Material.RedSandstoneSlab,
+ Material.RedSandstoneStairs,
+ Material.RedSandstoneWall,
+ Material.RedShulkerBox,
+ Material.RedTerracotta,
+ Material.RedstoneBlock,
+ Material.Sandstone,
+ Material.SandstoneSlab,
+ Material.SandstoneStairs,
+ Material.SandstoneWall,
+ Material.ShulkerBox,
+ Material.Smoker,
+ Material.SmoothQuartz,
+ Material.SmoothQuartzSlab,
+ Material.SmoothQuartzStairs,
+ Material.SmoothRedSandstone,
+ Material.SmoothRedSandstoneSlab,
+ Material.SmoothRedSandstoneStairs,
+ Material.SmoothSandstone,
+ Material.SmoothSandstoneSlab,
+ Material.SmoothSandstoneStairs,
+ Material.SmoothStone,
+ Material.SmoothStoneSlab,
+ Material.Spawner,
+ Material.StickyPiston,
+ Material.Stone,
+ Material.StoneBrickSlab,
+ Material.StoneBrickStairs,
+ Material.StoneBrickWall,
+ Material.StoneBricks,
+ Material.StoneButton,
+ Material.StonePressurePlate,
+ Material.StoneSlab,
+ Material.StoneStairs,
+ Material.Stonecutter,
+ Material.Terracotta,
+ Material.WarpedNylium,
+ Material.WhiteConcrete,
+ Material.WhiteGlazedTerracotta,
+ Material.WhiteShulkerBox,
+ Material.WhiteTerracotta,
+ Material.YellowConcrete,
+ Material.YellowGlazedTerracotta,
+ Material.YellowShulkerBox,
+ Material.YellowTerracotta
+ };
+ // Minable by Stone, iron, diamond, netherite.
+ private static readonly List pickaxeTier1 = new List()
+ {
+ Material.IronBlock,
+ Material.IronOre,
+ Material.LapisBlock,
+ Material.LapisOre,
+ Material.Terracotta,
+ };
+ // Minable by Iron, diamond, netherite.
+ private static readonly List pickaxeTier2 = new List()
+ {
+ Material.DiamondBlock,
+ Material.DiamondOre,
+ Material.EmeraldBlock,
+ Material.EmeraldOre,
+ Material.GoldBlock,
+ Material.GoldOre,
+ Material.RedstoneOre,
+ };
+ // Minable by Diamond, Netherite.
+ private static readonly List pickaxeTier3 = new List()
+ {
+ Material.AncientDebris,
+ Material.CryingObsidian,
+ Material.NetheriteBlock,
+ Material.Obsidian,
+ Material.RespawnAnchor
+ };
+
+ // Every shovel can mine every block (speed difference).
+ private static readonly List shovel = new List()
+ {
+ Material.BlackConcretePowder,
+ Material.BlueConcretePowder,
+ Material.BrownConcretePowder,
+ Material.Clay,
+ Material.CoarseDirt,
+ Material.CyanConcretePowder,
+ Material.Dirt,
+ Material.Farmland,
+ Material.Grass,
+ Material.GrassBlock,
+ Material.GrassPath,
+ Material.Gravel,
+ Material.GrayConcretePowder,
+ Material.GreenConcretePowder,
+ Material.LightBlueConcretePowder,
+ Material.LightGrayConcretePowder,
+ Material.LimeConcretePowder,
+ Material.MagentaConcretePowder,
+ Material.Mycelium,
+ Material.OrangeConcretePowder,
+ Material.PinkConcretePowder,
+ Material.Podzol,
+ Material.PrismarineSlab,
+ Material.PurpleConcretePowder,
+ Material.RedConcretePowder,
+ Material.RedSand,
+ Material.Sand,
+ Material.Snow,
+ Material.SnowBlock,
+ Material.SoulSand,
+ Material.SoulSoil,
+ Material.WhiteConcretePowder,
+ Material.YellowConcretePowder
+ };
+ // Every axe can mine every block (speed difference).
+ private static readonly List axe = new List()
+ {
+ Material.AcaciaButton,
+ Material.AcaciaDoor,
+ Material.AcaciaFence,
+ Material.AcaciaFenceGate,
+ Material.AcaciaLog,
+ Material.AcaciaPlanks,
+ Material.AcaciaPressurePlate,
+ Material.AcaciaSign,
+ Material.AcaciaSlab,
+ Material.AcaciaStairs,
+ Material.AcaciaTrapdoor,
+ Material.AcaciaWallSign,
+ Material.AcaciaWood,
+ Material.Barrel,
+ Material.BeeNest,
+ Material.Beehive,
+ Material.BirchButton,
+ Material.BirchDoor,
+ Material.BirchFence,
+ Material.BirchFenceGate,
+ Material.BirchLog,
+ Material.BirchPlanks,
+ Material.BirchPressurePlate,
+ Material.BirchSign,
+ Material.BirchSlab,
+ Material.BirchStairs,
+ Material.BirchTrapdoor,
+ Material.BirchWallSign,
+ Material.BirchWood,
+ Material.BlackBanner,
+ Material.BlackWallBanner,
+ Material.BlueBanner,
+ Material.BlueWallBanner,
+ Material.Bookshelf,
+ Material.BrownBanner,
+ Material.BrownMushroomBlock,
+ Material.BrownWallBanner,
+ Material.Campfire,
+ Material.CartographyTable,
+ Material.Chest,
+ Material.Cocoa,
+ Material.Composter,
+ Material.CraftingTable,
+ Material.CrimsonButton,
+ Material.CrimsonDoor,
+ Material.CrimsonFence,
+ Material.CrimsonFenceGate,
+ Material.CrimsonHyphae,
+ Material.CrimsonPlanks,
+ Material.CrimsonPressurePlate,
+ Material.CrimsonSign,
+ Material.CrimsonSlab,
+ Material.CrimsonStairs,
+ Material.CrimsonStem,
+ Material.CrimsonTrapdoor,
+ Material.CrimsonWallSign,
+ Material.CyanBanner,
+ Material.CyanWallBanner,
+ Material.DarkOakButton,
+ Material.DarkOakDoor,
+ Material.DarkOakFence,
+ Material.DarkOakFenceGate,
+ Material.DarkOakLog,
+ Material.DarkOakPlanks,
+ Material.DarkOakPressurePlate,
+ Material.DarkOakSign,
+ Material.DarkOakSlab,
+ Material.DarkOakStairs,
+ Material.DarkOakTrapdoor,
+ Material.DarkOakWallSign,
+ Material.DarkOakWood,
+ Material.DaylightDetector,
+ Material.FletchingTable,
+ Material.GrayBanner,
+ Material.GrayWallBanner,
+ Material.GreenBanner,
+ Material.GreenWallBanner,
+ Material.JackOLantern,
+ Material.Jukebox,
+ Material.JungleButton,
+ Material.JungleDoor,
+ Material.JungleFence,
+ Material.JungleFenceGate,
+ Material.JungleLog,
+ Material.JunglePlanks,
+ Material.JunglePressurePlate,
+ Material.JungleSign,
+ Material.JungleSlab,
+ Material.JungleStairs,
+ Material.JungleTrapdoor,
+ Material.JungleWallSign,
+ Material.JungleWood,
+ Material.Ladder,
+ Material.Lectern,
+ Material.LightBlueBanner,
+ Material.LightBlueWallBanner,
+ Material.LightGrayBanner,
+ Material.LightGrayWallBanner,
+ Material.LimeBanner,
+ Material.LimeWallBanner,
+ Material.Loom,
+ Material.MagentaBanner,
+ Material.MagentaWallBanner,
+ Material.Melon,
+ Material.MushroomStem,
+ Material.NoteBlock,
+ Material.OakButton,
+ Material.OakDoor,
+ Material.OakFence,
+ Material.OakFenceGate,
+ Material.OakLog,
+ Material.OakPlanks,
+ Material.OakPressurePlate,
+ Material.OakSign,
+ Material.OakSlab,
+ Material.OakStairs,
+ Material.OakTrapdoor,
+ Material.OakWallSign,
+ Material.OakWood,
+ Material.OrangeBanner,
+ Material.OrangeWallBanner,
+ Material.PinkBanner,
+ Material.PinkWallBanner,
+ Material.Pumpkin,
+ Material.PurpleBanner,
+ Material.PurpleWallBanner,
+ Material.RedBanner,
+ Material.RedMushroomBlock,
+ Material.RedWallBanner,
+ Material.SmithingTable,
+ Material.SoulCampfire,
+ Material.SpruceButton,
+ Material.SpruceDoor,
+ Material.SpruceFence,
+ Material.SpruceFenceGate,
+ Material.SpruceLog,
+ Material.SprucePlanks,
+ Material.SprucePressurePlate,
+ Material.SpruceSign,
+ Material.SpruceSlab,
+ Material.SpruceStairs,
+ Material.SpruceTrapdoor,
+ Material.SpruceWallSign,
+ Material.SpruceWood,
+ Material.StrippedAcaciaLog,
+ Material.StrippedAcaciaWood,
+ Material.StrippedBirchLog,
+ Material.StrippedBirchWood,
+ Material.StrippedCrimsonHyphae,
+ Material.StrippedCrimsonStem,
+ Material.StrippedDarkOakLog,
+ Material.StrippedDarkOakWood,
+ Material.StrippedDarkOakWood,
+ Material.StrippedJungleLog,
+ Material.StrippedJungleWood,
+ Material.StrippedOakLog,
+ Material.StrippedOakWood,
+ Material.StrippedSpruceLog,
+ Material.StrippedSpruceWood,
+ Material.StrippedWarpedHyphae,
+ Material.StrippedWarpedStem,
+ Material.TrappedChest,
+ Material.Vine,
+ Material.WarpedButton,
+ Material.WarpedDoor,
+ Material.WarpedFence,
+ Material.WarpedFenceGate,
+ Material.WarpedHyphae,
+ Material.WarpedPlanks,
+ Material.WarpedPressurePlate,
+ Material.WarpedSign,
+ Material.WarpedSlab,
+ Material.WarpedStairs,
+ Material.WarpedStem,
+ Material.WarpedTrapdoor,
+ Material.WarpedWallSign,
+ Material.WhiteBanner,
+ Material.WhiteWallBanner,
+ Material.YellowBanner,
+ Material.YellowWallBanner
+ };
+ // Every block a shear can mine.
+ private static readonly List shears = new List()
+ {
+ Material.AcaciaLeaves,
+ Material.BirchLeaves,
+ Material.BlackWool,
+ Material.BlueWool,
+ Material.BrownWool,
+ Material.Cobweb,
+ Material.CyanWool,
+ Material.DarkOakLeaves,
+ Material.GrayWool,
+ Material.GreenWool,
+ Material.JungleLeaves,
+ Material.LightBlueWool,
+ Material.LightGrayWool,
+ Material.LimeWool,
+ Material.MagentaWool,
+ Material.OakLeaves,
+ Material.OrangeWool,
+ Material.PinkWool,
+ Material.PurpleWool,
+ Material.RedWool,
+ Material.SpruceLeaves,
+ Material.WhiteWool,
+ Material.YellowWool,
+ };
+ // Every block that is mined with a sword.
+ private static readonly List sword = new List()
+ {
+ Material.Bamboo,
+ Material.Cobweb,
+ Material.InfestedChiseledStoneBricks,
+ Material.InfestedCobblestone,
+ Material.InfestedCrackedStoneBricks,
+ Material.InfestedMossyStoneBricks,
+ Material.InfestedStone,
+ Material.InfestedStoneBricks,
+ };
+ // Every block that can be mined with a hoe.
+ private static readonly List hoe = new List()
+ {
+ Material.AcaciaLeaves,
+ Material.BirchLeaves,
+ Material.DarkOakLeaves,
+ Material.HayBlock,
+ Material.JungleLeaves,
+ Material.NetherWartBlock,
+ Material.OakLeaves,
+ Material.Shroomlight,
+ Material.Sponge,
+ Material.SpruceLeaves,
+ Material.Target,
+ Material.WarpedWartBlock,
+ Material.WetSponge,
+ };
+ // Liquids
+ private static readonly List bucket = new List()
+ {
+ Material.Lava,
+ Material.Water
+ };
+
+ // Unbreakable Blocks
+ private static readonly List unbreakable = new List()
+ {
+ Material.Air,
+ Material.Barrier,
+ Material.Bedrock,
+ Material.BubbleColumn,
+ Material.ChainCommandBlock,
+ Material.CommandBlock,
+ Material.EndGateway,
+ Material.EndPortal,
+ Material.EndPortalFrame,
+ Material.Jigsaw,
+ Material.NetherPortal,
+ Material.RepeatingCommandBlock,
+ Material.StructureBlock,
+ Material.StructureVoid
+ };
+
+ ///
+ /// Evaluates the right tool for the job
+ ///
+ /// Enter the Material of a block
+ /// Returns a list of tools that can be used, best to worst
+ public static ItemType[] GetCorrectToolForBlock(Material block)
+ {
+ if (pickaxeTier0.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheritePickaxe,
+ ItemType.DiamondPickaxe,
+ ItemType.IronPickaxe,
+ ItemType.GoldenPickaxe,
+ ItemType.StonePickaxe,
+ ItemType.WoodenPickaxe,
+ };
+ }
+ else if (pickaxeTier1.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheritePickaxe,
+ ItemType.DiamondPickaxe,
+ ItemType.IronPickaxe,
+ ItemType.GoldenPickaxe,
+ ItemType.StonePickaxe,
+ };
+ }
+ else if (pickaxeTier2.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheritePickaxe,
+ ItemType.DiamondPickaxe,
+ ItemType.IronPickaxe,
+ };
+ }
+ else if (pickaxeTier3.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheritePickaxe,
+ ItemType.DiamondPickaxe,
+ };
+ }
+ else if (shovel.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheriteShovel,
+ ItemType.DiamondShovel,
+ ItemType.IronShovel,
+ ItemType.GoldenShovel,
+ ItemType.StoneShovel,
+ ItemType.WoodenShovel,
+ };
+ }
+ else if (axe.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheriteAxe,
+ ItemType.DiamondAxe,
+ ItemType.IronAxe,
+ ItemType.GoldenAxe,
+ ItemType.StoneAxe,
+ ItemType.WoodenAxe,
+ };
+ }
+ else if (shears.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.Shears,
+ };
+ }
+ else if (sword.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheriteSword,
+ ItemType.DiamondSword,
+ ItemType.IronSword,
+ ItemType.GoldenSword,
+ ItemType.StoneSword,
+ ItemType.WoodenSword,
+ };
+ }
+ else if (hoe.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.NetheriteHoe,
+ ItemType.DiamondHoe,
+ ItemType.IronHoe,
+ ItemType.GoldenHoe,
+ ItemType.StoneHoe,
+ ItemType.WoodenHoe,
+ };
+ }
+ else if (bucket.Contains(block))
+ {
+ return new ItemType[]
+ {
+ ItemType.Bucket,
+ };
+ }
+ else { return new ItemType[0]; }
+ }
+
+ public static bool IsUnbreakable(Material block) { return unbreakable.Contains(block); }
+ }
+}
diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj
index 5e8061de..e4bfa040 100644
--- a/MinecraftClient/MinecraftClient.csproj
+++ b/MinecraftClient/MinecraftClient.csproj
@@ -75,6 +75,8 @@
+
+
diff --git a/MinecraftClient/config/ChatBots/MineCube.cs b/MinecraftClient/config/ChatBots/MineCube.cs
new file mode 100644
index 00000000..fffb56ec
--- /dev/null
+++ b/MinecraftClient/config/ChatBots/MineCube.cs
@@ -0,0 +1,315 @@
+//MCCScript 1.0
+
+MCC.LoadBot(new MineCube());
+
+//MCCScript Extensions
+
+class MineCube : ChatBot
+{
+ public override void Initialize()
+ {
+ if (!GetTerrainEnabled())
+ {
+ LogToConsole(Translations.Get("extra.terrainandmovement_required"));
+ UnloadBot();
+ return;
+ }
+ RegisterChatBotCommand("mine", "Mine a cube from a to b", "/mine x y z OR /mine x1 y1 z1 x2 y2 z2", EvaluateMineCommand);
+ RegisterChatBotCommand("mineup", "Walk over a flat cubic platform of blocks and mine everything above you", "/mine x1 y1 z1 x2 y2 z2 (y1 = y2)", EvaluateMineCommand);
+ LogToConsole("Mining bot created by Daenges.");
+ }
+
+ ///
+ /// Dig out a 2 Block high cube and let the bot walk through it
+ /// mining all blocks above it that it can reach.
+ ///
+ /// Area that the bot should walk through. (The lower Y coordinate of the 2 high cube.)
+ public void MineUp(Cube walkingArea)
+ {
+ foreach (Layer lay in walkingArea.LayersInCube)
+ {
+ foreach (Row r in lay.RowsInLayer)
+ {
+ foreach (Location loc in r.BlocksInRow)
+ {
+ Location currentLoc = GetCurrentLocation();
+
+ if (MoveToLocation(new Location(loc.X, loc.Y, loc.Z)))
+ {
+ while (Math.Round(GetCurrentLocation().Distance(loc)) > 1)
+ {
+ Thread.Sleep(200);
+ }
+ }
+ else
+ {
+ // This block is not reachable for some reason.
+ // Keep on going with the next collumn.
+ LogDebugToConsole("Unable to walk to: " + loc.X.ToString() + " " + (loc.Y).ToString() + " " + loc.Z.ToString());
+ continue;
+ }
+
+ for (int height = Convert.ToInt32(Math.Round(currentLoc.Y)) + 2; height < Convert.ToInt32(Math.Round(currentLoc.Y)) + 7; height++)
+ {
+ Location mineLocation = new Location(loc.X, height, loc.Z);
+ Material mineLocationMaterial = GetWorld().GetBlock(mineLocation).Type;
+
+ // Stop mining process if breaking the next block could endager the bot
+ // through falling blocks or liquids.
+ if (IsGravityBlockAbove(mineLocation) || IsSorroundedByLiquid(mineLocation)) { break; }
+ // Skip this block if it can not be mined.
+ if (Material2Tool.IsUnbreakable(mineLocationMaterial)) { continue; }
+
+ //DateTime start = DateTime.Now;
+ // Search this tool in hotbar and select the correct slot
+ SelectCorrectSlotInHotbar(
+ // Returns the correct tool for this type
+ Material2Tool.GetCorrectToolForBlock(
+ // returns the type of the current block
+ mineLocationMaterial));
+
+ // Unable to check when breaking is over.
+ if (DigBlock(mineLocation))
+ {
+ short i = 0; // Maximum wait time of 10 sec.
+ while (GetWorld().GetBlock(mineLocation).Type != Material.Air && i <= 100)
+ {
+ Thread.Sleep(100);
+ i++;
+ }
+ }
+ else
+ {
+ LogDebugToConsole("Unable to break this block: " + mineLocation.ToString());
+ }
+ }
+ }
+ }
+ }
+ LogToConsole("Finished mining up.");
+ }
+
+ ///
+ /// Mines out a cube of blocks from top to bottom.
+ ///
+ /// The cube that should be mined.
+ public void Mine(Cube cubeToMine)
+ {
+ foreach (Layer lay in cubeToMine.LayersInCube)
+ {
+ foreach (Row r in lay.RowsInLayer)
+ {
+ foreach (Location loc in r.BlocksInRow)
+ {
+ Material locMaterial = GetWorld().GetBlock(loc).Type;
+ if (!Material2Tool.IsUnbreakable(locMaterial) && !IsSorroundedByLiquid(loc))
+ {
+ if (GetHeadLocation(GetCurrentLocation()).Distance(loc) > 5)
+ {
+ // Unable to detect when walking is over and goal is reached.
+ if (MoveToLocation(new Location(loc.X, loc.Y + 1, loc.Z)))
+ {
+ while (GetCurrentLocation().Distance(loc) > 2)
+ {
+ Thread.Sleep(200);
+ }
+
+ }
+ else
+ {
+ LogDebugToConsole("Unable to walk to: " + loc.X.ToString() + " " + (loc.Y + 1).ToString() + " " + loc.Z.ToString());
+ }
+ }
+
+ //DateTime start = DateTime.Now;
+ // Search this tool in hotbar and select the correct slot
+ SelectCorrectSlotInHotbar(
+ // Returns the correct tool for this type
+ Material2Tool.GetCorrectToolForBlock(
+ // returns the type of the current block
+ GetWorld().GetBlock(loc).Type));
+
+ // Unable to check when breaking is over.
+ if (DigBlock(loc))
+ {
+ short i = 0; // Maximum wait time of 10 sec.
+ while (GetWorld().GetBlock(loc).Type != Material.Air && i <= 100)
+ {
+ Thread.Sleep(100);
+ i++;
+ }
+ }
+ else
+ {
+ LogDebugToConsole("Unable to break this block: " + loc.ToString());
+ }
+ }
+ }
+ }
+ }
+ LogToConsole("Mining finished.");
+ }
+
+ public Func GetHeadLocation = locFeet => new Location(locFeet.X, locFeet.Y + 1, locFeet.Z);
+
+ private void SelectCorrectSlotInHotbar(ItemType[] tools)
+ {
+ if (GetInventoryEnabled())
+ {
+ foreach (ItemType tool in tools)
+ {
+ int[] tempArray = GetPlayerInventory().SearchItem(tool);
+ // Check whether an item could be found and make sure that it is in
+ // a hotbar slot (36-44).
+ if (tempArray.Length > 0 && tempArray[0] > 35)
+ {
+ // Changeslot takes numbers from 0-8
+ ChangeSlot(Convert.ToInt16(tempArray[0] - 36));
+ break;
+ }
+ }
+ }
+ else
+ {
+ LogToConsole("Activate Inventory Handling.");
+ }
+ }
+
+ public bool IsGravityBlockAbove(Location block)
+ {
+ World world = GetWorld();
+ double blockX = Math.Round(block.X);
+ double blockY = Math.Round(block.Y);
+ double blockZ = Math.Round(block.Z);
+
+ List gravityBlockList = new List(new Material[] { Material.Gravel, Material.Sand, Material.RedSand, Material.Scaffolding, Material.Anvil, });
+
+
+ var temptype = world.GetBlock(new Location(blockX, blockY + 1, blockZ)).Type;
+ var tempLoc = gravityBlockList.Contains(world.GetBlock(new Location(blockX, blockY + 1, blockZ)).Type);
+
+ return
+ // Block can not fall down on player e.g. Sand, Gravel etc.
+ gravityBlockList.Contains(world.GetBlock(new Location(blockX, blockY + 1, blockZ)).Type);
+ }
+
+ public bool IsSorroundedByLiquid(Location block)
+ {
+ World world = GetWorld();
+ double blockX = Math.Round(block.X);
+ double blockY = Math.Round(block.Y);
+ double blockZ = Math.Round(block.Z);
+
+ List liquidBlockList = new List(new Material[] { Material.Water, Material.Lava, });
+
+ return // Liquid can not flow down the hole. Liquid is unable to flow diagonally.
+ liquidBlockList.Contains(world.GetBlock(new Location(blockX, blockY + 1, blockZ)).Type) ||
+ liquidBlockList.Contains(world.GetBlock(new Location(blockX - 1, blockY, blockZ)).Type) ||
+ liquidBlockList.Contains(world.GetBlock(new Location(blockX + 1, blockY, blockZ)).Type) ||
+ liquidBlockList.Contains(world.GetBlock(new Location(blockX, blockY, blockZ - 1)).Type) ||
+ liquidBlockList.Contains(world.GetBlock(new Location(blockX, blockY, blockZ + 1)).Type);
+ }
+
+ ///
+ private string getHelpPage()
+ {
+ return
+ "Usage of the mine bot:\n" +
+ "/mine OR /mine \n" +
+ "to excavate a cube of blocks from top to bottom. (2 high area above the cube must be dug free by hand.)\n" +
+ "/mineup OR /mineup \n" +
+ "to walk over a quadratic field of blocks and simultaniously mine everything above the head. \n" +
+ "(Mines up to 5 Blocks, stops if gravel or lava would fall. 2 High area below this must be dug fee by hand.)\n";
+ }
+
+ ///
+ /// Evaluates the given command
+ ///
+ ///
+ ///
+ ///
+ private string EvaluateMineCommand(string command, string[] args)
+ {
+ if (args.Length > 2)
+ {
+ Location startBlock;
+ Location stopBlock;
+
+ if (args.Length > 5)
+ {
+ try
+ {
+ startBlock = new Location(
+ double.Parse(args[0]),
+ double.Parse(args[1]),
+ double.Parse(args[2])
+ );
+
+ stopBlock = new Location(
+ double.Parse(args[3]),
+ double.Parse(args[4]),
+ double.Parse(args[5])
+ );
+
+ }
+ catch (Exception e)
+ {
+ LogDebugToConsole(e.ToString());
+ return "Please enter correct coordinates as numbers.\n" + getHelpPage();
+ }
+ }
+ else
+ {
+ Location tempLoc = GetCurrentLocation();
+ startBlock = new Location(Math.Round(tempLoc.X),
+ Math.Round(tempLoc.Y),
+ Math.Round(tempLoc.Z));
+
+ try
+ {
+ stopBlock = new Location(
+ double.Parse(args[0]),
+ double.Parse(args[1]),
+ double.Parse(args[2])
+ );
+ }
+ catch (Exception e)
+ {
+ LogDebugToConsole(e.ToString());
+ return "Please enter correct coordinates as numbers.\n" + getHelpPage();
+ }
+ }
+
+ if (command.Contains("mineup"))
+ {
+ if (Math.Round(startBlock.Y) != Math.Round(stopBlock.Y))
+ {
+ return "Both blocks must have the same Y value!\n" + getHelpPage();
+ }
+
+ List materialWhitelist = new List() { Material.Air };
+ Thread tempThread = new Thread(() => MineUp(CubeFromWorld.GetBlocksAsCube(GetWorld(), startBlock, stopBlock, materialWhitelist, isBlacklist: false)));
+ tempThread.Start();
+ return "Start mining up.";
+ }
+ else
+ {
+ // Turn the cube around, so the bot always starts from the top.
+ if (stopBlock.Y > startBlock.Y)
+ {
+ Location temp = stopBlock;
+ stopBlock = startBlock;
+ startBlock = temp;
+ }
+
+ List blacklistedMaterials = new List() { Material.Air, Material.Water, Material.Lava };
+ Thread tempThread = new Thread(() => Mine(CubeFromWorld.GetBlocksAsCube(GetWorld(), startBlock, stopBlock, blacklistedMaterials)));
+ tempThread.Start();
+
+ return "Start mining cube.";
+ }
+ }
+
+ return "Invalid command syntax.\n" + getHelpPage();
+ }
+}
\ No newline at end of file