public AiPlayer(T2DAnimatedSprite player, T2DAnimatedSprite actualPlayer)
        {
            _player = player;
            _actualPlayer = actualPlayer;

            _count = 0;
            _random = new Random(0);
        }
        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner))
                return false;

            // record our scene object
            _sceneObject = owner as T2DAnimatedSprite;

            // make sure this component is being used properly
            // (this might be too strict, but better safe than sorry)
            if (_sceneObject == null || _sceneObject.MountedTo == null)
            {
                Assert.Fatal(false, "ActorPuppetComponent must be used on a T2DAnimatedSprite that's mounted to a T2DSceneObject that has an ActorComponent. \n\nThe owner of the ActorPuppetComponent will be deleted if this message is ignored.");
                owner.MarkForDelete = true;
                return false;
            }

            // find the actor component of the object we're mounted to
            if (_sceneObject.MountedTo.TestObjectType(PlatformerData.ActorObjectType))
                _master = _sceneObject.MountedTo.Components.FindComponent<ActorComponent>();

            // make sure there is a valid actor
            if (_master == null)
            {
                Assert.Fatal(false, "ActorPuppetComponent must be used on a T2DAnimatedSprite that's mounted to a T2DSceneObject that has an ActorComponent. \n\nThe owner of the ActorPuppetComponent will be deleted if this message is ignored.");
                owner.MarkForDelete = true;
                return false;
            }

            // create the dummy pivot object
            _pivotObject = new T2DSceneObject();
            _pivotObject.Size = _master.Actor.Size;
            _pivotObject.Position = _master.Actor.Position;
            _pivotObject.CreateWithLinkPoints = true;
            TorqueObjectDatabase.Instance.Register(_pivotObject);

            // get the current offset of the mounted puppet sprite
            _sceneObject.SnapToMount();
            Vector2 offset = (_sceneObject.Position - _master.Actor.Position) / (_master.Actor.Size / 2);

            // account for flipped objects
            // (when the mount position is updated it will reverse this if it was supposed to be flipped)
            if (_master.Actor.FlipX)
                offset.X = -offset.X;

            if (_master.Actor.FlipY)
                offset.Y = -offset.Y;

            // do the big switcheroo
            // (mount pivot object offset by actorPivotOffset to the center of the master actor
            // scene object and offset by actorPivotOffset)
            _pivotObject.LinkPoints.AddLinkPoint("SpriteOffset", offset, 0);
            _master.Actor.LinkPoints.AddLinkPoint("Center", Vector2.Zero, 0);

            _pivotObject.Mount(_master.Actor, "Center", _actorPivotOffset, 0, true);
            _pivotObject.SnapToMount();

            _sceneObject.Dismount();
            _sceneObject.Mount(_pivotObject, "SpriteOffset", -_actorPivotOffset, 0, true);
            _sceneObject.SnapToMount();

            // make sure we have the correct mounting settings
            // (it's only actually neccesary that TrackMountRotation be false if the
            // RotateToGroundSurface is enabled.
            // the other field values just make good sense)
            _sceneObject.TrackMountRotation = true;
            _sceneObject.IsOwnedByMount = true;
            _sceneObject.InheritMountFlip = true;
            _sceneObject.InheritMountVisibility = true;
            _sceneObject.UseMountForce = false;

            _pivotObject.TrackMountRotation = false;
            _pivotObject.IsOwnedByMount = true;
            _pivotObject.InheritMountFlip = true;
            _pivotObject.InheritMountVisibility = true;
            _pivotObject.UseMountForce = false;

            // set the master's AnimatedSprite property to this object
            // (note: it's possible that this overwrites another ActorPuppet on the master
            // object. as to why you would ever need two animated sprite puppets on the
            // same actor, i have no clue)
            _master.AnimatedSprite = _sceneObject;
            _master.ActorPuppet = this;

            // set the proper object type of this component's owner
            _sceneObject.SetObjectType(PlatformerData.ActorObjectType, true);

            return true;
        }
        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner))
                return false;

            // store the owner as a static sprite
            _actor = owner as T2DSceneObject;

            // if there is no animated sprite specified use the owner
            if (_animatedSprite == null)
                _animatedSprite = _actor as T2DAnimatedSprite;

            // set the object type of the scene object
            _actor.SetObjectType(PlatformerData.ActorObjectType, true);

            // make sure we have both a collision and physics component..
            Assert.Fatal(_actor.Collision != null && _actor.Physics != null, "Actor must have a collision component and a physics component.");

            // make sure we have collision enabled
            _actor.CollisionsEnabled = true;
            _actor.Collision.SolveOverlap = true;

            // preserve existing collision types, if any
            if (_actor.Collision.CollidesWith.Equals(TorqueObjectType.AllObjects))
            {
                _actor.Collision.CollidesWith = PlatformerData.PlatformObjectType
                                                + PlatformerData.ActorTriggerObjectType
                                                + PlatformerData.CollectibleObjectType
                                                + PlatformerData.DamageTriggerObjecType;
            }
            else
            {
                _actor.Collision.CollidesWith += PlatformerData.PlatformObjectType
                                                + PlatformerData.ActorTriggerObjectType
                                                + PlatformerData.CollectibleObjectType
                                                + PlatformerData.DamageTriggerObjecType;
            }

            // preserve existing early-out object types
            _actor.Collision.EarlyOutObjectType += PlatformerData.OneWayPlatformObjectType;

            // set the collision delegates
            _actor.Collision.OnCollision = OnCollision;
            _actor.Collision.TestEarlyOut = TestEarlyOut;

            // make sure ProcessCollisionsAtRest is enabled
            // (this ensures that our passive DirectionalTriggerComponents work)
            _actor.Physics.ProcessCollisionsAtRest = true;

            // set default respawn position to the current position
            _respawnPosition = _actor.Position;

            // if PoolWithComponents is true on the scene object, reset the Actor
            if (_actor.PoolWithComponents)
                _resetActor();

            // notify the controller that this actor spawned
            if (Controller != null)
                (Controller as ActorController).ActorSpawned(this);

            // process any extra data we might have collected from XML
            _processXMLDataLists();

            // initialize animation manager
            // (this will handle all our animations and transitions)
            _initAnimationManager();

            _health = _maxHealth;

            // return true
            return true;
        }