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