v1.0.8.24: Context menu visibility fix; Duty List objectives match by quest name

Made-with: Cursor
This commit is contained in:
2026-03-04 21:31:22 -05:00
parent 293f83dc36
commit 7c46a50b7e
8 changed files with 53 additions and 17 deletions
+25
View File
@@ -0,0 +1,25 @@
using HSUI.Interface;
namespace HSUI.Helpers
{
/// <summary>
/// Tracks which HUD element currently has its context menu open, so visibility can be ignored for that element
/// while the menu is open (e.g. "hide unless hovered" would otherwise hide the element when the mouse moves to the menu).
/// </summary>
public static class ContextMenuVisibilityHelper
{
private static HudElement? _elementWithContextMenuOpen;
/// <summary>Call when opening a context menu for this element.</summary>
public static void SetContextMenuOpen(HudElement? element)
{
_elementWithContextMenuOpen = element;
}
/// <summary>True if the given element currently has its context menu open.</summary>
public static bool IsContextMenuOpenFor(HudElement element)
{
return _elementWithContextMenuOpen != null && _elementWithContextMenuOpen == element;
}
}
}
+13 -12
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.</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 by quest name to avoid wrong objectives when array order differs from NormalQuests order.</summary>
private static unsafe void TryFillObjectivesFromToDoListStringArray(List<DutyListEntry> result)
{
if (result.Count == 0) return;
@@ -229,20 +229,21 @@ namespace HSUI.Helpers
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 = "";
if (i < questCount)
obj = ReadSlot(questCount + i).Trim();
if (string.IsNullOrWhiteSpace(obj))
int titleIdx = -1;
for (int j = 0; j < questCount; j++)
{
int titleIdx = -1;
for (int j = 0; j < questCount; j++)
{
if (string.Equals(ReadSlot(j).Trim(), entry.QuestName, StringComparison.OrdinalIgnoreCase))
{ titleIdx = j; break; }
}
if (titleIdx >= 0)
obj = ReadSlot(questCount + titleIdx).Trim();
if (string.Equals(ReadSlot(j).Trim(), entry.QuestName, 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 };
}