Update dungeon/trial json schema to allow notes (similar to quest battles)

This commit is contained in:
Liza 2025-03-03 02:52:57 +01:00
parent 6c27b7d85e
commit 5c904d6cb3
Signed by: liza
GPG Key ID: 2C41B84815CF6445
65 changed files with 393 additions and 177 deletions

View File

@ -0,0 +1,30 @@
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()))));
}
}

View File

@ -117,11 +117,8 @@ internal static class QuestStepExtensions
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)

View File

@ -62,6 +62,7 @@ public static class RoslynShortcuts
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(),

View File

@ -112,8 +112,10 @@
{
"TerritoryId": 138,
"InteractionType": "Duty",
"ContentFinderConditionId": 4,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 4,
"Enabled": true
}
}
]
},

View File

@ -75,8 +75,10 @@
{
"TerritoryId": 146,
"InteractionType": "Duty",
"ContentFinderConditionId": 56,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 56,
"Enabled": true
}
}
]
},

View File

@ -62,8 +62,10 @@
{
"TerritoryId": 140,
"InteractionType": "Duty",
"ContentFinderConditionId": 3,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 3,
"Enabled": true
}
}
]
},

View File

@ -57,8 +57,10 @@
{
"TerritoryId": 148,
"InteractionType": "Duty",
"ContentFinderConditionId": 2,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 2,
"Enabled": true
}
}
]
},

View File

@ -44,8 +44,10 @@
{
"TerritoryId": 153,
"InteractionType": "Duty",
"ContentFinderConditionId": 1,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 1,
"Enabled": true
}
}
]
},

View File

@ -66,8 +66,13 @@
{
"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"
]
}
}
]
},

View File

@ -85,8 +85,13 @@
{
"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"
]
}
}
]
},

View File

@ -45,8 +45,10 @@
{
"TerritoryId": 139,
"InteractionType": "Duty",
"ContentFinderConditionId": 57,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 57,
"Enabled": true
}
}
]
},

View File

@ -59,8 +59,14 @@
{
"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"
]
}
}
]
},

View File

@ -38,8 +38,10 @@
{
"TerritoryId": 331,
"InteractionType": "Duty",
"ContentFinderConditionId": 58,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 58,
"Enabled": true
}
}
]
},

View File

@ -195,8 +195,10 @@
{
"TerritoryId": 147,
"InteractionType": "Duty",
"ContentFinderConditionId": 15,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 15,
"Enabled": true
}
}
]
},

View File

@ -46,8 +46,10 @@
{
"TerritoryId": 147,
"InteractionType": "Duty",
"ContentFinderConditionId": 16,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 16,
"Enabled": true
}
}
]
},
@ -72,8 +74,10 @@
{
"TerritoryId": 1053,
"InteractionType": "Duty",
"ContentFinderConditionId": 830,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 830,
"Enabled": true
}
}
]
},

View File

@ -88,8 +88,10 @@
{
"TerritoryId": 155,
"InteractionType": "Duty",
"ContentFinderConditionId": 27,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 27,
"Enabled": true
}
}
]
},

View File

@ -107,8 +107,10 @@
{
"TerritoryId": 156,
"InteractionType": "Duty",
"ContentFinderConditionId": 32,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 32,
"Enabled": true
}
}
]
},

View File

@ -78,8 +78,10 @@
{
"TerritoryId": 398,
"InteractionType": "Duty",
"ContentFinderConditionId": 37,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 37,
"Enabled": true
}
}
]
},

View File

@ -42,8 +42,10 @@
{
"TerritoryId": 418,
"InteractionType": "Duty",
"ContentFinderConditionId": 39,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 39,
"Enabled": true
}
}
]
},

View File

@ -59,8 +59,10 @@
{
"TerritoryId": 419,
"InteractionType": "Duty",
"ContentFinderConditionId": 34,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 34,
"Enabled": true
}
}
]
},

View File

@ -110,8 +110,10 @@
{
"TerritoryId": 399,
"InteractionType": "Duty",
"ContentFinderConditionId": 31,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 31,
"Enabled": true
}
}
]
},

View File

@ -62,8 +62,10 @@
{
"TerritoryId": 402,
"InteractionType": "Duty",
"ContentFinderConditionId": 38,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 38,
"Enabled": true
}
}
]
},
@ -88,7 +90,10 @@
{
"TerritoryId": 402,
"InteractionType": "Duty",
"ContentFinderConditionId": 90
"DutyOptions": {
"ContentFinderConditionId": 90,
"Enabled": false
}
}
]
},

View File

@ -77,8 +77,11 @@
{
"TerritoryId": 463,
"InteractionType": "Duty",
"ContentFinderConditionId": 141,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 141,
"Enabled": true,
"TestedAutoDutyVersion": "0.0.0.191"
}
}
]
},

View File

@ -57,8 +57,14 @@
{
"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"
]
}
}
]
},

View File

@ -198,7 +198,10 @@
{
"TerritoryId": 180,
"InteractionType": "Duty",
"ContentFinderConditionId": 60
"DutyOptions": {
"ContentFinderConditionId": 60,
"Enabled": false
}
}
]
},

View File

@ -109,8 +109,10 @@
{
"TerritoryId": 152,
"InteractionType": "Duty",
"ContentFinderConditionId": 219,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 219,
"Enabled": true
}
}
]
},

View File

@ -87,8 +87,10 @@
{
"TerritoryId": 680,
"InteractionType": "Duty",
"ContentFinderConditionId": 238,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 238,
"Enabled": true
}
}
]
},

View File

@ -114,8 +114,10 @@
{
"TerritoryId": 614,
"InteractionType": "Duty",
"ContentFinderConditionId": 241,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 241,
"Enabled": true
}
}
]
},

View File

@ -114,8 +114,10 @@
{
"TerritoryId": 620,
"InteractionType": "Duty",
"ContentFinderConditionId": 242,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 242,
"Enabled": true
}
}
]
},

View File

@ -98,8 +98,10 @@
{
"TerritoryId": 621,
"InteractionType": "Duty",
"ContentFinderConditionId": 279,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 279,
"Enabled": true
}
}
]
},

View File

@ -40,8 +40,10 @@
{
"TerritoryId": 614,
"InteractionType": "Duty",
"ContentFinderConditionId": 585,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 585,
"Enabled": true
}
}
]
},

View File

@ -27,8 +27,10 @@
{
"TerritoryId": 829,
"InteractionType": "Duty",
"ContentFinderConditionId": 611,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 611,
"Enabled": true
}
}
]
},

View File

@ -120,8 +120,10 @@
{
"TerritoryId": 813,
"InteractionType": "Duty",
"ContentFinderConditionId": 676,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 676,
"Enabled": true
}
}
]
},

View File

@ -49,8 +49,10 @@
{
"TerritoryId": 816,
"InteractionType": "Duty",
"ContentFinderConditionId": 649,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 649,
"Enabled": true
}
}
]
},

View File

@ -61,8 +61,10 @@
{
"TerritoryId": 817,
"InteractionType": "Duty",
"ContentFinderConditionId": 651,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 651,
"Enabled": true
}
}
]
},

View File

@ -62,8 +62,10 @@
{
"TerritoryId": 814,
"InteractionType": "Duty",
"ContentFinderConditionId": 659,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 659,
"Enabled": true
}
}
]
},
@ -88,7 +90,10 @@
{
"TerritoryId": 880,
"InteractionType": "Duty",
"ContentFinderConditionId": 666
"DutyOptions": {
"ContentFinderConditionId": 666,
"Enabled": false
}
}
]
},

View File

@ -40,8 +40,10 @@
{
"TerritoryId": 814,
"InteractionType": "Duty",
"ContentFinderConditionId": 714,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 714,
"Enabled": true
}
}
]
},

View File

@ -55,8 +55,10 @@
{
"TerritoryId": 957,
"InteractionType": "Duty",
"ContentFinderConditionId": 783,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 783,
"Enabled": true
}
}
]
},

View File

@ -71,8 +71,10 @@
{
"TerritoryId": 957,
"InteractionType": "Duty",
"ContentFinderConditionId": 789,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 789,
"Enabled": true
}
}
]
},

View File

@ -39,8 +39,10 @@
{
"TerritoryId": 961,
"InteractionType": "Duty",
"ContentFinderConditionId": 787,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 787,
"Enabled": true
}
}
]
},

View File

@ -38,8 +38,13 @@
{
"TerritoryId": 956,
"InteractionType": "Duty",
"ContentFinderConditionId": 786,
"AutoDutyEnabled": false
"DutyOptions": {
"ContentFinderConditionId": 786,
"Enabled": false,
"Notes": [
"No VBM module"
]
}
}
]
},
@ -64,8 +69,10 @@
{
"TerritoryId": 1030,
"InteractionType": "Duty",
"ContentFinderConditionId": 790,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 790,
"Enabled": true
}
}
]
},

View File

@ -23,8 +23,13 @@
{
"TerritoryId": 957,
"InteractionType": "Duty",
"ContentFinderConditionId": 844,
"AutoDutyEnabled": false
"DutyOptions": {
"ContentFinderConditionId": 844,
"Enabled": false,
"Notes": [
"No VBM module"
]
}
}
]
},

View File

@ -71,8 +71,13 @@
{
"TerritoryId": 1056,
"InteractionType": "Duty",
"ContentFinderConditionId": 869,
"AutoDutyEnabled": false
"DutyOptions": {
"ContentFinderConditionId": 869,
"Enabled": false,
"Notes": [
"No VBM module"
]
}
}
]
},

View File

@ -56,9 +56,10 @@
{
"TerritoryId": 958,
"InteractionType": "Duty",
"Comment": "Lapis Manalis",
"ContentFinderConditionId": 896,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 896,
"Enabled": true
}
}
]
},

View File

@ -160,8 +160,13 @@
{
"TerritoryId": 962,
"InteractionType": "Duty",
"ContentFinderConditionId": 822,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 822,
"Enabled": false,
"Notes": [
"Navigation issues for area transitions"
]
}
}
]
},

View File

@ -24,8 +24,10 @@
{
"TerritoryId": 1162,
"InteractionType": "Duty",
"ContentFinderConditionId": 823,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 823,
"Enabled": true
}
}
]
},

View File

@ -58,8 +58,10 @@
{
"TerritoryId": 1185,
"InteractionType": "Duty",
"ContentFinderConditionId": 826,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 826,
"Enabled": true
}
}
]
},

View File

@ -23,8 +23,10 @@
{
"TerritoryId": 1187,
"InteractionType": "Duty",
"ContentFinderConditionId": 824,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 824,
"Enabled": true
}
}
]
},

View File

@ -115,8 +115,10 @@
{
"TerritoryId": 1189,
"InteractionType": "Duty",
"ContentFinderConditionId": 829,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 829,
"Enabled": true
}
}
]
},

View File

@ -60,8 +60,10 @@
{
"TerritoryId": 1219,
"InteractionType": "Duty",
"ContentFinderConditionId": 831,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 831,
"Enabled": true
}
}
]
},

View File

@ -49,8 +49,10 @@
{
"TerritoryId": 1191,
"InteractionType": "Duty",
"ContentFinderConditionId": 825,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 825,
"Enabled": true
}
}
]
},
@ -75,7 +77,13 @@
{
"TerritoryId": 1220,
"InteractionType": "Duty",
"ContentFinderConditionId": 995
"DutyOptions": {
"ContentFinderConditionId": 995,
"Enabled": false,
"Notes": [
"No VBM module"
]
}
}
]
},

View File

@ -56,8 +56,10 @@
{
"TerritoryId": 1192,
"InteractionType": "Duty",
"ContentFinderConditionId": 827,
"AutoDutyEnabled": true
"DutyOptions": {
"ContentFinderConditionId": 827,
"Enabled": true
}
}
]
},
@ -82,7 +84,10 @@
{
"TerritoryId": 1221,
"InteractionType": "Duty",
"ContentFinderConditionId": 984
"DutyOptions": {
"ContentFinderConditionId": 984,
"Enabled": false
}
}
]
},

View File

@ -122,8 +122,14 @@
{
"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"
]
}
}
]
},

View File

@ -1238,13 +1238,35 @@
},
"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"
@ -1254,7 +1276,7 @@
}
},
"required": [
"ContentFinderConditionId"
"DutyOptions"
]
}
},

View File

@ -0,0 +1,10 @@
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; } = [];
}

View File

@ -73,8 +73,7 @@ public sealed class QuestStep
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; }

View File

@ -165,8 +165,8 @@ internal sealed class QuestRegistry
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,
@ -262,15 +262,15 @@ internal sealed class QuestRegistry
.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;
}
}

View File

@ -23,9 +23,9 @@ internal static class SendNotification
{
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),

View File

@ -23,17 +23,17 @@ internal static class Duty
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);
}
}
}

View File

@ -53,7 +53,7 @@ internal static class WaitAtEnd
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()];

View File

@ -19,7 +19,7 @@ internal sealed class TerritoryData
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)
{
@ -52,7 +52,7 @@ internal sealed class TerritoryData
.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,
@ -90,7 +90,7 @@ internal sealed class TerritoryData
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
{
@ -101,7 +101,7 @@ internal sealed class TerritoryData
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)

View File

@ -4,6 +4,7 @@ using Dalamud.Plugin.Ipc.Exceptions;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps;
using Questionable.Data;
using Questionable.Model.Questing;
namespace Questionable.External;
@ -31,22 +32,22 @@ internal sealed class AutoDutyIpc
_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)

View File

@ -1,5 +1,9 @@
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;
@ -61,4 +65,29 @@ internal abstract class ConfigComponent
++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);
}
}

View File

@ -18,6 +18,7 @@ using Questionable.Controller;
using Questionable.Data;
using Questionable.External;
using Questionable.Model;
using Questionable.Model.Questing;
namespace Questionable.Windows.ConfigComponents;
@ -125,12 +126,11 @@ internal sealed class DutyConfigComponent : ConfigComponent
{
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;
@ -159,6 +159,8 @@ internal sealed class DutyConfigComponent : ConfigComponent
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())

View File

@ -460,32 +460,7 @@ internal sealed class SinglePlayerDutyConfigComponent : ConfigComponent
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())