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; } } }