public static bool Go(Voxel voxel, Voxel.Coord center, int radius, Action<List<DynamicVoxel>> callback = null) { if (!voxel[center].Permanent) { // Break off a chunk of this voxel into a new DynamicMap. List<Voxel.Coord> edges = new List<Voxel.Coord>(); Voxel.Coord ripStart = center.Move(-radius, -radius, -radius); Voxel.Coord ripEnd = center.Move(radius, radius, radius); Dictionary<Voxel.Box, bool> permanentBoxes = new Dictionary<Voxel.Box, bool>(); foreach (Voxel.Coord c in ripStart.CoordinatesBetween(ripEnd)) { Voxel.Box box = voxel.GetBox(c); if (box != null && box.Type.Permanent) permanentBoxes[box] = true; } foreach (Voxel.Box b in permanentBoxes.Keys) { // Top and bottom for (int x = b.X - 1; x <= b.X + b.Width; x++) { for (int z = b.Z - 1; z <= b.Z + b.Depth; z++) { Voxel.Coord coord = new Voxel.Coord { X = x, Y = b.Y + b.Height, Z = z }; if (coord.Between(ripStart, ripEnd)) edges.Add(coord); coord = new Voxel.Coord { X = x, Y = b.Y - 1, Z = z }; if (coord.Between(ripStart, ripEnd)) edges.Add(coord); } } // Outer shell for (int y = b.Y; y < b.Y + b.Height; y++) { // Left and right for (int z = b.Z - 1; z <= b.Z + b.Depth; z++) { Voxel.Coord coord = new Voxel.Coord { X = b.X - 1, Y = y, Z = z }; if (coord.Between(ripStart, ripEnd)) edges.Add(coord); coord = new Voxel.Coord { X = b.X + b.Width, Y = y, Z = z }; if (coord.Between(ripStart, ripEnd)) edges.Add(coord); } // Backward and forward for (int x = b.X; x < b.X + b.Width; x++) { Voxel.Coord coord = new Voxel.Coord { X = x, Y = y, Z = b.Z - 1 }; if (coord.Between(ripStart, ripEnd)) edges.Add(coord); coord = new Voxel.Coord { X = x, Y = y, Z = b.Z + b.Depth }; if (coord.Between(ripStart, ripEnd)) edges.Add(coord); } } } if (edges.Contains(center)) return false; // Top and bottom for (int x = ripStart.X; x <= ripEnd.X; x++) { for (int z = ripStart.Z; z <= ripEnd.Z; z++) { Voxel.Coord c = new Voxel.Coord { X = x, Y = ripStart.Y, Z = z }; Voxel.State s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) edges.Add(c); c = new Voxel.Coord { X = x, Y = ripEnd.Y, Z = z }; s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) edges.Add(c); } } // Sides for (int y = ripStart.Y + 1; y <= ripEnd.Y - 1; y++) { // Left and right for (int z = ripStart.Z; z <= ripEnd.Z; z++) { Voxel.Coord c = new Voxel.Coord { X = ripStart.X, Y = y, Z = z }; Voxel.State s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) edges.Add(c); c = new Voxel.Coord { X = ripEnd.X, Y = y, Z = z }; s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) edges.Add(c); } // Backward and forward for (int x = ripStart.X; x <= ripEnd.X; x++) { Voxel.Coord c = new Voxel.Coord { X = x, Y = y, Z = ripStart.Z }; Voxel.State s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) edges.Add(c); c = new Voxel.Coord { X = x, Y = y, Z = ripEnd.Z }; s = voxel[c]; if (s != Voxel.States.Empty && !s.Permanent) edges.Add(c); } } Propagator p = WorldFactory.Instance.Get<Propagator>(); foreach (Voxel.Coord c in edges) p.SparksLowPriority(voxel.GetAbsolutePosition(c), Propagator.Spark.Dangerous); voxel.Empty(edges); voxel.Regenerate(callback); return true; } return false; }