v1.0.8.25: Duty List objectives — match by name only, prefer game string array

Made-with: Cursor
This commit is contained in:
2026-03-04 21:40:02 -05:00
parent 7c46a50b7e
commit bd9164c896
5 changed files with 29 additions and 14 deletions
+21 -9
View File
@@ -198,7 +198,7 @@ namespace HSUI.Helpers
return false;
}
/// <summary>Read objective text from the game's ToDoList string array (same data the default Duty List UI uses). Layout: titles at 0..QuestCount-1, details at QuestCount..2*QuestCount-1. Pairs by quest name to avoid wrong objectives when array order differs from NormalQuests order.</summary>
/// <summary>Read objective text from the game's ToDoList string array (same data the default Duty List UI uses). Layout: titles at 0..QuestCount-1, details at QuestCount..2*QuestCount-1. Pairs only by quest name (or fuzzy match) so we never assign the wrong objective when array order differs from NormalQuests.</summary>
private static unsafe void TryFillObjectivesFromToDoListStringArray(List<DutyListEntry> result)
{
if (result.Count == 0) return;
@@ -227,23 +227,35 @@ namespace HSUI.Helpers
for (int i = 0; i < result.Count; i++)
{
var entry = result[i];
if (!string.IsNullOrWhiteSpace(entry.ObjectiveText)) continue;
// Prefer matching by quest name: game's string array order can differ from NormalQuests order (e.g. display order), so index-based pairing can assign wrong objectives to the top entries.
string obj = "";
int titleIdx = -1;
var questNameTrim = entry.QuestName.Trim();
if (string.IsNullOrWhiteSpace(questNameTrim)) continue;
// Exact match first (case-insensitive)
for (int j = 0; j < questCount; j++)
{
if (string.Equals(ReadSlot(j).Trim(), entry.QuestName, StringComparison.OrdinalIgnoreCase))
var title = ReadSlot(j).Trim();
if (string.Equals(title, questNameTrim, StringComparison.OrdinalIgnoreCase))
{ titleIdx = j; break; }
}
// Fuzzy match for truncated/abbreviated names: game may shorten the title in the array
if (titleIdx < 0)
{
for (int j = 0; j < questCount; j++)
{
var title = ReadSlot(j).Trim();
if (string.IsNullOrWhiteSpace(title)) continue;
if (title.StartsWith(questNameTrim, StringComparison.OrdinalIgnoreCase) ||
questNameTrim.StartsWith(title, StringComparison.OrdinalIgnoreCase))
{ titleIdx = j; break; }
}
}
if (titleIdx >= 0)
obj = ReadSlot(questCount + titleIdx).Trim();
// Fallback: use index when name match failed (e.g. trimmed name difference or empty slot)
if (string.IsNullOrWhiteSpace(obj) && i < questCount)
obj = ReadSlot(questCount + i).Trim();
if (string.IsNullOrWhiteSpace(obj)) continue;
result[i] = entry with { ObjectiveText = obj };
}