public OuiJournalCollabProgressInLobby(OuiJournal journal, string levelSet, bool displayIcons) : base(journal) { string skullTexture = MTN.Journal.Has("CollabUtils2Skulls/" + levelSet) ? "CollabUtils2Skulls/" + levelSet : "skullblue"; string minDeathsTexture = MTN.Journal.Has("CollabUtils2MinDeaths/" + levelSet) ? "CollabUtils2MinDeaths/" + levelSet : "CollabUtils2MinDeaths/SpringCollab2020/1-Beginner"; PageTexture = "page"; table = new Table() .AddColumn(new TextCell(Dialog.Clean("journal_progress"), new Vector2(0f, 0.5f), 1f, Color.Black * 0.7f, displayIcons ? 360f : 420f)); if (displayIcons) { table .AddColumn(new EmptyCell(0f)) .AddColumn(new EmptyCell(64f)); } table.AddColumn(new EmptyCell(0f)) .AddColumn(new EmptyCell(64f)) .AddColumn(new IconCell("strawberry", 150f)) .AddColumn(new IconCell(skullTexture, 100f)) .AddColumn(new IconCell(minDeathsTexture, 100f)); if (OuiJournalCollabProgressDashCountMod.IsDashCountEnabled()) { table.AddColumn(new IconCell("max480/DashCountMod/dashes", 80f)); } table .AddColumn(new IconCell("time", 220f)) .AddColumn(new IconCell("CollabUtils2/speed_berry_pbs_heading", 220f)) .AddColumn(new EmptyCell(30f)); }
public OuiJournalCollabProgressInOverworld(OuiJournal journal) : base(journal) { bool displaySpeedBerryColumn = shouldDisplaySpeedBerryColumn(); PageTexture = "page"; table = new Table() .AddColumn(new TextCell(Dialog.Clean("journal_progress"), new Vector2(0f, 0.5f), 1f, Color.Black * 0.7f, 420f)) .AddColumn(new EmptyCell(20f)) .AddColumn(new EmptyCell(64f)) .AddColumn(new IconCell("strawberry", 150f)) .AddColumn(new IconCell("skullblue", 100f)) .AddColumn(new IconCell("CollabUtils2MinDeaths/SpringCollab2020/1-Beginner", 100f)); if (OuiJournalCollabProgressDashCountMod.IsDashCountEnabled()) { table.AddColumn(new IconCell("max480/DashCountMod/dashes", 80f)); } table .AddColumn(new IconCell("time", 220f)) .AddColumn(new IconCell("CollabUtils2/speed_berry_pbs_heading", 220f)) .AddColumn(new EmptyCell(30f)); int totalStrawberries = 0; int totalDeaths = 0; int sumOfBestDeaths = 0; int sumOfBestDashes = 0; long totalTime = 0; long sumOfBestTimes = 0; bool allLevelsDone = true; bool allSpeedBerriesDone = true; bool allMapsCompletedInSingleRun = true; foreach (AreaStats item in SaveData.Instance.Areas_Safe) { AreaData areaData = AreaData.Get(item.ID_Safe); if (areaData.GetLevelSet() == SaveData.Instance.LevelSet) { string lobbyMapLevelSetName = LobbyHelper.GetLobbyLevelSet(areaData.GetSID()); LevelSetStats lobbyMapLevelSet = null; if (lobbyMapLevelSetName != null) { lobbyMapLevelSet = SaveData.Instance.GetLevelSetStatsFor(lobbyMapLevelSetName); } int lobbyStrawberries = item.TotalStrawberries; int lobbyTotalStrawberries = areaData.Mode[0].TotalStrawberries; int lobbyDeaths = item.Modes[0].Deaths; int lobbySumOfBestDeaths = 0; int lobbySumOfBestDashes = OuiJournalCollabProgressDashCountMod.DisplaysTotalDashes() ? OuiJournalCollabProgressDashCountMod.GetLevelDashesForJournalProgress(item) : 0; long lobbyTotalTime = item.TotalTimePlayed; long lobbySumOfBestTimes = 0; bool lobbyLevelsDone = true; int lobbySpeedBerryLevel = 1; bool lobbySilverBerriesObtained = true; bool lobbyAllMapsCompletedInSingleRun = true; foreach (AreaStats lobbyMap in lobbyMapLevelSet?.Areas ?? new List <AreaStats>()) { AreaData lobbyAreaData = AreaData.Get(lobbyMap.ID_Safe); lobbyStrawberries += lobbyMap.TotalStrawberries; lobbyTotalStrawberries += lobbyAreaData.Mode[0].TotalStrawberries; lobbyDeaths += lobbyMap.Modes[0].Deaths; lobbyTotalTime += lobbyMap.TotalTimePlayed; lobbyAllMapsCompletedInSingleRun &= lobbyMap.Modes[0].SingleRunCompleted; if (displaySpeedBerryColumn) { if (CollabMapDataProcessor.SpeedBerries.TryGetValue(lobbyMap.GetSID(), out CollabMapDataProcessor.SpeedBerryInfo mapSpeedBerryInfo) && CollabModule.Instance.SaveData.SpeedBerryPBs.TryGetValue(lobbyMap.GetSID(), out long mapSpeedBerryPB)) { lobbySpeedBerryLevel = Math.Max(getRankLevel(mapSpeedBerryInfo, mapSpeedBerryPB), lobbySpeedBerryLevel); lobbySumOfBestTimes += mapSpeedBerryPB; } else { lobbySpeedBerryLevel = 4; } } else { if (lobbyMap.Modes[0].BestTime > 0f) { lobbySumOfBestTimes += lobbyMap.Modes[0].BestTime; } else { lobbySpeedBerryLevel = 4; } } bool goldenBerryNotObtained = !lobbyMap.Modes[0].Strawberries.Any(berry => lobbyAreaData.Mode[0].MapData.Goldenberries.Any(golden => golden.ID == berry.ID && golden.Level.Name == berry.Level)); bool silverBerryNotObtained = !CollabMapDataProcessor.SilverBerries.TryGetValue(lobbyMap.GetLevelSet(), out Dictionary <string, EntityID> levelSetBerries) || !levelSetBerries.TryGetValue(lobbyMap.GetSID(), out EntityID berryID) || !lobbyMap.Modes[0].Strawberries.Contains(berryID); if (goldenBerryNotObtained && silverBerryNotObtained) { lobbySilverBerriesObtained = false; lobbySumOfBestDeaths += lobbyMap.Modes[0].BestDeaths; } lobbySumOfBestDashes += OuiJournalCollabProgressDashCountMod.GetLevelDashesForJournalProgress(lobbyMap); if (!lobbyMap.Modes[0].HeartGem) { lobbyLevelsDone = false; } } string strawberryText = null; if (lobbyStrawberries > 0 || lobbyTotalStrawberries > 0) { strawberryText = lobbyStrawberries.ToString(); if (lobbyLevelsDone) { strawberryText = strawberryText + "/" + lobbyTotalStrawberries; } } else { strawberryText = "-"; } string heartTexturePath = lobbyMapLevelSetName ?? areaData.GetSID(); string heartTexture = MTN.Journal.Has("CollabUtils2Hearts/" + heartTexturePath) ? "CollabUtils2Hearts/" + heartTexturePath : "heartgem0"; string areaName = Dialog.Clean(areaData.Name); if (Dialog.Has(areaData.Name + "_journal")) { areaName = Dialog.Clean(areaData.Name + "_journal"); } Row row = table.AddRow() .Add(new TextCell(areaName, new Vector2(1f, 0.5f), 0.6f, TextColor)) .Add(null) .Add(new IconCell(item.Modes[0].HeartGem ? heartTexture : "dot")) .Add(new TextCell(strawberryText, TextJustify, 0.5f, TextColor)); if (lobbyTotalTime > 0) { row.Add(new TextCell(Dialog.Deaths(lobbyDeaths), TextJustify, 0.5f, TextColor)); } else { row.Add(new IconCell("dot")); } if (lobbyLevelsDone) { AreaStats stats = SaveData.Instance.GetAreaStatsFor(areaData.ToKey()); if (lobbyMapLevelSet == null) { row.Add(new TextCell(Dialog.Deaths(item.Modes[0].BestDeaths), TextJustify, 0.5f, TextColor)); sumOfBestDeaths += item.Modes[0].BestDeaths; } else if (lobbySilverBerriesObtained) { row.Add(new IconCell("CollabUtils2/golden_strawberry")); } else if (lobbyAllMapsCompletedInSingleRun) { row.Add(new TextCell(Dialog.Deaths(lobbySumOfBestDeaths), TextJustify, 0.5f, TextColor)); } else { row.Add(new IconCell("dot")); } } else { row.Add(new IconCell("dot")); allLevelsDone = false; } if (OuiJournalCollabProgressDashCountMod.IsDashCountEnabled()) { if (lobbyMapLevelSet == null) { if ((OuiJournalCollabProgressDashCountMod.DisplaysTotalDashes() && item.TotalTimePlayed > 0) || item.Modes[0].SingleRunCompleted) { row.Add(new TextCell(Dialog.Deaths(OuiJournalCollabProgressDashCountMod.GetLevelDashesForJournalProgress(item)), TextJustify, 0.5f, TextColor)); sumOfBestDashes += OuiJournalCollabProgressDashCountMod.GetLevelDashesForJournalProgress(item); } else { row.Add(new IconCell("dot")); } } else if ((OuiJournalCollabProgressDashCountMod.DisplaysTotalDashes() && item.TotalTimePlayed > 0) || lobbyAllMapsCompletedInSingleRun) { row.Add(new TextCell(Dialog.Deaths(lobbySumOfBestDashes), TextJustify, 0.5f, TextColor)); } else { row.Add(new IconCell("dot")); } } if (lobbyTotalTime > 0) { row.Add(new TextCell(Dialog.Time(lobbyTotalTime), TextJustify, 0.5f, TextColor)); } else { row.Add(new IconCell("dot")); } if (lobbyMapLevelSet == null) { row.Add(new TextCell("-", TextJustify, 0.5f, TextColor)).Add(null); } else if (lobbySpeedBerryLevel < 4) { if (displaySpeedBerryColumn) { row.Add(new TextCell(Dialog.Time(lobbySumOfBestTimes), TextJustify, 0.5f, getRankColor(lobbySpeedBerryLevel))); row.Add(new IconCell(getRankIcon(lobbySpeedBerryLevel))); sumOfBestTimes += lobbySumOfBestTimes; } else { row.Add(new TextCell(Dialog.Time(lobbySumOfBestTimes), TextJustify, 0.5f, TextColor)).Add(null); sumOfBestTimes += lobbySumOfBestTimes; } } else { row.Add(new IconCell("dot")).Add(null); allSpeedBerriesDone = false; } totalStrawberries += lobbyStrawberries; totalDeaths += lobbyDeaths; sumOfBestDeaths += lobbySumOfBestDeaths; sumOfBestDashes += lobbySumOfBestDashes; totalTime += lobbyTotalTime; allMapsCompletedInSingleRun &= lobbyAllMapsCompletedInSingleRun; if (!lobbyLevelsDone) { allLevelsDone = false; } } } table.AddRow(); Row totalsRow = table.AddRow() .Add(new TextCell(Dialog.Clean("journal_totals"), new Vector2(1f, 0.5f), 0.7f, TextColor)).Add(null) .Add(null) .Add(new TextCell(totalStrawberries.ToString(), TextJustify, 0.6f, TextColor)) .Add(new TextCell(Dialog.Deaths(totalDeaths), TextJustify, 0.6f, TextColor)) .Add(new TextCell(allLevelsDone && allMapsCompletedInSingleRun ? Dialog.Deaths(sumOfBestDeaths) : "-", TextJustify, 0.6f, TextColor)); if (OuiJournalCollabProgressDashCountMod.IsDashCountEnabled()) { totalsRow.Add(new TextCell(OuiJournalCollabProgressDashCountMod.DisplaysTotalDashes() || (allLevelsDone && allMapsCompletedInSingleRun) ? Dialog.Deaths(sumOfBestDashes) : "-", TextJustify, 0.6f, TextColor)); } totalsRow .Add(new TextCell(Dialog.Time(totalTime), TextJustify, 0.6f, TextColor)) .Add(new TextCell(allSpeedBerriesDone ? Dialog.Time(sumOfBestTimes) : "-", TextJustify, 0.6f, TextColor)).Add(null); for (int l = 1; l < SaveData.Instance.UnlockedModes; l++) { totalsRow.Add(null); } totalsRow.Add(new TextCell(Dialog.Time(SaveData.Instance.Time), TextJustify, 0.6f, TextColor)); table.AddRow(); }
public static List <OuiJournalCollabProgressInLobby> GeneratePages(OuiJournal journal, string levelSet, bool showOnlyDiscovered) { bool displaySpeedBerryColumn = shouldDisplaySpeedBerryColumn(levelSet); List <OuiJournalCollabProgressInLobby> pages = new List <OuiJournalCollabProgressInLobby>(); int rowCount = 0; int totalStrawberries = 0; int totalDeaths = 0; int sumOfBestDeaths = 0; int sumOfBestDashes = 0; long totalTime = 0; long sumOfBestTimes = 0; bool allMapsDone = true; bool allLevelsDone = true; bool allSpeedBerriesDone = true; string heartTexture = MTN.Journal.Has("CollabUtils2Hearts/" + levelSet) ? "CollabUtils2Hearts/" + levelSet : "heartgem0"; int mapsPerPage = 12; int mapAmount = SaveData.Instance.Areas_Safe.Where(item => !AreaData.Get(item.ID_Safe).Interlude_Safe && (!showOnlyDiscovered || item.TotalTimePlayed > 0)).Count(); // we want to display the map icons if they're not actually all the same. ^^' bool displayIcons = AreaData.Areas .Where(area => !area.Interlude_Safe) .Select(area => area.Icon) .Distinct() .Count() > 1; OuiJournalCollabProgressInLobby currentPage = new OuiJournalCollabProgressInLobby(journal, levelSet, displayIcons); pages.Add(currentPage); if (mapAmount >= mapsPerPage) { // we want the last page to contain at least 2 maps. while (mapAmount % mapsPerPage < 2) { mapsPerPage--; } } List <AreaStats> sortedMaps = new List <AreaStats>(SaveData.Instance.Areas_Safe) .Where(map => !AreaData.Get(map).Interlude_Safe) .ToList(); // sort maps by icon name if all of their icons start with [number]-... // because then we know the ordering is intentional (and not accidental like easy > hard > medium) Regex startsWithNumber = new Regex(".*/[0-9]+-.*"); if (sortedMaps.Select(map => AreaData.Get(map).Icon ?? "").All(icon => startsWithNumber.IsMatch(icon))) { sortedMaps.Sort((a, b) => { AreaData adata = AreaData.Get(a); AreaData bdata = AreaData.Get(b); bool aHeartSide = LobbyHelper.IsHeartSide(a.GetSID()); bool bHeartSide = LobbyHelper.IsHeartSide(b.GetSID()); // heart sides should appear last. if (aHeartSide && !bHeartSide) { return(1); } if (!aHeartSide && bHeartSide) { return(-1); } // sort by icon name, then by map bin name. return(adata.Icon == bdata.Icon ? adata.Name.CompareTo(bdata.Name) : adata.Icon.CompareTo(bdata.Icon)); }); } foreach (AreaStats item in sortedMaps) { AreaData areaData = AreaData.Get(item.ID_Safe); if (LobbyHelper.IsHeartSide(areaData.GetSID())) { if (allMapsDone || item.TotalTimePlayed > 0) { // add a separator, like the one between regular maps and Farewell currentPage.table.AddRow(); } else { // all maps weren't complete yet, and the heart side was never accessed: hide the heart side for now. continue; } } if (showOnlyDiscovered && item.TotalTimePlayed <= 0) { // skip the map, because it was not discovered yet. // since it wasn't discovered, we can already say all maps weren't done though. allMapsDone = false; allLevelsDone = false; allSpeedBerriesDone = false; continue; } string strawberryText = null; if (areaData.Mode[0].TotalStrawberries > 0 || item.TotalStrawberries > 0) { strawberryText = item.TotalStrawberries.ToString(); if (item.Modes[0].Completed) { strawberryText = strawberryText + "/" + areaData.Mode[0].TotalStrawberries; } } else { strawberryText = "-"; } Row row = currentPage.table.AddRow() .Add(new TextCell(Dialog.Clean(areaData.Name), new Vector2(1f, 0.5f), 0.6f, currentPage.TextColor)); if (displayIcons) { row.Add(null).Add(new IconCellFromGui(GFX.Gui.Has(areaData.Icon) ? areaData.Icon : "areas/null", 60f, 50f)); } row.Add(null) .Add(new IconCell(item.Modes[0].HeartGem ? heartTexture : "dot")) .Add(new TextCell(strawberryText, currentPage.TextJustify, 0.5f, currentPage.TextColor)); if (item.TotalTimePlayed > 0) { row.Add(new TextCell(Dialog.Deaths(item.Modes[0].Deaths), currentPage.TextJustify, 0.5f, currentPage.TextColor)); } else { row.Add(new IconCell("dot")); } AreaStats stats = SaveData.Instance.GetAreaStatsFor(areaData.ToKey()); if (CollabMapDataProcessor.SilverBerries.TryGetValue(areaData.GetLevelSet(), out Dictionary <string, EntityID> levelSetBerries) && levelSetBerries.TryGetValue(areaData.GetSID(), out EntityID berryID) && stats.Modes[0].Strawberries.Contains(berryID)) { // silver berry was obtained! row.Add(new IconCell("CollabUtils2/silver_strawberry")); } else if (stats.Modes[0].Strawberries.Any(berry => areaData.Mode[0].MapData.Goldenberries.Any(golden => golden.ID == berry.ID && golden.Level.Name == berry.Level))) { // golden berry was obtained! row.Add(new IconCell("CollabUtils2/golden_strawberry")); } else if (item.Modes[0].SingleRunCompleted) { row.Add(new TextCell(Dialog.Deaths(item.Modes[0].BestDeaths), currentPage.TextJustify, 0.5f, currentPage.TextColor)); sumOfBestDeaths += item.Modes[0].BestDeaths; } else { // the player didn't ever do a single run. row.Add(new IconCell("dot")); allLevelsDone = false; } if (OuiJournalCollabProgressDashCountMod.IsDashCountEnabled()) { if ((OuiJournalCollabProgressDashCountMod.DisplaysTotalDashes() && item.TotalTimePlayed > 0) || item.Modes[0].SingleRunCompleted) { row.Add(new TextCell(Dialog.Deaths(OuiJournalCollabProgressDashCountMod.GetLevelDashesForJournalProgress(item)), currentPage.TextJustify, 0.5f, currentPage.TextColor)); sumOfBestDashes += OuiJournalCollabProgressDashCountMod.GetLevelDashesForJournalProgress(item); } else { row.Add(new IconCell("dot")); } } if (item.TotalTimePlayed > 0) { row.Add(new TextCell(Dialog.Time(item.TotalTimePlayed), currentPage.TextJustify, 0.5f, currentPage.TextColor)); } else { row.Add(new IconCell("dot")); } if (displaySpeedBerryColumn) { if (CollabMapDataProcessor.SpeedBerries.TryGetValue(item.GetSID(), out CollabMapDataProcessor.SpeedBerryInfo speedBerryInfo) && CollabModule.Instance.SaveData.SpeedBerryPBs.TryGetValue(item.GetSID(), out long speedBerryPB)) { row.Add(new TextCell(Dialog.Time(speedBerryPB), currentPage.TextJustify, 0.5f, getRankColor(speedBerryInfo, speedBerryPB))); row.Add(new IconCell(getRankIcon(speedBerryInfo, speedBerryPB))); sumOfBestTimes += speedBerryPB; } else { row.Add(new IconCell("dot")).Add(null); allSpeedBerriesDone = false; } } else { if (item.Modes[0].BestTime > 0f) { row.Add(new TextCell(Dialog.Time(item.Modes[0].BestTime), currentPage.TextJustify, 0.5f, currentPage.TextColor)).Add(null); sumOfBestTimes += item.Modes[0].BestTime; } else { row.Add(new IconCell("dot")).Add(null); allSpeedBerriesDone = false; } } totalStrawberries += item.TotalStrawberries; totalDeaths += item.Modes[0].Deaths; totalTime += item.TotalTimePlayed; if (!item.Modes[0].HeartGem) { allMapsDone = false; } rowCount++; if (rowCount >= mapsPerPage) { // split the next zones into another page. rowCount = 0; currentPage = new OuiJournalCollabProgressInLobby(journal, levelSet, displayIcons); pages.Add(currentPage); } } if (currentPage.table.Rows > 1) { currentPage.table.AddRow(); Row totalsRow = currentPage.table.AddRow() .Add(new TextCell(Dialog.Clean("journal_totals"), new Vector2(1f, 0.5f), 0.7f, currentPage.TextColor)).Add(null); if (displayIcons) { totalsRow.Add(null).Add(null); } totalsRow.Add(null) .Add(new TextCell(totalStrawberries.ToString(), currentPage.TextJustify, 0.6f, currentPage.TextColor)) .Add(new TextCell(Dialog.Deaths(totalDeaths), currentPage.TextJustify, 0.6f, currentPage.TextColor)) .Add(new TextCell(allLevelsDone ? Dialog.Deaths(sumOfBestDeaths) : "-", currentPage.TextJustify, 0.6f, currentPage.TextColor)); if (OuiJournalCollabProgressDashCountMod.IsDashCountEnabled()) { totalsRow.Add(new TextCell(OuiJournalCollabProgressDashCountMod.DisplaysTotalDashes() || allLevelsDone ? Dialog.Deaths(sumOfBestDashes) : "-", currentPage.TextJustify, 0.6f, currentPage.TextColor)); } totalsRow .Add(new TextCell(Dialog.Time(totalTime), currentPage.TextJustify, 0.6f, currentPage.TextColor)) .Add(new TextCell(allSpeedBerriesDone ? Dialog.Time(sumOfBestTimes) : "-", currentPage.TextJustify, 0.6f, currentPage.TextColor)).Add(null); for (int l = 1; l < SaveData.Instance.UnlockedModes; l++) { totalsRow.Add(null); } totalsRow.Add(new TextCell(Dialog.Time(SaveData.Instance.Time), currentPage.TextJustify, 0.6f, currentPage.TextColor)); currentPage.table.AddRow(); } return(pages); }