--- /dev/null
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Questionable.Model.Questing;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+using static Questionable.QuestPathGenerator.RoslynShortcuts;
+
+namespace Questionable.QuestPathGenerator.RoslynElements;
+
+internal static class DutyOptionsExtensions
+{
+ public static ExpressionSyntax ToExpressionSyntax(this DutyOptions dutyOptions)
+ {
+ var emptyOptions = new DutyOptions();
+ return ObjectCreationExpression(
+ IdentifierName(nameof(DutyOptions)))
+ .WithInitializer(
+ InitializerExpression(
+ SyntaxKind.ObjectInitializerExpression,
+ SeparatedList<ExpressionSyntax>(
+ SyntaxNodeList(
+ Assignment(nameof(DutyOptions.Enabled),
+ dutyOptions.Enabled, emptyOptions.Enabled)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(DutyOptions.ContentFinderConditionId),
+ dutyOptions.ContentFinderConditionId, emptyOptions.ContentFinderConditionId)
+ .AsSyntaxNodeOrToken(),
+ AssignmentList(nameof(DutyOptions.Notes), dutyOptions.Notes)
+ .AsSyntaxNodeOrToken()))));
+ }
+}
Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination,
emptyStep.JumpDestination)
.AsSyntaxNodeOrToken(),
- Assignment(nameof(QuestStep.ContentFinderConditionId),
- step.ContentFinderConditionId, emptyStep.ContentFinderConditionId)
- .AsSyntaxNodeOrToken(),
- Assignment(nameof(QuestStep.AutoDutyEnabled),
- step.AutoDutyEnabled, emptyStep.AutoDutyEnabled)
+ Assignment(nameof(QuestStep.DutyOptions), step.DutyOptions,
+ emptyStep.DutyOptions)
.AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.SinglePlayerDutyOptions), step.SinglePlayerDutyOptions,
emptyStep.SinglePlayerDutyOptions)
ComplexCombatData complexCombatData => complexCombatData.ToExpressionSyntax(),
QuestWorkValue questWorkValue => questWorkValue.ToExpressionSyntax(),
List<QuestWorkValue> list => list.ToExpressionSyntax(), // TODO fix in AssignmentList
+ DutyOptions dutyOptions => dutyOptions.ToExpressionSyntax(),
SinglePlayerDutyOptions dutyOptions => dutyOptions.ToExpressionSyntax(),
SkipConditions skipConditions => skipConditions.ToExpressionSyntax(),
SkipStepConditions skipStepConditions => skipStepConditions.ToExpressionSyntax(),
{
"TerritoryId": 138,
"InteractionType": "Duty",
- "ContentFinderConditionId": 4,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 4,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 146,
"InteractionType": "Duty",
- "ContentFinderConditionId": 56,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 56,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 140,
"InteractionType": "Duty",
- "ContentFinderConditionId": 3,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 3,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 148,
"InteractionType": "Duty",
- "ContentFinderConditionId": 2,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 2,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 153,
"InteractionType": "Duty",
- "ContentFinderConditionId": 1,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 1,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 148,
"InteractionType": "Duty",
- "ContentFinderConditionId": 6,
- "AutoDutyEnabled": false
+ "DutyOptions": {
+ "ContentFinderConditionId": 6,
+ "Enabled": false,
+ "Notes": [
+ "(after boss 2) Will not pick up the bloody parchment, and instead run off to open a random unrelated chest that it can't reach"
+ ]
+ }
}
]
},
{
"TerritoryId": 137,
"InteractionType": "Duty",
- "ContentFinderConditionId": 8,
- "AutoDutyEnabled": false
+ "DutyOptions": {
+ "ContentFinderConditionId": 8,
+ "Enabled": false,
+ "Notes": [
+ "(boss 2) Will walk out of the boss arena to try and attack optional enemies on the upper level, thus resetting the boss and breaking the path"
+ ]
+ }
}
]
},
{
"TerritoryId": 139,
"InteractionType": "Duty",
- "ContentFinderConditionId": 57,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 57,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 155,
"InteractionType": "Duty",
- "ContentFinderConditionId": 11,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 11,
+ "Enabled": false,
+ "Notes": [
+ "(boss 1) AI will not face cleaves away from healer, typically killing them",
+ "(boss 3) AI will not face cleaves away from healer, which doesn't always kill them"
+ ]
+ }
}
]
},
{
"TerritoryId": 331,
"InteractionType": "Duty",
- "ContentFinderConditionId": 58,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 58,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 147,
"InteractionType": "Duty",
- "ContentFinderConditionId": 15,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 15,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 147,
"InteractionType": "Duty",
- "ContentFinderConditionId": 16,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 16,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1053,
"InteractionType": "Duty",
- "ContentFinderConditionId": 830,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 830,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 155,
"InteractionType": "Duty",
- "ContentFinderConditionId": 27,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 27,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 156,
"InteractionType": "Duty",
- "ContentFinderConditionId": 32,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 32,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 398,
"InteractionType": "Duty",
- "ContentFinderConditionId": 37,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 37,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 418,
"InteractionType": "Duty",
- "ContentFinderConditionId": 39,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 39,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 419,
"InteractionType": "Duty",
- "ContentFinderConditionId": 34,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 34,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 399,
"InteractionType": "Duty",
- "ContentFinderConditionId": 31,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 31,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 402,
"InteractionType": "Duty",
- "ContentFinderConditionId": 38,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 38,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 402,
"InteractionType": "Duty",
- "ContentFinderConditionId": 90
+ "DutyOptions": {
+ "ContentFinderConditionId": 90,
+ "Enabled": false
+ }
}
]
},
{
"TerritoryId": 463,
"InteractionType": "Duty",
- "ContentFinderConditionId": 141,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 141,
+ "Enabled": true,
+ "TestedAutoDutyVersion": "0.0.0.191"
+ }
}
]
},
{
"TerritoryId": 155,
"InteractionType": "Duty",
- "ContentFinderConditionId": 182,
- "AutoDutyEnabled": false
+ "DutyOptions": {
+ "ContentFinderConditionId": 182,
+ "Enabled": false,
+ "Notes": [
+ "(after boss 1) the drawbridges being up will lead you to die from the spikes",
+ "(after boss 1) the lift isn't working properly"
+ ]
+ }
}
]
},
{
"TerritoryId": 180,
"InteractionType": "Duty",
- "ContentFinderConditionId": 60
+ "DutyOptions": {
+ "ContentFinderConditionId": 60,
+ "Enabled": false
+ }
}
]
},
{
"TerritoryId": 152,
"InteractionType": "Duty",
- "ContentFinderConditionId": 219,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 219,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 680,
"InteractionType": "Duty",
- "ContentFinderConditionId": 238,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 238,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 614,
"InteractionType": "Duty",
- "ContentFinderConditionId": 241,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 241,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 620,
"InteractionType": "Duty",
- "ContentFinderConditionId": 242,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 242,
+ "Enabled": true
+ }
}
]
},
{\r
"TerritoryId": 621,\r
"InteractionType": "Duty",\r
- "ContentFinderConditionId": 279,\r
- "AutoDutyEnabled": true\r
+ "DutyOptions": {\r
+ "ContentFinderConditionId": 279,\r
+ "Enabled": true\r
+ }\r
}\r
]\r
},\r
{
"TerritoryId": 614,
"InteractionType": "Duty",
- "ContentFinderConditionId": 585,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 585,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 829,
"InteractionType": "Duty",
- "ContentFinderConditionId": 611,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 611,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 813,
"InteractionType": "Duty",
- "ContentFinderConditionId": 676,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 676,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 816,
"InteractionType": "Duty",
- "ContentFinderConditionId": 649,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 649,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 817,
"InteractionType": "Duty",
- "ContentFinderConditionId": 651,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 651,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 814,
"InteractionType": "Duty",
- "ContentFinderConditionId": 659,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 659,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 880,
"InteractionType": "Duty",
- "ContentFinderConditionId": 666
+ "DutyOptions": {
+ "ContentFinderConditionId": 666,
+ "Enabled": false
+ }
}
]
},
{
"TerritoryId": 814,
"InteractionType": "Duty",
- "ContentFinderConditionId": 714,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 714,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 957,
"InteractionType": "Duty",
- "ContentFinderConditionId": 783,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 783,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 957,
"InteractionType": "Duty",
- "ContentFinderConditionId": 789,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 789,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 961,
"InteractionType": "Duty",
- "ContentFinderConditionId": 787,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 787,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 956,
"InteractionType": "Duty",
- "ContentFinderConditionId": 786,
- "AutoDutyEnabled": false
+ "DutyOptions": {
+ "ContentFinderConditionId": 786,
+ "Enabled": false,
+ "Notes": [
+ "No VBM module"
+ ]
+ }
}
]
},
{
"TerritoryId": 1030,
"InteractionType": "Duty",
- "ContentFinderConditionId": 790,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 790,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 957,
"InteractionType": "Duty",
- "ContentFinderConditionId": 844,
- "AutoDutyEnabled": false
+ "DutyOptions": {
+ "ContentFinderConditionId": 844,
+ "Enabled": false,
+ "Notes": [
+ "No VBM module"
+ ]
+ }
}
]
},
{
"TerritoryId": 1056,
"InteractionType": "Duty",
- "ContentFinderConditionId": 869,
- "AutoDutyEnabled": false
+ "DutyOptions": {
+ "ContentFinderConditionId": 869,
+ "Enabled": false,
+ "Notes": [
+ "No VBM module"
+ ]
+ }
}
]
},
{
"TerritoryId": 958,
"InteractionType": "Duty",
- "Comment": "Lapis Manalis",
- "ContentFinderConditionId": 896,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 896,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 962,
"InteractionType": "Duty",
- "ContentFinderConditionId": 822,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 822,
+ "Enabled": false,
+ "Notes": [
+ "Navigation issues for area transitions"
+ ]
+ }
}
]
},
{
"TerritoryId": 1162,
"InteractionType": "Duty",
- "ContentFinderConditionId": 823,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 823,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1185,
"InteractionType": "Duty",
- "ContentFinderConditionId": 826,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 826,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1187,
"InteractionType": "Duty",
- "ContentFinderConditionId": 824,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 824,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1189,
"InteractionType": "Duty",
- "ContentFinderConditionId": 829,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 829,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1219,
"InteractionType": "Duty",
- "ContentFinderConditionId": 831,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 831,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1191,
"InteractionType": "Duty",
- "ContentFinderConditionId": 825,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 825,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1220,
"InteractionType": "Duty",
- "ContentFinderConditionId": 995
+ "DutyOptions": {
+ "ContentFinderConditionId": 995,
+ "Enabled": false,
+ "Notes": [
+ "No VBM module"
+ ]
+ }
}
]
},
{
"TerritoryId": 1192,
"InteractionType": "Duty",
- "ContentFinderConditionId": 827,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 827,
+ "Enabled": true
+ }
}
]
},
{
"TerritoryId": 1221,
"InteractionType": "Duty",
- "ContentFinderConditionId": 984
+ "DutyOptions": {
+ "ContentFinderConditionId": 984,
+ "Enabled": false
+ }
}
]
},
{
"TerritoryId": 1191,
"InteractionType": "Duty",
- "ContentFinderConditionId": 1008,
- "AutoDutyEnabled": true
+ "DutyOptions": {
+ "ContentFinderConditionId": 1008,
+ "Enabled": true,
+ "Notes": [
+ "(boss 2) Requires vbm's auto-turn gaze option",
+ "(boss 3) Dashes (such as on SMN) will dash into the hole"
+ ]
+ }
}
]
},
},
"then": {
"properties": {
- "ContentFinderConditionId": {
- "type": "integer",
- "exclusiveMinimum": 0,
- "exclusiveMaximum": 3000
- },
- "AutoDutyEnabled": {
- "type": "boolean"
+ "DutyOptions": {
+ "type": "object",
+ "properties": {
+ "ContentFinderConditionId": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "exclusiveMaximum": 3000
+ },
+ "Enabled": {
+ "type": "boolean"
+ },
+ "Notes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "TestedAutoDutyVersion": {
+ "type": "string",
+ "pattern": "^0\\.\\d+\\.\\d+\\.\\d+$"
+ },
+ "$": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "ContentFinderConditionId",
+ "Enabled"
+ ]
},
"DataId": {
"type": "null"
}
},
"required": [
- "ContentFinderConditionId"
+ "DutyOptions"
]
}
},
--- /dev/null
+using System.Collections.Generic;
+
+namespace Questionable.Model.Questing;
+
+public class DutyOptions
+{
+ public bool Enabled { get; set; }
+ public uint ContentFinderConditionId { get; set; }
+ public List<string> Notes { get; set; } = [];
+}
public float? CombatDelaySecondsAtStart { get; set; }
public JumpDestination? JumpDestination { get; set; }
- public uint? ContentFinderConditionId { get; set; }
- public bool AutoDutyEnabled { get; set; }
+ public DutyOptions? DutyOptions { get; set; }
public SinglePlayerDutyOptions? SinglePlayerDutyOptions { get; set; }
public byte SinglePlayerDutyIndex => SinglePlayerDutyOptions?.Index ?? 0;
public SkipConditions? SkipConditions { get; set; }
foreach (var dutyStep in quest.AllSteps().Where(x =>
x.Step.InteractionType is EInteractionType.Duty or EInteractionType.SinglePlayerDuty))
{
- if (dutyStep.Step is { InteractionType: EInteractionType.Duty, ContentFinderConditionId: not null })
- _contentFinderConditionIds[dutyStep.Step.ContentFinderConditionId!.Value] =
+ if (dutyStep.Step is { InteractionType: EInteractionType.Duty, DutyOptions: { } dutyOptions })
+ _contentFinderConditionIds[dutyOptions.ContentFinderConditionId] =
(quest.Id, dutyStep.Step);
else if (dutyStep.Step.InteractionType == EInteractionType.SinglePlayerDuty &&
_territoryData.TryGetContentFinderConditionForSoloInstance(quest.Id,
.ToList();
}
- public bool TryGetDutyByContentFinderConditionId(uint cfcId, out bool autoDutyEnabledByDefault)
+ public bool TryGetDutyByContentFinderConditionId(uint cfcId, [NotNullWhen(true)] out DutyOptions? dutyOptions)
{
if (_contentFinderConditionIds.TryGetValue(cfcId, out var value))
{
- autoDutyEnabledByDefault = value.Step.AutoDutyEnabled;
- return true;
+ dutyOptions = value.Step.DutyOptions;
+ return dutyOptions != null;
}
- autoDutyEnabledByDefault = false;
+ dutyOptions = null;
return false;
}
}
{
EInteractionType.Snipe when !automatonIpc.IsAutoSnipeEnabled =>
new Task(step.InteractionType, step.Comment),
- EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled) =>
- new Task(step.InteractionType, step.ContentFinderConditionId.HasValue
- ? territoryData.GetContentFinderCondition(step.ContentFinderConditionId.Value)?.Name
+ EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.DutyOptions) =>
+ new Task(step.InteractionType, step.DutyOptions?.ContentFinderConditionId is {} contentFinderConditionId
+ ? territoryData.GetContentFinderCondition(contentFinderConditionId)?.Name
: step.Comment),
EInteractionType.SinglePlayerDuty when !bossModIpc.IsConfiguredToRunSoloInstance(quest.Id, step.SinglePlayerDutyOptions) =>
new Task(step.InteractionType, quest.Info.Name),
if (step.InteractionType != EInteractionType.Duty)
yield break;
- ArgumentNullException.ThrowIfNull(step.ContentFinderConditionId);
+ ArgumentNullException.ThrowIfNull(step.DutyOptions);
- if (autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled))
+ if (autoDutyIpc.IsConfiguredToRunContent(step.DutyOptions))
{
- yield return new StartAutoDutyTask(step.ContentFinderConditionId.Value);
- yield return new WaitAutoDutyTask(step.ContentFinderConditionId.Value);
+ yield return new StartAutoDutyTask(step.DutyOptions.ContentFinderConditionId);
+ yield return new WaitAutoDutyTask(step.DutyOptions.ContentFinderConditionId);
yield return new WaitAtEnd.WaitNextStepOrSequence();
}
else
{
- yield return new OpenDutyFinderTask(step.ContentFinderConditionId.Value);
+ yield return new OpenDutyFinderTask(step.DutyOptions.ContentFinderConditionId);
}
}
}
case EInteractionType.Snipe:
return [new WaitNextStepOrSequence()];
- case EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.ContentFinderConditionId, step.AutoDutyEnabled):
+ case EInteractionType.Duty when !autoDutyIpc.IsConfiguredToRunContent(step.DutyOptions):
case EInteractionType.SinglePlayerDuty when !bossModIpc.IsConfiguredToRunSoloInstance(quest.Id, step.SinglePlayerDutyOptions):
return [new EndAutomation()];
private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
private readonly ImmutableDictionary<uint, string> _instanceNames;
private readonly ImmutableDictionary<uint, ContentFinderConditionData> _contentFinderConditions;
- private readonly ImmutableDictionary<(ElementId QuestId, byte Index), uint> _questsToCfc;
+ private readonly ImmutableDictionary<(ElementId QuestId, byte Index), uint> _questBattlesToContentFinderCondition;
public TerritoryData(IDataManager dataManager)
{
.Select(x => new ContentFinderConditionData(x, dataManager.Language))
.ToImmutableDictionary(x => x.ContentFinderConditionId, x => x);
- _questsToCfc = dataManager.GetExcelSheet<Quest>()
+ _questBattlesToContentFinderCondition = dataManager.GetExcelSheet<Quest>()
.Where(x => x is { RowId: > 0, IssuerLocation.RowId: > 0 })
.SelectMany(GetQuestBattles)
.Select(x => (x.QuestId, x.Index,
public bool TryGetContentFinderConditionForSoloInstance(ElementId questId, byte index,
[NotNullWhen(true)] out ContentFinderConditionData? contentFinderConditionData)
{
- if (_questsToCfc.TryGetValue((questId, index), out uint cfcId))
+ if (_questBattlesToContentFinderCondition.TryGetValue((questId, index), out uint cfcId))
return _contentFinderConditions.TryGetValue(cfcId, out contentFinderConditionData);
else
{
public IEnumerable<(ElementId QuestId, byte Index, ContentFinderConditionData Data)> GetAllQuestsWithQuestBattles()
{
- return _questsToCfc.Select(x => (x.Key.QuestId, x.Key.Index, _contentFinderConditions[x.Value]));
+ return _questBattlesToContentFinderCondition.Select(x => (x.Key.QuestId, x.Key.Index, _contentFinderConditions[x.Value]));
}
private static string FixName(string name, ClientLanguage language)
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps;
using Questionable.Data;
+using Questionable.Model.Questing;
namespace Questionable.External;
_stop = pluginInterface.GetIpcSubscriber<object>("AutoDuty.Stop");
}
- public bool IsConfiguredToRunContent(uint? cfcId, bool enabledByDefault)
+ public bool IsConfiguredToRunContent(DutyOptions? dutyOptions)
{
- if (cfcId == null)
+ if (dutyOptions == null || dutyOptions.ContentFinderConditionId == 0)
return false;
if (!_configuration.Duties.RunInstancedContentWithAutoDuty)
return false;
- if (_configuration.Duties.BlacklistedDutyCfcIds.Contains(cfcId.Value))
+ if (_configuration.Duties.BlacklistedDutyCfcIds.Contains(dutyOptions.ContentFinderConditionId))
return false;
- if (_configuration.Duties.WhitelistedDutyCfcIds.Contains(cfcId.Value) &&
- _territoryData.TryGetContentFinderCondition(cfcId.Value, out _))
+ if (_configuration.Duties.WhitelistedDutyCfcIds.Contains(dutyOptions.ContentFinderConditionId) &&
+ _territoryData.TryGetContentFinderCondition(dutyOptions.ContentFinderConditionId, out _))
return true;
- return enabledByDefault && HasPath(cfcId.Value);
+ return dutyOptions.Enabled && HasPath(dutyOptions.ContentFinderConditionId);
}
public bool HasPath(uint cfcId)
+using System.Collections.Generic;
using System.Text;
using Dalamud.Game.Text;
+using Dalamud.Interface;
+using Dalamud.Interface.Colors;
+using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using ImGuiNET;
++byteCount;
return Encoding.UTF8.GetString(ptr, byteCount);
}
+
+ protected static void DrawNotes(bool enabledByDefault, IReadOnlyList<string> notes)
+ {
+ using var color = new ImRaii.Color();
+ color.Push(ImGuiCol.TextDisabled, !enabledByDefault ? ImGuiColors.DalamudYellow : ImGuiColors.ParsedBlue);
+
+ ImGui.SameLine();
+ using (ImRaii.PushFont(UiBuilder.IconFont))
+ {
+ if (!enabledByDefault)
+ ImGui.TextDisabled(FontAwesomeIcon.ExclamationTriangle.ToIconString());
+ else
+ ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
+ }
+
+ if (!ImGui.IsItemHovered())
+ return;
+
+ using var _ = ImRaii.Tooltip();
+
+ ImGui.TextColored(ImGuiColors.DalamudYellow,
+ "While testing, the following issues have been found:");
+ foreach (string note in notes)
+ ImGui.BulletText(note);
+ }
}
using Questionable.Data;
using Questionable.External;
using Questionable.Model;
+using Questionable.Model.Questing;
namespace Questionable.Windows.ConfigComponents;
{
foreach (var (cfcId, territoryId, name) in cfcNames)
{
- if (_questRegistry.TryGetDutyByContentFinderConditionId(cfcId,
- out bool autoDutyEnabledByDefault))
+ if (_questRegistry.TryGetDutyByContentFinderConditionId(cfcId, out DutyOptions? dutyOptions))
{
ImGui.TableNextRow();
- string[] labels = autoDutyEnabledByDefault
+ string[] labels = dutyOptions.Enabled
? SupportedCfcOptions
: UnsupportedCfcOptions;
int value = 0;
if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(cfcId))
ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty",
FontAwesomeIcon.Times, ImGuiColors.DalamudRed);
+ else if (dutyOptions.Notes.Count > 0)
+ DrawNotes(dutyOptions.Enabled, dutyOptions.Notes);
}
if (ImGui.TableNextColumn())
FontAwesomeIcon.Times, ImGuiColors.DalamudRed);
}
else if (dutyInfo.Notes.Count > 0)
- {
- using var color = new ImRaii.Color();
- if (!dutyInfo.EnabledByDefault)
- color.Push(ImGuiCol.TextDisabled, ImGuiColors.DalamudYellow);
- else
- color.Push(ImGuiCol.TextDisabled, ImGuiColors.ParsedBlue);
-
- ImGui.SameLine();
- using (ImRaii.PushFont(UiBuilder.IconFont))
- {
- if (!dutyInfo.EnabledByDefault)
- ImGui.TextDisabled(FontAwesomeIcon.ExclamationTriangle.ToIconString());
- else
- ImGui.TextDisabled(FontAwesomeIcon.InfoCircle.ToIconString());
- }
-
- if (ImGui.IsItemHovered())
- {
- using var _ = ImRaii.Tooltip();
-
- ImGui.TextColored(ImGuiColors.DalamudYellow,
- "While testing, the following issues have been found:");
- foreach (string note in dutyInfo.Notes)
- ImGui.BulletText(note);
- }
- }
+ DrawNotes(dutyInfo.EnabledByDefault, dutyInfo.Notes);
}
if (ImGui.TableNextColumn())