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