Skip to content
8 changes: 4 additions & 4 deletions ConsistencyTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ private void EventsOnRunStarted() {
}

private void EventsOnRunEnded(bool died, bool won) {
ChokeRateStat.ChokeRateData = null; //Reset caching
StatManager.InvalidateCachedStats();
IngameOverlay?.SetGoldenState(false);
}
private void Events_OnChangedRoom(string roomName, bool isPreviousRoom) {
Expand Down Expand Up @@ -930,8 +930,8 @@ private void ChangeChapter(Session session) {
//fix for SpeedrunTool savestate inconsistency
TouchedBerries.Clear();

//Reset caching of choke rate data
ChokeRateStat.ChokeRateData = null;
//Reset caching
StatManager.InvalidateCachedStats();

//Cause initial stats calculation
SetNewRoom(CurrentRoomName, false);
Expand Down Expand Up @@ -1591,7 +1591,7 @@ public void RemoveRoomGoldenBerryDeaths(bool removeOne = false) {
}

//Reset cached choke rate data for graph
ChokeRateStat.ChokeRateData = null;
ChokeRateStat.InvalidateCache();
SaveChapterStats();
}
public void WipeChapterGoldenBerryDeaths() {
Expand Down
10 changes: 10 additions & 0 deletions ConsistencyTrackerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@
public void CreatePathGoldenTierSettingsEntry(TextMenu menu, bool inGame) {
TextMenuExt.SubMenu subMenu = new TextMenuExt.SubMenu("Path Golden Tier Settings", false);
menu.Add(subMenu);
TextMenu.Item menuItem;

Check warning on line 493 in ConsistencyTrackerSettings.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'menuItem' is declared but never used

Check warning on line 493 in ConsistencyTrackerSettings.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'menuItem' is declared but never used

if (!inGame) {
subMenu.Add(new TextMenu.SubHeader(Dialog.Clean("MODOPTION_CCT_PATH_MANAGEMENT_NOT_IN_GAME_HINT"), false));
Expand Down Expand Up @@ -1175,6 +1175,9 @@
[SettingIgnore]
public bool IngameOverlayGraphShowGoldenPbBar { get; set; } = true;

[SettingIgnore]
public bool IngameOverlayGraphShowSuccessRateColors { get; set; } = false;

[SettingIgnore]
public bool IngameOverlayGraphCurrentRoomExplicit { get; set; } = true;

Expand Down Expand Up @@ -1434,6 +1437,13 @@
}
});
subMenu.AddDescription(menu, menuItem, "Shows your PB room as a golden bar at the bottom of the graph.");

subMenu.Add(menuItem = new TextMenu.OnOff("Graph Show Success Rate Colors", IngameOverlayGraphShowSuccessRateColors) {
OnValueChange = v => {
IngameOverlayGraphShowSuccessRateColors = v;
}
});
subMenu.AddDescription(menu, menuItem, "Colors bars in graph to match room success rate color.");

subMenu.Add(menuItem = new TextMenu.OnOff("Graph Current Room Indicator Explicit", IngameOverlayGraphCurrentRoomExplicit) {
OnValueChange = v => {
Expand Down
32 changes: 31 additions & 1 deletion Entities/GraphOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class GraphOverlay : Entity {
private static int BackgroundDim => Mod.ModSettings.IngameOverlayGraphBackgroundDim;

private Dictionary<RoomInfo, Tuple<int, float, int, float>> ChokeRateData { get; set; }
private Dictionary<RoomInfo, float> SuccessRateData { get; set; }
private int HighestDifficulty { get; set; }
private RoomInfo PbRoom { get; set; }
private RoomInfo PbRoomSession { get; set; }
Expand All @@ -43,6 +44,7 @@ public GraphOverlay() {
}

private void EventsOnAfterSavingStats() {
StatManager.InvalidateCachedStats();
UpdateOverlay();
}

Expand All @@ -55,6 +57,7 @@ public void UpdateOverlay() {
if (path == null || stats == null) return;

ChokeRateData = ChokeRateStat.GetRoomData(path, stats);
SuccessRateData = SuccessRateStat.GetRoomData(path, stats);
PbRoom = StatsUtil.GetFurthestGoldenRun(path, stats);
PbRoomSession = StatsUtil.GetFurthestGoldenRunSession(path, stats);

Expand Down Expand Up @@ -121,6 +124,8 @@ public override void Render() {
int availableBarHeight = Height - (ShowGoldenPbBar ? 3 + 1 : 0) - (currentRoomIndicatorExplicit ? 3 + 1 : 0);
int barWidth = (availableBarWidth - ((barCount - 1) * BarSpacing)) / barCount;
int paddingX = (availableBarWidth - (barWidth * barCount) - ((barCount - 1) * BarSpacing)) / 2;

bool showSuccessRateColors = Mod.ModSettings.IngameOverlayGraphShowSuccessRateColors;

//Walk path and draw the bars
int barsDrawn = 0;
Expand Down Expand Up @@ -152,6 +157,31 @@ public override void Render() {
if (!visitedCurrent) {
barColor = Color.Gray;
}

//Color code for success rate display
if (showSuccessRateColors) {
barHeight = Math.Max(3, barHeight);

if (SuccessRateData.ContainsKey(rInfo)) {
float successRate = SuccessRateData[rInfo];
if (float.IsNaN(successRate)) {
barColor = Color.Gray;
} else if (successRate > ((float)Mod.ModSettings.LiveDataChapterBarLightGreenPercent / 100 - 0.001)) {
// Light green
barColor = Color.LightGreen;
} else if (successRate > ((float)Mod.ModSettings.LiveDataChapterBarGreenPercent / 100 - 0.001)) {
// Green
barColor = Color.Green;
} else if (successRate > ((float)Mod.ModSettings.LiveDataChapterBarYellowPercent / 100 - 0.001)) {
// Yellow
barColor = Color.Yellow;
} else {
// Red
barColor = Color.Red;
}

}
}

//Draw checkpoint indicator over the empty space before this bar
if (!isFirstCheckpoint && rInfo.RoomNumberInCP == 1 && Mod.ModSettings.IngameOverlayGraphShowCheckpointIndicator) {
Expand Down Expand Up @@ -286,4 +316,4 @@ private static Vector2 ResolvePosition(StatTextPosition pos, int width, int heig
return position;
}
}
}
}
4 changes: 4 additions & 0 deletions Models/ChapterStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -745,13 +745,17 @@ public void AddAttempt(bool success) {
}

PreviousAttempts.Add(success);

SuccessRateStat.InvalidateCache();
}

public void RemoveLastAttempt() {
if (PreviousAttempts.Count <= 0) {
return;
}
PreviousAttempts.RemoveAt(PreviousAttempts.Count-1);

SuccessRateStat.InvalidateCache();
}

public long GetTimeForCategory(TimeCategory category) {
Expand Down
8 changes: 7 additions & 1 deletion Stats/ChokeRateStat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public override string FormatSummary(PathInfo chapterPath, ChapterStats chapterS
return null;
}

public static Dictionary<RoomInfo, Tuple<int, float, int, float>> ChokeRateData { get; set; } = null;
private static Dictionary<RoomInfo, Tuple<int, float, int, float>> ChokeRateData = null;
/// <summary>
/// Gets the following data for every room: Golden Entries, Golden Success Rate, Golden Entries Session, Golden Success Rate Session
/// </summary>
Expand Down Expand Up @@ -320,6 +320,12 @@ public static Dictionary<RoomInfo, Tuple<int, float, int, float>> GetRoomData(Pa
ChokeRateData = roomData;
return roomData;
}
/// <summary>
/// Deletes cached room choke rate data, resulting in it being recomputed next time it is requested.
/// </summary>
public static void InvalidateCache() {
ChokeRateData = null;
}

/// <summary>
/// Gets the following data for every room: Golden Entries Session, Golden Success Rate Session
Expand Down
9 changes: 9 additions & 0 deletions Stats/StatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,15 @@ public bool DeleteFormat(string formatName) {
Mod.SaveChapterStats();
return true;
}

/// <summary>
/// Resets the caches used by stats shown in the graph overlay.
/// Currently, resets cache for `ChokeRateStat` and `SuccessRateStat`.
/// </summary>
public static void InvalidateCachedStats() {
ChokeRateStat.InvalidateCache();
SuccessRateStat.InvalidateCache();
}
#endregion

#region Format file IO
Expand Down
28 changes: 28 additions & 0 deletions Stats/SuccessRateStat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,34 @@ public override string FormatSummary(PathInfo chapterPath, ChapterStats chapterS
return null;
}

private static Dictionary<RoomInfo, float> SuccessRateData = null;
/// <summary>
/// Gets the success rate data (based on fraction of successes in latest `StatManager.AttemptCount` attempts) for each room.
/// </summary>
public static Dictionary<RoomInfo, float> GetRoomData(PathInfo chapterPath, ChapterStats chapterStats) {
if (SuccessRateData != null) return SuccessRateData;

int attemptCount = StatManager.AttemptCount;
var roomData = new Dictionary<RoomInfo, float>();

foreach (CheckpointInfo cpInfo in chapterPath.Checkpoints) {
foreach (RoomInfo rInfo in cpInfo.Rooms) {
RoomStats data = chapterStats.GetRoom(rInfo);
float successRate = data.AverageSuccessOverN(attemptCount);
roomData.Add(rInfo, successRate);
}
}

SuccessRateData = roomData;
return roomData;
}
/// <summary>
/// Deletes cached room success rate data, resulting in it being recomputed next time it is requested.
/// </summary>
public static void InvalidateCache() {
SuccessRateData = null;
}


//success-rate;Room SR: {room:successRate} | CP: {checkpoint:successRate} | Total: {chapter:successRate}
public override List<KeyValuePair<string, string>> GetPlaceholderExplanations() {
Expand Down
Loading