Ejemplo n.º 1
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);
            }
        }
Ejemplo n.º 2
0
            public override IEnumerable <Status> Run()
            {
                Creature.CurrentCharacterMode  = Creature.CharacterMode.Walking;
                Creature.OverrideCharacterMode = false;
                while (true)
                {
                    // ERROR CHECKS / INITIALIZING
                    Agent.Physics.Orientation = Physics.OrientMode.RotateY;
                    //Agent.Physics.CollideMode = Physics.CollisionMode.UpDown;

                    List <Creature.MoveAction> path = GetPath();

                    if (path == null)
                    {
                        SetPath(null);
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }
                    else if (path.Count > 0)
                    {
                        TargetVoxel = path.ElementAt(0).Voxel;
                    }
                    else
                    {
                        yield return(Status.Success);

                        break;
                    }

                    Creature.MoveAction currentAction = path.ElementAt(0);

                    // IF WE ARE MOVING
                    if (TargetVoxel != null)
                    {
                        Agent.Physics.IsSleeping = false;
                        Agent.LocalControlTimeout.Update(DwarfTime.LastTime);
                        ValidPathTimer.Update(DwarfTime.LastTime);

                        // Check if the path has been made invalid
                        if (ValidPathTimer.HasTriggered && !IsPathValid(path))
                        {
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            yield return(Status.Fail);
                        }

                        if (Agent.LocalControlTimeout.HasTriggered)
                        {
                            Vector3 target       = TargetVoxel.Position + new Vector3(.5f, .5f, .5f);
                            float   distToTarget = (target - Agent.Position).Length();
                            while (distToTarget > 0.1f)
                            {
                                Agent.Position = 0.9f * Agent.Position + 0.1f * target;
                                distToTarget   = (target - Agent.Position).Length();
                                yield return(Status.Running);
                            }
                            Agent.LocalControlTimeout.Reset(Agent.LocalControlTimeout.TargetTimeSeconds);
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            yield return(Status.Running);
                        }


                        if (PreviousTargetVoxel == null)
                        {
                            LocalTarget = TargetVoxel.Position + new Vector3(0.5f, 0.5f, 0.5f);
                        }
                        else
                        {
                            LocalTarget = MathFunctions.ClosestPointToLineSegment(Agent.Position,
                                                                                  PreviousTargetVoxel.Position,
                                                                                  TargetVoxel.Position, 0.25f) + new Vector3(0.5f, 0.5f, 0.5f);
                        }

                        Vector3 desiredVelocity = (LocalTarget - Agent.Position);
                        desiredVelocity.Normalize();
                        desiredVelocity *= Creature.Stats.MaxSpeed;

                        Vector3 output =
                            Agent.Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds,
                                                                desiredVelocity,
                                                                Creature.Physics.Velocity);

                        output.Y = 0.0f;
                        Agent.Creature.Physics.ApplyForce(output * 0.25f,
                                                          (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds);

                        float yDifference = (LocalTarget - Agent.Position).Y;

                        if (yDifference > 0.25f)
                        {
                            Agent.Jump(DwarfTime.LastTime);
                        }


                        if (Agent.DrawPath)
                        {
                            Drawer3D.DrawLineList(
                                new List <Vector3> {
                                LocalTarget, Agent.Creature.Physics.GlobalTransform.Translation
                            },
                                Color.White, 0.01f);

                            List <Vector3> points =
                                path.Select(v => v.Voxel.Position + new Vector3(0.5f, 0.5f, 0.5f)).ToList();

                            Drawer3D.DrawLineList(points, Color.Red, 0.1f);
                        }

                        bool goToNextNode;
                        if (path.Count > 1)
                        {
                            goToNextNode = (yDifference < 0.05 &&
                                            (LocalTarget - Agent.Creature.Physics.GlobalTransform.Translation).Length() <
                                            0.5f);
                        }
                        else
                        {
                            goToNextNode = (LocalTarget - Agent.Creature.Physics.GlobalTransform.Translation).Length() <
                                           0.25f;
                        }

                        if (goToNextNode)
                        {
                            if (path.Count > 0)
                            {
                                PreviousTargetVoxel = TargetVoxel;
                                Agent.LocalControlTimeout.Reset(Agent.LocalControlTimeout.TargetTimeSeconds);
                                TargetVoxel = path[0].Voxel;
                                path.RemoveAt(0);
                            }
                            else
                            {
                                PreviousTargetVoxel = null;
                                SetPath(null);
                                yield return(Status.Success);

                                break;
                            }
                        }
                    }
                    else
                    {
                        PreviousTargetVoxel = null;
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    yield return(Status.Running);
                }
            }