diff --git a/Directory.Build.targets b/Directory.Build.targets
index 8d0cd3238..b914cd1eb 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,5 +1,5 @@
- 2.5
+ 2.6
diff --git a/GatheringPathRenderer/RendererPlugin.cs b/GatheringPathRenderer/RendererPlugin.cs
index 55dee9847..636100ad3 100644
--- a/GatheringPathRenderer/RendererPlugin.cs
+++ b/GatheringPathRenderer/RendererPlugin.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
@@ -147,6 +148,7 @@ public sealed class RendererPlugin : IDalamudPlugin
{
JsonSerializerOptions options = new()
{
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
WriteIndented = true,
};
@@ -161,6 +163,7 @@ public sealed class RendererPlugin : IDalamudPlugin
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Indented = true
});
newNode.WriteTo(writer, options);
@@ -234,7 +237,7 @@ public sealed class RendererPlugin : IDalamudPlugin
Enabled = true,
overlayText =
$"{location.Root.Groups.IndexOf(group)} // {node.DataId} / {node.Locations.IndexOf(x)}",
- overlayBGColor = isUnsaved ? 0xFF2020FF : 0,
+ overlayBGColor = isUnsaved ? 0xFF2020FF : 0xFF000000,
},
new Element(ElementType.CircleAtFixedCoordinates)
{
diff --git a/GatheringPaths/7.x - Dawntrail/Kozama'uka/946__BTN.json b/GatheringPaths/7.x - Dawntrail/Kozama'uka/946__BTN.json
new file mode 100644
index 000000000..b97d0790f
--- /dev/null
+++ b/GatheringPaths/7.x - Dawntrail/Kozama'uka/946__BTN.json
@@ -0,0 +1,105 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
+ "Author": "liza",
+ "TerritoryId": 1188,
+ "AetheryteShortcut": "Kozama'uka - Ok'hanu",
+ "FlyBetweenNodes": true,
+ "Groups": [
+ {
+ "Nodes": [
+ {
+ "DataId": 34520,
+ "Locations": [
+ {
+ "Position": {
+ "X": 759.8123,
+ "Y": 26.14559,
+ "Z": -561.7435
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34521,
+ "Locations": [
+ {
+ "Position": {
+ "X": 791.0515,
+ "Y": 25.74059,
+ "Z": -545.9295
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34522,
+ "Locations": [
+ {
+ "Position": {
+ "X": 821.4519,
+ "Y": 28.47348,
+ "Z": -533.9607
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34517,
+ "Locations": [
+ {
+ "Position": {
+ "X": 840.8483,
+ "Y": 34.05744,
+ "Z": -586.0533
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34518,
+ "Locations": [
+ {
+ "Position": {
+ "X": 837.7969,
+ "Y": 33.55795,
+ "Z": -619.7623
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34519,
+ "Locations": [
+ {
+ "Position": {
+ "X": 784.021,
+ "Y": 24.16835,
+ "Z": -598.9781
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/GatheringPaths/7.x - Dawntrail/Urqopacha/961__MIN.json b/GatheringPaths/7.x - Dawntrail/Urqopacha/961__MIN.json
new file mode 100644
index 000000000..566b0c304
--- /dev/null
+++ b/GatheringPaths/7.x - Dawntrail/Urqopacha/961__MIN.json
@@ -0,0 +1,118 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
+ "Author": "liza",
+ "TerritoryId": 1187,
+ "AetheryteShortcut": "Urqopacha - Wachunpelo",
+ "FlyBetweenNodes": false,
+ "Groups": [
+ {
+ "Nodes": [
+ {
+ "DataId": 34646,
+ "Locations": [
+ {
+ "Position": {
+ "X": 227.4615,
+ "Y": -89.93336,
+ "Z": -225.4792
+ },
+ "MinimumAngle": 150,
+ "MaximumAngle": 250
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34641,
+ "Locations": [
+ {
+ "Position": {
+ "X": 249.5856,
+ "Y": -97.79176,
+ "Z": -217.3474
+ },
+ "MinimumAngle": 135,
+ "MaximumAngle": 215
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34642,
+ "Locations": [
+ {
+ "Position": {
+ "X": 257.8141,
+ "Y": -99.51778,
+ "Z": -217.7757
+ },
+ "MinimumAngle": 130,
+ "MaximumAngle": 240
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34643,
+ "Fly": true,
+ "Locations": [
+ {
+ "Position": {
+ "X": 274.7205,
+ "Y": -99.65348,
+ "Z": -201.6824
+ },
+ "MinimumAngle": 220,
+ "MaximumAngle": 270
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34644,
+ "Locations": [
+ {
+ "Position": {
+ "X": 278.0735,
+ "Y": -101.2599,
+ "Z": -194.8121
+ },
+ "MinimumAngle": 200,
+ "MaximumAngle": 300
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34645,
+ "Locations": [
+ {
+ "Position": {
+ "X": 308.4911,
+ "Y": -100.6525,
+ "Z": -174.6859
+ },
+ "MinimumAngle": 145,
+ "MaximumAngle": 210
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/GatheringPaths/7.x - Dawntrail/Yak T'el/955__BTN.json b/GatheringPaths/7.x - Dawntrail/Yak T'el/955__BTN.json
new file mode 100644
index 000000000..68779daa9
--- /dev/null
+++ b/GatheringPaths/7.x - Dawntrail/Yak T'el/955__BTN.json
@@ -0,0 +1,117 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
+ "Author": "liza",
+ "TerritoryId": 1189,
+ "AetheryteShortcut": "Yak T'el - Iq Br'aax",
+ "FlyBetweenNodes": true,
+ "Groups": [
+ {
+ "Nodes": [
+ {
+ "DataId": 34601,
+ "Locations": [
+ {
+ "Position": {
+ "X": 484.1779,
+ "Y": 16.59889,
+ "Z": -304.2079
+ },
+ "MinimumAngle": -185,
+ "MaximumAngle": 20
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34599,
+ "Locations": [
+ {
+ "Position": {
+ "X": 509.181,
+ "Y": 21.64949,
+ "Z": -349.9709
+ },
+ "MinimumAngle": -25,
+ "MaximumAngle": 80
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34597,
+ "Locations": [
+ {
+ "Position": {
+ "X": 534.7657,
+ "Y": 19.33411,
+ "Z": -333.3713
+ },
+ "MinimumAngle": 155,
+ "MaximumAngle": 275
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34600,
+ "Locations": [
+ {
+ "Position": {
+ "X": 525.0291,
+ "Y": 11.97125,
+ "Z": -252.6589
+ },
+ "MinimumAngle": 145,
+ "MaximumAngle": 265
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34598,
+ "Locations": [
+ {
+ "Position": {
+ "X": 518.5205,
+ "Y": 9.694121,
+ "Z": -223.9382
+ },
+ "MinimumAngle": 65,
+ "MaximumAngle": 170
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "Nodes": [
+ {
+ "DataId": 34602,
+ "Locations": [
+ {
+ "Position": {
+ "X": 480.2552,
+ "Y": 10.94543,
+ "Z": -234.4949
+ },
+ "MinimumAngle": 95,
+ "MaximumAngle": 180
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/GatheringPaths/7.x - Dawntrail/Yak T'el/970__MIN.json b/GatheringPaths/7.x - Dawntrail/Yak T'el/970__MIN.json
index 3cafe5312..27cfb7e2d 100644
--- a/GatheringPaths/7.x - Dawntrail/Yak T'el/970__MIN.json
+++ b/GatheringPaths/7.x - Dawntrail/Yak T'el/970__MIN.json
@@ -2,6 +2,7 @@
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "liza",
"TerritoryId": 1189,
+ "AetheryteShortcut": "Yak T'el - Mamook",
"Groups": [
{
"Nodes": [
@@ -112,4 +113,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/GatheringPaths/gatheringlocation-v1.json b/GatheringPaths/gatheringlocation-v1.json
index baac742c5..ffb288ab5 100644
--- a/GatheringPaths/gatheringlocation-v1.json
+++ b/GatheringPaths/gatheringlocation-v1.json
@@ -34,6 +34,11 @@
"$ref": "https://git.carvel.li/liza/Questionable/raw/branch/master/Questionable.Model/common-schema.json#/$defs/AethernetShard"
}
},
+ "FlyBetweenNodes": {
+ "description": "If nodes are close enough together, flying makes no sense due to the pathfinding overhead",
+ "type": "boolean",
+ "default": true
+ },
"Groups": {
"type": "array",
"items": {
@@ -49,6 +54,9 @@
"minimum": 30000,
"maximum": 50000
},
+ "Fly": {
+ "type": "boolean"
+ },
"Locations": {
"type": "array",
"items": {
diff --git a/QuestPathGenerator/GatheringSourceGenerator.cs b/QuestPathGenerator/GatheringSourceGenerator.cs
index 589aabb24..6ba6efbb1 100644
--- a/QuestPathGenerator/GatheringSourceGenerator.cs
+++ b/QuestPathGenerator/GatheringSourceGenerator.cs
@@ -143,6 +143,7 @@ public class GatheringSourceGenerator : ISourceGenerator
{
try
{
+ var emptyRoot = new GatheringRoot();
return ObjectCreationExpression(
IdentifierName(nameof(GatheringRoot)))
.WithInitializer(
@@ -151,10 +152,17 @@ public class GatheringSourceGenerator : ISourceGenerator
SeparatedList(
SyntaxNodeList(
AssignmentList(nameof(GatheringRoot.Author), root.Author).AsSyntaxNodeOrToken(),
- Assignment(nameof(GatheringRoot.TerritoryId), root.TerritoryId, default)
+ Assignment(nameof(GatheringRoot.TerritoryId), root.TerritoryId, emptyRoot.TerritoryId)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringRoot.AetheryteShortcut), root.AetheryteShortcut,
+ emptyRoot.AetheryteShortcut)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringRoot.AethernetShortcut), root.AethernetShortcut,
+ emptyRoot.AethernetShortcut)
+ .AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringRoot.FlyBetweenNodes), root.FlyBetweenNodes,
+ emptyRoot.FlyBetweenNodes)
.AsSyntaxNodeOrToken(),
- Assignment(nameof(GatheringRoot.AetheryteShortcut), root.AetheryteShortcut, null),
- Assignment(nameof(GatheringRoot.AethernetShortcut), root.AethernetShortcut, null),
AssignmentList(nameof(GatheringRoot.Groups), root.Groups).AsSyntaxNodeOrToken()))));
}
catch (Exception e)
diff --git a/QuestPathGenerator/RoslynShortcuts.cs b/QuestPathGenerator/RoslynShortcuts.cs
index 21b4a8206..d8ff117d1 100644
--- a/QuestPathGenerator/RoslynShortcuts.cs
+++ b/QuestPathGenerator/RoslynShortcuts.cs
@@ -408,6 +408,8 @@ public static class RoslynShortcuts
Assignment(nameof(GatheringNode.DataId), nodeLocation.DataId,
emptyLocation.DataId)
.AsSyntaxNodeOrToken(),
+ Assignment(nameof(GatheringNode.Fly), nodeLocation.Fly, emptyLocation.Fly)
+ .AsSyntaxNodeOrToken(),
AssignmentList(nameof(GatheringNode.Locations), nodeLocation.Locations)
.AsSyntaxNodeOrToken()))));
}
diff --git a/QuestPaths/7.x - Dawntrail/Leves/BTN/L1770_All Stars.json b/QuestPaths/7.x - Dawntrail/Leves/BTN/L1770_All Stars.json
new file mode 100644
index 000000000..293ab4d6b
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Leves/BTN/L1770_All Stars.json
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "Position": {
+ "X": 767.05066,
+ "Y": 24.645323,
+ "Z": -561.67883
+ },
+ "TerritoryId": 1188,
+ "InteractionType": "InitiateLeve",
+ "AetheryteShortcut": "Kozama'uka - Ok'hanu",
+ "Fly": true,
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
+ },
+ {
+ "TerritoryId": 1188,
+ "InteractionType": "None",
+ "RequiredGatheredItems": [
+ {
+ "ItemId": 2003516,
+ "AlternativeItemId": 2003517,
+ "ItemCount": 999
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/7.x - Dawntrail/Leves/BTN/L1779_New Start for the Cinderfield.json b/QuestPaths/7.x - Dawntrail/Leves/BTN/L1779_New Start for the Cinderfield.json
new file mode 100644
index 000000000..d7abd6096
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Leves/BTN/L1779_New Start for the Cinderfield.json
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "Position": {
+ "X": 518.05945,
+ "Y": 19.47163,
+ "Z": -335.71478
+ },
+ "TerritoryId": 1189,
+ "InteractionType": "InitiateLeve",
+ "AetheryteShortcut": "Yak T'el - Iq Br'aax",
+ "Fly": true,
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
+ },
+ {
+ "TerritoryId": 1189,
+ "InteractionType": "None",
+ "RequiredGatheredItems": [
+ {
+ "ItemId": 2003529,
+ "AlternativeItemId": 2003530,
+ "ItemCount": 999
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/7.x - Dawntrail/Leves/MIN/L1785_Old and Bubbly.json b/QuestPaths/7.x - Dawntrail/Leves/MIN/L1785_Old and Bubbly.json
new file mode 100644
index 000000000..e5f1f2991
--- /dev/null
+++ b/QuestPaths/7.x - Dawntrail/Leves/MIN/L1785_Old and Bubbly.json
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/QuestPaths/quest-v1.json",
+ "Author": "liza",
+ "QuestSequence": [
+ {
+ "Sequence": 1,
+ "Steps": [
+ {
+ "Position": {
+ "X": 228.24704,
+ "Y": -91.93331,
+ "Z": -229.72751
+ },
+ "TerritoryId": 1187,
+ "InteractionType": "InitiateLeve",
+ "AetheryteShortcut": "Urqopacha - Wachunpelo",
+ "Fly": true,
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
+ },
+ {
+ "TerritoryId": 1187,
+ "InteractionType": "None",
+ "RequiredGatheredItems": [
+ {
+ "ItemId": 2003539,
+ "AlternativeItemId": 2003540,
+ "ItemCount": 999
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/QuestPaths/7.x - Dawntrail/Leves/MIN/L1794_Vestiges of War.json b/QuestPaths/7.x - Dawntrail/Leves/MIN/L1794_Vestiges of War.json
index ecbe236ab..75e19368b 100644
--- a/QuestPaths/7.x - Dawntrail/Leves/MIN/L1794_Vestiges of War.json
+++ b/QuestPaths/7.x - Dawntrail/Leves/MIN/L1794_Vestiges of War.json
@@ -30,8 +30,7 @@
"AlternativeItemId": 2003553,
"ItemCount": 999
}
- ],
- "$.0": "41635 → 970"
+ ]
}
]
}
diff --git a/Questionable.Model/Gathering/GatheringNode.cs b/Questionable.Model/Gathering/GatheringNode.cs
index a88f53ebd..9a3ed58cb 100644
--- a/Questionable.Model/Gathering/GatheringNode.cs
+++ b/Questionable.Model/Gathering/GatheringNode.cs
@@ -5,6 +5,7 @@ namespace Questionable.Model.Gathering;
public sealed class GatheringNode
{
public uint DataId { get; set; }
+ public bool Fly { get; set; }
public List Locations { get; set; } = [];
}
diff --git a/Questionable.Model/Gathering/GatheringRoot.cs b/Questionable.Model/Gathering/GatheringRoot.cs
index 9011f5625..b1f98ca85 100644
--- a/Questionable.Model/Gathering/GatheringRoot.cs
+++ b/Questionable.Model/Gathering/GatheringRoot.cs
@@ -16,5 +16,6 @@ public sealed class GatheringRoot
public EAetheryteLocation? AetheryteShortcut { get; set; }
public AethernetShortcut? AethernetShortcut { get; set; }
+ public bool FlyBetweenNodes { get; set; } = true;
public List Groups { get; set; } = [];
}
diff --git a/Questionable.Model/Questing/EInteractionType.cs b/Questionable.Model/Questing/EInteractionType.cs
index b52458caf..4ad648154 100644
--- a/Questionable.Model/Questing/EInteractionType.cs
+++ b/Questionable.Model/Questing/EInteractionType.cs
@@ -36,4 +36,7 @@ public enum EInteractionType
AcceptLeve,
InitiateLeve,
CompleteLeve,
+
+ // unmapped extra types below
+ InternalGather,
}
diff --git a/Questionable/Controller/GameUiController.cs b/Questionable/Controller/GameUiController.cs
index 3a518a1b6..4b366c7dc 100644
--- a/Questionable/Controller/GameUiController.cs
+++ b/Questionable/Controller/GameUiController.cs
@@ -846,24 +846,43 @@ internal sealed class GameUiController : IDisposable
_logger.LogInformation("Leve {Index} = {Id}, {Name}", i, questInfo.QuestId, questInfo.Name);
*/
- _framework.RunOnTick(() =>
- {
- _questController.SetPendingQuest(nextQuest);
- _questController.SetNextQuest(null);
-
- var agent = UIModule.Instance()->GetAgentModule()->GetAgentByInternalId(AgentId.LeveQuest);
- var returnValue = stackalloc AtkValue[1];
- var selectQuest = stackalloc AtkValue[]
- {
- new() { Type = ValueType.Int, Int = 3 },
- new() { Type = ValueType.UInt, UInt = nextQuest.Quest.Id.Value }
- };
- agent->ReceiveEvent(returnValue, selectQuest, 2, 0);
- addon->Close(true);
- }, TimeSpan.FromMilliseconds(100));
+ _framework.RunOnTick(() => AcceptLeveOrWait(nextQuest), TimeSpan.FromMilliseconds(100));
}
}
+ private unsafe void AcceptLeveOrWait(QuestController.QuestProgress nextQuest, int counter = 0)
+ {
+ var agent = UIModule.Instance()->GetAgentModule()->GetAgentByInternalId(AgentId.LeveQuest);
+ if (agent->IsAgentActive() &&
+ _gameGui.TryGetAddonByName("GuildLeve", out AddonGuildLeve* addonGuildLeve) &&
+ LAddon.IsAddonReady(&addonGuildLeve->AtkUnitBase) &&
+ _gameGui.TryGetAddonByName("JournalDetail", out AtkUnitBase* addonJournalDetail) &&
+ LAddon.IsAddonReady(addonJournalDetail))
+ {
+ AcceptLeve(agent, addonGuildLeve, nextQuest);
+ }
+ else if (counter >= 10)
+ _logger.LogWarning("Unable to accept leve?");
+ else
+ _framework.RunOnTick(() => AcceptLeveOrWait(nextQuest, counter + 1), TimeSpan.FromMilliseconds(100));
+ }
+
+ private unsafe void AcceptLeve(AgentInterface* agent, AddonGuildLeve* addon,
+ QuestController.QuestProgress nextQuest)
+ {
+ _questController.SetPendingQuest(nextQuest);
+ _questController.SetNextQuest(null);
+
+ var returnValue = stackalloc AtkValue[1];
+ var selectQuest = stackalloc AtkValue[]
+ {
+ new() { Type = ValueType.Int, Int = 3 },
+ new() { Type = ValueType.UInt, UInt = nextQuest.Quest.Id.Value }
+ };
+ agent->ReceiveEvent(returnValue, selectQuest, 2, 0);
+ addon->Close(true);
+ }
+
private StringOrRegex? ResolveReference(Quest? quest, string? excelSheet, ExcelRef? excelRef, bool isRegExp)
{
if (excelRef == null)
diff --git a/Questionable/Controller/GatheringController.cs b/Questionable/Controller/GatheringController.cs
index 446c38c21..53878e531 100644
--- a/Questionable/Controller/GatheringController.cs
+++ b/Questionable/Controller/GatheringController.cs
@@ -144,7 +144,8 @@ internal sealed unsafe class GatheringController : MiniTaskController x.Position.Y).Max() + 5f,
Z = currentNode.Locations.Sum(x => x.Position.Z) / currentNode.Locations.Count,
};
- bool fly = _gameFunctions.IsFlyingUnlocked(_currentRequest.Root.TerritoryId);
+ bool fly = (currentNode.Fly || _currentRequest.Root.FlyBetweenNodes)
+ && _gameFunctions.IsFlyingUnlocked(_currentRequest.Root.TerritoryId);
Vector3? pointOnFloor = _navmeshIpc.GetPointOnFloor(averagePosition, true);
if (pointOnFloor != null)
pointOnFloor = pointOnFloor.Value with { Y = pointOnFloor.Value.Y + (fly ? 3f : 0f) };
@@ -155,9 +156,11 @@ internal sealed unsafe class GatheringController : MiniTaskController()
- .With(_currentRequest.Root.TerritoryId, currentNode));
+ .With(_currentRequest.Root.TerritoryId,
+ currentNode.Fly || _currentRequest.Root.FlyBetweenNodes,
+ currentNode));
_taskQueue.Enqueue(_serviceProvider.GetRequiredService()
- .With(currentNode.DataId, null, EInteractionType.None, true));
+ .With(currentNode.DataId, null, EInteractionType.InternalGather, true));
_taskQueue.Enqueue(_serviceProvider.GetRequiredService()
.With(_currentRequest.Data, currentNode));
if (_currentRequest.Data.Collectability > 0)
@@ -197,8 +200,8 @@ internal sealed unsafe class GatheringController : MiniTaskController
- _objectTable.FirstOrDefault(y =>
- currentNode.DataId == y.DataId && Vector3.Distance(x.Position, y.Position) < 0.1f))
+ _objectTable.FirstOrDefault(y =>
+ currentNode.DataId == y.DataId && Vector3.Distance(x.Position, y.Position) < 0.1f))
.ToList();
// Are any of the nodes too far away to be found? This is likely around ~100 yalms. All closer gathering
diff --git a/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs b/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs
index ff27374ed..84b9c8889 100644
--- a/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs
+++ b/Questionable/Controller/Steps/Gathering/MoveToLandingLocation.cs
@@ -20,12 +20,14 @@ internal sealed class MoveToLandingLocation(
ILogger logger) : ITask
{
private ushort _territoryId;
+ private bool _flyBetweenNodes;
private GatheringNode _gatheringNode = null!;
private ITask _moveTask = null!;
- public ITask With(ushort territoryId, GatheringNode gatheringNode)
+ public ITask With(ushort territoryId, bool flyBetweenNodes, GatheringNode gatheringNode)
{
_territoryId = territoryId;
+ _flyBetweenNodes = flyBetweenNodes;
_gatheringNode = gatheringNode;
return this;
}
@@ -47,7 +49,7 @@ internal sealed class MoveToLandingLocation(
logger.LogInformation("Preliminary landing location: {Location}, with degrees = {Degrees}, range = {Range}",
target.ToString("G", CultureInfo.InvariantCulture), degrees, range);
- bool fly = gameFunctions.IsFlyingUnlocked(_territoryId);
+ bool fly = _flyBetweenNodes && gameFunctions.IsFlyingUnlocked(_territoryId);
_moveTask = serviceProvider.GetRequiredService()
.With(_territoryId, target, 0.25f, dataId: _gatheringNode.DataId, fly: fly,
ignoreDistanceToObject: true);
@@ -56,5 +58,5 @@ internal sealed class MoveToLandingLocation(
public ETaskResult Update() => _moveTask.Update();
- public override string ToString() => $"Land/{_moveTask}";
+ public override string ToString() => $"Land/{_moveTask}/{_flyBetweenNodes}";
}
diff --git a/Questionable/Controller/Steps/Interactions/Interact.cs b/Questionable/Controller/Steps/Interactions/Interact.cs
index e45a2da75..dc50ac06a 100644
--- a/Questionable/Controller/Steps/Interactions/Interact.cs
+++ b/Questionable/Controller/Steps/Interactions/Interact.cs
@@ -116,6 +116,9 @@ internal static class Interact
if (_interactionState == EInteractionState.InteractionConfirmed)
return ETaskResult.TaskComplete;
+ if (InteractionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
+ return ETaskResult.TaskComplete;
+
IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId);
if (gameObject == null || !gameObject.IsTargetable || !HasAnyMarker(gameObject))
return ETaskResult.StillRunning;
diff --git a/Questionable/Controller/Steps/Leves/InitiateLeve.cs b/Questionable/Controller/Steps/Leves/InitiateLeve.cs
index 1c9ee563d..42cd8a484 100644
--- a/Questionable/Controller/Steps/Leves/InitiateLeve.cs
+++ b/Questionable/Controller/Steps/Leves/InitiateLeve.cs
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.Game.Event;
+using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using LLib.GameUI;
@@ -22,6 +24,7 @@ internal static class InitiateLeve
if (step.InteractionType != EInteractionType.InitiateLeve)
yield break;
+ yield return serviceProvider.GetRequiredService().With(quest.Id);
yield return serviceProvider.GetRequiredService().With(quest.Id);
yield return serviceProvider.GetRequiredService().With(quest.Id);
yield return serviceProvider.GetRequiredService();
@@ -32,6 +35,33 @@ internal static class InitiateLeve
=> throw new NotImplementedException();
}
+ internal sealed unsafe class SkipInitiateIfActive : ITask
+ {
+ private ElementId _elementId = null!;
+
+ public ITask With(ElementId elementId)
+ {
+ _elementId = elementId;
+ return this;
+ }
+
+ public bool Start() => true;
+
+ public ETaskResult Update()
+ {
+ var director = UIState.Instance()->DirectorTodo.Director;
+ if (director != null &&
+ director->EventHandlerInfo != null &&
+ director->EventHandlerInfo->EventId.ContentId == EventHandlerType.GatheringLeveDirector &&
+ director->ContentId == _elementId.Value)
+ return ETaskResult.SkipRemainingTasksForStep;
+
+ return ETaskResult.TaskComplete;
+ }
+
+ public override string ToString() => $"CheckIfAlreadyActive({_elementId})";
+ }
+
internal sealed unsafe class OpenJournal : ITask
{
private ElementId _elementId = null!;
diff --git a/Questionable/QuestionablePlugin.cs b/Questionable/QuestionablePlugin.cs
index a8e5bfe96..4b3b635d1 100644
--- a/Questionable/QuestionablePlugin.cs
+++ b/Questionable/QuestionablePlugin.cs
@@ -158,7 +158,10 @@ public sealed class QuestionablePlugin : IDalamudPlugin
.AddTaskWithFactory();
serviceCollection
- .AddTaskWithFactory();
serviceCollection
diff --git a/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs b/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs
index 61bb05633..52bcd6592 100644
--- a/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs
+++ b/Questionable/Windows/QuestComponents/CreationUtilsComponent.cs
@@ -119,10 +119,10 @@ internal sealed class CreationUtilsComponent
ImGui.Text($"Ico: {director->IconId}");
if (director->EventHandlerInfo != null)
{
- ImGui.Text($" EHI: {director->EventHandlerInfo->EventId.ContentId}");
- ImGui.Text($" EHI: {director->EventHandlerInfo->EventId.Id}");
- ImGui.Text($" EHI: {director->EventHandlerInfo->EventId.EntryId}");
- ImGui.Text($" EHI: {director->EventHandlerInfo->Flags}");
+ ImGui.Text($" EHI CI: {director->EventHandlerInfo->EventId.ContentId}");
+ ImGui.Text($" EHI EI: {director->EventHandlerInfo->EventId.Id}");
+ ImGui.Text($" EHI EEI: {director->EventHandlerInfo->EventId.EntryId}");
+ ImGui.Text($" EHI F: {director->EventHandlerInfo->Flags}");
}
}
#endif