muffin v7.38.2

This commit is contained in:
alydev 2025-11-19 12:01:37 +10:00
parent 0336b9c9e9
commit bbc394c386
10 changed files with 737 additions and 437 deletions

View file

@ -1606,6 +1606,11 @@
"type": "string" "type": "string"
} }
}, },
"DutyMode": {
"type": "integer",
"description": "Overrides the default duty mode for this specific duty. 0 = Duty Support, 1 = Unsync (Solo), 2 = Unsync (Party). If not specified, uses the global configuration setting.",
"enum": [0, 1, 2]
},
"TestedAutoDutyVersion": { "TestedAutoDutyVersion": {
"type": "string", "type": "string",
"pattern": "^0\\.\\d+\\.\\d+\\.\\d+$" "pattern": "^0\\.\\d+\\.\\d+\\.\\d+$"
@ -1625,7 +1630,8 @@
"required": [ "required": [
"ContentFinderConditionId", "ContentFinderConditionId",
"Enabled" "Enabled"
] ],
"additionalProperties": false
}, },
"DataId": { "DataId": {
"type": "null" "type": "null"

View file

@ -35792,7 +35792,7 @@ public static class AssemblyQuestLoader
CollectionsMarshal.SetCount(list33, num2); CollectionsMarshal.SetCount(list33, num2);
span3 = CollectionsMarshal.AsSpan(list33); span3 = CollectionsMarshal.AsSpan(list33);
index2 = 0; index2 = 0;
span3[index2] = new QuestStep(EInteractionType.AcceptQuest, 1002236u, new Vector3(185.10718f, 14.095934f, 677.33264f), 135) span3[index2] = new QuestStep(EInteractionType.CompleteQuest, 1002236u, new Vector3(185.10718f, 14.095934f, 677.33264f), 135)
{ {
AetheryteShortcut = EAetheryteLocation.LowerLaNosceaMorabyDrydocks AetheryteShortcut = EAetheryteLocation.LowerLaNosceaMorabyDrydocks
}; };

View file

@ -11,4 +11,6 @@ public class DutyOptions
public bool LowPriority { get; set; } public bool LowPriority { get; set; }
public List<string> Notes { get; set; } = new List<string>(); public List<string> Notes { get; set; } = new List<string>();
public EDutyMode? DutyMode { get; set; }
} }

View file

@ -0,0 +1,8 @@
namespace Questionable.Model.Questing;
public enum EDutyMode
{
Support,
UnsyncSolo,
UnsyncParty
}

View file

@ -3,7 +3,9 @@ using System.Collections.Generic;
using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Conditions;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Group;
using LLib.Gear; using LLib.Gear;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Common; using Questionable.Controller.Steps.Common;
using Questionable.Controller.Steps.Shared; using Questionable.Controller.Steps.Shared;
using Questionable.Controller.Utils; using Questionable.Controller.Utils;
@ -17,7 +19,7 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class Duty internal static class Duty
{ {
internal sealed class Factory(AutoDutyIpc autoDutyIpc) : ITaskFactory internal sealed class Factory(AutoDutyIpc autoDutyIpc, Configuration configuration) : ITaskFactory
{ {
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{ {
@ -26,36 +28,94 @@ internal static class Duty
yield break; yield break;
} }
ArgumentNullException.ThrowIfNull(step.DutyOptions, "step.DutyOptions"); ArgumentNullException.ThrowIfNull(step.DutyOptions, "step.DutyOptions");
uint contentFinderConditionId;
int dutyMode;
if (autoDutyIpc.IsConfiguredToRunContent(step.DutyOptions)) if (autoDutyIpc.IsConfiguredToRunContent(step.DutyOptions))
{ {
contentFinderConditionId = step.DutyOptions.ContentFinderConditionId; AutoDutyIpc.DutyMode dutyMode = GetDutyMode(step.DutyOptions.ContentFinderConditionId, step.DutyOptions.DutyMode);
ElementId id = quest.Id; if (dutyMode == AutoDutyIpc.DutyMode.UnsyncRegular && (step.DutyOptions.DutyMode == EDutyMode.UnsyncParty || (!step.DutyOptions.DutyMode.HasValue && configuration.Duties.DutyModeOverrides.TryGetValue(step.DutyOptions.ContentFinderConditionId, out var value) && value == EDutyMode.UnsyncParty) || (!step.DutyOptions.DutyMode.HasValue && !configuration.Duties.DutyModeOverrides.ContainsKey(step.DutyOptions.ContentFinderConditionId) && configuration.Duties.DefaultDutyMode == EDutyMode.UnsyncParty)))
if (id is QuestId)
{ {
ushort value = id.Value; yield return new WaitForPartyTask();
if (value >= 357 && value <= 360) }
{ yield return new StartAutoDutyTask(step.DutyOptions.ContentFinderConditionId, dutyMode);
dutyMode = 2; yield return new WaitAutoDutyTask(step.DutyOptions.ContentFinderConditionId);
goto IL_00b2; if (!QuestWorkUtils.HasCompletionFlags(step.CompletionQuestVariablesFlags))
} {
yield return new WaitAtEnd.WaitNextStepOrSequence();
} }
dutyMode = 1;
goto IL_00b2;
} }
if (!step.DutyOptions.LowPriority) else if (!step.DutyOptions.LowPriority)
{ {
yield return new OpenDutyFinderTask(step.DutyOptions.ContentFinderConditionId); yield return new OpenDutyFinderTask(step.DutyOptions.ContentFinderConditionId);
} }
yield break; }
IL_00b2:
yield return new StartAutoDutyTask(contentFinderConditionId, (AutoDutyIpc.DutyMode)dutyMode); private AutoDutyIpc.DutyMode GetDutyMode(uint cfcId, EDutyMode? stepDutyMode)
yield return new WaitAutoDutyTask(step.DutyOptions.ContentFinderConditionId); {
if (!QuestWorkUtils.HasCompletionFlags(step.CompletionQuestVariablesFlags)) if (stepDutyMode.HasValue)
{ {
yield return new WaitAtEnd.WaitNextStepOrSequence(); return ConvertToAutoDutyMode(stepDutyMode.Value);
} }
if (configuration.Duties.DutyModeOverrides.TryGetValue(cfcId, out var value))
{
return ConvertToAutoDutyMode(value);
}
return ConvertToAutoDutyMode(configuration.Duties.DefaultDutyMode);
}
private static AutoDutyIpc.DutyMode ConvertToAutoDutyMode(EDutyMode mode)
{
return mode switch
{
EDutyMode.Support => AutoDutyIpc.DutyMode.Support,
EDutyMode.UnsyncSolo => AutoDutyIpc.DutyMode.UnsyncRegular,
EDutyMode.UnsyncParty => AutoDutyIpc.DutyMode.UnsyncRegular,
_ => AutoDutyIpc.DutyMode.Support,
};
}
}
internal sealed record WaitForPartyTask : ITask
{
public override string ToString()
{
return "WaitForParty";
}
}
internal sealed class WaitForPartyExecutor(IChatGui chatGui, ILogger<WaitForPartyExecutor> logger) : TaskExecutor<WaitForPartyTask>()
{
private DateTime _lastWarningTime = DateTime.MinValue;
protected override bool Start()
{
logger.LogInformation("Waiting for party members before starting duty...");
return true;
}
public unsafe override ETaskResult Update()
{
GroupManager* ptr = GroupManager.Instance();
if (ptr == null)
{
return ETaskResult.StillRunning;
}
byte memberCount = ptr->MainGroup.MemberCount;
bool isAlliance = ptr->MainGroup.IsAlliance;
if (memberCount > 1 || isAlliance)
{
logger.LogInformation("Party detected with {MemberCount} members, proceeding with duty", memberCount);
return ETaskResult.TaskComplete;
}
if (DateTime.Now - _lastWarningTime > TimeSpan.FromSeconds(10L))
{
chatGui.Print("[Questionable] Waiting for party members before starting duty (Unsync Party mode)...", "Questionable", 576);
_lastWarningTime = DateTime.Now;
}
return ETaskResult.StillRunning;
}
public override bool ShouldInterruptOnDamage()
{
return false;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -72,6 +72,18 @@ internal sealed class QuestionableIpc : IDisposable
private const string IpcExportQuestPriority = "Questionable.ExportQuestPriority"; private const string IpcExportQuestPriority = "Questionable.ExportQuestPriority";
private const string IpcGetDefaultDutyMode = "Questionable.GetDefaultDutyMode";
private const string IpcSetDefaultDutyMode = "Questionable.SetDefaultDutyMode";
private const string IpcGetDutyModeOverride = "Questionable.GetDutyModeOverride";
private const string IpcSetDutyModeOverride = "Questionable.SetDutyModeOverride";
private const string IpcClearDutyModeOverride = "Questionable.ClearDutyModeOverride";
private const string IpcClearAllDutyModeOverrides = "Questionable.ClearAllDutyModeOverrides";
private readonly QuestController _questController; private readonly QuestController _questController;
private readonly QuestRegistry _questRegistry; private readonly QuestRegistry _questRegistry;
@ -80,6 +92,10 @@ internal sealed class QuestionableIpc : IDisposable
private readonly ManualPriorityComponent _manualPriorityComponent; private readonly ManualPriorityComponent _manualPriorityComponent;
private readonly Configuration _configuration;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly ICallGateProvider<bool> _isRunning; private readonly ICallGateProvider<bool> _isRunning;
private readonly ICallGateProvider<string?> _getCurrentQuestId; private readonly ICallGateProvider<string?> _getCurrentQuestId;
@ -114,13 +130,27 @@ internal sealed class QuestionableIpc : IDisposable
private readonly ICallGateProvider<string> _exportQuestPriority; private readonly ICallGateProvider<string> _exportQuestPriority;
public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, ManualPriorityComponent manualPriorityComponent, IDalamudPluginInterface pluginInterface) private readonly ICallGateProvider<int> _getDefaultDutyMode;
private readonly ICallGateProvider<int, bool> _setDefaultDutyMode;
private readonly ICallGateProvider<uint, int> _getDutyModeOverride;
private readonly ICallGateProvider<uint, int, bool> _setDutyModeOverride;
private readonly ICallGateProvider<uint, bool> _clearDutyModeOverride;
private readonly ICallGateProvider<bool> _clearAllDutyModeOverrides;
public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, ManualPriorityComponent manualPriorityComponent, Configuration configuration, IDalamudPluginInterface pluginInterface)
{ {
QuestionableIpc questionableIpc = this; QuestionableIpc questionableIpc = this;
_questController = questController; _questController = questController;
_questRegistry = questRegistry; _questRegistry = questRegistry;
_questFunctions = questFunctions; _questFunctions = questFunctions;
_manualPriorityComponent = manualPriorityComponent; _manualPriorityComponent = manualPriorityComponent;
_configuration = configuration;
_pluginInterface = pluginInterface;
_isRunning = pluginInterface.GetIpcProvider<bool>("Questionable.IsRunning"); _isRunning = pluginInterface.GetIpcProvider<bool>("Questionable.IsRunning");
_isRunning.RegisterFunc(() => questController.AutomationType != QuestController.EAutomationType.Manual || questController.IsRunning); _isRunning.RegisterFunc(() => questController.AutomationType != QuestController.EAutomationType.Manual || questController.IsRunning);
_getCurrentQuestId = pluginInterface.GetIpcProvider<string>("Questionable.GetCurrentQuestId"); _getCurrentQuestId = pluginInterface.GetIpcProvider<string>("Questionable.GetCurrentQuestId");
@ -156,6 +186,18 @@ internal sealed class QuestionableIpc : IDisposable
_insertQuestPriority.RegisterFunc(InsertQuestPriority); _insertQuestPriority.RegisterFunc(InsertQuestPriority);
_exportQuestPriority = pluginInterface.GetIpcProvider<string>("Questionable.ExportQuestPriority"); _exportQuestPriority = pluginInterface.GetIpcProvider<string>("Questionable.ExportQuestPriority");
_exportQuestPriority.RegisterFunc(_manualPriorityComponent.EncodeQuestPriority); _exportQuestPriority.RegisterFunc(_manualPriorityComponent.EncodeQuestPriority);
_getDefaultDutyMode = pluginInterface.GetIpcProvider<int>("Questionable.GetDefaultDutyMode");
_getDefaultDutyMode.RegisterFunc(GetDefaultDutyMode);
_setDefaultDutyMode = pluginInterface.GetIpcProvider<int, bool>("Questionable.SetDefaultDutyMode");
_setDefaultDutyMode.RegisterFunc(SetDefaultDutyMode);
_getDutyModeOverride = pluginInterface.GetIpcProvider<uint, int>("Questionable.GetDutyModeOverride");
_getDutyModeOverride.RegisterFunc(GetDutyModeOverride);
_setDutyModeOverride = pluginInterface.GetIpcProvider<uint, int, bool>("Questionable.SetDutyModeOverride");
_setDutyModeOverride.RegisterFunc(SetDutyModeOverride);
_clearDutyModeOverride = pluginInterface.GetIpcProvider<uint, bool>("Questionable.ClearDutyModeOverride");
_clearDutyModeOverride.RegisterFunc(ClearDutyModeOverride);
_clearAllDutyModeOverrides = pluginInterface.GetIpcProvider<bool>("Questionable.ClearAllDutyModeOverrides");
_clearAllDutyModeOverrides.RegisterFunc(ClearAllDutyModeOverrides);
} }
private bool StartQuest(string questId, bool single) private bool StartQuest(string questId, bool single)
@ -296,8 +338,67 @@ internal sealed class QuestionableIpc : IDisposable
return true; return true;
} }
private int GetDefaultDutyMode()
{
return (int)_configuration.Duties.DefaultDutyMode;
}
private bool SetDefaultDutyMode(int dutyMode)
{
if (!Enum.IsDefined(typeof(EDutyMode), dutyMode))
{
return false;
}
_configuration.Duties.DefaultDutyMode = (EDutyMode)dutyMode;
_pluginInterface.SavePluginConfig(_configuration);
return true;
}
private int GetDutyModeOverride(uint contentFinderConditionId)
{
if (_configuration.Duties.DutyModeOverrides.TryGetValue(contentFinderConditionId, out var value))
{
return (int)value;
}
return -1;
}
private bool SetDutyModeOverride(uint contentFinderConditionId, int dutyMode)
{
if (!Enum.IsDefined(typeof(EDutyMode), dutyMode))
{
return false;
}
_configuration.Duties.DutyModeOverrides[contentFinderConditionId] = (EDutyMode)dutyMode;
_pluginInterface.SavePluginConfig(_configuration);
return true;
}
private bool ClearDutyModeOverride(uint contentFinderConditionId)
{
bool num = _configuration.Duties.DutyModeOverrides.Remove(contentFinderConditionId);
if (num)
{
_pluginInterface.SavePluginConfig(_configuration);
}
return num;
}
private bool ClearAllDutyModeOverrides()
{
_configuration.Duties.DutyModeOverrides.Clear();
_pluginInterface.SavePluginConfig(_configuration);
return true;
}
public void Dispose() public void Dispose()
{ {
_clearAllDutyModeOverrides.UnregisterFunc();
_clearDutyModeOverride.UnregisterFunc();
_setDutyModeOverride.UnregisterFunc();
_getDutyModeOverride.UnregisterFunc();
_setDefaultDutyMode.UnregisterFunc();
_getDefaultDutyMode.UnregisterFunc();
_exportQuestPriority.UnregisterFunc(); _exportQuestPriority.UnregisterFunc();
_insertQuestPriority.UnregisterFunc(); _insertQuestPriority.UnregisterFunc();
_clearQuestPriority.UnregisterFunc(); _clearQuestPriority.UnregisterFunc();

View file

@ -27,6 +27,10 @@ internal sealed class DutyConfigComponent : ConfigComponent
private const string DutyClipboardPrefix = "qst:duty:"; private const string DutyClipboardPrefix = "qst:duty:";
private const string ModePrefix = "M:";
private static readonly string[] DutyModeLabels = new string[3] { "Duty Support", "Unsync (Solo)", "Unsync (Party)" };
private readonly QuestRegistry _questRegistry; private readonly QuestRegistry _questRegistry;
private readonly AutoDutyIpc _autoDutyIpc; private readonly AutoDutyIpc _autoDutyIpc;
@ -72,6 +76,21 @@ internal sealed class DutyConfigComponent : ConfigComponent
} }
ImGui.SameLine(); ImGui.SameLine();
ImGuiComponents.HelpMarker("The combat module used for this is configured by AutoDuty, ignoring whichever selection you've made in Questionable's \"General\" configuration."); ImGuiComponents.HelpMarker("The combat module used for this is configured by AutoDuty, ignoring whichever selection you've made in Questionable's \"General\" configuration.");
using (ImRaii.Disabled(!v))
{
ImGui.Spacing();
ImGui.Text("Default duty mode:");
ImGui.SameLine();
int currentItem = (int)base.Configuration.Duties.DefaultDutyMode;
ImGui.SetNextItemWidth(200f);
if (ImGui.Combo("##DefaultDutyMode", ref currentItem, in DutyModeLabels, DutyModeLabels.Length))
{
base.Configuration.Duties.DefaultDutyMode = (EDutyMode)currentItem;
Save();
}
ImGui.SameLine();
ImGuiComponents.HelpMarker("\ufffd Duty Support: Run with NPC party members (level synced)\n\ufffd Unsync (Solo): Run alone at your current level (unsynced)\n\ufffd Unsync (Party): Run with your party at current level (unsynced)\n\nYou can override this setting for individual duties below.");
}
ImGui.Separator(); ImGui.Separator();
using (ImRaii.Disabled(!v)) using (ImRaii.Disabled(!v))
{ {
@ -94,7 +113,7 @@ internal sealed class DutyConfigComponent : ConfigComponent
private void DrawConfigTable(bool runInstancedContentWithAutoDuty) private void DrawConfigTable(bool runInstancedContentWithAutoDuty)
{ {
using ImRaii.IEndObject endObject = ImRaii.Child("DutyConfiguration", new Vector2(650f, 400f), border: true); using ImRaii.IEndObject endObject = ImRaii.Child("DutyConfiguration", new Vector2(950f, 400f), border: true);
if (!endObject) if (!endObject)
{ {
return; return;
@ -119,44 +138,49 @@ internal sealed class DutyConfigComponent : ConfigComponent
ImU8String table = new ImU8String(6, 1); ImU8String table = new ImU8String(6, 1);
table.AppendLiteral("Duties"); table.AppendLiteral("Duties");
table.AppendFormatted(eExpansionVersion); table.AppendFormatted(eExpansionVersion);
using ImRaii.IEndObject endObject2 = ImRaii.Table(table, 2, ImGuiTableFlags.SizingFixedFit); using ImRaii.IEndObject endObject2 = ImRaii.Table(table, 3, ImGuiTableFlags.SizingFixedFit);
if (!ImRaii.IEndObject.op_True(endObject2)) if (!ImRaii.IEndObject.op_True(endObject2))
{ {
continue; continue;
} }
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch); ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("Options", ImGuiTableColumnFlags.WidthFixed, 200f); ImGui.TableSetupColumn("Enabled", ImGuiTableColumnFlags.WidthFixed, 200f);
ImGui.TableSetupColumn("Mode", ImGuiTableColumnFlags.WidthFixed, 150f);
if (!_contentFinderConditionNames.TryGetValue(eExpansionVersion, out List<DutyInfo> value)) if (!_contentFinderConditionNames.TryGetValue(eExpansionVersion, out List<DutyInfo> value))
{ {
continue; continue;
} }
foreach (var (num3, value2, text2) in value) foreach (DutyInfo item3 in value)
{ {
if (!_questRegistry.TryGetDutyByContentFinderConditionId(num3, out DutyOptions dutyOptions)) item3.Deconstruct(out uint CfcId, out uint TerritoryId, out string Name);
uint num = CfcId;
uint value2 = TerritoryId;
string text = Name;
if (!_questRegistry.TryGetDutyByContentFinderConditionId(num, out DutyOptions dutyOptions))
{ {
continue; continue;
} }
ImGui.TableNextRow(); ImGui.TableNextRow();
string[] items = (dutyOptions.Enabled ? SupportedCfcOptions : UnsupportedCfcOptions); string[] items = (dutyOptions.Enabled ? SupportedCfcOptions : UnsupportedCfcOptions);
int currentItem = 0; int currentItem = 0;
if (base.Configuration.Duties.WhitelistedDutyCfcIds.Contains(num3)) if (base.Configuration.Duties.WhitelistedDutyCfcIds.Contains(num))
{ {
currentItem = 1; currentItem = 1;
} }
if (base.Configuration.Duties.BlacklistedDutyCfcIds.Contains(num3)) if (base.Configuration.Duties.BlacklistedDutyCfcIds.Contains(num))
{ {
currentItem = 2; currentItem = 2;
} }
if (ImGui.TableNextColumn()) if (ImGui.TableNextColumn())
{ {
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(text2); ImGui.TextUnformatted(text);
if (ImGui.IsItemHovered() && base.Configuration.Advanced.AdditionalStatusInformation) if (ImGui.IsItemHovered() && base.Configuration.Advanced.AdditionalStatusInformation)
{ {
using ImRaii.IEndObject endObject3 = ImRaii.Tooltip(); using ImRaii.IEndObject endObject3 = ImRaii.Tooltip();
if (endObject3) if (endObject3)
{ {
ImGui.TextUnformatted(text2); ImGui.TextUnformatted(text);
ImGui.Separator(); ImGui.Separator();
table = new ImU8String(13, 1); table = new ImU8String(13, 1);
table.AppendLiteral("TerritoryId: "); table.AppendLiteral("TerritoryId: ");
@ -164,11 +188,11 @@ internal sealed class DutyConfigComponent : ConfigComponent
ImGui.BulletText(table); ImGui.BulletText(table);
table = new ImU8String(26, 1); table = new ImU8String(26, 1);
table.AppendLiteral("ContentFinderConditionId: "); table.AppendLiteral("ContentFinderConditionId: ");
table.AppendFormatted(num3); table.AppendFormatted(num);
ImGui.BulletText(table); ImGui.BulletText(table);
} }
} }
if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(num3)) if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(num))
{ {
ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty", FontAwesomeIcon.Times, ImGuiColors.DalamudRed); ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty", FontAwesomeIcon.Times, ImGuiColors.DalamudRed);
} }
@ -177,31 +201,72 @@ internal sealed class DutyConfigComponent : ConfigComponent
ConfigComponent.DrawNotes(dutyOptions.Enabled, dutyOptions.Notes); ConfigComponent.DrawNotes(dutyOptions.Enabled, dutyOptions.Notes);
} }
} }
if (ImGui.TableNextColumn())
{
table = new ImU8String(16, 1);
table.AppendLiteral("##DungeonEnabled");
table.AppendFormatted(num);
using (ImRaii.PushId(table))
{
ImGui.SetNextItemWidth(200f);
if (ImGui.Combo(string.Empty, ref currentItem, in items, items.Length))
{
base.Configuration.Duties.WhitelistedDutyCfcIds.Remove(num);
base.Configuration.Duties.BlacklistedDutyCfcIds.Remove(num);
switch (currentItem)
{
case 1:
base.Configuration.Duties.WhitelistedDutyCfcIds.Add(num);
break;
case 2:
base.Configuration.Duties.BlacklistedDutyCfcIds.Add(num);
break;
}
Save();
}
}
}
if (!ImGui.TableNextColumn()) if (!ImGui.TableNextColumn())
{ {
continue; continue;
} }
table = new ImU8String(9, 1); table = new ImU8String(13, 1);
table.AppendLiteral("##Dungeon"); table.AppendLiteral("##DungeonMode");
table.AppendFormatted(num3); table.AppendFormatted(num);
using (ImRaii.PushId(table)) using (ImRaii.PushId(table))
{ {
ImGui.SetNextItemWidth(200f); EDutyMode value3;
if (ImGui.Combo(string.Empty, ref currentItem, in items, items.Length)) bool flag = base.Configuration.Duties.DutyModeOverrides.TryGetValue(num, out value3);
EDutyMode num2 = (flag ? value3 : ((EDutyMode)(-1)));
Name = "Use Default";
string[] dutyModeLabels = DutyModeLabels;
int num3 = 0;
string[] array = new string[1 + dutyModeLabels.Length];
array[num3] = Name;
num3++;
ReadOnlySpan<string> readOnlySpan = new ReadOnlySpan<string>(dutyModeLabels);
readOnlySpan.CopyTo(new Span<string>(array).Slice(num3, readOnlySpan.Length));
num3 += readOnlySpan.Length;
string[] items2 = array;
int currentItem2 = (int)(num2 + 1);
ImGui.SetNextItemWidth(150f);
if (ImGui.Combo(string.Empty, ref currentItem2, in items2, items2.Length))
{ {
base.Configuration.Duties.WhitelistedDutyCfcIds.Remove(num3); if (currentItem2 == 0)
base.Configuration.Duties.BlacklistedDutyCfcIds.Remove(num3);
switch (currentItem)
{ {
case 1: base.Configuration.Duties.DutyModeOverrides.Remove(num);
base.Configuration.Duties.WhitelistedDutyCfcIds.Add(num3); }
break; else
case 2: {
base.Configuration.Duties.BlacklistedDutyCfcIds.Add(num3); base.Configuration.Duties.DutyModeOverrides[num] = (EDutyMode)(currentItem2 - 1);
break;
} }
Save(); Save();
} }
if (ImGui.IsItemHovered())
{
EDutyMode eDutyMode = (flag ? value3 : base.Configuration.Duties.DefaultDutyMode);
ImGui.SetTooltip(flag ? ("Override: " + DutyModeLabels[(int)eDutyMode]) : ("Using default: " + DutyModeLabels[(int)eDutyMode]));
}
} }
} }
} }
@ -261,13 +326,14 @@ internal sealed class DutyConfigComponent : ConfigComponent
private void DrawClipboardButtons() private void DrawClipboardButtons()
{ {
using (ImRaii.Disabled(base.Configuration.Duties.WhitelistedDutyCfcIds.Count + base.Configuration.Duties.BlacklistedDutyCfcIds.Count == 0)) using (ImRaii.Disabled(base.Configuration.Duties.WhitelistedDutyCfcIds.Count + base.Configuration.Duties.BlacklistedDutyCfcIds.Count + base.Configuration.Duties.DutyModeOverrides.Count == 0))
{ {
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Copy, "Export to clipboard")) if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Copy, "Export to clipboard"))
{ {
IEnumerable<string> first = base.Configuration.Duties.WhitelistedDutyCfcIds.Select((uint x) => $"{"+"}{x}"); IEnumerable<string> first = base.Configuration.Duties.WhitelistedDutyCfcIds.Select((uint x) => $"{"+"}{x}");
IEnumerable<string> second = base.Configuration.Duties.BlacklistedDutyCfcIds.Select((uint x) => $"{"-"}{x}"); IEnumerable<string> second = base.Configuration.Duties.BlacklistedDutyCfcIds.Select((uint x) => $"{"-"}{x}");
ImGui.SetClipboardText("qst:duty:" + Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Join(";", first.Concat(second))))); IEnumerable<string> second2 = base.Configuration.Duties.DutyModeOverrides.Select((KeyValuePair<uint, EDutyMode> x) => $"{"M:"}{x.Key}:{x.Value}");
ImGui.SetClipboardText("qst:duty:" + Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Join(";", first.Concat(second).Concat(second2)))));
} }
} }
ImGui.SameLine(); ImGui.SameLine();
@ -282,6 +348,7 @@ internal sealed class DutyConfigComponent : ConfigComponent
string text2 = Encoding.UTF8.GetString(Convert.FromBase64String(text)); string text2 = Encoding.UTF8.GetString(Convert.FromBase64String(text));
base.Configuration.Duties.WhitelistedDutyCfcIds.Clear(); base.Configuration.Duties.WhitelistedDutyCfcIds.Clear();
base.Configuration.Duties.BlacklistedDutyCfcIds.Clear(); base.Configuration.Duties.BlacklistedDutyCfcIds.Clear();
base.Configuration.Duties.DutyModeOverrides.Clear();
string[] array = text2.Split(";"); string[] array = text2.Split(";");
foreach (string text3 in array) foreach (string text3 in array)
{ {
@ -293,7 +360,22 @@ internal sealed class DutyConfigComponent : ConfigComponent
{ {
base.Configuration.Duties.BlacklistedDutyCfcIds.Add(result2); base.Configuration.Duties.BlacklistedDutyCfcIds.Add(result2);
} }
if (!text3.StartsWith("M:", StringComparison.InvariantCulture))
{
continue;
}
ReadOnlySpan<char> span = text3.AsSpan("M:".Length);
int num2 = span.IndexOf(':');
if (num2 > 0 && uint.TryParse(span.Slice(0, num2), CultureInfo.InvariantCulture, out var result3))
{
int num3 = num2 + 1;
if (int.TryParse(span.Slice(num3, span.Length - num3), CultureInfo.InvariantCulture, out var result4) && Enum.IsDefined(typeof(EDutyMode), result4))
{
base.Configuration.Duties.DutyModeOverrides[result3] = (EDutyMode)result4;
}
}
} }
Save();
} }
} }
@ -305,6 +387,8 @@ internal sealed class DutyConfigComponent : ConfigComponent
{ {
base.Configuration.Duties.WhitelistedDutyCfcIds.Clear(); base.Configuration.Duties.WhitelistedDutyCfcIds.Clear();
base.Configuration.Duties.BlacklistedDutyCfcIds.Clear(); base.Configuration.Duties.BlacklistedDutyCfcIds.Clear();
base.Configuration.Duties.DutyModeOverrides.Clear();
base.Configuration.Duties.DefaultDutyMode = EDutyMode.Support;
Save(); Save();
} }
} }

View file

@ -69,6 +69,10 @@ internal sealed class Configuration : IPluginConfiguration
public HashSet<uint> BlacklistedDutyCfcIds { get; set; } = new HashSet<uint>(); public HashSet<uint> BlacklistedDutyCfcIds { get; set; } = new HashSet<uint>();
public EDutyMode DefaultDutyMode { get; set; }
public Dictionary<uint, EDutyMode> DutyModeOverrides { get; set; } = new Dictionary<uint, EDutyMode>();
public Dictionary<string, bool> ExpansionHeaderStates { get; set; } = new Dictionary<string, bool>(); public Dictionary<string, bool> ExpansionHeaderStates { get; set; } = new Dictionary<string, bool>();
} }

View file

@ -153,6 +153,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin, IDisposable
serviceCollection.AddTaskFactoryAndExecutor<AetheryteFreeOrFavored.Register, AetheryteFreeOrFavored.Factory, AetheryteFreeOrFavored.DoRegister>(); serviceCollection.AddTaskFactoryAndExecutor<AetheryteFreeOrFavored.Register, AetheryteFreeOrFavored.Factory, AetheryteFreeOrFavored.DoRegister>();
serviceCollection.AddTaskFactoryAndExecutor<Combat.Task, Combat.Factory, Combat.HandleCombat>(); serviceCollection.AddTaskFactoryAndExecutor<Combat.Task, Combat.Factory, Combat.HandleCombat>();
serviceCollection.AddTaskFactoryAndExecutor<Duty.OpenDutyFinderTask, Duty.Factory, Duty.OpenDutyFinderExecutor>(); serviceCollection.AddTaskFactoryAndExecutor<Duty.OpenDutyFinderTask, Duty.Factory, Duty.OpenDutyFinderExecutor>();
serviceCollection.AddTaskExecutor<Duty.WaitForPartyTask, Duty.WaitForPartyExecutor>();
serviceCollection.AddTaskExecutor<Duty.StartAutoDutyTask, Duty.StartAutoDutyExecutor>(); serviceCollection.AddTaskExecutor<Duty.StartAutoDutyTask, Duty.StartAutoDutyExecutor>();
serviceCollection.AddTaskExecutor<Duty.WaitAutoDutyTask, Duty.WaitAutoDutyExecutor>(); serviceCollection.AddTaskExecutor<Duty.WaitAutoDutyTask, Duty.WaitAutoDutyExecutor>();
serviceCollection.AddTaskFactory<Emote.Factory>(); serviceCollection.AddTaskFactory<Emote.Factory>();