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; }