Compare commits

..

9 Commits

21 changed files with 216 additions and 28 deletions

View File

@ -1,5 +1,5 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>2.15</Version> <Version>2.16</Version>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -42,14 +42,18 @@
"X": 419.309, "X": 419.309,
"Y": -10.25133, "Y": -10.25133,
"Z": -784.8259 "Z": -784.8259
} },
"MinimumAngle": -25,
"MaximumAngle": 85
}, },
{ {
"Position": { "Position": {
"X": 410.6989, "X": 410.6989,
"Y": -10.9656, "Y": -10.9656,
"Z": -790.8315 "Z": -790.8315
} },
"MinimumAngle": -20,
"MaximumAngle": 95
} }
] ]
} }

View File

@ -52,8 +52,8 @@
"Y": -47.86026, "Y": -47.86026,
"Z": -394.9654 "Z": -394.9654
}, },
"MinimumAngle": -120, "MinimumAngle": -145,
"MaximumAngle": 120 "MaximumAngle": -95
} }
] ]
} }

View File

@ -20,6 +20,15 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"Position": {
"X": -392.35907,
"Y": -14.000012,
"Z": 635.3141
},
"TerritoryId": 1191,
"InteractionType": "WalkTo"
},
{ {
"Position": { "Position": {
"X": -415.87146, "X": -415.87146,

View File

@ -55,6 +55,24 @@
{ {
"Sequence": 255, "Sequence": 255,
"Steps": [ "Steps": [
{
"Position": {
"X": 184.68884,
"Y": 99.24859,
"Z": -171.97504
},
"TerritoryId": 1191,
"InteractionType": "WalkTo"
},
{
"Position": {
"X": 148.14713,
"Y": 100.07344,
"Z": -135.20776
},
"TerritoryId": 1191,
"InteractionType": "WalkTo"
},
{ {
"DataId": 2013966, "DataId": 2013966,
"Position": { "Position": {

View File

@ -69,6 +69,7 @@
"Y": 0.003171, "Y": 0.003171,
"Z": 1.296936 "Z": 1.296936
}, },
"StopDistance": 5,
"TerritoryId": 1171, "TerritoryId": 1171,
"InteractionType": "CompleteQuest" "InteractionType": "CompleteQuest"
} }

View File

@ -21,6 +21,34 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1049443,
"Position": {
"X": -177.56934,
"Y": 29.999998,
"Z": -601.15967
},
"TerritoryId": 1191,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5153,
"AetheryteShortcut": "Heritage Found - The Outskirts",
"SkipConditions": {
"AetheryteShortcutIf": {
"InSameTerritory": true
}
}
},
{
"DataId": 1050805,
"Position": {
"X": -153.09375,
"Y": 34.946026,
"Z": -581.0178
},
"TerritoryId": 1191,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5160
},
{ {
"DataId": 1048053, "DataId": 1048053,
"Position": { "Position": {
@ -29,8 +57,7 @@
"Z": -828.58014 "Z": -828.58014
}, },
"TerritoryId": 1191, "TerritoryId": 1191,
"InteractionType": "Interact", "InteractionType": "Interact"
"AetheryteShortcut": "Heritage Found - The Outskirts"
} }
] ]
}, },

View File

@ -37,6 +37,17 @@
{ {
"Sequence": 2, "Sequence": 2,
"Steps": [ "Steps": [
{
"DataId": 1049505,
"Position": {
"X": -209.85736,
"Y": 7.49638,
"Z": 595.9104
},
"TerritoryId": 1191,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5159
},
{ {
"DataId": 1048099, "DataId": 1048099,
"Position": { "Position": {
@ -53,6 +64,17 @@
{ {
"Sequence": 3, "Sequence": 3,
"Steps": [ "Steps": [
{
"DataId": 1049501,
"Position": {
"X": -592.7062,
"Y": -2.4803436,
"Z": -489.28055
},
"TerritoryId": 1191,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5156
},
{ {
"DataId": 1048116, "DataId": 1048116,
"Position": { "Position": {

View File

@ -32,7 +32,8 @@
"Z": -565.48413 "Z": -565.48413
}, },
"TerritoryId": 1191, "TerritoryId": 1191,
"InteractionType": "Interact" "InteractionType": "Interact",
"Fly": true
} }
] ]
}, },

View File

@ -21,6 +21,17 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1050617,
"Position": {
"X": -631.4031,
"Y": 2.9305653E-07,
"Z": 497.12354
},
"TerritoryId": 1192,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5174
},
{ {
"DataId": 1047884, "DataId": 1047884,
"Position": { "Position": {

View File

@ -21,6 +21,41 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1048243,
"Position": {
"X": 57.87744,
"Y": 53.200012,
"Z": 772.03015
},
"TerritoryId": 1192,
"InteractionType": "Interact",
"AetheryteShortcut": "Living Memory - Leynode Mnemo",
"TargetTerritoryId": 1192,
"SkipConditions": {
"StepIf": {
"QuestsCompleted": [
5176
]
},
"AetheryteShortcutIf": {
"QuestsCompleted": [
5176
]
}
}
},
{
"DataId": 1050621,
"Position": {
"X": 477.1344,
"Y": -0.034497976,
"Z": 711.6654
},
"TerritoryId": 1192,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5176
},
{ {
"DataId": 1047917, "DataId": 1047917,
"Position": { "Position": {

View File

@ -21,6 +21,44 @@
{ {
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{
"DataId": 1050625,
"Position": {
"X": 628.6869,
"Y": 24.99949,
"Z": -283.3753
},
"TerritoryId": 1192,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5178,
"AetheryteShortcut": "Living Memory - Leynode Pyro",
"SkipConditions": {
"AetheryteShortcutIf": {
"QuestsCompleted": [
5178
]
}
}
},
{
"DataId": 1050632,
"Position": {
"X": 538.9944,
"Y": 25.001822,
"Z": -194.3847
},
"TerritoryId": 1192,
"InteractionType": "AcceptQuest",
"PickUpQuestId": 5179,
"AetheryteShortcut": "Living Memory - Leynode Pyro",
"SkipConditions": {
"AetheryteShortcutIf": {
"QuestsCompleted": [
5179
]
}
}
},
{ {
"DataId": 1047971, "DataId": 1047971,
"Position": { "Position": {

View File

@ -33,8 +33,12 @@
}, },
"TerritoryId": 1192, "TerritoryId": 1192,
"InteractionType": "WalkTo", "InteractionType": "WalkTo",
"AetheryteShortcut": "Living Memory - Leynode Mnemo", "$": "Leynode Mnemo to Meso Terminal waypoint",
"$": "Leynode Mnemo to Meso Terminal waypoint" "SkipConditions": {
"StepIf": {
"Flying": "Unlocked"
}
}
}, },
{ {
"DataId": 1048014, "DataId": 1048014,
@ -44,7 +48,8 @@
"Z": 363.05774 "Z": 363.05774
}, },
"TerritoryId": 1192, "TerritoryId": 1192,
"InteractionType": "Interact" "InteractionType": "Interact",
"Fly": true
} }
] ]
}, },

View File

@ -42,6 +42,7 @@ internal sealed class InteractionUiController : IDisposable
private readonly GatheringPointRegistry _gatheringPointRegistry; private readonly GatheringPointRegistry _gatheringPointRegistry;
private readonly QuestRegistry _questRegistry; private readonly QuestRegistry _questRegistry;
private readonly QuestData _questData; private readonly QuestData _questData;
private readonly TerritoryData _territoryData;
private readonly IGameGui _gameGui; private readonly IGameGui _gameGui;
private readonly ITargetManager _targetManager; private readonly ITargetManager _targetManager;
private readonly IClientState _clientState; private readonly IClientState _clientState;
@ -61,6 +62,7 @@ internal sealed class InteractionUiController : IDisposable
GatheringPointRegistry gatheringPointRegistry, GatheringPointRegistry gatheringPointRegistry,
QuestRegistry questRegistry, QuestRegistry questRegistry,
QuestData questData, QuestData questData,
TerritoryData territoryData,
IGameGui gameGui, IGameGui gameGui,
ITargetManager targetManager, ITargetManager targetManager,
IPluginLog pluginLog, IPluginLog pluginLog,
@ -77,6 +79,7 @@ internal sealed class InteractionUiController : IDisposable
_gatheringPointRegistry = gatheringPointRegistry; _gatheringPointRegistry = gatheringPointRegistry;
_questRegistry = questRegistry; _questRegistry = questRegistry;
_questData = questData; _questData = questData;
_territoryData = territoryData;
_gameGui = gameGui; _gameGui = gameGui;
_targetManager = targetManager; _targetManager = targetManager;
_clientState = clientState; _clientState = clientState;
@ -101,7 +104,9 @@ internal sealed class InteractionUiController : IDisposable
} }
} }
private bool ShouldHandleUiInteractions => _isInitialCheck || _questController.IsRunning; private bool ShouldHandleUiInteractions => _isInitialCheck ||
_questController.IsRunning ||
_territoryData.IsQuestBattleInstance(_clientState.TerritoryType);
internal unsafe void HandleCurrentDialogueChoices() internal unsafe void HandleCurrentDialogueChoices()
{ {

View File

@ -735,7 +735,9 @@ internal sealed class QuestController : MiniTaskController<QuestController>, IDi
return false; return false;
QuestStep? currentStep = currentSequence?.FindStep(currentQuest.Step); QuestStep? currentStep = currentSequence?.FindStep(currentQuest.Step);
return currentStep?.AetheryteShortcut != null; return currentStep?.AetheryteShortcut != null &&
(currentStep.SkipConditions?.AetheryteShortcutIf?.QuestsCompleted.Count ?? 0) == 0 &&
(currentStep.SkipConditions?.AetheryteShortcutIf?.QuestsAccepted.Count ?? 0) == 0;
} }
public bool TryPickPriorityQuest() public bool TryPickPriorityQuest()

View File

@ -41,7 +41,7 @@ internal static class Combat
ArgumentNullException.ThrowIfNull(step.DataId); ArgumentNullException.ThrowIfNull(step.DataId);
yield return interactFactory.Interact(step.DataId.Value, quest, EInteractionType.None, true); yield return interactFactory.Interact(step.DataId.Value, quest, EInteractionType.None, true);
yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(2)); yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(1));
yield return CreateTask(quest, sequence, step); yield return CreateTask(quest, sequence, step);
break; break;
} }
@ -53,14 +53,14 @@ internal static class Combat
yield return useItemFactory.OnObject(quest.Id, step.DataId.Value, step.ItemId.Value, yield return useItemFactory.OnObject(quest.Id, step.DataId.Value, step.ItemId.Value,
step.CompletionQuestVariablesFlags, true); step.CompletionQuestVariablesFlags, true);
yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(2)); yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(1));
yield return CreateTask(quest, sequence, step); yield return CreateTask(quest, sequence, step);
break; break;
} }
case EEnemySpawnType.AutoOnEnterArea: case EEnemySpawnType.AutoOnEnterArea:
if (step.CombatDelaySecondsAtStart == null) if (step.CombatDelaySecondsAtStart == null)
yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(2)); yield return new WaitAtEnd.WaitDelay(TimeSpan.FromSeconds(1));
// automatically triggered when entering area, i.e. only unmount // automatically triggered when entering area, i.e. only unmount
yield return CreateTask(quest, sequence, step); yield return CreateTask(quest, sequence, step);

View File

@ -174,6 +174,14 @@ internal static class Interact
logger.LogInformation("Interaction was most likely triggered"); logger.LogInformation("Interaction was most likely triggered");
_interactionState = EInteractionState.InteractionConfirmed; _interactionState = EInteractionState.InteractionConfirmed;
} }
else if (dataId is >= 1047901 and <= 1047905 &&
condition[ConditionFlag.Disguised] &&
flag == ConditionFlag.Mounting71 && // why the fuck is this the flag that's used, instead of OccupiedIn[Quest]Event
value)
{
logger.LogInformation("(A Knight of Alexandria) Interaction was most likely triggered");
_interactionState = EInteractionState.InteractionConfirmed;
}
} }
private enum EInteractionState private enum EInteractionState

View File

@ -142,10 +142,10 @@ internal static class AethernetShortcut
logger.LogInformation("Moving to S9 aetheryte"); logger.LogInformation("Moving to S9 aetheryte");
List<Vector3> nearbyPoints = List<Vector3> nearbyPoints =
[ [
new(7.225532f, 8.467899f, -7.1670876f), new(0, 8.442986f, 9),
new(7.177844f, 8.467899f, 7.2216787f), new(9, 8.442986f, 0),
new(-7.0762224f, 8.467898f, 7.1924725f), new(-9, 8.442986f, 0),
new(-7.1289554f, 8.467898f, -7.0594683f) new(0, 8.442986f, -9),
]; ];
Vector3 closestPoint = nearbyPoints.MinBy(x => (playerPosition - x).Length()); Vector3 closestPoint = nearbyPoints.MinBy(x => (playerPosition - x).Length());

View File

@ -12,7 +12,7 @@ internal sealed class TerritoryData
{ {
private readonly ImmutableDictionary<uint, string> _territoryNames; private readonly ImmutableDictionary<uint, string> _territoryNames;
private readonly ImmutableHashSet<ushort> _territoriesWithMount; private readonly ImmutableHashSet<ushort> _territoriesWithMount;
private readonly ImmutableHashSet<ushort> _dutyTerritories; private readonly ImmutableDictionary<ushort, uint> _dutyTerritories;
private readonly ImmutableDictionary<ushort, string> _instanceNames; private readonly ImmutableDictionary<ushort, string> _instanceNames;
public TerritoryData(IDataManager dataManager) public TerritoryData(IDataManager dataManager)
@ -35,8 +35,7 @@ internal sealed class TerritoryData
_dutyTerritories = dataManager.GetExcelSheet<TerritoryType>()! _dutyTerritories = dataManager.GetExcelSheet<TerritoryType>()!
.Where(x => x.RowId > 0 && x.ContentFinderCondition.Row != 0) .Where(x => x.RowId > 0 && x.ContentFinderCondition.Row != 0)
.Select(x => (ushort)x.RowId) .ToImmutableDictionary(x => (ushort)x.RowId, x => x.ContentFinderCondition.Value!.ContentType.Row);
.ToImmutableHashSet();
_instanceNames = dataManager.GetExcelSheet<ContentFinderCondition>()! _instanceNames = dataManager.GetExcelSheet<ContentFinderCondition>()!
.Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6) .Where(x => x.RowId > 0 && x.Content != 0 && x.ContentLinkType == 1 && x.ContentType.Row != 6)
@ -56,7 +55,10 @@ internal sealed class TerritoryData
public bool CanUseMount(ushort territoryId) => _territoriesWithMount.Contains(territoryId); public bool CanUseMount(ushort territoryId) => _territoriesWithMount.Contains(territoryId);
public bool IsDutyInstance(ushort territoryId) => _dutyTerritories.Contains(territoryId); public bool IsDutyInstance(ushort territoryId) => _dutyTerritories.ContainsKey(territoryId);
public bool IsQuestBattleInstance(ushort territoryId) =>
_dutyTerritories.TryGetValue(territoryId, out uint contentType) && contentType == 7;
public string? GetInstanceName(ushort instanceId) => _instanceNames.GetValueOrDefault(instanceId); public string? GetInstanceName(ushort instanceId) => _instanceNames.GetValueOrDefault(instanceId);
} }

View File

@ -39,7 +39,7 @@ internal sealed class QuestInfo : IQuestInfo
{ {
new(new QuestId((ushort)(quest.PreviousQuest[0].Row & 0xFFFF)), quest.Unknown7), new(new QuestId((ushort)(quest.PreviousQuest[0].Row & 0xFFFF)), quest.Unknown7),
new(new QuestId((ushort)(quest.PreviousQuest[1].Row & 0xFFFF))), new(new QuestId((ushort)(quest.PreviousQuest[1].Row & 0xFFFF))),
new(new QuestId((ushort)(quest.PreviousQuest[1].Row & 0xFFFF))) new(new QuestId((ushort)(quest.PreviousQuest[2].Row & 0xFFFF)))
} }
.Where(x => x.QuestId.Value != 0) .Where(x => x.QuestId.Value != 0)
.ToImmutableList(); .ToImmutableList();

View File

@ -200,7 +200,7 @@ internal sealed class QuestTooltipComponent
if (questInfo.IsMainScenarioQuest) if (questInfo.IsMainScenarioQuest)
name += $" ({questInfo.QuestId}, MSQ)"; name += $" ({questInfo.QuestId}, MSQ)";
else else
name += $" {questInfo.Name} ({questInfo.QuestId})"; name += $" ({questInfo.QuestId})";
return name; return name;
} }