public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { if (_timer == null) { InitTimer(state); } // Check if the Game has closed, but only if it was running before. // this check should save the overhead of a syscall when not transitioning if (_pauseOnExit && IsTransitioning() && GetGw2Process() == null) { if (state.CurrentPhase == TimerPhase.Running) { _timer.Pause(); _wasAutoPaused = true; } return; } // need to remember transition state before update, since position will not be updated if (state.CurrentPhase == TimerPhase.NotRunning) { _wasPlayingTransition = IsTransitioning(); } // accumulate ticks var lastTick = _client.Mumble.Tick; var lastPosition = AvatarPosition; _client.Mumble.Update(); var mapId = _client.Mumble.MapId; var mapCheckpoints = _checkpoints.GetValueOrDefault(mapId, null); if (lastTick == _client.Mumble.Tick) { _noTickUpdateCount++; } else { _noTickUpdateCount = 0; } if (state.CurrentPhase == TimerPhase.NotRunning) // From here the timer has to be started { StartTimerIfNeeded(lastPosition, _wasPlayingTransition); return; } var playingTransition = IsTransitioning(); var avatarPosition = AvatarPosition; Log.Info($"\n[{avatarPosition.X}, {avatarPosition.Z}],"); if (_loadingScreen != LoadingScreen.Include) { // Loading-Screen Start if (IsLoading()) { switch (state.CurrentPhase) { case TimerPhase.Running when _loadingScreen == LoadingScreen.Exclude: _timer.Pause(); _wasAutoPaused = true; Log.Info("Pausing during a loading screen"); break; case TimerPhase.Paused when _loadingScreen == LoadingScreen.Only && _wasAutoPaused: _timer.Pause(); _wasAutoPaused = false; Log.Info("Starting to time loading screen"); break; } } // Not Loading-Screen else { switch (state.CurrentPhase) { case TimerPhase.Running when _loadingScreen == LoadingScreen.Only: _timer.Pause(); _wasAutoPaused = true; Log.Info("Pausing after a loading screen"); break; // if paused in transition, which is not a loading screen, do not unpause, probably character select after restart case TimerPhase.Paused when _loadingScreen == LoadingScreen.Exclude && _wasAutoPaused && !IsTransitioning(): _timer.Pause(); _wasAutoPaused = false; Log.Info("Starting after a loading screen"); break; } } } // Redo Check to skip empty maps if (mapCheckpoints == null) { return; } for (var i = _lastCheckpoint.GetValueOrDefault(mapId, -1) + 1; i < mapCheckpoints.Count; i++) { var checkpoint = mapCheckpoints[i]; var isOnArea = checkpoint.IsPointInArea(avatarPosition, _client.Mumble.IsInCombat); if (!isOnArea) { continue; } handleStandingOnArea(checkpoint, i, state, playingTransition, mapId); break; } _wasPlayingTransition = playingTransition; }