Example #1
0
        /// <summary>
        /// Instantiates level data using the properties of the connection (seed, size, difficulty)
        /// </summary>
        public LevelData(LocationConnection locationConnection)
        {
            Seed             = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
            Biome            = locationConnection.Biome;
            Type             = LevelType.LocationConnection;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome);
            Difficulty       = locationConnection.Difficulty;

            float sizeFactor = MathUtils.InverseLerp(
                MapGenerationParams.Instance.SmallLevelConnectionLength,
                MapGenerationParams.Instance.LargeLevelConnectionLength,
                locationConnection.Length);
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, sizeFactor);

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));

            var rand = new MTRandom(ToolBox.StringToInt(Seed));

            InitialDepth = (int)MathHelper.Lerp(GenerationParams.InitialDepthMin, GenerationParams.InitialDepthMax, (float)rand.NextDouble());

            HasBeaconStation = rand.NextDouble() < locationConnection.Locations.Select(l => l.Type.BeaconStationChance).Max();
            IsBeaconActive   = false;
        }
Example #2
0
        /// <summary>
        /// Instantiates level data using the properties of the connection (seed, size, difficulty)
        /// </summary>
        public LevelData(LocationConnection locationConnection)
        {
            Seed             = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
            Biome            = locationConnection.Biome;
            Type             = LevelType.LocationConnection;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome);
            Difficulty       = locationConnection.Difficulty;

            float sizeFactor = MathUtils.InverseLerp(
                MapGenerationParams.Instance.SmallLevelConnectionLength,
                MapGenerationParams.Instance.LargeLevelConnectionLength,
                locationConnection.Length);
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, sizeFactor);

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));

            var rand = new MTRandom(ToolBox.StringToInt(Seed));

            InitialDepth = (int)MathHelper.Lerp(GenerationParams.InitialDepthMin, GenerationParams.InitialDepthMax, (float)rand.NextDouble());

            //minimum difficulty of the level before hunting grounds can appear
            float huntingGroundsDifficultyThreshold = 25;
            //probability of hunting grounds appearing in 100% difficulty levels
            float maxHuntingGroundsProbability = 0.3f;

            HasHuntingGrounds = OriginallyHadHuntingGrounds = rand.NextDouble() < MathUtils.InverseLerp(huntingGroundsDifficultyThreshold, 100.0f, Difficulty) * maxHuntingGroundsProbability;

            HasBeaconStation = !HasHuntingGrounds && rand.NextDouble() < locationConnection.Locations.Select(l => l.Type.BeaconStationChance).Max();
            IsBeaconActive   = false;
        }
Example #3
0
        public LevelData(string seed, float difficulty, float sizeFactor, LevelGenerationParams generationParams, Biome biome)
        {
            Seed             = seed ?? throw new ArgumentException("Seed was null");
            Biome            = biome ?? throw new ArgumentException("Biome was null");
            GenerationParams = generationParams ?? throw new ArgumentException("Level generation parameters were null");
            Type             = GenerationParams.Type;
            Difficulty       = difficulty;

            sizeFactor = MathHelper.Clamp(sizeFactor, 0.0f, 1.0f);
            int width = (int)MathHelper.Lerp(generationParams.MinWidth, generationParams.MaxWidth, sizeFactor);

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(generationParams.Height, Level.GridCellSize));
        }
Example #4
0
        /// <summary>
        /// Instantiates level data using the properties of the location
        /// </summary>
        public LevelData(Location location)
        {
            Seed             = location.BaseName;
            Biome            = location.Biome;
            Type             = LevelType.Outpost;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.Outpost, Biome);
            Difficulty       = 0.0f;

            var rand  = new MTRandom(ToolBox.StringToInt(Seed));
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, (float)rand.NextDouble());

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));
        }
Example #5
0
        public void Draw(SpriteBatch spriteBatch)
        {
            if (GameMain.DebugDraw)
            {
                var cells = level.GetCells(GameMain.GameScreen.Cam.WorldViewCenter, 2);
                foreach (VoronoiCell cell in cells)
                {
                    GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y - 10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);

                    GUI.DrawLine(spriteBatch,
                                 new Vector2(cell.edges[0].point1.X, -cell.edges[0].point1.Y),
                                 new Vector2(cell.Center.X, -cell.Center.Y),
                                 Color.Blue * 0.5f);

                    foreach (GraphEdge edge in cell.edges)
                    {
                        GUI.DrawLine(spriteBatch, new Vector2(edge.point1.X, -edge.point1.Y),
                                     new Vector2(edge.point2.X, -edge.point2.Y), cell.body == null ? Color.Cyan * 0.5f : Color.White);
                    }

                    foreach (Vector2 point in cell.bodyVertices)
                    {
                        GUI.DrawRectangle(spriteBatch, new Vector2(point.X, -point.Y), new Vector2(10.0f, 10.0f), Color.White, true);
                    }
                }
            }


            Vector2 pos = new Vector2(0.0f, -level.Size.Y);

            if (GameMain.GameScreen.Cam.WorldView.Y < -pos.Y - 1024)
            {
                return;
            }

            pos.X = GameMain.GameScreen.Cam.WorldView.X - 1024;

            int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 1024 + 4.0f) * 1024);

            GUI.DrawRectangle(spriteBatch, new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)-GameMain.GameScreen.Cam.WorldView.Y, width, (int)(GameMain.GameScreen.Cam.WorldView.Y + pos.Y) - 30), Color.Black, true);
            spriteBatch.Draw(shaftTexture,
                             new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)pos.Y - 1000, width, 1024),
                             new Rectangle(0, 0, width, -1024),
                             level.BackgroundColor, 0.0f,
                             Vector2.Zero,
                             SpriteEffects.None, 0.0f);
        }
Example #6
0
        /// <summary>
        /// Instantiates level data using the properties of the connection (seed, size, difficulty)
        /// </summary>
        public LevelData(LocationConnection locationConnection)
        {
            Seed             = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
            Biome            = locationConnection.Biome;
            Type             = LevelType.LocationConnection;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome);
            Difficulty       = locationConnection.Difficulty;

            float sizeFactor = MathUtils.InverseLerp(
                MapGenerationParams.Instance.SmallLevelConnectionLength,
                MapGenerationParams.Instance.LargeLevelConnectionLength,
                locationConnection.Length);
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, sizeFactor);

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));
        }
Example #7
0
        public void Draw(SpriteBatch spriteBatch)
        {
            if (GameMain.DebugDraw)
            {
                var cells = level.GetCells(GameMain.GameScreen.Cam.WorldViewCenter, 2);
                foreach (VoronoiCell cell in cells)
                {
                    GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y - 10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);

                    GUI.DrawLine(spriteBatch,
                                 new Vector2(cell.edges[0].point1.X, -cell.edges[0].point1.Y),
                                 new Vector2(cell.Center.X, -cell.Center.Y),
                                 Color.Blue * 0.5f);

                    foreach (GraphEdge edge in cell.edges)
                    {
                        GUI.DrawLine(spriteBatch, new Vector2(edge.point1.X, -edge.point1.Y),
                                     new Vector2(edge.point2.X, -edge.point2.Y), cell.body == null ? Color.Cyan * 0.5f : Color.White);
                    }

                    foreach (Vector2 point in cell.bodyVertices)
                    {
                        GUI.DrawRectangle(spriteBatch, new Vector2(point.X, -point.Y), new Vector2(10.0f, 10.0f), Color.White, true);
                    }
                }

                foreach (List <Vector2> nodeList in level.SmallTunnels)
                {
                    for (int i = 1; i < nodeList.Count; i++)
                    {
                        GUI.DrawLine(spriteBatch,
                                     new Vector2(nodeList[i - 1].X, -nodeList[i - 1].Y),
                                     new Vector2(nodeList[i].X, -nodeList[i].Y),
                                     Color.Lerp(Color.Yellow, Color.Red, i / (float)nodeList.Count), 0, 10);
                    }
                }
            }

            Vector2 pos = new Vector2(0.0f, -level.Size.Y);

            if (GameMain.GameScreen.Cam.WorldView.Y >= -pos.Y - 1024)
            {
                pos.X = GameMain.GameScreen.Cam.WorldView.X - 1024;
                int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 1024 + 4.0f) * 1024);

                GUI.DrawRectangle(spriteBatch, new Rectangle(
                                      (int)(MathUtils.Round(pos.X, 1024)),
                                      -GameMain.GameScreen.Cam.WorldView.Y,
                                      width,
                                      (int)(GameMain.GameScreen.Cam.WorldView.Y + pos.Y) - 30),
                                  Color.Black, true);

                spriteBatch.Draw(shaftTexture,
                                 new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)pos.Y - 1000, width, 1024),
                                 new Rectangle(0, 0, width, -1024),
                                 level.BackgroundColor, 0.0f,
                                 Vector2.Zero,
                                 SpriteEffects.None, 0.0f);
            }

            if (GameMain.GameScreen.Cam.WorldView.Y - GameMain.GameScreen.Cam.WorldView.Height < level.SeaFloorTopPos + 1024)
            {
                pos = new Vector2(GameMain.GameScreen.Cam.WorldView.X - 1024, -level.BottomPos);

                int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 1024 + 4.0f) * 1024);

                GUI.DrawRectangle(spriteBatch, new Rectangle(
                                      (int)(MathUtils.Round(pos.X, 1024)),
                                      (int)-(level.BottomPos - 30),
                                      width,
                                      (int)(level.BottomPos - (GameMain.GameScreen.Cam.WorldView.Y - GameMain.GameScreen.Cam.WorldView.Height))),
                                  Color.Black, true);

                spriteBatch.Draw(shaftTexture,
                                 new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)-level.BottomPos, width, 1024),
                                 new Rectangle(0, 0, width, -1024),
                                 level.BackgroundColor, 0.0f,
                                 Vector2.Zero,
                                 SpriteEffects.FlipVertically, 0.0f);
            }
        }
Example #8
0
        public void DrawDebugOverlay(SpriteBatch spriteBatch, Camera cam)
        {
            if (GameMain.DebugDraw && cam.Zoom > 0.1f)
            {
                var cells = level.GetCells(cam.WorldViewCenter, 2);
                foreach (VoronoiCell cell in cells)
                {
                    GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y - 10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);

                    GUI.DrawLine(spriteBatch,
                                 new Vector2(cell.Edges[0].Point1.X + cell.Translation.X, -(cell.Edges[0].Point1.Y + cell.Translation.Y)),
                                 new Vector2(cell.Center.X, -(cell.Center.Y)),
                                 Color.Blue * 0.5f);

                    foreach (GraphEdge edge in cell.Edges)
                    {
                        GUI.DrawLine(spriteBatch, new Vector2(edge.Point1.X + cell.Translation.X, -(edge.Point1.Y + cell.Translation.Y)),
                                     new Vector2(edge.Point2.X + cell.Translation.X, -(edge.Point2.Y + cell.Translation.Y)), edge.NextToCave ? Color.Red : (cell.Body == null ? Color.Cyan * 0.5f : (edge.IsSolid ? Color.White : Color.Gray)),
                                     width: edge.NextToCave ? 8 : 1);
                    }

                    foreach (Vector2 point in cell.BodyVertices)
                    {
                        GUI.DrawRectangle(spriteBatch, new Vector2(point.X + cell.Translation.X, -(point.Y + cell.Translation.Y)), new Vector2(10.0f, 10.0f), Color.White, true);
                    }
                }

                /*foreach (List<Point> nodeList in level.SmallTunnels)
                 * {
                 *  for (int i = 1; i < nodeList.Count; i++)
                 *  {
                 *      GUI.DrawLine(spriteBatch,
                 *          new Vector2(nodeList[i - 1].X, -nodeList[i - 1].Y),
                 *          new Vector2(nodeList[i].X, -nodeList[i].Y),
                 *          Color.Lerp(Color.Yellow, GUI.Style.Red, i / (float)nodeList.Count), 0, 10);
                 *  }
                 * }*/

                foreach (var abyssIsland in level.AbyssIslands)
                {
                    GUI.DrawRectangle(spriteBatch, new Vector2(abyssIsland.Area.X, -abyssIsland.Area.Y - abyssIsland.Area.Height), abyssIsland.Area.Size.ToVector2(), Color.Cyan, thickness: 5);
                }

                foreach (var ruin in level.Ruins)
                {
                    ruin.DebugDraw(spriteBatch);
                }
            }

            Vector2 pos = new Vector2(0.0f, -level.Size.Y);

            if (cam.WorldView.Y >= -pos.Y - 1024)
            {
                int topBarrierWidth  = level.GenerationParams.WallEdgeSprite.Texture.Width;
                int topBarrierHeight = level.GenerationParams.WallEdgeSprite.Texture.Height;

                pos.X = cam.WorldView.X - topBarrierWidth;
                int width = (int)(Math.Ceiling(cam.WorldView.Width / 1024 + 4.0f) * topBarrierWidth);

                GUI.DrawRectangle(spriteBatch, new Rectangle(
                                      (int)MathUtils.Round(pos.X, topBarrierWidth),
                                      -cam.WorldView.Y,
                                      width,
                                      (int)(cam.WorldView.Y + pos.Y) - 60),
                                  Color.Black, true);

                spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
                                 new Rectangle((int)MathUtils.Round(pos.X, topBarrierWidth), (int)(pos.Y - topBarrierHeight + level.GenerationParams.WallEdgeExpandOutwardsAmount), width, topBarrierHeight),
                                 new Rectangle(0, 0, width, -topBarrierHeight),
                                 GameMain.LightManager?.LightingEnabled ?? false ? GameMain.LightManager.AmbientLight : level.WallColor, 0.0f,
                                 Vector2.Zero,
                                 SpriteEffects.None, 0.0f);
            }

            if (cam.WorldView.Y - cam.WorldView.Height < level.SeaFloorTopPos + 1024)
            {
                int bottomBarrierWidth  = level.GenerationParams.WallEdgeSprite.Texture.Width;
                int bottomBarrierHeight = level.GenerationParams.WallEdgeSprite.Texture.Height;
                pos = new Vector2(cam.WorldView.X - bottomBarrierWidth, -level.BottomPos);
                int width = (int)(Math.Ceiling(cam.WorldView.Width / bottomBarrierWidth + 4.0f) * bottomBarrierWidth);

                GUI.DrawRectangle(spriteBatch, new Rectangle(
                                      (int)(MathUtils.Round(pos.X, bottomBarrierWidth)),
                                      -(level.BottomPos - 60),
                                      width,
                                      level.BottomPos - (cam.WorldView.Y - cam.WorldView.Height)),
                                  Color.Black, true);

                spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
                                 new Rectangle((int)MathUtils.Round(pos.X, bottomBarrierWidth), -level.BottomPos - (int)level.GenerationParams.WallEdgeExpandOutwardsAmount, width, bottomBarrierHeight),
                                 new Rectangle(0, 0, width, -bottomBarrierHeight),
                                 GameMain.LightManager?.LightingEnabled ?? false ? GameMain.LightManager.AmbientLight : level.WallColor, 0.0f,
                                 Vector2.Zero,
                                 SpriteEffects.FlipVertically, 0.0f);
            }
        }
        public void Draw(SpriteBatch spriteBatch, Camera cam)
        {
            if (GameMain.DebugDraw && cam.Zoom > 0.1f)
            {
                var cells = level.GetCells(cam.WorldViewCenter, 2);
                foreach (VoronoiCell cell in cells)
                {
                    GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y - 10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);

                    GUI.DrawLine(spriteBatch,
                                 new Vector2(cell.Edges[0].Point1.X + cell.Translation.X, -(cell.Edges[0].Point1.Y + cell.Translation.Y)),
                                 new Vector2(cell.Center.X, -(cell.Center.Y)),
                                 Color.Blue * 0.5f);

                    foreach (GraphEdge edge in cell.Edges)
                    {
                        GUI.DrawLine(spriteBatch, new Vector2(edge.Point1.X + cell.Translation.X, -(edge.Point1.Y + cell.Translation.Y)),
                                     new Vector2(edge.Point2.X + cell.Translation.X, -(edge.Point2.Y + cell.Translation.Y)), cell.Body == null ? Color.Cyan * 0.5f : Color.White);
                    }

                    foreach (Vector2 point in cell.BodyVertices)
                    {
                        GUI.DrawRectangle(spriteBatch, new Vector2(point.X + cell.Translation.X, -(point.Y + cell.Translation.Y)), new Vector2(10.0f, 10.0f), Color.White, true);
                    }
                }

                foreach (List <Point> nodeList in level.SmallTunnels)
                {
                    for (int i = 1; i < nodeList.Count; i++)
                    {
                        GUI.DrawLine(spriteBatch,
                                     new Vector2(nodeList[i - 1].X, -nodeList[i - 1].Y),
                                     new Vector2(nodeList[i].X, -nodeList[i].Y),
                                     Color.Lerp(Color.Yellow, GUI.Style.Red, i / (float)nodeList.Count), 0, 10);
                    }
                }

                foreach (var ruin in level.Ruins)
                {
                    ruin.DebugDraw(spriteBatch);
                }
            }

            Vector2 pos = new Vector2(0.0f, -level.Size.Y);

            if (cam.WorldView.Y >= -pos.Y - 1024)
            {
                pos.X = cam.WorldView.X - 1024;
                int width = (int)(Math.Ceiling(cam.WorldView.Width / 1024 + 4.0f) * 1024);

                GUI.DrawRectangle(spriteBatch, new Rectangle(
                                      (int)(MathUtils.Round(pos.X, 1024)),
                                      -cam.WorldView.Y,
                                      width,
                                      (int)(cam.WorldView.Y + pos.Y) - 30),
                                  Color.Black, true);

                spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
                                 new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)pos.Y - 1000, width, 1024),
                                 new Rectangle(0, 0, width, -1024),
                                 level.BackgroundTextureColor, 0.0f,
                                 Vector2.Zero,
                                 SpriteEffects.None, 0.0f);
            }

            if (cam.WorldView.Y - cam.WorldView.Height < level.SeaFloorTopPos + 1024)
            {
                pos = new Vector2(cam.WorldView.X - 1024, -level.BottomPos);

                int width = (int)(Math.Ceiling(cam.WorldView.Width / 1024 + 4.0f) * 1024);

                GUI.DrawRectangle(spriteBatch, new Rectangle(
                                      (int)(MathUtils.Round(pos.X, 1024)),
                                      (int)-(level.BottomPos - 30),
                                      width,
                                      (int)(level.BottomPos - (cam.WorldView.Y - cam.WorldView.Height))),
                                  Color.Black, true);

                spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
                                 new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)-level.BottomPos, width, 1024),
                                 new Rectangle(0, 0, width, -1024),
                                 level.BackgroundTextureColor, 0.0f,
                                 Vector2.Zero,
                                 SpriteEffects.FlipVertically, 0.0f);
            }
        }
Example #10
0
        void UpdateClimbing()
        {
            if (character.SelectedConstruction == null || character.SelectedConstruction.GetComponent <Ladder>() == null)
            {
                Anim = Animation.None;
                return;
            }

            onGround        = false;
            IgnorePlatforms = true;

            Vector2 tempTargetMovement = TargetMovement;

            tempTargetMovement.Y = Math.Min(tempTargetMovement.Y, 1.0f);

            movement = MathUtils.SmoothStep(movement, tempTargetMovement, 0.3f);

            Limb leftFoot  = GetLimb(LimbType.LeftFoot);
            Limb rightFoot = GetLimb(LimbType.RightFoot);
            Limb head      = GetLimb(LimbType.Head);
            Limb torso     = GetLimb(LimbType.Torso);

            Limb waist = GetLimb(LimbType.Waist);

            Limb leftHand  = GetLimb(LimbType.LeftHand);
            Limb rightHand = GetLimb(LimbType.RightHand);

            Vector2 ladderSimPos = ConvertUnits.ToSimUnits(
                character.SelectedConstruction.Rect.X + character.SelectedConstruction.Rect.Width / 2.0f,
                character.SelectedConstruction.Rect.Y);

            float stepHeight = ConvertUnits.ToSimUnits(30.0f);

            if (currentHull == null && character.SelectedConstruction.Submarine != null)
            {
                ladderSimPos += character.SelectedConstruction.Submarine.SimPosition;
            }
            else if (currentHull.Submarine != null && currentHull.Submarine != character.SelectedConstruction.Submarine)
            {
                ladderSimPos += character.SelectedConstruction.Submarine.SimPosition - currentHull.Submarine.SimPosition;
            }

            MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.9f - colliderHeightFromFloor), 10.5f);
            MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.7f - colliderHeightFromFloor), 10.5f);
            MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, Collider.SimPosition.Y + 0.6f - colliderHeightFromFloor), 10.5f);

            Collider.MoveToPos(new Vector2(ladderSimPos.X - 0.2f * Dir, Collider.SimPosition.Y), 10.5f);

            bool slide = targetMovement.Y < -1.1f;

            Vector2 handPos = new Vector2(
                ladderSimPos.X,
                Collider.SimPosition.Y + 0.8f + movement.Y * 0.1f - ladderSimPos.Y);

            handPos.Y = Math.Min(-0.2f, handPos.Y) - colliderHeightFromFloor;

            MoveLimb(leftHand,
                     new Vector2(handPos.X,
                                 (slide ? handPos.Y : MathUtils.Round(handPos.Y - stepHeight, stepHeight * 2.0f) + stepHeight) + ladderSimPos.Y),
                     5.2f);

            MoveLimb(rightHand,
                     new Vector2(handPos.X,
                                 (slide ? handPos.Y : MathUtils.Round(handPos.Y, stepHeight * 2.0f)) + ladderSimPos.Y),
                     5.2f);

            leftHand.body.ApplyTorque(Dir * 2.0f);
            rightHand.body.ApplyTorque(Dir * 2.0f);

            Vector2 footPos = new Vector2(
                handPos.X - Dir * 0.05f,
                Collider.SimPosition.Y + 0.9f - colliderHeightFromFloor - stepHeight * 2.7f - ladderSimPos.Y - 0.7f);

            //if (movement.Y < 0) footPos.Y += 0.05f;

            MoveLimb(leftFoot,
                     new Vector2(footPos.X,
                                 (slide ? footPos.Y : MathUtils.Round(footPos.Y + stepHeight, stepHeight * 2.0f) - stepHeight) + ladderSimPos.Y),
                     15.5f, true);

            MoveLimb(rightFoot,
                     new Vector2(footPos.X,
                                 (slide ? footPos.Y : MathUtils.Round(footPos.Y, stepHeight * 2.0f)) + ladderSimPos.Y),
                     15.5f, true);

            //apply torque to the legs to make the knees bend
            Limb leftLeg  = GetLimb(LimbType.LeftLeg);
            Limb rightLeg = GetLimb(LimbType.RightLeg);

            leftLeg.body.ApplyTorque(Dir * -8.0f);
            rightLeg.body.ApplyTorque(Dir * -8.0f);

            float movementFactor = (handPos.Y / stepHeight) * (float)Math.PI;

            movementFactor = 0.8f + (float)Math.Abs(Math.Sin(movementFactor));

            Vector2 subSpeed = currentHull != null || character.SelectedConstruction.Submarine == null
                ? Vector2.Zero : character.SelectedConstruction.Submarine.Velocity;

            Vector2 climbForce = new Vector2(0.0f, movement.Y + 0.3f) * movementFactor;

            //if (climbForce.Y > 0.5f) climbForce.Y = Math.Max(climbForce.Y, 1.3f);

            //apply forces to the collider to move the Character up/down
            Collider.ApplyForce((climbForce * 20.0f + subSpeed * 50.0f) * Collider.Mass);
            head.body.SmoothRotate(0.0f);

            if (!character.SelectedConstruction.Prefab.Triggers.Any())
            {
                character.SelectedConstruction = null;
                return;
            }

            Rectangle trigger = character.SelectedConstruction.Prefab.Triggers.FirstOrDefault();

            trigger = character.SelectedConstruction.TransformTrigger(trigger);

            bool notClimbing = false;

            if (character.IsRemotePlayer && GameMain.Server == null)
            {
                notClimbing = character.IsKeyDown(InputType.Left) || character.IsKeyDown(InputType.Right);
            }
            else
            {
                notClimbing = Math.Abs(targetMovement.X) > 0.05f ||
                              (TargetMovement.Y < 0.0f && ConvertUnits.ToSimUnits(trigger.Height) + handPos.Y < HeadPosition) ||
                              (TargetMovement.Y > 0.0f && handPos.Y > 0.1f);
            }

            if (notClimbing)
            {
                Anim = Animation.None;
                character.SelectedConstruction = null;
                IgnorePlatforms = false;
            }
        }