private bool isGoldSplit() { int splitIndex = state.CurrentSplitIndex - 1; TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, state.CurrentTimingMethod); return(state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod] == null || curSegment < state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod]); }
public string BuildMessage() { string ret = Value; int lastSplit = State.CurrentSplitIndex - 1; TimeSpan?deltaTime = LiveSplitStateHelper.GetPreviousSegmentDelta(State, lastSplit, State.CurrentComparison, this.TimingMethod); TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(State, lastSplit, this.TimingMethod); if (!formatSet) { if (Accuracy == TimeAccuracy.Tenths) { TimeFormat += "'.'f"; } else if (Accuracy == TimeAccuracy.Hundredths) { TimeFormat += "'.'ff"; } else if (Accuracy == TimeAccuracy.Thousandths) { TimeFormat += "'.'fff"; } formatSet = true; } ret = ret.Replace("%t", curSegment.Value.ToString(TimeFormat)); ret = ret.Replace("%n", State.Run[lastSplit].Name); if (deltaTime.HasValue) { ret = ret.Replace("%d", deltaTime.Value.ToString((deltaTime < TimeSpan.Zero ? "\\-" : "") + TimeFormat)); } return(ret); }
private static RunState GetRunState(LiveSplitState state, int splitIndex) { if (splitIndex < 0) { return(RunState.Indetermined); } TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, state.CurrentTimingMethod); if (curSegment != null) { if (state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod] == null || curSegment < state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod]) { return(RunState.BestSegment); } } var timeDifference = state.Run[splitIndex].SplitTime[state.CurrentTimingMethod] - state.Run[splitIndex].Comparisons[state.CurrentComparison][state.CurrentTimingMethod]; if (timeDifference == null) { return(RunState.Indetermined); } if (timeDifference < TimeSpan.Zero) { if (LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod) > TimeSpan.Zero) { return(RunState.AheadLosing); } return(RunState.AheadGaining); } if (LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod) < TimeSpan.Zero) { return(RunState.BehindGaining); } return(RunState.BehindLosing); }
private void State_OnSplit(object sender, EventArgs e) { if (State.CurrentPhase == TimerPhase.Ended) { if ((State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod] == null || State.Run.Last().SplitTime[State.CurrentTimingMethod] < State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod]) && Settings.PersonalBest) { SendPayload("PersonalBest"); } else { if (Settings.NotAPersonalBest) { SendPayload("NotAPersonalBest"); } } } else { string payload = null; var splitIndex = State.CurrentSplitIndex - 1; var timeDifference = State.Run[splitIndex].SplitTime[State.CurrentTimingMethod] - State.Run[splitIndex].Comparisons[State.CurrentComparison][State.CurrentTimingMethod]; if (timeDifference != null) { if (timeDifference < TimeSpan.Zero) { payload = "SplitAheadGaining"; if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) > TimeSpan.Zero) { payload = "SplitAheadLosing"; } } else { payload = "SplitBehindLosing"; if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) < TimeSpan.Zero) { payload = "SplitBehindGaining"; } } } //Check for best segment TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(State, splitIndex, State.CurrentTimingMethod); if (curSegment != null) { if (State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod] == null || curSegment < State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod]) { payload = "BestSegment"; } } if (string.IsNullOrEmpty(payload)) { payload = "Split"; } SendPayload(payload); } }
protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData data) { var comparison = data.Comparison == "Current Comparison" ? state.CurrentComparison : data.Comparison; if (!state.Run.Comparisons.Contains(comparison)) { comparison = state.CurrentComparison; } var timingMethod = state.CurrentTimingMethod; if (data.TimingMethod == "Real Time") { timingMethod = TimingMethod.RealTime; } else if (data.TimingMethod == "Game Time") { timingMethod = TimingMethod.GameTime; } var type = data.Type; var splitIndex = state.Run.IndexOf(Split); if (splitIndex < state.CurrentSplitIndex) { if (type == ColumnType.SplitTime || type == ColumnType.SegmentTime) { label.ForeColor = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor; if (type == ColumnType.SplitTime) { label.Text = TimeFormatter.Format(Split.SplitTime[timingMethod]); } else //SegmentTime { var segmentTime = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, timingMethod); label.Text = TimeFormatter.Format(segmentTime); } } if (type == ColumnType.DeltaorSplitTime || type == ColumnType.Delta) { var deltaTime = Split.SplitTime[timingMethod] - Split.Comparisons[comparison][timingMethod]; var color = LiveSplitStateHelper.GetSplitColor(state, deltaTime, splitIndex, true, true, comparison, timingMethod); if (color == null) { color = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor; } label.ForeColor = color.Value; if (type == ColumnType.DeltaorSplitTime) { if (deltaTime != null) { label.Text = DeltaTimeFormatter.Format(deltaTime); } else { label.Text = TimeFormatter.Format(Split.SplitTime[timingMethod]); } } else if (type == ColumnType.Delta) { label.Text = DeltaTimeFormatter.Format(deltaTime); } } else if (type == ColumnType.SegmentDeltaorSegmentTime || type == ColumnType.SegmentDelta) { var segmentDelta = LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, comparison, timingMethod); var color = LiveSplitStateHelper.GetSplitColor(state, segmentDelta, splitIndex, false, true, comparison, timingMethod); if (color == null) { color = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor; } label.ForeColor = color.Value; if (type == ColumnType.SegmentDeltaorSegmentTime) { if (segmentDelta != null) { label.Text = DeltaTimeFormatter.Format(segmentDelta); } else { label.Text = TimeFormatter.Format(LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, timingMethod)); } } else if (type == ColumnType.SegmentDelta) { label.Text = DeltaTimeFormatter.Format(segmentDelta); } } } else { if (type == ColumnType.SplitTime || type == ColumnType.SegmentTime || type == ColumnType.DeltaorSplitTime || type == ColumnType.SegmentDeltaorSegmentTime) { if (Split == state.CurrentSplit) { label.ForeColor = Settings.OverrideTimesColor ? Settings.CurrentTimesColor : state.LayoutSettings.TextColor; } else { label.ForeColor = Settings.OverrideTimesColor ? Settings.AfterTimesColor : state.LayoutSettings.TextColor; } if (type == ColumnType.SplitTime || type == ColumnType.DeltaorSplitTime) { label.Text = TimeFormatter.Format(Split.Comparisons[comparison][timingMethod]); } else //SegmentTime or SegmentTimeorSegmentDeltaTime { var previousTime = TimeSpan.Zero; for (var index = splitIndex - 1; index >= 0; index--) { var comparisonTime = state.Run[index].Comparisons[comparison][timingMethod]; if (comparisonTime != null) { previousTime = comparisonTime.Value; break; } } label.Text = TimeFormatter.Format(Split.Comparisons[comparison][timingMethod] - previousTime); } } //Live Delta var splitDelta = type == ColumnType.DeltaorSplitTime || type == ColumnType.Delta; var bestDelta = LiveSplitStateHelper.CheckLiveDelta(state, splitDelta, comparison, timingMethod); if (bestDelta != null && Split == state.CurrentSplit && (type == ColumnType.DeltaorSplitTime || type == ColumnType.Delta || type == ColumnType.SegmentDeltaorSegmentTime || type == ColumnType.SegmentDelta)) { if (splitDelta) //DeltaorSplitTime or Delta { label.Text = DeltaTimeFormatter.Format(bestDelta); } else //SegmentDeltaorSegmentTime or SegmentDelta { label.Text = DeltaTimeFormatter.Format(LiveSplitStateHelper.GetLiveSegmentDelta(state, splitIndex, comparison, timingMethod)); } label.ForeColor = Settings.OverrideDeltasColor ? Settings.DeltasColor : state.LayoutSettings.TextColor; } else if (type == ColumnType.Delta || type == ColumnType.SegmentDelta) { label.Text = ""; } } }
private Image GetIcon(LiveSplitState state, int splitIndex, out bool customizedIcon) { var icon = Split.Icon; customizedIcon = true; if (this.Settings.DisplayIcons) { var attemptIconOverride = false; var currentSegmantHasBeenSplit = (state.CurrentSplitIndex > splitIndex); var updateBasedOnCurrentRun = (this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.ComparisonAndCurrentRun || this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.CurrentRun); var updateBasedOnComparison = (this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.ComparisonAndCurrentRun || this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.Comparison); if (updateBasedOnComparison) { attemptIconOverride = true; } else if (updateBasedOnCurrentRun && currentSegmantHasBeenSplit) { attemptIconOverride = true; } // If this split has already gone past: if (attemptIconOverride) { var splitState = SplitState.Unknown; var previousSegmentTime = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, state.CurrentTimingMethod); var overrideAsSkippedPBSplit = false; // Use the skipped split icon if they specified to override for the current run // if the segment has been split (and skipped) if (previousSegmentTime == null && currentSegmantHasBeenSplit && updateBasedOnCurrentRun) { overrideAsSkippedPBSplit = true; } // Use the skipped split icon if they specified to override compared to the PB else if (updateBasedOnComparison) { // Don't override whatever's in PB if they've split this segment and specificed to update on teh current run // We don't want a skipped PB segment to cause a "return" later on here. if (!(currentSegmantHasBeenSplit && updateBasedOnCurrentRun)) { // the PB was a skipped split? var PBSplit = state.Run[splitIndex]; if (PBSplit != null) { var PBSplittime = PBSplit.PersonalBestSplitTime; if (state.CurrentTimingMethod == TimingMethod.GameTime) { overrideAsSkippedPBSplit = (PBSplittime.GameTime == null); } else if (state.CurrentTimingMethod == TimingMethod.RealTime) { overrideAsSkippedPBSplit = (PBSplittime.RealTime == null); } } } } if (overrideAsSkippedPBSplit && this.Settings.SkippedSplitIcon != null && this.Settings.SkippedSplitIcon.IconState == GradedIconState.Default) { if (string.IsNullOrWhiteSpace(this.Settings.SkippedSplitIcon.Base64Bytes)) { icon = null; } else { // It was a skipped split Image cached; if (!GradedIcons.TryGetValue(this.Settings.SkippedSplitIcon.Base64Bytes + "_ss", out cached)) { icon = getBitmapFromBase64(this.Settings.SkippedSplitIcon.Base64Bytes); GradedIcons.Add(this.Settings.SkippedSplitIcon.Base64Bytes + "_ss", icon); } else { icon = cached; } } customizedIcon = true; return(icon); } var getCurrentSplitPercentageBehindBestSegment = new Func <decimal>(() => { // say your best segment is 100s // it makes sense to do like < 105 = A // < 110 = B // 0.05 = (105-100)/100 double bestMilliseconds = 0; if (state.CurrentTimingMethod == TimingMethod.GameTime) { bestMilliseconds = Split.BestSegmentTime.GameTime?.TotalMilliseconds ?? 0; } else if (state.CurrentTimingMethod == TimingMethod.RealTime) { bestMilliseconds = Split.BestSegmentTime.RealTime?.TotalMilliseconds ?? 0; } // No current best segment, gold split guaranteed A+? if (bestMilliseconds <= 0) { return(0); } double currentMilliseconds = 0; if (currentSegmantHasBeenSplit && updateBasedOnCurrentRun) { if (previousSegmentTime != null) { currentMilliseconds = previousSegmentTime.Value.TotalMilliseconds; } } else { double personalBestTimeMilliseconds = 0; double priorsplitMilliseconds = 0; if (state.CurrentTimingMethod == TimingMethod.GameTime) { personalBestTimeMilliseconds = Split.PersonalBestSplitTime.GameTime?.TotalMilliseconds ?? 0; if (splitIndex > 0) // At index 0, there is no prior split, and the PB split IS the total ms for it { priorsplitMilliseconds = state.Run[splitIndex - 1].PersonalBestSplitTime.GameTime?.TotalMilliseconds ?? 0; } } else if (state.CurrentTimingMethod == TimingMethod.RealTime) { personalBestTimeMilliseconds = Split.PersonalBestSplitTime.RealTime?.TotalMilliseconds ?? 0; if (splitIndex > 0) // At index 0, there is no prior split, and the PB split IS the total ms for it { priorsplitMilliseconds = state.Run[splitIndex - 1].PersonalBestSplitTime.RealTime?.TotalMilliseconds ?? 0; } } currentMilliseconds = (personalBestTimeMilliseconds - priorsplitMilliseconds); } // you were super amazing or i messed up: if (currentMilliseconds <= 0) { return(-1); } return(Convert.ToDecimal((((currentMilliseconds - bestMilliseconds) / bestMilliseconds) * ((double)100)))); }); if ((!string.IsNullOrWhiteSpace(this.Settings.BehindLosingTimeIcon.Base64Bytes) && this.Settings.BehindLosingTimeIcon.IconState == GradedIconState.Default) || (!string.IsNullOrWhiteSpace(this.Settings.BehindGainingTimeIcon.Base64Bytes) && this.Settings.BehindGainingTimeIcon.IconState == GradedIconState.Default) || (!string.IsNullOrWhiteSpace(this.Settings.AheadLosingTimeIcon.Base64Bytes) && this.Settings.AheadLosingTimeIcon.IconState == GradedIconState.Default) || (!string.IsNullOrWhiteSpace(this.Settings.AheadGainingTimeIcon.Base64Bytes) && this.Settings.AheadGainingTimeIcon.IconState == GradedIconState.Default) || (!string.IsNullOrWhiteSpace(this.Settings.BestSegmentIcon.Base64Bytes) && this.Settings.BestSegmentIcon.IconState == GradedIconState.Default)) { var segmentDelta = LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod); splitState = this.GetSplitState(state, segmentDelta, splitIndex, state.CurrentComparison, state.CurrentTimingMethod); } var iconToUse = SplitState.Unknown; if (!string.IsNullOrWhiteSpace(this.Settings.BehindLosingTimeIcon.Base64Bytes) && this.Settings.BehindLosingTimeIcon.IconState != GradedIconState.Disabled) { if (this.Settings.BehindLosingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.BehindLosing) { iconToUse = splitState; } else if (this.Settings.BehindLosingTimeIcon.IconState == GradedIconState.PercentageSplit) { var percentage = getCurrentSplitPercentageBehindBestSegment(); if (percentage < this.Settings.BehindLosingTimeIcon.PercentageBehind) { iconToUse = SplitState.BehindLosing; } } } if (!string.IsNullOrWhiteSpace(this.Settings.BehindGainingTimeIcon.Base64Bytes) && this.Settings.BehindGainingTimeIcon.IconState != GradedIconState.Disabled) { if (this.Settings.BehindGainingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.BehindGaining) { iconToUse = splitState; } else if (this.Settings.BehindGainingTimeIcon.IconState == GradedIconState.PercentageSplit) { var percentage = getCurrentSplitPercentageBehindBestSegment(); if (percentage < this.Settings.BehindGainingTimeIcon.PercentageBehind) { iconToUse = SplitState.BehindGaining; } } } if (!string.IsNullOrWhiteSpace(this.Settings.AheadLosingTimeIcon.Base64Bytes) && this.Settings.AheadLosingTimeIcon.IconState != GradedIconState.Disabled) { if (this.Settings.AheadLosingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.AheadLosing) { iconToUse = splitState; } else if (this.Settings.AheadLosingTimeIcon.IconState == GradedIconState.PercentageSplit) { var percentage = getCurrentSplitPercentageBehindBestSegment(); if (percentage < this.Settings.AheadLosingTimeIcon.PercentageBehind) { iconToUse = SplitState.AheadLosing; } } } if (!string.IsNullOrWhiteSpace(this.Settings.AheadGainingTimeIcon.Base64Bytes) && this.Settings.AheadGainingTimeIcon.IconState != GradedIconState.Disabled) { if (this.Settings.AheadGainingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.AheadGaining) { iconToUse = splitState; } else if (this.Settings.AheadGainingTimeIcon.IconState == GradedIconState.PercentageSplit) { var percentage = getCurrentSplitPercentageBehindBestSegment(); if (percentage < this.Settings.AheadGainingTimeIcon.PercentageBehind) { iconToUse = SplitState.AheadGaining; } } } if (!string.IsNullOrWhiteSpace(this.Settings.BestSegmentIcon.Base64Bytes) && this.Settings.BestSegmentIcon.IconState != GradedIconState.Disabled) { if (this.Settings.BestSegmentIcon.IconState == GradedIconState.Default && splitState == SplitState.BestSegment) { iconToUse = splitState; } else if (this.Settings.BestSegmentIcon.IconState == GradedIconState.PercentageSplit) { var percentage = getCurrentSplitPercentageBehindBestSegment(); if (percentage < this.Settings.BestSegmentIcon.PercentageBehind) { iconToUse = SplitState.BestSegment; } } } if (iconToUse == SplitState.BestSegment) { Image cached; if (!GradedIcons.TryGetValue(this.Settings.BestSegmentIcon.Base64Bytes + "_1", out cached)) { icon = getBitmapFromBase64(this.Settings.BestSegmentIcon.Base64Bytes); GradedIcons.Add(this.Settings.BestSegmentIcon.Base64Bytes + "_1", icon); } else { icon = cached; } customizedIcon = true; } else if (iconToUse == SplitState.AheadGaining) { Image cached; if (!GradedIcons.TryGetValue(this.Settings.AheadGainingTimeIcon.Base64Bytes + "_2", out cached)) { icon = getBitmapFromBase64(this.Settings.AheadGainingTimeIcon.Base64Bytes); GradedIcons.Add(this.Settings.AheadGainingTimeIcon.Base64Bytes + "_2", icon); } else { icon = cached; } customizedIcon = true; } else if (iconToUse == SplitState.AheadLosing) { Image cached; if (!GradedIcons.TryGetValue(this.Settings.AheadLosingTimeIcon.Base64Bytes + "_3", out cached)) { icon = getBitmapFromBase64(this.Settings.AheadLosingTimeIcon.Base64Bytes); GradedIcons.Add(this.Settings.AheadLosingTimeIcon.Base64Bytes + "_3", icon); } else { icon = cached; } customizedIcon = true; } else if (iconToUse == SplitState.BehindGaining) { Image cached; if (!GradedIcons.TryGetValue(this.Settings.BehindGainingTimeIcon.Base64Bytes + "_4", out cached)) { icon = getBitmapFromBase64(this.Settings.BehindGainingTimeIcon.Base64Bytes); GradedIcons.Add(this.Settings.BehindGainingTimeIcon.Base64Bytes + "_4", icon); } else { icon = cached; } customizedIcon = true; } else if (iconToUse == SplitState.BehindLosing) { Image cached; if (!GradedIcons.TryGetValue(this.Settings.BehindLosingTimeIcon.Base64Bytes + "_5", out cached)) { icon = getBitmapFromBase64(this.Settings.BehindLosingTimeIcon.Base64Bytes); GradedIcons.Add(this.Settings.BehindLosingTimeIcon.Base64Bytes + "_5", icon); } else { icon = cached; } customizedIcon = true; } } } return(icon); }
private void State_OnSplit(object sender, EventArgs e) { if (State.CurrentPhase == TimerPhase.Ended) { if (State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod] == null || State.Run.Last().SplitTime[State.CurrentTimingMethod] < State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod]) { PlaySound(Settings.PersonalBest, Settings.PersonalBestVolume); } else { PlaySound(Settings.NotAPersonalBest, Settings.NotAPersonalBestVolume); } } else { var path = string.Empty; int volume = Settings.SplitVolume; var splitIndex = State.CurrentSplitIndex - 1; var timeDifference = State.Run[splitIndex].SplitTime[State.CurrentTimingMethod] - State.Run[splitIndex].Comparisons[State.CurrentComparison][State.CurrentTimingMethod]; if (timeDifference != null) { if (timeDifference < TimeSpan.Zero) { path = Settings.SplitAheadGaining; volume = Settings.SplitAheadGainingVolume; if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) > TimeSpan.Zero) { path = Settings.SplitAheadLosing; volume = Settings.SplitAheadLosingVolume; } } else { path = Settings.SplitBehindLosing; volume = Settings.SplitBehindLosingVolume; if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) < TimeSpan.Zero) { path = Settings.SplitBehindGaining; volume = Settings.SplitBehindGainingVolume; } } } //Check for best segment TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(State, splitIndex, State.CurrentTimingMethod); if (curSegment != null) { if (State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod] == null || curSegment < State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod]) { path = Settings.BestSegment; volume = Settings.BestSegmentVolume; } } if (string.IsNullOrEmpty(path)) { path = Settings.Split; } PlaySound(path, volume); } }