private static void Follow() { if (!_currentlyFollowing || _followedThing == null) { return; } Vector3 newCameraPosition; if (!_followedThing.Spawned && _followedThing.holder != null) { // thing is in some sort of container IThingContainerOwner holder = _followedThing.holder.owner; // if holder is a pawn's carrytracker we can use the smoother positions of the pawns's drawposition Pawn_CarryTracker tracker = holder as Pawn_CarryTracker; if (tracker != null) { newCameraPosition = tracker.pawn.DrawPos; } // otherwise the holder int location will have to do else { newCameraPosition = holder.GetPosition().ToVector3Shifted(); } } // thing is spawned in world, just use the things drawPos else if (_followedThing.Spawned) { newCameraPosition = _followedThing.DrawPos; } // we've lost track of whatever it was we were following else { StopFollow(); return; } // to avoid cancelling the following immediately after it starts, allow the camera to move to the followed thing once // before starting to compare positions if (_cameraHasJumpedAtLeastOnce) { // the actual location of the camera right now var currentCameraPosition = Find.CameraDriver.MapPosition; // the location the camera has been requested to be at var requestedCameraPosition = GetRequestedCameraPosition().ToIntVec3(); // these normally stay in sync while following is active, since we were the last to request where the camera should go. // If they get out of sync, it's because the camera has been asked to jump to somewhere else, and we should stop // following our thing. if (Math.Abs(currentCameraPosition.x - requestedCameraPosition.x) > 1 || Math.Abs(currentCameraPosition.z - requestedCameraPosition.z) > 1) { StopFollow(); return; } } Find.CameraDriver.JumpTo(newCameraPosition); _cameraHasJumpedAtLeastOnce = true; }
// Called every frame when the mod is enabled. public virtual void Update() { if (Enabled) { try { // shut it off if we're manually scrolling (keys) if (CurrentlyFollowing) { if (followBreakingKeyBindingDefs.Any(key => key.IsDown)) { Messages.Message("FollowMe.Cancel".Translate(followedLabel), MessageSound.Negative); followedThing = null; CurrentlyFollowing = false; } } // TODO: figure out how to shut it off when scrolling by mouse? // get selection Thing newFollowedThing = Find.Selector.SingleSelectedObject as Thing; // start/stop following thing on key press if (FollowKey.KeyDownEvent) { Log.Message("FollowMe :: Follow key pressed"); // nothing to cancel or start following if (!CurrentlyFollowing && newFollowedThing == null) { if (Find.Selector.NumSelected > 1) { Messages.Message("FollowMe.RejectMultiple".Translate(), MessageSound.RejectInput); } else if (Find.Selector.NumSelected == 0) { Messages.Message("FollowMe.RejectNoSelection".Translate(), MessageSound.RejectInput); } else { Messages.Message("FollowMe.RejectNotAThing".Translate(), MessageSound.RejectInput); } } // cancel current follow else if (CurrentlyFollowing && newFollowedThing == null || newFollowedThing == followedThing) { Messages.Message("FollowMe.Cancel".Translate(followedLabel), MessageSound.Negative); followedThing = null; CurrentlyFollowing = false; } // follow new thing else if (newFollowedThing != null) { followedThing = newFollowedThing; CurrentlyFollowing = true; Messages.Message("FollowMe.Follow".Translate(followedLabel), MessageSound.Negative); } } // try follow whatever thing is selected if (CurrentlyFollowing && followedThing != null) { if (!followedThing.Spawned && followedThing.holder != null) { // thing is in some sort of container IThingContainerOwner holder = followedThing.holder.owner; // if holder is a pawn's carrytracker we can use the smoother positions of the pawns's drawposition Pawn_CarryTracker tracker = holder as Pawn_CarryTracker; if (tracker != null) { Find.CameraMap.JumpTo(tracker.pawn.DrawPos); } // otherwise the holder int location will have to do else { Find.CameraMap.JumpTo(holder.GetPosition()); } } else if (followedThing.Spawned) { // thing is spawned in world, just use the things drawPos Find.CameraMap.JumpTo(followedThing.DrawPos); } else { // we've lost track of whatever it was we were following Log.Message("FollowMe.Cancel".Translate(followedLabel)); CurrentlyFollowing = false; followedThing = null; } } } // catch exception to avoid error spam catch (Exception e) { Enabled = false; Log.Error(e.ToString()); } } }