public override void PreCollisionTestUpdate(GameThing thing) { Movement movement = thing.Movement; DesiredMovement desiredMovement = thing.DesiredMovement; GameActor.State state = thing.CurrentState; float secs = Time.GameTimeFrameSeconds; if (state != GameActor.State.Dead || state != GameThing.State.Squashed) { if (state == GameActor.State.Active) { // Only do movement if we are not being held. if (thing.ActorHoldingThis == null) { // Check if we're up in the air. If so, then we don't kick up // any dust. We can still turn while in the air but it doesn't // affect the direction we're moving until we hit the ground. float terrainHeight = Terrain.GetTerrainAndPathHeight(Top(movement.Position)); bool falling = terrainHeight == 0.0f; float heightAboveGround = movement.Altitude - terrainHeight - MinHeight; if (landing) { // This version doesn't clamp movement to only work forward and backward. ApplyDesiredMovementWhenFalling(movement, desiredMovement); } else { ApplyDesiredMovement(movement, desiredMovement); } // Are we waiting to land? if (landing && movement.Velocity.Z < 0.0f) { // Are we close enough? float predictedHeight = heightAboveGround + movement.Velocity.Z * preLandDelay; if (predictedHeight < CloseToGround) { startLandAnimation = true; landing = false; if (TerrainDataValid && Feelers != null) { Foley.PlayCollision(thing, Feelers[0].TerrainMaterialInfo.TerrainType); } else { Foley.PlayCollision(thing, 0); } } } onGround = heightAboveGround < CloseToGround; onGround = onGround && !falling; if (onGround) { // The bot is on the ground. // Only jump if on the ground and not already jumping. if (Jump && !jumping && !landing) { startJumpAnimation = true; // Tell animation to start. jumping = true; jumpStartTime = Time.GameTimeTotalSeconds; jumpVelocity = new Vector2(movement.Velocity.X, movement.Velocity.Y); float len = jumpVelocity.Length(); if (len > 0.1f) { jumpVelocity /= len; } else { jumpVelocity = new Vector2(movement.Facing.X, movement.Facing.Y); jumpVelocity.Normalize(); } } } // Always clear jump flag. Jump = false; if (jumping && !landing) { // If the pre delay time has passed, do the jump. if (Time.GameTimeTotalSeconds > jumpStartTime + preJumpDelay) { movement.Velocity += new Vector3(0, 0, effectiveJumpStrength); jumping = false; landing = true; } } HandleMovement(movement); // Apply drag to velocity. ApplyFriction(movement, desiredMovement, applyVertical: false); // Apply external force. movement.Velocity += desiredMovement.ExternalForce.GetValueOrDefault() / thing.Mass * secs; // Move due to velocity. movement.Position += movement.Velocity * secs; } // end of if not held. } // end of if active. } // end of if not dead } // end of PreCollisionTestUpdate()