using System; using System.Collections.Generic; using System.Linq; using Dalamud.Plugin.Services; using Lumina.Excel.Sheets; using Microsoft.Extensions.Logging; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Data; internal sealed class JournalData { internal sealed class Genre { public uint Id { get; } public string Name { get; } public uint CategoryId { get; } public List Quests { get; } public bool IsUnderOtherQuests { get; set; } public Genre(JournalGenre journalGenre, List quests) { Id = journalGenre.RowId; Name = journalGenre.Name.ToString(); CategoryId = journalGenre.JournalCategory.RowId; Quests = quests; IsUnderOtherQuests = false; } public Genre(uint id, string name, uint categoryId, List quests) { Id = id; Name = name; CategoryId = categoryId; Quests = quests; IsUnderOtherQuests = false; } public Genre(uint id, string name, uint categoryId, List quests, bool isUnderOtherQuests = false) { Id = id; Name = name; CategoryId = categoryId; Quests = quests; IsUnderOtherQuests = isUnderOtherQuests; } } internal sealed class Category { public uint Id { get; } = journalCategory.RowId; public string Name { get; } = journalCategory.Name.ToString(); public uint SectionId { get; } = journalCategory.JournalSection.RowId; public IReadOnlyList Genres { get; } public Category(JournalCategory journalCategory, IReadOnlyList genres) { Genres = genres; base._002Ector(); } } internal sealed class Section { public uint Id { get; } = journalSection.RowId; public string Name { get; } = journalSection.Name.ToString(); public IReadOnlyList Categories { get; } public Section(JournalSection journalSection, IReadOnlyList categories) { Categories = categories; base._002Ector(); } } private readonly ILogger _logger; public List Genres { get; } public List Categories { get; } public List
Sections { get; } public int? OtherQuestsSectionRowId { get; private set; } public JournalData(IDataManager dataManager, QuestData questData, ILogger logger) { JournalData journalData = this; _logger = logger; List list = (from x in dataManager.GetExcelSheet() where x.RowId != 0 && x.Icon > 0 select new Genre(x, questData.GetAllByJournalGenre(x.RowId))).ToList(); QuestRedo row = dataManager.GetExcelSheet().GetRow(1u); QuestRedo row2 = dataManager.GetExcelSheet().GetRow(2u); QuestRedo row3 = dataManager.GetExcelSheet().GetRow(3u); Genre genreLimsa = new Genre(4294967292u, "Starting in Limsa Lominsa", 1u, (from x in new uint[2] { 108u, 109u }.Concat(row.QuestRedoParam.Select((QuestRedo.QuestRedoParamStruct x) => x.Quest.RowId)) where x != 0 select questData.GetQuestInfo(QuestId.FromRowId(x))).ToList()); Genre genreGridania = new Genre(4294967293u, "Starting in Gridania", 1u, (from x in new uint[3] { 85u, 123u, 124u }.Concat(row2.QuestRedoParam.Select((QuestRedo.QuestRedoParamStruct x) => x.Quest.RowId)) where x != 0 select questData.GetQuestInfo(QuestId.FromRowId(x))).ToList()); Genre genreUldah = new Genre(4294967294u, "Starting in Ul'dah", 1u, (from x in new uint[3] { 568u, 569u, 570u }.Concat(row3.QuestRedoParam.Select((QuestRedo.QuestRedoParamStruct x) => x.Quest.RowId)) where x != 0 select questData.GetQuestInfo(QuestId.FromRowId(x))).ToList()); list.InsertRange(0, new Genre[3] { genreLimsa, genreGridania, genreUldah }); list.Single((Genre x) => x.Id == 1).Quests.RemoveAll((IQuestInfo x) => genreLimsa.Quests.Contains(x) || genreGridania.Quests.Contains(x) || genreUldah.Quests.Contains(x)); Genres = list.ToList(); Categories = (from x in dataManager.GetExcelSheet() where x.RowId != 0 select new Category(x, journalData.Genres.Where((Genre y) => y.CategoryId == x.RowId).ToList())).ToList(); Sections = (from x in dataManager.GetExcelSheet() select new Section(x, journalData.Categories.Where((Category y) => y.SectionId == x.RowId).ToList())).ToList(); _logger.LogDebug("Resolving OtherQuests section id..."); OtherQuestsSectionRowId = GetOtherQuestsSectionRowId(dataManager); _logger.LogDebug("Resolved OtherQuestsSectionRowId = {Id}", OtherQuestsSectionRowId); int? otherQuestsSectionRowId = OtherQuestsSectionRowId; if (otherQuestsSectionRowId.HasValue) { int valueOrDefault = otherQuestsSectionRowId.GetValueOrDefault(); uint otherIdU = (uint)valueOrDefault; Section section = Sections.FirstOrDefault((Section s) => s.Id == otherIdU); if (section != null) { int num = 0; foreach (Category category in section.Categories) { foreach (Genre genre in category.Genres) { genre.IsUnderOtherQuests = true; num++; } } _logger.LogInformation("Marked {Count} genres as under 'Other Quests' (section id {Id})", num, valueOrDefault); } else { _logger.LogWarning("OtherQuestsSectionRowId {Id} found but matching Section not present in constructed Sections", valueOrDefault); } } else { _logger.LogDebug("OtherQuestsSectionRowId not found - falling back to localized name lookup when necessary"); } } private int? GetOtherQuestsSectionRowId(IDataManager dataManager) { JournalSection journalSection = dataManager.GetExcelSheet().FirstOrDefault((JournalSection s) => s.Name.ToString() == "Other Quests"); int? result = ((journalSection.RowId != 0) ? new int?((int)journalSection.RowId) : ((int?)null)); if (!result.HasValue) { Section section = Sections.FirstOrDefault((Section s) => s.Name.Equals("Other Quests", StringComparison.OrdinalIgnoreCase)); if (section != null) { result = (int)section.Id; } } return result; } }