Esempio n. 1
0
 public VoxelHandle GetContainingVoxel()
 {
     return(new VoxelHandle(Manager.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(Position)));
 }
Esempio n. 2
0
        override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater)
        {
            base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater);

            if (Debugger.Switches.DrawRailNetwork)
            {
                DrawNeighborConnection(TrackAbove);
                DrawNeighborConnection(TrackBelow);
            }

            if (Primitive == null)
            {
                Primitive = new RawPrimitive();
                var voxel = GetContainingVoxel();
                AddSideQuad(voxel, new GlobalVoxelOffset(1, 0, 0), (float)Math.PI * 0.5f, new Vector3(0.45f, 0.0f, 0.0f));
                AddSideQuad(voxel, new GlobalVoxelOffset(0, 0, 1), 0.0f, new Vector3(0.0f, 0.0f, 0.45f));
                AddSideQuad(voxel, new GlobalVoxelOffset(-1, 0, 0), (float)Math.PI * 0.5f, new Vector3(-0.45f, 0.0f, 0.0f));
                AddSideQuad(voxel, new GlobalVoxelOffset(0, 0, -1), 0.0f, new Vector3(0.0f, 0.0f, -0.45f));
            }

            if (Primitive.VertexCount == 0)
            {
                return;
            }

            var under = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position));

            if (under.IsValid)
            {
                Color color = new Color(under.Sunlight ? 255 : 0, 255, 0);
                LightRamp = color;
            }
            else
            {
                LightRamp = new Color(200, 255, 0);
            }

            Color origTint = effect.VertexColorTint;

            if (!Active)
            {
                DoStipple(effect);
            }
            effect.VertexColorTint = VertexColor;
            effect.LightRamp       = LightRamp;
            effect.World           = GlobalTransform;

            effect.MainTexture = Sheet.GetTexture();


            effect.EnableWind = false;

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Primitive.Render(graphicsDevice);
            }

            effect.VertexColorTint = origTint;
            if (!Active && !String.IsNullOrEmpty(previousEffect))
            {
                effect.CurrentTechnique = effect.Techniques[previousEffect];
            }
        }
Esempio n. 3
0
 public IEnumerable <VoxelHandle> EnumerateExits()
 {
     foreach (var neighborVoxel in VoxelHelpers.EnumerateManhattanNeighbors2D_Y(GlobalVoxelCoordinate.FromVector3(Position)))
     {
         var below          = neighborVoxel + new GlobalVoxelOffset(0, -1, 0);
         var neighborHandle = new VoxelHandle(Manager.World.ChunkManager, neighborVoxel);
         if (neighborHandle.IsValid && neighborHandle.IsEmpty)
         {
             var belowHandle = new VoxelHandle(Manager.World.ChunkManager, below);
             if (belowHandle.IsValid && !belowHandle.IsEmpty)
             {
                 yield return(neighborHandle);
             }
         }
     }
 }
Esempio n. 4
0
        public static VoxelChunk GenerateChunk(GlobalChunkCoordinate ID, ChunkGeneratorSettings Settings)
        {
            var origin      = new GlobalVoxelCoordinate(ID, new LocalVoxelCoordinate(0, 0, 0));
            var worldDepth  = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY;
            var waterHeight = NormalizeHeight(Settings.Overworld.GenerationSettings.SeaLevel + 1.0f / worldDepth);

            var c = new VoxelChunk(Settings.World.ChunkManager, ID);

            for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
            {
                for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                {
                    var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), Settings.Overworld.InstanceSettings.Origin);
                    var biomeData         = Settings.Overworld.Map.GetBiomeAt(new Vector3(x + origin.X, 0, z + origin.Z), Settings.Overworld.InstanceSettings.Origin);

                    var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height));
                    var height           = MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2);
                    var stoneHeight      = (int)MathFunctions.Clamp((int)(height - (biomeData.SoilLayer.Depth + (Math.Sin(overworldPosition.X) + Math.Cos(overworldPosition.Y)))), 1, height);

                    for (int y = 0; y < VoxelConstants.ChunkSizeY; y++)
                    {
                        var globalY = origin.Y + y;
                        var voxel   = VoxelHandle.UnsafeCreateLocalHandle(c, new LocalVoxelCoordinate(x, y, z));

                        if (globalY == 0)
                        {
                            voxel.RawSetType(Library.GetVoxelType("Bedrock"));
                            continue;
                        }

                        // Below the stone line, use subsurface layers.
                        if (globalY <= stoneHeight && stoneHeight > 1)
                        {
                            var depth           = stoneHeight - globalY;
                            var subsurfaceLayer = 0;
                            while (depth > 0 && subsurfaceLayer < biomeData.SubsurfaceLayers.Count - 1)
                            {
                                depth           -= biomeData.SubsurfaceLayers[subsurfaceLayer].Depth;
                                subsurfaceLayer += 1;
                            }

                            voxel.RawSetType(Library.GetVoxelType(biomeData.SubsurfaceLayers[subsurfaceLayer].VoxelType));
                        }
                        // Otherwise, on the surface.
                        else if ((globalY == (int)height || globalY == stoneHeight) && normalizedHeight > waterHeight)
                        {
                            voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType));

                            if (!String.IsNullOrEmpty(biomeData.GrassDecal))
                            {
                                if (!biomeData.ClumpGrass || (biomeData.ClumpGrass &&
                                                              Settings.NoiseGenerator.Noise(overworldPosition.X / biomeData.ClumpSize, 0, overworldPosition.Y / biomeData.ClumpSize) > biomeData.ClumpTreshold))
                                {
                                    voxel.RawSetGrass(Library.GetGrassType(biomeData.GrassDecal).ID);
                                }
                            }
                        }
                        else if (globalY > height && globalY > 0)
                        {
                            voxel.RawSetType(Library.EmptyVoxelType);
                        }
                        else if (normalizedHeight <= waterHeight)
                        {
                            voxel.RawSetType(Library.GetVoxelType(biomeData.ShoreVoxel));
                        }
                        else
                        {
                            voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType));
                        }
                    }
                }
            }

            return(c);
        }
Esempio n. 5
0
        public override void Update(DwarfGame game, DwarfTime time)
        {
            if (Player.IsCameraRotationModeActive())
            {
                Player.VoxSelector.Enabled = false;
                Player.World.SetMouse(null);
                Player.BodySelector.Enabled = false;
                return;
            }

            Player.VoxSelector.Enabled       = true;
            Player.BodySelector.Enabled      = false;
            Player.VoxSelector.DrawBox       = false;
            Player.VoxSelector.DrawVoxel     = true;
            Player.VoxSelector.SelectionType = VoxelSelectionType.SelectEmpty;

            if (Player.World.IsMouseOverGui)
            {
                Player.World.SetMouse(Player.World.MousePointer);
            }
            else
            {
                Player.World.SetMouse(new Gui.MousePointer("mouse", 1, 4));
            }

            // Don't attempt any camera control if the user is trying to type intoa focus item.
            if (Player.World.Gui.FocusItem != null && !Player.World.Gui.FocusItem.IsAnyParentTransparent() && !Player.World.Gui.FocusItem.IsAnyParentHidden())
            {
                return;
            }
            KeyboardState state    = Keyboard.GetState();
            bool          leftKey  = state.IsKeyDown(ControlSettings.Mappings.RotateObjectLeft);
            bool          rightKey = state.IsKeyDown(ControlSettings.Mappings.RotateObjectRight);

            if (LeftPressed && !leftKey)
            {
                if (PathVoxels.Count > 1)
                {
                    var matched         = false;
                    var firstDelta      = CompassOrientationHelper.GetVoxelDelta(PathVoxels[0], PathVoxels[1]);
                    var firstConnection = new CompassConnection(OverrideStartingOrientation ? StartingOppositeOrientation : CompassOrientationHelper.Opposite(firstDelta), firstDelta);

                    var orientationDelta = 1;

                    for (; orientationDelta < 8 && !matched; ++orientationDelta)
                    {
                        firstConnection.A = CompassOrientationHelper.Rotate(firstConnection.A, 1);
                        foreach (var piece in RailLibrary.EnumeratePieces().Where(p => p.CompassConnections.Count != 0))
                        {
                            for (int j = 0; j < 4 && !matched; ++j)
                            {
                                foreach (var compassConnection in piece.CompassConnections)
                                {
                                    if (compassConnection.RotateToPiece((PieceOrientation)j) == firstConnection)
                                    {
                                        matched = true;
                                    }
                                }
                            }
                            if (matched)
                            {
                                break;
                            }
                        }
                    }

                    if (matched)
                    {
                        StartingOppositeOrientation = firstConnection.A;
                    }

                    OverrideStartingOrientation = true;
                }
            }
            if (RightPressed && !rightKey)
            {
                if (PathVoxels.Count > 1)
                {
                    var matched        = false;
                    var lastDelta      = CompassOrientationHelper.GetVoxelDelta(PathVoxels[PathVoxels.Count - 1], PathVoxels[PathVoxels.Count - 2]);
                    var lastConnection = new CompassConnection(lastDelta, OverrideEndingOrientation ? EndingOppositeOrientation : CompassOrientationHelper.Opposite(lastDelta));

                    var orientationDelta = 1;

                    for (; orientationDelta < 8 && !matched; ++orientationDelta)
                    {
                        lastConnection.B = CompassOrientationHelper.Rotate(lastConnection.B, 1);
                        foreach (var piece in RailLibrary.EnumeratePieces().Where(p => p.CompassConnections.Count != 0))
                        {
                            for (int j = 0; j < 4 && !matched; ++j)
                            {
                                foreach (var compassConnection in piece.CompassConnections)
                                {
                                    if (compassConnection.RotateToPiece((PieceOrientation)j) == lastConnection)
                                    {
                                        matched = true;
                                    }
                                }
                            }
                            if (matched)
                            {
                                break;
                            }
                        }
                    }

                    if (matched)
                    {
                        EndingOppositeOrientation = lastConnection.B;
                    }

                    OverrideEndingOrientation = true;
                }
            }
            LeftPressed  = leftKey;
            RightPressed = rightKey;

            var tint = Color.White;

            if (!Dragging)
            {
            }
            else
            {
                var voxelUnderMouse = Player.VoxSelector.VoxelUnderMouse;
                if (voxelUnderMouse == DragStartVoxel)
                {
                    // Create single straight preview piece
                }
                else
                {
                    var destinationPoint = voxelUnderMouse.Coordinate;

                    // Prevent path finding from attempting slopes - not supported yet.
                    destinationPoint = new GlobalVoxelCoordinate(destinationPoint.X, DragStartVoxel.Coordinate.Y, destinationPoint.Z);
                    var currentVoxel = DragStartVoxel.Coordinate;

                    PathVoxels.Clear();
                    PathVoxels.Add(currentVoxel);

                    while (true)
                    {
                        var   closestDirection = 0;
                        float closestDistance  = float.PositiveInfinity;
                        for (var i = 0; i < 8; ++i)
                        {
                            var offsetPos = currentVoxel + CompassOrientationHelper.GetOffset((CompassOrientation)i);
                            var distance  = (destinationPoint.ToVector3() - offsetPos.ToVector3()).LengthSquared();
                            if (distance < closestDistance)
                            {
                                closestDistance  = distance;
                                closestDirection = i;
                            }
                        }

                        var nextCoordinate = currentVoxel + CompassOrientationHelper.GetOffset((CompassOrientation)closestDirection);
                        PathVoxels.Add(nextCoordinate);
                        if (PathVoxels.Count >= 100)
                        {
                            break;
                        }

                        if (nextCoordinate == destinationPoint)
                        {
                            break;
                        }
                        currentVoxel = nextCoordinate;
                    }

                    // Iterate PathVoxels, determining deltas and using them to decide which piece to create.
                    var pathCompassConnections = new List <CompassConnection>();

                    if (PathVoxels.Count > 1)
                    {
                        var firstDelta = CompassOrientationHelper.GetVoxelDelta(PathVoxels[0], PathVoxels[1]);
                        pathCompassConnections.Add(new CompassConnection(OverrideStartingOrientation ? StartingOppositeOrientation : CompassOrientationHelper.Opposite(firstDelta), firstDelta));

                        for (var i = 1; i < PathVoxels.Count - 1; ++i)
                        {
                            pathCompassConnections.Add(new CompassConnection(
                                                           CompassOrientationHelper.GetVoxelDelta(PathVoxels[i], PathVoxels[i - 1]),
                                                           CompassOrientationHelper.GetVoxelDelta(PathVoxels[i], PathVoxels[i + 1])));
                        }

                        var lastDelta = CompassOrientationHelper.GetVoxelDelta(PathVoxels[PathVoxels.Count - 1], PathVoxels[PathVoxels.Count - 2]);
                        pathCompassConnections.Add(new CompassConnection(lastDelta, OverrideEndingOrientation ? EndingOppositeOrientation : CompassOrientationHelper.Opposite(lastDelta)));
                    }

                    var bodyCounter = 0;
                    var previousPieceAddedTrailingDiagonals = false;

                    for (var i = 0; i < pathCompassConnections.Count; ++i)
                    {
                        var pieceAdded = false;

                        foreach (var piece in RailLibrary.EnumeratePieces().Where(p => p.CompassConnections.Count != 0))
                        {
                            var matchedOrientation = PieceOrientation.North;
                            CompassConnection matchedConnection = new CompassConnection();
                            bool matched = false;
                            for (int j = 0; j < 4 && !matched; ++j)
                            {
                                foreach (var compassConnection in piece.CompassConnections)
                                {
                                    var rotated = compassConnection.RotateToPiece((PieceOrientation)j);
                                    if (rotated == pathCompassConnections[i])
                                    {
                                        matched            = true;
                                        matchedOrientation = (PieceOrientation)j;
                                        matchedConnection  = pathCompassConnections[i];
                                        break;
                                    }
                                }
                            }

                            if (matched)
                            {
                                var newPiece = new JunctionPiece
                                {
                                    Offset      = new Point(PathVoxels[i].X - DragStartVoxel.Coordinate.X, PathVoxels[i].Z - DragStartVoxel.Coordinate.Z),
                                    RailPiece   = piece.Name,
                                    Orientation = matchedOrientation
                                };

                                if (PreviewBodies.Count <= bodyCounter)
                                {
                                    PreviewBodies.Add(RailHelper.CreatePreviewBody(Player.World.ComponentManager, DragStartVoxel, newPiece));
                                }
                                else
                                {
                                    PreviewBodies[bodyCounter].UpdatePiece(newPiece, DragStartVoxel);
                                }

                                bodyCounter += 1;
                                pieceAdded   = true;

                                if (!previousPieceAddedTrailingDiagonals &&
                                    (matchedConnection.A == CompassOrientation.Northeast || matchedConnection.A == CompassOrientation.Southeast || matchedConnection.A == CompassOrientation.Southwest ||
                                     matchedConnection.A == CompassOrientation.Northwest))
                                {
                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.A, newPiece, 7, 5);
                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.A, newPiece, 1, 1);
                                }

                                if (matchedConnection.B == CompassOrientation.Northeast || matchedConnection.B == CompassOrientation.Southeast || matchedConnection.B == CompassOrientation.Southwest ||
                                    matchedConnection.B == CompassOrientation.Northwest)
                                {
                                    previousPieceAddedTrailingDiagonals = true;

                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.B, newPiece, 7, 5);
                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.B, newPiece, 1, 1);
                                }
                                else
                                {
                                    previousPieceAddedTrailingDiagonals = false;
                                }

                                break;
                            }
                        }

                        if (!pieceAdded)
                        {
                            break;
                        }
                    }

                    // Clean up any excess preview entities.
                    var lineSize = bodyCounter;

                    while (bodyCounter < PreviewBodies.Count)
                    {
                        PreviewBodies[bodyCounter].GetRoot().Delete();
                        bodyCounter += 1;
                    }

                    PreviewBodies = PreviewBodies.Take(lineSize).ToList();
                }
            }

            CanPlace = RailHelper.CanPlace(Player, PreviewBodies);
            if (CanPlace)
            {
                tint = GameSettings.Default.Colors.GetColor("Positive", Color.Green);
            }
            else
            {
                tint = GameSettings.Default.Colors.GetColor("Negative", Color.Red);
            }

            foreach (var body in PreviewBodies)
            {
                body.SetVertexColorRecursive(tint);
            }
        }
Esempio n. 6
0
        public static float GetAverageHeight(int X, int Z, int Width, int Height, ChunkGeneratorSettings Settings)
        {
            var avgHeight = 0;
            var numHeight = 0;

            for (var dx = 0; dx < Width; dx++)
            {
                for (var dz = 0; dz < Height; dz++)
                {
                    var worldPos  = new Vector3(X + dx, (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1, Z + dz);
                    var baseVoxel = VoxelHelpers.FindFirstVoxelBelowIncludingWater(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));

                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }

                    avgHeight += baseVoxel.Coordinate.Y + 1;
                    numHeight += 1;
                }
            }

            if (numHeight == 0)
            {
                return(0);
            }
            return(avgHeight / numHeight);
        }
Esempio n. 7
0
        public static BalloonPortVoxelSets GenerateBalloonPort(ChunkManager chunkManager, float x, float z, int size, ChunkGeneratorSettings Settings)
        {
            var centerCoordinate = GlobalVoxelCoordinate.FromVector3(new Vector3(x, (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1, z));

            var averageHeight = (int)GetAverageHeight(centerCoordinate.X - size, centerCoordinate.Y - size, size * 2 + 1, size * 2 + 1, Settings);

            // Next, create the balloon port by deciding which voxels to fill.
            var balloonPortDesignations = new List <VoxelHandle>();

            for (int dx = -size; dx <= size; dx++)
            {
                for (int dz = -size; dz <= size; dz++)
                {
                    var worldPos = new Vector3(centerCoordinate.X + dx, centerCoordinate.Y, centerCoordinate.Z + dz);

                    var baseVoxel = VoxelHelpers.FindFirstVoxelBelow(chunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));

                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }

                    var h = baseVoxel.Coordinate.Y + 1;

                    for (int y = averageHeight; y < h && y < chunkManager.World.WorldSizeInVoxels.Y; y++)
                    {
                        var v = chunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(baseVoxel.Coordinate.X, y, baseVoxel.Coordinate.Z));
                        v.RawSetType(Library.GetVoxelType(0));
                        v.RawSetIsExplored();
                        v.QuickSetLiquid(LiquidType.None, 0);
                    }

                    if (averageHeight < h)
                    {
                        h = averageHeight;
                    }

                    bool isPosX = (dx == size && dz == 0);
                    bool isPosZ = (dz == size & dx == 0);
                    bool isNegX = (dx == -size && dz == 0);
                    bool isNegZ = (dz == -size && dz == 0);
                    bool isSide = (isPosX || isNegX || isPosZ || isNegZ);

                    Vector3 offset = Vector3.Zero;

                    if (isSide)
                    {
                        if (isPosX)
                        {
                            offset = Vector3.UnitX;
                        }
                        else if (isPosZ)
                        {
                            offset = Vector3.UnitZ;
                        }
                        else if (isNegX)
                        {
                            offset = -Vector3.UnitX;
                        }
                        else if (isNegZ)
                        {
                            offset = -Vector3.UnitZ;
                        }
                    }

                    // Fill from the top height down to the bottom.
                    for (int y = Math.Max(0, h - 1); y < averageHeight && y < chunkManager.World.WorldSizeInVoxels.Y; y++)
                    {
                        var v = chunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(baseVoxel.Coordinate.X, y, baseVoxel.Coordinate.Z));
                        if (!v.IsValid)
                        {
                            throw new InvalidProgramException("Voxel was invalid while creating a new game's initial zones. This should not happen.");
                        }

                        v.RawSetType(Library.GetVoxelType("Scaffold"));
                        v.IsPlayerBuilt = true;
                        v.QuickSetLiquid(LiquidType.None, 0);
                        v.Sunlight = false;

                        if (y == averageHeight - 1)
                        {
                            v.RawSetIsExplored();

                            balloonPortDesignations.Add(v);
                        }

                        if (isSide)
                        {
                            var ladderPos = new Vector3(worldPos.X, y, worldPos.Z) + offset + Vector3.One * 0.5f;
                            var ladderVox = chunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(ladderPos));
                            if (ladderVox.IsValid && ladderVox.IsEmpty)
                            {
                                var ladder = EntityFactory.CreateEntity <Ladder>("Ladder", ladderPos);
                                Settings.World.PlayerFaction.OwnedObjects.Add(ladder);
                                ladder.Tags.Add("Moveable");
                                ladder.Tags.Add("Deconstructable");
                            }
                        }
                    }

                    CastSunlightColumn(baseVoxel.Coordinate.X, baseVoxel.Coordinate.Z, Settings);
                }
            }

            return(new BalloonPortVoxelSets
            {
                StockpileVoxels = balloonPortDesignations,
            });
        }
Esempio n. 8
0
        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 9
0
        override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater)
        {
            base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater);

            if (Debugger.Switches.DrawRailNetwork)
            {
                //Drawer3D.DrawBox(GetContainingVoxel().GetBoundingBox(), Color.White, 0.01f, true);
                //Drawer3D.DrawLine(GetContainingVoxel().GetBoundingBox().Center(), GlobalTransform.Translation, Color.White, 0.01f);
                var transform = Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)Piece.Orientation) * GlobalTransform;
                if (Library.GetRailPiece(Piece.RailPiece).HasValue(out var piece))
                {
                    foreach (var spline in piece.SplinePoints)
                    {
                        for (var i = 1; i < spline.Count; ++i)
                        {
                            Drawer3D.DrawLine(Vector3.Transform(spline[i - 1], transform),
                                              Vector3.Transform(spline[i], transform), Color.Purple, 0.1f);
                        }
                    }

                    foreach (var connection in piece.EnumerateConnections())
                    {
                        Drawer3D.DrawLine(Vector3.Transform(connection.Item1, transform) + new Vector3(0.0f, 0.2f, 0.0f),
                                          Vector3.Transform(connection.Item2, transform) + new Vector3(0.0f, 0.2f, 0.0f),
                                          Color.Brown, 0.1f);
                    }


                    //foreach (var neighborConnection in NeighborRails)
                    //{
                    //    var neighbor = Manager.FindComponent(neighborConnection.NeighborID);
                    //    if (neighbor == null)
                    //        Drawer3D.DrawLine(Position, Position + Vector3.UnitY, Color.CornflowerBlue, 0.1f);
                    //    else
                    //        Drawer3D.DrawLine(Position + new Vector3(0.0f, 0.5f, 0.0f), (neighbor as Body).Position + new Vector3(0.0f, 0.5f, 0.0f), Color.Teal, 0.1f);
                    //}
                }
            }

            if (!IsVisible)
            {
                return;
            }

            if (Primitive == null)
            {
                var bounds = Vector4.Zero;
                var uvs    = Sheet.GenerateTileUVs(Frame, out bounds);

                if (Library.GetRailPiece(Piece.RailPiece).HasValue(out var rawPiece))
                {
                    var transform = Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)Piece.Orientation);
                    var realShape = 0;

                    if (rawPiece.AutoSlope)
                    {
                        var transformedConnections = GetTransformedConnections();
                        var matchingNeighbor1      = NeighborRails.FirstOrDefault(n => (n.Position - transformedConnections[0].Item1 - new Vector3(0.0f, 1.0f, 0.0f)).LengthSquared() < 0.001f);
                        var matchingNeighbor2      = NeighborRails.FirstOrDefault(n => (n.Position - transformedConnections[1].Item1 - new Vector3(0.0f, 1.0f, 0.0f)).LengthSquared() < 0.001f);

                        if (matchingNeighbor1 != null && matchingNeighbor2 != null)
                        {
                            realShape = 3;
                        }
                        else if (matchingNeighbor1 != null)
                        {
                            realShape = 1;
                        }
                        else if (matchingNeighbor2 != null)
                        {
                            realShape = 2;
                        }
                    }

                    Primitive = new RawPrimitive();
                    Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(-0.5f, VertexHeightOffsets[realShape, 0], 0.5f), transform), Color.White, Color.White, uvs[0], bounds));
                    Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(0.5f, VertexHeightOffsets[realShape, 1], 0.5f), transform), Color.White, Color.White, uvs[1], bounds));
                    Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(0.5f, VertexHeightOffsets[realShape, 2], -0.5f), transform), Color.White, Color.White, uvs[2], bounds));
                    Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(-0.5f, VertexHeightOffsets[realShape, 3], -0.5f), transform), Color.White, Color.White, uvs[3], bounds));
                    Primitive.AddIndicies(new short[] { 0, 1, 3, 1, 2, 3 });

                    var       sideBounds = Vector4.Zero;
                    Vector2[] sideUvs    = null;

                    sideUvs = Sheet.GenerateTileUVs(new Point(3, 4), out sideBounds);

                    AddScaffoldGeometry(transform, sideBounds, sideUvs, -1.0f, false);

                    if (realShape == 3)
                    {
                        AddScaffoldGeometry(transform, sideBounds, sideUvs, 0.0f, false);
                    }
                    else if (realShape == 1)
                    {
                        sideUvs = Sheet.GenerateTileUVs(new Point(0, 4), out sideBounds);
                        AddScaffoldGeometry(transform, sideBounds, sideUvs, 0.0f, true);
                    }
                    else if (realShape == 2)
                    {
                        sideUvs = Sheet.GenerateTileUVs(new Point(0, 4), out sideBounds);
                        AddScaffoldGeometry(transform, sideBounds, sideUvs, 0.0f, false);
                    }

                    // Todo: Make these static and avoid recalculating them constantly.
                    var bumperBackBounds  = Vector4.Zero;
                    var bumperBackUvs     = Sheet.GenerateTileUVs(new Point(0, 5), out bumperBackBounds);
                    var bumperFrontBounds = Vector4.Zero;
                    var bumperFrontUvs    = Sheet.GenerateTileUVs(new Point(1, 5), out bumperFrontBounds);
                    var bumperSideBounds  = Vector4.Zero;
                    var bumperSideUvs     = Sheet.GenerateTileUVs(new Point(2, 5), out bumperSideBounds);

                    foreach (var connection in GetTransformedConnections())
                    {
                        var matchingNeighbor = NeighborRails.FirstOrDefault(n => (n.Position - connection.Item1).LengthSquared() < 0.001f);
                        if (matchingNeighbor == null && rawPiece.AutoSlope)
                        {
                            matchingNeighbor = NeighborRails.FirstOrDefault(n => (n.Position - connection.Item1 - new Vector3(0.0f, 1.0f, 0.0f)).LengthSquared() < 0.001f);
                        }

                        if (matchingNeighbor == null)
                        {
                            var bumperOffset = connection.Item1 - GlobalTransform.Translation;
                            var bumperGap    = Vector3.Normalize(bumperOffset) * 0.1f;
                            var bumperAngle  = AngleBetweenVectors(new Vector2(bumperOffset.X, bumperOffset.Z), new Vector2(0, 0.5f));

                            var xDiag = bumperOffset.X <-0.001f || bumperOffset.X> 0.001f;
                            var zDiag = bumperOffset.Z <-0.001f || bumperOffset.Z> 0.001f;

                            if (xDiag && zDiag)
                            {
                                var y = bumperOffset.Y;
                                bumperOffset  *= sqrt2;
                                bumperOffset.Y = y;

                                var endBounds = Vector4.Zero;
                                var endUvs    = Sheet.GenerateTileUVs(new Point(6, 2), out endBounds);
                                Primitive.AddQuad(
                                    Matrix.CreateRotationY((float)Math.PI * 1.25f)
                                    * Matrix.CreateRotationY(bumperAngle)
                                    // This offset would not be correct if diagonals could slope.
                                    * Matrix.CreateTranslation(new Vector3(Sign(bumperOffset.X), 0.0f, Sign(bumperOffset.Z))),
                                    Color.White, Color.White, endUvs, endBounds);
                            }

                            Primitive.AddQuad(
                                Matrix.CreateRotationX(-(float)Math.PI * 0.5f)
                                * Matrix.CreateTranslation(0.0f, 0.3f, -0.2f)
                                * Matrix.CreateRotationY(bumperAngle)
                                * Matrix.CreateTranslation(bumperOffset + bumperGap),
                                Color.White, Color.White, bumperBackUvs, bumperBackBounds);

                            Primitive.AddQuad(
                                Matrix.CreateRotationX(-(float)Math.PI * 0.5f)
                                * Matrix.CreateTranslation(0.0f, 0.3f, -0.2f)
                                * Matrix.CreateRotationY(bumperAngle)
                                * Matrix.CreateTranslation(bumperOffset),
                                Color.White, Color.White, bumperFrontUvs, bumperFrontBounds);

                            var firstVoxelBelow = VoxelHelpers.FindFirstVoxelBelow(GetContainingVoxel());
                            if (firstVoxelBelow.IsValid && firstVoxelBelow.RampType == RampType.None)

                            //     if (VoxelHelpers.FindFirstVoxelBelow(GetContainingVoxel()).RampType == RampType.None)
                            {
                                Primitive.AddQuad(
                                    Matrix.CreateRotationX(-(float)Math.PI * 0.5f)
                                    * Matrix.CreateRotationY(-(float)Math.PI * 0.5f)
                                    * Matrix.CreateTranslation(0.3f, 0.3f, 0.18f)
                                    * Matrix.CreateRotationY(bumperAngle)
                                    * Matrix.CreateTranslation(bumperOffset),
                                    Color.White, Color.White, bumperSideUvs, bumperSideBounds);

                                Primitive.AddQuad(
                                    Matrix.CreateRotationX(-(float)Math.PI * 0.5f)
                                    * Matrix.CreateRotationY(-(float)Math.PI * 0.5f)
                                    * Matrix.CreateTranslation(-0.3f, 0.3f, 0.18f)
                                    * Matrix.CreateRotationY(bumperAngle)
                                    * Matrix.CreateTranslation(bumperOffset),
                                    Color.White, Color.White, bumperSideUvs, bumperSideBounds);
                            }
                        }
                    }
                }
            }

            // Everything that draws should set it's tint, making this pointless.

            var under = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position));

            if (under.IsValid)
            {
                Color color = new Color(under.Sunlight ? 255 : 0, 255, 0);
                LightRamp = color;
            }
            else
            {
                LightRamp = new Color(200, 255, 0);
            }

            Color origTint = effect.VertexColorTint;

            if (!Active)
            {
                DoStipple(effect);
            }
            effect.VertexColorTint = VertexColor;
            effect.LightRamp       = LightRamp;
            effect.World           = GlobalTransform;

            effect.MainTexture = Sheet.GetTexture();


            effect.EnableWind = false;

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Primitive.Render(graphicsDevice);
            }

            effect.VertexColorTint = origTint;
            if (!Active)
            {
                EndDraw(effect);
            }
        }
Esempio n. 10
0
        public Microsoft.Xna.Framework.Vector3 GetSpawnLocation(WorldManager world, EntitySpawnLocation SpawnLocation)
        {
            Microsoft.Xna.Framework.Vector3 location = location = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(world.ChunkManager, GlobalVoxelCoordinate.FromVector3(MonsterSpawner.GetRandomWorldEdge(world)))).WorldPosition + Microsoft.Xna.Framework.Vector3.Up * 1.5f;
            switch (SpawnLocation)
            {
            case EntitySpawnLocation.BalloonPort:
            {
                var balloonport = world.EnumerateZones().OfType <BalloonPort>();
                if (balloonport.Any())
                {
                    location = Datastructures.SelectRandom(balloonport).GetBoundingBox().Center() + Microsoft.Xna.Framework.Vector3.Up * 1.5f;
                }
                break;
            }

            case EntitySpawnLocation.RandomZone:
            {
                var zones = world.EnumerateZones();
                if (zones.Any())
                {
                    location = Datastructures.SelectRandom(zones).GetBoundingBox().Center() + Microsoft.Xna.Framework.Vector3.Up * 1.5f;
                }
                break;
            }

            case EntitySpawnLocation.WorldEdge:
            {
                // already computed
                break;
            }
            }

            return(location);
        }
Esempio n. 11
0
        public static void GenerateRuin(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            var noiseVector = Chunk.Origin.ToVector3() * Settings.CaveNoiseScale;
            var ruinsNoise  = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z);

            if (Math.Abs(ruinsNoise) > GameSettings.Default.GenerationRuinsRate)
            {
                return;
            }

            int structureWidth = MathFunctions.RandInt(4, 16);
            int structureDepth = MathFunctions.RandInt(4, 16);
            int xOffset        = MathFunctions.RandInt(0, VoxelConstants.ChunkSizeX - structureWidth);
            int zOffset        = MathFunctions.RandInt(0, VoxelConstants.ChunkSizeZ - structureDepth);
            int wallHeight     = MathFunctions.RandInt(2, 6);
            int heightOffset   = MathFunctions.RandInt(-4, 2);

            var biome     = Settings.Overworld.Map.GetBiomeAt(Chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin);
            var avgHeight = GetAverageHeight(Chunk.Origin.X, Chunk.Origin.Z, structureWidth, structureDepth, Settings);

            bool[] doors = new bool[4];

            for (int k = 0; k < 4; k++)
            {
                doors[k] = MathFunctions.RandEvent(0.5f);
            }

            for (int dx = 0; dx < structureWidth; dx++)
            {
                for (int dz = 0; dz < structureDepth; dz++)
                {
                    var worldPos = new Vector3(Chunk.Origin.X + dx + xOffset, avgHeight + heightOffset, Chunk.Origin.Z + dz + zOffset);

                    var baseVoxel  = Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos));
                    var underVoxel = VoxelHelpers.FindFirstVoxelBelow(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));
                    var decay      = Settings.NoiseGenerator.Generate(worldPos.X * 0.05f, worldPos.Y * 0.05f, worldPos.Z * 0.05f);

                    if (decay > 0.7f)
                    {
                        continue;
                    }
                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }
                    if (baseVoxel.Coordinate.Y == (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1)
                    {
                        continue;
                    }
                    if (!underVoxel.IsValid)
                    {
                        continue;
                    }

                    var edge = (dx == 0 || dx == structureWidth - 1) || (dz == 0 || dz == structureDepth - 1);
                    if (!edge && !baseVoxel.IsEmpty)
                    {
                        continue;
                    }

                    if (edge)
                    {
                        baseVoxel.RawSetType(Library.GetVoxelType(biome.RuinWallType));
                    }
                    else
                    {
                        baseVoxel.RawSetType(Library.GetVoxelType(biome.RuinFloorType));
                    }

                    bool[] wallState = new bool[4];
                    wallState[0] = dx == 0;
                    wallState[1] = dx == structureWidth - 1;
                    wallState[2] = dz == 0;
                    wallState[3] = dz == structureDepth - 1;

                    bool[] doorState = new bool[4];
                    doorState[0] = Math.Abs(dz - structureDepth / 2) < 1;
                    doorState[1] = doorState[0];
                    doorState[2] = Math.Abs(dx - structureWidth / 2) < 1;
                    doorState[3] = doorState[2];

                    for (int dy = 1; dy < (baseVoxel.Coordinate.Y - underVoxel.Coordinate.Y); dy++)
                    {
                        var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(underVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0));

                        if (!currVoxel.IsValid)
                        {
                            continue;
                        }

                        currVoxel.RawSetType(underVoxel.Type);
                    }

                    underVoxel.RawSetGrass(0);

                    if (edge)
                    {
                        for (int dy = 1; dy < wallHeight * (1.0f - decay) && dy < (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 2; dy++)
                        {
                            var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(baseVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0));

                            if (!currVoxel.IsValid)
                            {
                                continue;
                            }

                            if (currVoxel.Coordinate.Y == VoxelConstants.ChunkSizeY - 1)
                            {
                                continue;
                            }

                            bool door = false;
                            for (int k = 0; k < 4; k++)
                            {
                                if (wallState[k] && doors[k] && doorState[k])
                                {
                                    door = true;
                                    break;
                                }
                            }

                            if (door && dy < 3)
                            {
                                continue;
                            }

                            currVoxel.RawSetType(Library.GetVoxelType(biome.RuinWallType));
                        }
                    }
                }
            }
        }
Esempio n. 12
0
        public void OnClicked(int X, int Y)
        {
            Viewport viewPort = new Viewport(RenderTarget.Bounds);
            Vector3  forward  = (World.Camera.Target - World.Camera.Position);

            forward.Normalize();

            Vector3 pos    = viewPort.Unproject(new Vector3(X, Y, 0), Camera.ProjectionMatrix, Camera.ViewMatrix, Matrix.Identity);
            Vector3 target = new Vector3(pos.X, World.Camera.Position.Y, pos.Z);
            var     height = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(
                                                                  World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(target)))
                             .Coordinate.Y + 1;

            target.Y = Math.Max(height + 15, target.Y);
            target   = MathFunctions.Clamp(target, World.ChunkManager.Bounds);
            World.Camera.ZoomTargets.Clear();
            World.Camera.ZoomTargets.Add(target);
        }