Ejemplo n.º 1
0
        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()