Example #1
0
		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;
		}