public static bool CanPlace(WorldManager World, RailEntity PreviewEntity) { // Todo: Make sure this uses BuildObjectTool.IsValidPlacement to enforce building rules. var junctionPiece = PreviewEntity.GetPiece(); var actualPosition = PreviewEntity.GetContainingVoxel(); if (!actualPosition.IsValid) { return(false); } if (!actualPosition.IsEmpty) { return(false); } if (actualPosition.Coordinate.Y == 0) { return(false); // ??? } var voxelUnder = VoxelHelpers.GetVoxelBelow(actualPosition); if (voxelUnder.IsEmpty) { return(false); } var box = actualPosition.GetBoundingBox().Expand(-0.2f); foreach (var entity in World.EnumerateIntersectingObjects(box, CollisionType.Static)) { if ((entity as GameComponent).IsDead) { continue; } if (Object.ReferenceEquals(entity, PreviewEntity)) { continue; } if (Object.ReferenceEquals(entity.GetRoot(), PreviewEntity.GetRoot())) { continue; } if (entity is GenericVoxelListener) { continue; } if (entity is WorkPile) { continue; } if (entity is Health) { continue; } if (entity is CraftDetails) { continue; } if (entity is SimpleSprite) { continue; } if (FindPossibleCombination(junctionPiece, entity).HasValue(out var possibleCombination)) { var combinedPiece = new Rail.JunctionPiece { RailPiece = possibleCombination.Result, Orientation = Rail.OrientationHelper.Rotate((entity as RailEntity).GetPiece().Orientation, (int)possibleCombination.ResultRelativeOrientation), }; PreviewEntity.UpdatePiece(combinedPiece, PreviewEntity.GetContainingVoxel()); return(true); } if (Debugger.Switches.DrawToolDebugInfo) { Drawer3D.DrawBox(box, Color.Yellow, 0.2f, false); } World.UserInterface.ShowTooltip(String.Format("Can't place {0}. Entity in the way: {1}", junctionPiece.RailPiece, entity.ToString())); return(false); } return(true); }
public static void GenerateCaves(VoxelChunk Chunk, ChunkGeneratorSettings Settings) { if (Library.GetBiome("Cave").HasValue(out BiomeData caveBiome) && Library.GetBiome("Hell").HasValue(out BiomeData hellBiome)) { for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { for (int i = 0; i < Settings.CaveLevels.Count; i++) { // Does layer intersect this voxel? int y = Settings.CaveLevels[i]; if (y + Settings.MaxCaveHeight < Chunk.Origin.Y) { continue; } if (y >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY) { continue; } var coordinate = new GlobalVoxelCoordinate(Chunk.Origin.X + x, y, Chunk.Origin.Z + z); var data = GetCaveGenerationData(coordinate, i, Settings); var biome = (y <= Settings.HellLevel) ? hellBiome : caveBiome; if (!data.CaveHere) { continue; } for (int dy = 0; dy < data.Height; dy++) { var globalY = y + dy; // Prevent caves punching holes in bedrock. if (globalY <= 0) { continue; } // Check if voxel is inside chunk. if (globalY <= 0 || globalY < Chunk.Origin.Y || globalY >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY) { continue; } var voxel = VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, globalY - Chunk.Origin.Y, z)); // Prevent caves from breaking surface. bool caveBreaksSurface = false; foreach (var neighborCoordinate in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate)) { var v = Chunk.Manager.CreateVoxelHandle(neighborCoordinate); if (!v.IsValid || (v.Sunlight)) { caveBreaksSurface = true; break; } } if (caveBreaksSurface) { break; } voxel.RawSetType(Library.EmptyVoxelType); if (dy == 0) { // Place soil voxel and grass below cave. var below = VoxelHelpers.GetVoxelBelow(voxel); if (below.IsValid) { below.RawSetType(Library.GetVoxelType(biome.SoilLayer.VoxelType)); var grassType = Library.GetGrassType(biome.GrassDecal); if (grassType != null) { below.RawSetGrass(grassType.ID); } } // Spawn flora and fauna. if (data.Noise > Settings.CaveSize * 1.8f && globalY > Settings.LavaLevel) { GenerateCaveFlora(below, biome, Settings); GenerateCaveFauna(below, biome, Settings); } } } } } } } }