private void handleStandingOnArea(Checkpoint checkpoint, int checkpointIndex, LiveSplitState state, bool playingTransition, int mapId) { switch (checkpoint.CheckpointType) { case CheckpointType.StartingArea: if (_wasPlayingTransition && !playingTransition) { Log.Info( $"Resetting timer because {checkpoint.Name} is a starting area and a transition was playing."); _timer.Reset(); } break; case CheckpointType.Checkpoint: Log.Info($"Splitting because player is on {checkpoint.Name}"); _lastCheckpoint[mapId] = checkpointIndex; _timer.Split(); break; case CheckpointType.Boss: if (playingTransition) { Log.Info($"Splitting because player is on boss {checkpoint.Name} and a transition happened"); var currentSplit = state.CurrentSplit; _timer.Split(); currentSplit.SplitTime = new Time(currentSplit.SplitTime.RealTime?.Subtract( TimeSpan.FromMilliseconds(checkpoint.TimeSubtract))); } break; } }
public void HandleLoadEnd(long timestamp, string zoneName) { if (settings.LoadRemovalEnabled) { loadTimes += timestamp - startTimestamp.GetValueOrDefault(timestamp); state.IsGameTimePaused = false; state.LoadingTimes = TimeSpan.FromMilliseconds(loadTimes); } IZone zone = Zone.Parse(zoneName, encounteredZones); if (settings.LabSpeedrunningEnabled) { if (state.CurrentPhase == TimerPhase.NotRunning && LAB_ENTRANCE.Equals(previousZone)) { // Start the timer on the first zone of the lab. timer.Start(); } else { // And split on subsequent zones. timer.Split(); } } else if (settings.AutoSplitEnabled) { if (!encounteredZones.Contains(zone) && settings.SplitZones.Contains(zone)) { timer.Split(); } // Keep track of all encountered zones for part prediction. encounteredZones.Add(zone); } previousZone = zone; }
public override void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { state.IsGameTimePaused = true; bool start = false; lock (eventsLock) { foreach (var ev in events) { if (ev is GameEndEvent) { if (state.CurrentPhase == TimerPhase.Running && settings.ShouldSplitOnGameEnd()) { state.SetGameTime(ev.Time); model.Split(); } } else if (ev is MapChangeEvent) { var e = (MapChangeEvent)ev; if (visitedMaps.Add(e.Map) && settings.ShouldSplitOn(e.Map)) { state.SetGameTime(e.Time); model.Split(); } } else if (ev is TimerResetEvent) { if (settings.IsAutoResetEnabled()) { state.SetGameTime(ev.Time); model.Reset(); } } else if (ev is TimerStartEvent) { if (settings.IsAutoStartEnabled()) { state.SetGameTime(ev.Time); start = true; } } } events.Clear(); } if (start) { model.Start(); } TimeSpan curTime; lock (currentTimeLock) { curTime = currentTime; } state.SetGameTime(curTime); }
void gameMemory_OnMapChanged(object sender, string map) { if (map != @"levels\a10\a10") { _splitTime = DateTime.Now; _timer.Split(); } }
public void On_End() { if (_state.CurrentPhase == TimerPhase.Running && _settings.AutoEnd) { while (_state.CurrentSplitIndex < _state.Run.Count - 1) { _timer.SkipSplit(); } _timer.Split(); } }
void DoSplit() { // make split times accurate _timer.CurrentState.SetGameTime(this.GameTime); HotkeyProfile profile = _timer.CurrentState.Settings.HotkeyProfiles[_timer.CurrentState.CurrentHotkeyProfile]; bool before = profile.DoubleTapPrevention; profile.DoubleTapPrevention = false; _timer.Split(); profile.DoubleTapPrevention = before; }
private void Split(object sender, SplitEventArgs e) { var state = e.State; var run = state.Run; Log.Info("Splitting on " + e.SplitName + " (randomized: " + gameData.IsRandomized + ")"); if (gameData.IsRandomized) { if (e.Item) { // If this is an item, loading the game would add it again foreach (ISegment segment in state.Run) { if (segment.Name == e.SplitName) { Log.Info("Skipping a split on " + e.SplitName); return; } } } string oldSplit = state.CurrentSplit?.Name; Log.Info("current split: " + oldSplit); if (oldSplit == TRIFORCE || oldSplit == START) { Image icon = null; icons.TryGetValue(e.SplitName, out icon); state.CurrentSplit.Name = e.SplitName; state.CurrentSplit.Icon = icon; // If our new split is the Triforce room; OR if we're just overwriting the first split, don't add any further splits. if (e.SplitName != TRIFORCE && oldSplit != START) { // add a new unknown segment run.AddSegment(TRIFORCE, icon: icons[TRIFORCE]); } timer.Split(); } else { Log.Warning("Currently at split " + state.CurrentSplit.Name + " while trying to split " + e.SplitName); } } else if (!e.Item) { // split without fancy extra timer.Split(); } }
public bool split(Process dsProcess, TimerModel timer, PlayerPos playerPos, out bool loadSplitQueued, out bool finalSplitFlag) { loadSplitQueued = false; finalSplitFlag = false; if (!_enabled) { return(false); } _memWatcher.Update(dsProcess); if (_settingsNode.Checked && ((Convert.ToByte(_memWatcher.Old) >> _bitOffset) & 1) == 0 && ((Convert.ToByte(_memWatcher.Current) >> _bitOffset) & 1) == 1) { Trace.WriteLine("memory watcher changed: " + _key); if (_settingsNode.Level == 0) { Trace.WriteLine("_settingsNode.Level == 0"); if (_settingsNode.Nodes[0].Checked) { Trace.WriteLine("split: " + _key); timer.Split(); _enabled = false; return(true); } if (_splitLevelOneOnLoad) { if (_settingsNode.Nodes[1].Checked) { Trace.WriteLine("queued split: " + _key); loadSplitQueued = true; _enabled = false; if (_settingsNode.Nodes[1].Parent.Name == "SoulofCinder") { loadSplitQueued = false; finalSplitFlag = true; } return(true); } } } else { Trace.WriteLine("_settingsNode.Level == 1"); Trace.WriteLine("node key " + _settingsNode.Name); if (_settingsNode.Parent.Checked) { if (_splitLevelOneOnLoad) { Trace.WriteLine("queued split" + _key); loadSplitQueued = true; _enabled = false; return(true); } Trace.WriteLine("split: " + _key); timer.Split(); _enabled = false; return(true); } } } return(false); }
public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { _mem.Hook(); if (!_mem.IsHooked) { return; } if (_model.CurrentState.CurrentSplitIndex == -1) { CheckStart(); return; } if (_mem.GetGameState() != GameState.Playing) { return; } if (_settings.RandomizeSkins && !_playerRandomized) { _mem.RandomizePlayerAppearance(0); _playerRandomized = true; } CheckItemSplits(); // TODO: Generic enemy kill split system // Unspeakable Deep int len = _mem.GetCharCount(); for (int i = 0; i < len; i++) { if (_mem.GetCharType(i) != EnemyType.Leviathon || _mem.GetCharHealth(i) <= 0f || _enemyTrackers.Any(tracker => tracker.CharType == EnemyType.Leviathon)) { continue; } _enemyTrackers.Add(new EnemyHealthTracker(_mem, i)); } CheckCharKills(); if (_model.CurrentState.CurrentSplitIndex == _model.CurrentState.Run.Count - 1 && _mem.IsGameEnding()) { _model.Split(); } }
public override void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { if (!gameMemory.ProcessHook()) { return; } if (logic.ShouldStart()) { logic.ResetLogic(); if (liveSplitState.CurrentPhase == TimerPhase.Running) { timerModel.Reset(); } timerModel.Start(); } if (liveSplitState.CurrentPhase == TimerPhase.Running) { if (logic.ShouldSplit(liveSplitState.CurrentSplitIndex, liveSplitState.Run.Count)) { timerModel.Split(); } } }
private void NewLevelDat(object sender, RenamedEventArgs e) { if (e.Name == "session.lock") { MaybeStart(e.FullPath); } if (e.Name != "level.dat" || e.OldName != "level.dat_new" || e.ChangeType != WatcherChangeTypes.Renamed) { return; } if (timer.CurrentState.CurrentPhase != TimerPhase.Running) { return; } // It's possible that we're so fast that either Minecraft hasn't finished writing the file // or hasn't yet released the filesystem lock, so do the dumb hacky thing of retry for a few milliseconds lol for (var i = 0; i < NUM_RETRIES; i++) { try { var nbtFile = new NbtFile(e.FullPath); while (NewWool(nbtFile)) { timer.Split(); } return; } catch (Exception) { Thread.Sleep(RETRY_MS); } } }
public async Task UpdateState() { if (!IsConfigReady()) { Disconnect(); _update_timer.Interval = 1000; } else if (_mystate != MyState.READY) { _update_timer.Interval = 1000; Connect(); } else { _update_timer.Interval = 33; List <Split> splits = GenerateSplitList(); if (splits == null) { return; } if (await CheckSplits(splits, _state.CurrentSplitIndex)) { if (splits.Contains(_autostart)) { _model.Start(); } else { _model.Split(); } } } }
void gameMemory_OnSplitCompleted(object sender, GameMemory.SplitArea split, uint frame) { Debug.WriteLineIf(split != GameMemory.SplitArea.None, String.Format("[NoLoads] Trying to split {0}, State: {1} - {2}", split, _gameMemory.splitStates[(int)split], frame)); if (_state.CurrentPhase == TimerPhase.Running && !_gameMemory.splitStates[(int)split] && ((split == GameMemory.SplitArea.Prologue && this.Settings.Prologue) || (split == GameMemory.SplitArea.Sarif && this.Settings.Sarif) || (split == GameMemory.SplitArea.Detroit1 && this.Settings.Detroit1) || (split == GameMemory.SplitArea.FEMA && this.Settings.FEMA) || (split == GameMemory.SplitArea.Hengsha1 && this.Settings.Hengsha1) || (split == GameMemory.SplitArea.TaiYong1 && this.Settings.TaiYong1) || (split == GameMemory.SplitArea.TaiYong2 && this.Settings.TaiYong2) || (split == GameMemory.SplitArea.Picus && this.Settings.Picus) || (split == GameMemory.SplitArea.Detroit2 && this.Settings.Detroit2) || (split == GameMemory.SplitArea.TongsEnd && this.Settings.TongsEnd) || (split == GameMemory.SplitArea.Hengsha2 && this.Settings.Hengsha2) || (split == GameMemory.SplitArea.DLCBoat && this.Settings.TML_LeavingBoat) || (split == GameMemory.SplitArea.DLCUnderwater && this.Settings.TML_UnderwaterElevator) || (split == GameMemory.SplitArea.DLCEnd && this.Settings.TML_Finished) || (split == GameMemory.SplitArea.Singapore && this.Settings.Singapore) || (split == GameMemory.SplitArea.Panchaea && this.Settings.Panchaea))) { Trace.WriteLine(String.Format("[NoLoads] {0} Split - {1}", split, frame)); _timer.Split(); _gameMemory.splitStates[(int)split] = true; } }
public void HandleLevelUp(int level) { //while (timer.CurrentState.CurrentSplitIndex < level) //{ timer.Split(); //} }
void gameMemory_OnLevelChanged(object sender, EventArgs e) { if (this.Settings.SplitOnLevelChange) { _timer.Split(); } }
//Split on area completed void gameMemory_OnAreaCompleted(object sender, EventArgs e) { if (this.Settings.AutoStart) { _timer.Split(); } }
void DoSplit() { bool before = _state.Settings.DoubleTapPrevention; _state.Settings.DoubleTapPrevention = false; _timer.Split(); _state.Settings.DoubleTapPrevention = before; }
public async Task DoSplit() { if (_settings.Config.igt != null && _settings.Config.igt.active == "1" && _usb2snes.Connected()) { uint[] allAddresses = new uint[] { _settings.Config.igt.framesAddressInt, _settings.Config.igt.secondsAddressInt, _settings.Config.igt.minutesAddressInt, _settings.Config.igt.hoursAddressInt }; IEnumerable <uint> validAddresses = allAddresses.Where(address => address > 0); uint startingAddress = validAddresses.Min(); uint igtDataSize = (validAddresses.Max() + 2) - startingAddress; if (0 == igtDataSize || igtDataSize > 512) { Debug.WriteLine("DoSplit: IGT configuration invalid, skipping it"); } else { byte[] data; try { data = await _usb2snes.GetAddress((0xF50000 + startingAddress), igtDataSize); } catch { Debug.WriteLine("DoSplit: Exception getting address"); _model.Split(); return; } if (data.Count() == 0) { Debug.WriteLine("DoSplit: Get address failed to return result"); } else { Func <uint, int> readIgt = (address) => (0 == address) ? 0 : (data[address - startingAddress] + (data[(address + 1) - startingAddress] << 8)); int ms = (readIgt(_settings.Config.igt.framesAddressInt) * 1000) / 60; int sec = readIgt(_settings.Config.igt.secondsAddressInt); int min = readIgt(_settings.Config.igt.minutesAddressInt); int hr = readIgt(_settings.Config.igt.hoursAddressInt); var gt = new TimeSpan(0, hr, min, sec, ms); _state.SetGameTime(gt); } } } _model.Split(); }
// This is executed repeatedly as long as the game is connected and initialized. private void DoUpdate(LiveSplitState state) { OldState = State.RefreshValues(_game); if (!(RunMethod(_methods.update, state) ?? true)) { // If Update explicitly returns false, don't run anything else return; } // Call the start segment if the splits are not running, but ensure that the segment is called at least once. if (state.CurrentPhase == TimerPhase.NotRunning || !startMethodCalledFromUpdate) { if (RunMethod(_methods.start, state) ?? false) { if (_settings.GetBasicSettingValue("start") && state.CurrentPhase == TimerPhase.NotRunning) { _timer.Start(); } } startMethodCalledFromUpdate = true; } if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused) { if (_uses_game_time && !state.IsGameTimeInitialized) { _timer.InitializeGameTime(); } var is_paused = RunMethod(_methods.isLoading, state); if (is_paused != null) { state.IsGameTimePaused = is_paused; } var game_time = RunMethod(_methods.gameTime, state); if (game_time != null) { state.SetGameTime(game_time); } if (RunMethod(_methods.reset, state) ?? false) { if (_settings.GetBasicSettingValue("reset")) { _timer.Reset(); } } else if (RunMethod(_methods.split, state) ?? false) { if (_settings.GetBasicSettingValue("split")) { _timer.Split(); } } } }
// This is executed repeatedly as long as the game is connected and initialized. private void DoUpdate(LiveSplit.UI.Components.LiveSplitState state) { OldState = State.RefreshValues(_game); if (!(RunMethod(_methods.update, state) ?? true)) { // If Update explicitly returns false, don't run anything else return; } if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused) { if (_uses_game_time && !state.IsGameTimeInitialized) { _timer.InitializeGameTime(); } var is_paused = RunMethod(_methods.isLoading, state); if (is_paused != null) { state.IsGameTimePaused = is_paused; } var game_time = RunMethod(_methods.gameTime, state); if (game_time != null) { state.SetGameTime(game_time); } if (RunMethod(_methods.reset, state) ?? false) { if (_settings.GetBasicSettingValue("reset")) { _timer.Reset(); } } else if (RunMethod(_methods.split, state) ?? false) { if (_settings.GetBasicSettingValue("split")) { _timer.Split(); } } } if (state.CurrentPhase == TimerPhase.NotRunning) { if (RunMethod(_methods.start, state) ?? false) { if (_settings.GetBasicSettingValue("start")) { _timer.Start(); } } } }
public void DoSplit() { if (_game.name == "Super Metroid" && _usb2snes.Connected()) { var data = new byte[512]; data = _usb2snes.GetAddress((uint)(0xF509DA), (uint)512); int ms = (data[0] + (data[1] << 8)) * (1000 / 60); int sec = data[2] + (data[3] << 8); int min = data[4] + (data[5] << 8); int hr = data[6] + (data[7] << 8); var gt = new TimeSpan(0, hr, min, sec, ms); _state.SetGameTime(gt); _model.Split(); } else { _model.Split(); } }
private void GameMemory_OnSplitCompleted(object sender, int splitindex, uint frame) { Debug.WriteLineIf(splitindex != 0, String.Format("[NoLoads] Trying to split {0}, State: {1} - {2}", splitindex, _gameMemory.SplitStates[splitindex], frame)); if (_state.CurrentPhase == TimerPhase.Running && !_gameMemory.SplitStates[splitindex]) { Trace.WriteLine(String.Format("[NoLoads] {0} Split - {1}", splitindex, frame)); _timer.Split(); _gameMemory.SplitStates[splitindex] = true; } }
void gameMemory_OnSplitCompleted(object sender, SplitArea?split, uint frame) { if (_state.CurrentPhase == TimerPhase.Running && !splitStates[split.Value] && (bool)this.Settings.SplitSettings[split.Value]) { Trace.WriteLine(String.Format("[NoLoads] {0} Split - {1}", split, frame)); _timer.Split(); splitStates[split.Value] = true; } }
private void _gameMemory_OnSplit(object sender, SplitEventArgs e) { if (_state.CurrentPhase != TimerPhase.Running) { e.AutoSplit.Triggered = false; return; } Trace.WriteLine($"[NoLoads] {e.AutoSplit.Name} Split"); _timer.Split(); }
void DoSplit() { // make split times accurate _timer.CurrentState.SetGameTime(this.GameTime); bool before = _timer.CurrentState.Settings.DoubleTapPrevention; _timer.CurrentState.Settings.DoubleTapPrevention = false; _timer.Split(); _timer.CurrentState.Settings.DoubleTapPrevention = before; }
public void DoSplit() { if (_game.name == "Super Metroid" && core.Connected()) { var data = new byte[512]; core.SendCommand(core.usbint_server_opcode_e.USBINT_SERVER_OPCODE_GET, core.usbint_server_space_e.USBINT_SERVER_SPACE_SNES, core.usbint_server_flags_e.USBINT_SERVER_FLAGS_NONE, (uint)(0xF509DA), (uint)512); core.GetData(data, 0, 512); int ms = (data[0] + (data[1] << 8)) * (1000 / 60); int sec = data[2] + (data[3] << 8); int min = data[4] + (data[5] << 8); int hr = data[6] + (data[7] << 8); var gt = new TimeSpan(0, hr, min, sec, ms); _state.SetGameTime(gt); _model.Split(); } else { _model.Split(); } }
public void AttemptSplit() { if (!init()) { return; } _splitAttemptCnt++; if (_splitAttemptCnt % (int)(1 / _updateRateMuliplier) == 0) { //Load split if (_loadSplitQueued) { if (_timerInj.getOldTime() == _timerInj.getTime()) { _timer.Split(); _loadSplitQueued = false; } return; } if (_finalSplitFlag) { if (_timerInj.getTime() == 0) { _timer.Split(); _finalSplitFlag = false; } return; } if (_timerInj.getTime() == 0) { return; } _splits.process(_dsProcess, _timer, out _loadSplitQueued, out _finalSplitFlag); } }
public bool split(Process dsProcess, TimerModel timer, PlayerPos playerPos, out bool loadSplitQueued, out bool finalSplitFlag) { loadSplitQueued = false; finalSplitFlag = false; if (_enabled && _settingsNode.Checked) { if (_bb.intersect(dsProcess, playerPos)) { Trace.WriteLine("BBsplit"); timer.Split(); _enabled = false; return(true); } } return(false); }
public async Task DoSplit() { if (_settings.Config.igt != null && _settings.Config.igt.active == "1" && _usb2snes.Connected()) { var addressSizePairs = new List <Tuple <uint, uint> >(); addressSizePairs.Add(new Tuple <uint, uint>(_settings.Config.igt.framesAddressInt, 2)); addressSizePairs.Add(new Tuple <uint, uint>(_settings.Config.igt.secondsAddressInt, 2)); addressSizePairs.Add(new Tuple <uint, uint>(_settings.Config.igt.minutesAddressInt, 2)); addressSizePairs.Add(new Tuple <uint, uint>(_settings.Config.igt.hoursAddressInt, 2)); List <byte[]> data = null; try { data = await _usb2snes.GetAddress(addressSizePairs); } catch { Debug.WriteLine("DoSplit: Exception getting address"); _model.Split(); return; } if ((null == data) || (data.Count != addressSizePairs.Count)) { Debug.WriteLine("DoSplit: Get address failed to return result"); } else { int frames = (int)data[0][0] + ((int)data[0][1] << 8); int ms = (frames * 1000) / 60; int sec = (int)data[1][0] + ((int)data[1][1] << 8); int min = (int)data[2][0] + ((int)data[2][1] << 8); int hr = (int)data[3][0] + ((int)data[3][1] << 8); var gt = new TimeSpan(0, hr, min, sec, ms); _state.SetGameTime(gt); } } _model.Split(); }
void gameMemory_OnSplit(object sender, string level) { level = level.ToLower(); if (_state.CurrentPhase == TimerPhase.Running && Settings.AutoSplit && !_gameMemory.levels.Contains(level)) { Trace.WriteLine(String.Format("[NoLoads] Split \"{1}\" triggered - {0}", _gameMemory.frameCounter, level)); _timer.Split(); _gameMemory.levels.Add(level); } else { Trace.WriteLine(String.Format("[NoLoads] Tried to split \"{1}\" but it failed {2} - {0}", _gameMemory.frameCounter, level, (!_gameMemory.levels.Contains(level)) ? "because it was already split before" : "")); } }