protected override bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor)
        {
            base._confirmPickup(ourObject, theirObject, actor);

            if(actor is PlayerActorComponent)
            {
                if(ourObject.TestObjectType(PlatformerData.SpawnedObjectType))
                {
                    CheckpointSystemSpawnedObjectComponent spawnedComp = ourObject.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>();

                    if(spawnedComp != null)
                        spawnedComp.Recover = false;
                }

                // Play sound effect here!
                SoundManager.Instance.PlaySound("sounds", "checkpoint");
                CheckpointManager.Instance.CheckpointReached();

                // set the new respawn position of the actor
                if (SceneObject != null)
                    actor.RespawnPosition = SceneObject.Position;
                else
                    actor.RespawnPosition = actor.Actor.Position;

                //GUICanvas.Instance.SetContentControl(new Checkpoint_GUI(SceneObject.Position + new Vector2(0, -5)));
                effect.Spawn(SceneObject.Position);

                // true = yes, i was picked up. delete me!
                return true;
            }

            // false = no, this guy didn't pick me up.
            return false;
        }
        /// <summary>
        /// Decides whether or not the Actor should be allowed to pick this collectible up. Override this
        /// in derived classes. Default always returns true.
        /// </summary>
        /// <param name="ourObject">The scene object this CollectibleComponent is on.</param>
        /// <param name="theirObject">The scene object the ActorComponent is on.</param>
        /// <param name="actor">The ActorComponent that's trying to pick up this collectible.</param>
        /// <returns>True if the Actor should be allowed to pick up the collectible.</returns>
        protected virtual bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor)
        {
            if(theirObject.TestObjectType(PlatformerData.PlayerObjectType))
                if(effect != null)
                    effect.Spawn(SceneObject.Position);

            // this should be overridden by derived classes
            // a return value of false will result in the collectible remaining in the scene
            // a return value of true will result in the collectible being removed from the scene
            return true;
        }
        public void OnStayLadder(T2DSceneObject ourObject, T2DSceneObject theirObject)
        {
            // make sure the object is an actor type
            if (!theirObject.TestObjectType(PlatformerData.ActorObjectType))
                return;

            // grab the actor component
            ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>();

            // notify the actor that they are in a ladder and give them a reference
            if (actor != null && !actor.InLadder)
                actor.LadderObject = _ladder;
        }
        /// <summary>
        /// T2DOnCollision delegate to handle damage between the kushling and the player
        /// </summary>
        /// <param name="myObject">The kushling</param>
        /// <param name="theirObject">The collided object.</param>
        /// <param name="info">Collision information</param>
        /// <param name="resolve">How the collision will be resolved</param>
        /// <param name="physicsMaterial">The type of material that would affect the physics</param>
        public static void KushCollision(T2DSceneObject myObject, T2DSceneObject theirObject,
            T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            int damage = myObject.Components.FindComponent<KushlingActorComponent>().Damage;

            if (theirObject.TestObjectType(PlatformerData.ActorObjectType))
            {
                PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>();

                // Deal damage to the enemy
                if (actor != null && !actor.IsInvincible)
                    actor.TakeDamage(damage, myObject, true, true);
            }

            else if (theirObject.TestObjectType(PlatformerData.EnemyObjectType))
            {
                resolve = T2DPhysicsComponent.ClampCollision;
            }

            else
                resolve = null;
        }
        ///<summary>
        ///Callback for when the microbe collides with another object.
        ///</summary>
        ///<param name="ourObject">The microbe.</param>
        ///<param name="theirObject">The other object.</param>
        ///<param name="info">Information about the collision point.</param>
        ///<param name="resolve">Not used.</param>
        ///<param name="physicsMaterial">
        ///The physics properties of the objects.
        ///</param>
        public void OnCollision(
           T2DSceneObject ourObject,
           T2DSceneObject theirObject,
           T2DCollisionInfo info,
           ref T2DResolveCollisionDelegate resolve,
           ref T2DCollisionMaterial physicsMaterial)
        {
            if (!ourObject.MarkForDelete &&
               theirObject.TestObjectType(_collidesWith))
            {
                //handle microbe collision with another microbe
                if (theirObject.TestObjectType(
                   TorqueObjectDatabase.Instance.GetObjectType("microbe")))
                {
                    T2DPhysicsComponent.BounceCollision.Invoke(
                       ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.ClampCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.KillCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.RigidCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.StickyCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);
                }
                else if (theirObject.TestObjectType(
                   TorqueObjectDatabase.Instance.GetObjectType("projectile")))
                {
                    //T2DPhysicsComponent.BounceCollision.Invoke(
                    //  ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.ClampCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    T2DPhysicsComponent.KillCollision.Invoke(
                     ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.RigidCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);

                    //T2DPhysicsComponent.StickyCollision.Invoke(
                    //ourObject, theirObject, ref info, physicsMaterial, false);
                }
                //TODO: add handling for other object types
            }
        }
        /// <summary>
        /// T2DOnCollision delegate to handle damage between the melee scene object and enemies
        /// </summary>
        /// <param name="myObject">The melee scene object mounted on the player</param>
        /// <param name="theirObject">The enemy scene object</param>
        /// <param name="info">Collision information</param>
        /// <param name="resolve">How the collision will be resolved</param>
        /// <param name="physicsMaterial">The type of material that would affect the physics</param>
        public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject,
            T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage;

            if (theirObject.TestObjectType(PlatformerData.PlayerObjectType))
            {
                PlayerActorComponent actor = theirObject.Components.FindComponent<PlayerActorComponent>();

                // Deal damage to the enemy
                if (actor != null)
                    actor.TakeDamage(damage, myObject, true, true);
            }

            myObject.MarkForDelete = true;
        }
        public static void ProjCollision(T2DSceneObject projectile, T2DSceneObject targetObject,
            T2DCollisionInfo into, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial material)
        {
            int damage = projectile.Components.FindComponent<ProjectileComponent>().Damage;

            if (targetObject.TestObjectType(PlatformerData.ActorObjectType))
            {
                PlayerActorComponent actor = targetObject.Components.FindComponent<PlayerActorComponent>();

                // Deal damage to the enemy
                if (actor != null)
                    actor.TakeDamage(damage, projectile, true, true);
            }

            projectile.CollisionsEnabled = false;
            projectile.MarkForDelete = true;
        }
        protected override bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor)
        {
            base._confirmPickup(ourObject, theirObject, actor);

            if(actor is PlayerActorComponent)
            {
                if (ourObject.TestObjectType(PlatformerData.SpawnedObjectType))
                {
                    CheckpointSystemSpawnedObjectComponent spawnedObject = ourObject.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>();

                    if (spawnedObject != null)
                        spawnedObject.Recover = false;
                }

                actor.HealDamage(healingValue, ourObject);
                SoundManager.Instance.PlaySound("sounds", "health");
                // true = yes, i was picked up. delete me!
                return true;
            }

            // false = no, this guy didn't pick me up.
            return false;
        }
        protected override bool _confirmPickup(T2DSceneObject ourObject, T2DSceneObject theirObject, ActorComponent actor)
        {
            base._confirmPickup(ourObject, theirObject, actor);

            PlayerActorComponent player = actor as PlayerActorComponent;

            if (player != null)
            {
                if (ourObject.TestObjectType(PlatformerData.SpawnedObjectType))
                {
                    CheckpointSystemSpawnedObjectComponent spawnedObject = ourObject.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>();

                    if (spawnedObject != null)
                        spawnedObject.Recover = false;
                }

                player.AddGoldCrystal();
                SoundManager.Instance.PlaySound("sounds", "gold_crystal");

                return true;
            }

            return false;
        }
        /// <summary>
        /// T2DOnCollision delegate to handle damage between the melee scene object and enemies
        /// </summary>
        /// <param name="myObject">The melee scene object mounted on the player</param>
        /// <param name="theirObject">The enemy scene object</param>
        /// <param name="info">Collision information</param>
        /// <param name="resolve">How the collision will be resolved</param>
        /// <param name="physicsMaterial">The type of material that would affect the physics</param>
        public static void MeleeCollision(T2DSceneObject myObject, T2DSceneObject theirObject,
            T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            //theirObject.Collision.Images[0].
            int damage = myObject.Components.FindComponent<AttackCollisionComponent>().Damage;

            if(theirObject.TestObjectType(PlatformerData.ActorObjectType))
            {
                EnemyActorComponent actor = theirObject.Components.FindComponent<EnemyActorComponent>();

                // Deal damage to the enemy
                if (actor != null)
                    actor.TakeDamage(damage, theirObject);
            }

            else
            {
                WeakSpotComponent weakSpot = theirObject.Components.FindComponent<WeakSpotComponent>();

                if(weakSpot != null)
                    weakSpot.TakeDamage(damage, true);
            }

            myObject.MarkForDelete = true;
        }
        /// <summary>
        /// Callback for when the projectile collides with another object.
        /// </summary>
        /// <param name="ourObject">The projectile.</param>
        /// <param name="theirObject">The other object.</param>
        /// <param name="info">Information about the collision point.</param>
        /// <param name="resolve">Not used.</param>
        /// <param name="physicsMaterial">The physics properties of the objects.</param>
        public void OnCollision(
            T2DSceneObject ourObject,
            T2DSceneObject theirObject,
            T2DCollisionInfo info,
            ref T2DResolveCollisionDelegate resolve,
            ref T2DCollisionMaterial physicsMaterial)
        {
            if (!ourObject.MarkForDelete &&
                theirObject.TestObjectType(_collidesWith))
            {
                // If we hit a player object then activate its game pad vibration
                T2DStaticSprite psprite = theirObject as T2DStaticSprite;
                if (psprite != null)
                {
                    GamepadVibrationComponent vib =
                        psprite.Components.FindComponent<GamepadVibrationComponent>();
                    if (vib != null)
                    {
                        vib.SetLowSpeedVibration(0.1f, 0.8f);
                    }
                }

                if (theirObject.TestObjectType(TorqueObjectDatabase.Instance.GetObjectType("tank")))
                {
                    Explode(info, true);
                }
                else
                {
                    Explode(info, false);
                }
            }
        }
        protected override void _onEnter(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
        {
            if (!_enabled || !theirObject.TestObjectType(PlatformerData.ActorObjectType))
                return;

            ActorComponent actor = theirObject.Components.FindComponent<ActorComponent>();

            if (actor == null || !_confirmCheckpoint(actor))
                return;

            float currTime = TorqueEngineComponent.Instance.TorqueTime;

            if (_allowRecheck && currTime - _lastCheckTime < _recheckTimeout)
                return;

            actor.RespawnPosition = RespawnPositionObject.Position + RespawnOffset;

            CheckpointManager.Instance.CheckpointReached();

            if (_allowRecheck)
                _lastCheckTime = currTime;
            else
                _enabled = false;
        }
        /// <summary>
        /// Collision system calls this to optionally early-out of collisions with an object based on the EarlyOutObjectType on the 
        /// T2DCollisionComponent, which we set to ActorObjectType in _OnRegister. By default, platforms do not collide with anything
        /// actively, they are only collided against, so unless that is changed this code will only be called on if CollidesWith is 
        /// modified externally after this component is initialized.
        /// </summary>
        /// <param name="ourObject">The scene object that owns this component.</param>
        /// <param name="theirObject">The scene object that owns the ActorComponent.</param>
        /// <returns>True if a collision should occur. False otherwise.</returns>
        public bool TestEarlyOut(T2DSceneObject ourObject, T2DSceneObject theirObject)
        {
            // check if the object is an Actor
            if (theirObject.TestObjectType(PlatformerData.ActorObjectType))
            {
                // if this platform is in use, don't collide
                if (_active)
                    return false;
                else
                    return true;
            }

            // default to no collision
            return false;
        }
        public virtual bool TestEarlyOut(T2DSceneObject ourObject, T2DSceneObject theirObject)
        {
            // make sure it's a one-way platform that we're dealing with
            if (theirObject.TestObjectType(PlatformerData.PlatformObjectType))
            {
                // check if the platform is in our active platforms list
                if (_activePlatforms.Contains(theirObject))
                    // collide
                    return false;
                else
                    // don't collide
                    return true;
            }

            // default: collide
            return false;
        }
        public virtual void ResolveActorCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info, T2DCollisionMaterial physicsMaterial, bool handleBoth)
        {
            // this is a custom collision response mode for actors
            // make sure this method is being used on an Actor
            if (!ourObject.TestObjectType(PlatformerData.ActorObjectType))
                return;

            // make sure it's the right actor
            ActorComponent actor = ourObject.Components.FindComponent<ActorComponent>();
            if (actor == null)
                return;

            // check for a physics component
            if (_actor.Physics == null)
                return;

            // get their object's velocity
            Vector2 theirVel = Vector2.Zero;

            if (theirObject.Physics != null)
                theirVel = theirObject.Physics.Velocity;

            // check if it's a ground surface
            bool groundSurface = info.Normal.Y <= _maxGroundNormalY;

            // get the actor's velocity modified velocity by the destination object's velocity
            Vector2 vel = _actor.Physics.Velocity - theirVel;

            //get the dot product
            float dot = Vector2.Dot(vel, info.Normal);

            // if we're currently on the ground, do magical stuff
            if (_onGround && !groundSurface)
            {
                // don't let the clamp push us off the ground or into the ground!
                // accomplish this by clamping the collision normal against the ground normal
                float groundDot = Vector2.Dot(info.Normal, _groundSurfaceNormal);

                // remove any portion of the ground surface normal from the collision normal
                info.Normal -= groundDot * _groundSurfaceNormal;

                // cancel move speed (this isn't a ground surface that we hit)
                _moveSpeed.X = 0;
            }

            // return if we're moving away from the surface
            if (dot >= 0.0f)
                return;

            // if object was not a ground surface...
            if (!groundSurface)
            {
                // notify the controller that we hit a wall
                if (Controller as ActorController != null)
                    (Controller as ActorController).ActorHitWall(this, info, dot);

                // forfeit all inherited velocity
                // (we ran into something, just get rid of it!)
                _inheritedVelocity = Vector2.Zero;
            }
            else
            {
                // if we actually overlapped with a platform, correct by a small amount (1/10 of a unit)
                // (the purpose of _groundYBuffer is to avoid constant collisions from scraping across the ground.
                // if we are colliding with the ground regularly, _groundYBuffer is too low. this error correction
                // is intended to solve potential problems when prolonged penetration occurs.)
                _platformError += info.Normal * 0.1f;
            }

            // clamp our actial velocity anyway
            _actor.Physics.Velocity -= dot * info.Normal;

            // if we're not on the ground, just dump our velocity into our move speed
            // and let the actor's physics clamp it
            if (!_onGround)
                _moveSpeed.X = _actor.Physics.Velocity.X;
        }
        public virtual void OnCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
        {
            // call our custom collision resolve
            // (this is almost exactly the same as clamp, but takes *both* objects' velocity into account)
            if (theirObject.TestObjectType(PlatformerData.PlatformObjectType))
                resolve = ResolveActorCollision;
            else
                resolve = null;

            // if we hit a ladder, enable it
            if (theirObject.TestObjectType(PlatformerData.LadderObjectType))
            {
                // find the ladder component
                LadderComponent ladder = theirObject.Components.FindComponent<LadderComponent>();

                // enable it
                if (ladder != null)
                    ladder.Enabled = true;
            }
        }
        public override void Despawn(T2DSceneObject obj)
        {
            // make sure the object has the spawned object type
            if (obj.TestObjectType(PlatformerData.SpawnedObjectType))
            {
                // check for checkpoint system spawned object component
                CheckpointSystemSpawnedObjectComponent spawned = obj.Components.FindComponent<CheckpointSystemSpawnedObjectComponent>();

                // if the spawned object is marked to not recover, modify the spawn count
                if (spawned != null && !spawned.Recover)
                    _spawnCount++;
            }

            // call base despawn
            base.Despawn(obj);
        }
        public virtual bool TestEarlyOut(T2DSceneObject ourObject, T2DSceneObject theirObject)
        {
            // enable trigger when Actor's found
            if (theirObject.TestObjectType(PlatformerData.ActorObjectType))
                Enabled = true;

            // collide normally
            return false;
        }
        ///<summary>
        ///Callback for when the tank collides with another object.
        ///</summary>
        ///<param name="ourObject">The tank.</param>
        ///<param name="theirObject">The other object.</param>
        ///<param name="info">Information about the collision point.</param>
        ///<param name="resolve">Not used.</param>
        ///<param name="physicsMaterial">
        ///The physics properties of the objects.
        ///</param>
        public void OnCollision(
            T2DSceneObject ourObject,
            T2DSceneObject theirObject,
            T2DCollisionInfo info,
            ref T2DResolveCollisionDelegate resolve,
            ref T2DCollisionMaterial physicsMaterial)
        {
            if (ourObject.MarkForDelete ||
                !theirObject.TestObjectType(_collidesWith))
                return;

            //Set up gamepad vibration if this is a player object
            //also set up maxVelocity
            GamepadVibrationComponent vib =
                ourObject.Components.FindComponent<GamepadVibrationComponent>();
            TankMovementComponent mac =
                ourObject.Components.FindComponent<TankMovementComponent>();

            float maxSpeed = 0.1f; //avoid possible divide by zero below
            if (null != mac)
            {
                maxSpeed = mac.MaxForwardSpeed;
            }

            //Calculate Impact Velocity.
            Vector2 deltaImpactVelocity =
                _CalculateImpactVelocity(ourObject, theirObject, info);
            float impact = deltaImpactVelocity.Length();
            float vibration =
                MathHelper.Clamp((impact / (maxSpeed * 2.0f)), 0.0f, 1.0f);

            //Perform sound (on all objects) and vibration (players only)
            if (vibration < 0.3)
            {
                //High speed vibration for the small collisions
                if (vib != null)
                {
                    vib.SetHighSpeedVibration(0.2f, (vibration / 0.3f) * 0.8f);
                }

                if (vibration >= 0.1 &&
                    TorqueEngineComponent.Instance.TorqueTime >=
                    _nextSoftSoundPlayTime)
                {
                    Program.SoundBank.PlayCue("softCollision");
                    _nextSoftSoundPlayTime =
                        TorqueEngineComponent.Instance.TorqueTime +
                        SOUND_TIME_STEP +
                        TorqueUtil.GetFastRandomFloat(SOUND_TIME_STEP_VARIANCE);
                }
            }
            else
            {
                //Low speed vibration for the big collisions
                if (vib != null)
                {
                    vib.SetLowSpeedVibration(
                        0.2f,
                        ((vibration - 0.3f) / 0.7f) * 0.9f + 0.1f);
                }

                if (TorqueEngineComponent.Instance.TorqueTime >=
                    _nextHardSoundPlayTime)
                {
                    Program.SoundBank.PlayCue("hardCollision");
                    _nextHardSoundPlayTime =
                        TorqueEngineComponent.Instance.TorqueTime +
                        SOUND_TIME_STEP +
                        TorqueUtil.GetFastRandomFloat(SOUND_TIME_STEP_VARIANCE);
                }
            }
        }