bool OnMinDistance(List <Part> existingParts, int minimumDistance) { if (existingParts.Count > 0) { foreach (var ePart in existingParts) { if (Orientation == ePart.Orientation) { if (Orientation == PartOrientation.Horizontal) { foreach (var x in OccupiedIndexes.Select(i => i.x)) { if (ePart.OccupiedIndexes.Any(e => e.x == x)) { if (Mathf.Abs(ReferenceIndex.z - ePart.ReferenceIndex.z) <= minimumDistance) { return(false); } } } } else if (Orientation == PartOrientation.Vertical) { foreach (var z in OccupiedIndexes.Select(i => i.z)) { if (ePart.OccupiedIndexes.Any(ee => ee.z == z)) { if (Mathf.Abs(ReferenceIndex.x - ePart.ReferenceIndex.x) <= minimumDistance) { return(false); } } } } } } } return(true); }
/// <summary> /// Checks if the proposed position for a new ConfigurablePart is valid on its parent Grid. /// Utilized on <see cref="ConfigurablePart()"/> /// </summary> /// <returns>Boolean representing the validity</returns> private bool CheckValidDistance() { //Set the search sides according to index parity, even = negative, odd = positive Vector3Int[] evenSide = OccupiedIndexes.Where((x, i) => i % 2 == 0).ToArray(); Vector3Int[] oddSide = OccupiedIndexes.Where((x, i) => i % 2 != 0).ToArray(); //Set the search ranges according to part orientation, for boundary and for parallel parts and agnostic parts int boundaryRange = 4; int partsRange = 6; //Check, for both sides and both ranges if there is any impediment if (Orientation == PartOrientation.Horizontal) { //Try checking on both, starting from the even side, avoiding duplicates int[] pRange = new int[] { evenSide[0].z - partsRange, evenSide[0].z + partsRange + 1 }; int[] bRange = new int[] { evenSide[0].z - boundaryRange - 1, evenSide[0].z + boundaryRange + 2 }; foreach (var index in evenSide) { for (int z = pRange[0]; z <= pRange[1]; z++) { //Skip its own indexes if (z == index.z || z == index.z + 1) { continue; } //Return false if outside the grid if (z < 0 || z > Grid.Size.z - 1) { return(false); } Voxel checkVoxel = Grid.Voxels[index.x, index.y, z]; //Return false if, within boundary search range, the voxel is not active (avoid perpendicular boundary) if (z >= bRange[0] && z <= bRange[1]) { if (!checkVoxel.IsActive) { return(false); } } //Return false if a part is found and is not perpendicular if (checkVoxel.IsOccupied && checkVoxel.Part.Orientation != PartOrientation.Vertical) { return(false); } } } } if (Orientation == PartOrientation.Vertical) { //Try checking on both, starting from the even side, avoiding duplicates int[] pRange = new int[] { evenSide[0].x - partsRange, evenSide[0].x + partsRange + 1 }; int[] bRange = new int[] { evenSide[0].x - boundaryRange - 1, evenSide[0].x + boundaryRange + 2 }; foreach (var index in evenSide) { for (int x = pRange[0]; x <= pRange[1]; x++) { //Skip its own indexes if (x == index.x || x == index.x + 1) { continue; } //Return false if outside the grid if (x < 0 || x > Grid.Size.x - 1) { return(false); } Voxel checkVoxel = Grid.Voxels[x, index.y, index.z]; //Return false if, within boundary search range, the voxel is not active (avoid perpendicular boundary) if (x >= bRange[0] && x <= bRange[1]) { if (!checkVoxel.IsActive) { return(false); } } //Return false if a part is found and is not perpendicular if (checkVoxel.IsOccupied && checkVoxel.Part.Orientation != PartOrientation.Horizontal) { return(false); } } } } return(true); }