public void ApplyGravity() { if (Topography.IsNotInsideMapYBoundaries(Mobile.Position - new Vector2(0, Mobile.MobileFlipbook.SpriteHeight))) { if (Mobile.IsAlive) { Mobile.RequestDeath(CausaMortis.Bungee); } return; } int[] relPos = Topography.GetRelativePosition(Mobile.Position); //Compute the where is the next collidable block bellow the pawn int yPosition = 0; for (; yPosition < Math.Max(Parameter.TankMovementMinYStepping, GravitySpeed); yPosition++) { if (relPos[1] + yPosition >= Topography.CollidableForegroundMatrix.Length) { continue; } if (relPos[0] > 0 && relPos[0] < Topography.MapHeight && Topography.CollidableForegroundMatrix[relPos[1] + yPosition][relPos[0]]) { break; } } //If the unit isn't on the ground if (yPosition > 0) { //Update gravity values on the pawn if (IsFalling) { gravityDelayTimer += Parameter.ProjectileMovementFixedElapedTime; if (gravityDelayTimer > Parameter.TankMovementGravityDelay) { //Wind-changing accumulated offset Vector2 wForce = (LevelScene.MatchMetadata != null) ? LevelScene.MatchMetadata.WindForceComponents().ToVector2() : Vector2.Zero; windForceAccumulator = MathHelper.Clamp(windForceAccumulator + wForce.X / 45, -1, 1); //Add interpolated movement Vector2 newPosition = Mobile.Position + new Vector2((int)windForceAccumulator, Math.Min((int)GravitySpeed, yPosition)); //In case the mobile collides in walls the X axis stop updating in order to prevent wall clipping if (Topography.IsInsideMapBoundaries(newPosition) && !Topography.CheckCollision(newPosition)) { windForceAccumulator = 0; } Mobile.Position += new Vector2((int)windForceAccumulator, Math.Min((int)GravitySpeed, yPosition)); GravitySpeed += Parameter.TankMovementGravityFactor; //Reseting the accumulator if (Math.Abs(windForceAccumulator) >= 1) { windForceAccumulator = 0; } } } else { gravityDelayTimer = 0; GravitySpeed = Parameter.TankMovementInitialGravity; } //Reset the rotation BufferRotationInDegrees = 0; //Set the state to falling if (!IsFalling) { Mobile.ForceSynchronize = true; IsFalling = true; } IsMoving = false; //desiredPosition.Y = Mobile.Position.Y; Mobile.ChangeFlipbookState(ActorFlipbookState.Falling, true); } else { //Set the the falling state to false if (IsFalling == true) { IsFalling = false; windForceAccumulator = 0; Mobile.ChangeFlipbookState(ActorFlipbookState.Stand, true); } } }