230 lines
6.6 KiB
C#
230 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Dalamud.Plugin.Services;
|
|
using Lumina.Excel;
|
|
using Lumina.Excel.Sheets;
|
|
|
|
namespace QuestionableCompanion.Services;
|
|
|
|
public class EventQuestResolver
|
|
{
|
|
private readonly IDataManager dataManager;
|
|
|
|
private readonly IPluginLog log;
|
|
|
|
public EventQuestResolver(IDataManager dataManager, IPluginLog log)
|
|
{
|
|
this.dataManager = dataManager;
|
|
this.log = log;
|
|
}
|
|
|
|
public List<string> ResolveEventQuestDependencies(string eventQuestId)
|
|
{
|
|
List<string> dependencies = new List<string>();
|
|
ExcelSheet<Quest> questSheet = dataManager.GetExcelSheet<Quest>();
|
|
log.Information("[EventQuestResolver] Searching for quest with ID string: '" + eventQuestId + "'");
|
|
Quest? foundQuest = null;
|
|
foreach (Quest q in questSheet)
|
|
{
|
|
if (q.RowId != 0)
|
|
{
|
|
string questIdField = q.Id.ExtractText();
|
|
if (questIdField == eventQuestId || questIdField.EndsWith("_" + eventQuestId) || questIdField.EndsWith("_" + eventQuestId.PadLeft(5, '0')))
|
|
{
|
|
foundQuest = q;
|
|
log.Information($"[EventQuestResolver] Found quest by ID field: '{questIdField}' (searched for '{eventQuestId}')");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!foundQuest.HasValue || foundQuest.Value.RowId == 0)
|
|
{
|
|
log.Error("[EventQuestResolver] Quest with ID '" + eventQuestId + "' not found in Lumina");
|
|
return dependencies;
|
|
}
|
|
Quest quest = foundQuest.Value;
|
|
string questName = quest.Name.ExtractText();
|
|
log.Information($"[EventQuestResolver] Found quest: RowId={quest.RowId}, Name='{questName}', ID='{quest.Id.ExtractText()}'");
|
|
try
|
|
{
|
|
foreach (RowRef<Quest> prevQuestRef in quest.PreviousQuest)
|
|
{
|
|
if (prevQuestRef.RowId == 0)
|
|
{
|
|
continue;
|
|
}
|
|
Quest prevQuest = questSheet.GetRow(prevQuestRef.RowId);
|
|
if (prevQuest.RowId != 0)
|
|
{
|
|
string prevQuestName = prevQuest.Name.ExtractText();
|
|
string prevQuestIdString = prevQuest.Id.ExtractText();
|
|
string[] idParts = prevQuestIdString.Split('_');
|
|
string questIdNumber = ((idParts.Length > 1) ? idParts[1].TrimStart('0') : prevQuestIdString);
|
|
if (string.IsNullOrEmpty(questIdNumber))
|
|
{
|
|
questIdNumber = "0";
|
|
}
|
|
dependencies.Add(questIdNumber);
|
|
log.Information($"[EventQuestResolver] Found previous quest: RowId={prevQuestRef.RowId}, Name='{prevQuestName}', ID='{prevQuestIdString}' -> '{questIdNumber}'");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Warning("[EventQuestResolver] Error reading PreviousQuest: " + ex.Message);
|
|
}
|
|
try
|
|
{
|
|
foreach (RowRef<Quest> questLockRef in quest.QuestLock)
|
|
{
|
|
if (questLockRef.RowId == 0)
|
|
{
|
|
continue;
|
|
}
|
|
Quest lockQuest = questSheet.GetRow(questLockRef.RowId);
|
|
if (lockQuest.RowId != 0)
|
|
{
|
|
string lockQuestIdString = lockQuest.Id.ExtractText();
|
|
string[] idParts2 = lockQuestIdString.Split('_');
|
|
string questIdNumber2 = ((idParts2.Length > 1) ? idParts2[1].TrimStart('0') : lockQuestIdString);
|
|
if (string.IsNullOrEmpty(questIdNumber2))
|
|
{
|
|
questIdNumber2 = "0";
|
|
}
|
|
dependencies.Add(questIdNumber2);
|
|
log.Information($"[EventQuestResolver] Found quest lock: RowId={questLockRef.RowId}, ID='{lockQuestIdString}' -> '{questIdNumber2}'");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
log.Warning("[EventQuestResolver] Error reading QuestLock: " + ex2.Message);
|
|
}
|
|
dependencies = dependencies.Distinct().ToList();
|
|
log.Information($"[EventQuestResolver] Found {dependencies.Count} direct prerequisites");
|
|
if (dependencies.Count > 0)
|
|
{
|
|
log.Information("[EventQuestResolver] Event Quest " + eventQuestId + " requires: " + string.Join(", ", dependencies));
|
|
}
|
|
else
|
|
{
|
|
log.Information("[EventQuestResolver] Event Quest " + eventQuestId + " has no prerequisites");
|
|
}
|
|
return dependencies;
|
|
}
|
|
|
|
public bool IsValidQuest(string questId, out string classification)
|
|
{
|
|
string rawId = QuestIdParser.ParseQuestId(questId).rawId;
|
|
if (QuestIdParser.ClassifyQuestId(questId) == QuestIdType.EventQuest)
|
|
{
|
|
classification = "EventQuest";
|
|
log.Debug("[EventQuestResolver] Quest " + questId + " recognized as Event Quest (prefix detected)");
|
|
return true;
|
|
}
|
|
if (!uint.TryParse(rawId, out var questIdUint))
|
|
{
|
|
classification = "Invalid";
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
Quest quest = dataManager.GetExcelSheet<Quest>().GetRow(questIdUint);
|
|
if (quest.RowId != 0)
|
|
{
|
|
classification = "Standard";
|
|
log.Debug($"[EventQuestResolver] Quest {questId} found in Excel Sheet (RowId: {quest.RowId})");
|
|
return true;
|
|
}
|
|
classification = "NotFound";
|
|
return false;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Debug("[EventQuestResolver] Error checking quest availability: " + ex.Message);
|
|
classification = "Error";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool IsQuestAvailable(string questId)
|
|
{
|
|
string classification;
|
|
return IsValidQuest(questId, out classification);
|
|
}
|
|
|
|
public string GetQuestName(string questId)
|
|
{
|
|
string rawId = QuestIdParser.ParseQuestId(questId).rawId;
|
|
QuestIdType questType = QuestIdParser.ClassifyQuestId(questId);
|
|
if (!uint.TryParse(rawId, out var questIdUint))
|
|
{
|
|
if (questType == QuestIdType.EventQuest)
|
|
{
|
|
return "Event Quest " + questId;
|
|
}
|
|
return "Unknown Quest (" + questId + ")";
|
|
}
|
|
try
|
|
{
|
|
Quest quest = dataManager.GetExcelSheet<Quest>().GetRow(questIdUint);
|
|
if (quest.RowId != 0)
|
|
{
|
|
string name = quest.Name.ExtractText();
|
|
if (!string.IsNullOrEmpty(name))
|
|
{
|
|
if (questType == QuestIdType.EventQuest)
|
|
{
|
|
return name + " (" + questId + ")";
|
|
}
|
|
return name;
|
|
}
|
|
}
|
|
if (questType == QuestIdType.EventQuest)
|
|
{
|
|
return "Event Quest " + questId;
|
|
}
|
|
return "Quest " + questId;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
if (questType == QuestIdType.EventQuest)
|
|
{
|
|
return "Event Quest " + questId;
|
|
}
|
|
return "Quest " + questId;
|
|
}
|
|
}
|
|
|
|
public List<(string QuestId, string QuestName)> GetAvailableEventQuests()
|
|
{
|
|
List<(string, string)> eventQuests = new List<(string, string)>();
|
|
try
|
|
{
|
|
ExcelSheet<Quest> questSheet = dataManager.GetExcelSheet<Quest>();
|
|
if (questSheet == null)
|
|
{
|
|
log.Error("[EventQuestResolver] Failed to load Quest sheet");
|
|
return eventQuests;
|
|
}
|
|
foreach (Quest quest in questSheet)
|
|
{
|
|
if (quest.RowId != 0 && quest.JournalGenre.RowId == 9)
|
|
{
|
|
string questName = quest.Name.ExtractText();
|
|
if (!string.IsNullOrEmpty(questName))
|
|
{
|
|
eventQuests.Add((quest.RowId.ToString(), questName));
|
|
}
|
|
}
|
|
}
|
|
log.Information($"[EventQuestResolver] Found {eventQuests.Count} event quests");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[EventQuestResolver] Error getting event quests: " + ex.Message);
|
|
}
|
|
return eventQuests.OrderBy(((string, string) q) => q.Item2).ToList();
|
|
}
|
|
}
|