{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "Redacted",
- "ExtraQuestItems": [
- 2001426,
- 2001427
- ],
"Steps": [
{
"TerritoryId": 155,
"InteractionType": "None",
- "AetheryteShortcut": "Coerthas Central Highlands - Camp Dragonhead"
+ "AetheryteShortcut": "Coerthas Central Highlands - Camp Dragonhead",
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
}
],
+ "ExtraQuestItems": [
+ 2001426,
+ 2001427
+ ],
"Groups": [
{
"Nodes": [
"Y": 305.9586,
"Z": -236.1029
},
- "MinimumAngle": -300,
- "MaximumAngle": -130
+ "MinimumAngle": -270,
+ "MaximumAngle": -155,
+ "MinimumDistance": 1,
+ "MaximumDistance": 1.8
}
]
}
"Y": 321.804,
"Z": -231.1056
},
- "MinimumAngle": -300,
- "MaximumAngle": -40
+ "MinimumAngle": -285,
+ "MaximumAngle": -60
}
]
}
"Y": 309.1797,
"Z": -201.3309
},
- "MinimumAngle": 80,
- "MaximumAngle": 260
+ "MinimumAngle": 105,
+ "MaximumAngle": 220
},
{
"Position": {
"Y": 305.774,
"Z": -206.6072
},
- "MinimumAngle": -240,
- "MaximumAngle": -20
+ "MinimumAngle": -220,
+ "MaximumAngle": -30
}
]
}
"X": 325.9026,
"Y": 306.1053,
"Z": -278.1509
- }
+ },
+ "MinimumAngle": -350,
+ "MaximumAngle": -55
},
{
"Position": {
"X": 289.1882,
"Y": 302.4524,
"Z": -261.3322
- }
+ },
+ "MinimumAngle": -240,
+ "MaximumAngle": 20
}
]
}
]
}
]
-}
\ No newline at end of file
+}
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
- "ExtraQuestItems": [
- 2001415,
- 2001416
- ],
"Author": "Redacted",
"Steps": [
{
"TerritoryId": 156,
"InteractionType": "None",
- "AetheryteShortcut": "Mor Dhona"
+ "AetheryteShortcut": "Mor Dhona",
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
}
],
+ "ExtraQuestItems": [
+ 2001415,
+ 2001416
+ ],
"Groups": [
{
"Nodes": [
"Y": -15.49291,
"Z": -326.9827
},
- "MinimumAngle": -295,
- "MaximumAngle": -100
+ "MinimumAngle": -250,
+ "MaximumAngle": -115
},
{
"Position": {
"Y": -15.7935,
"Z": -321.7334
},
- "MinimumAngle": -235,
- "MaximumAngle": -60
+ "MinimumAngle": -190,
+ "MaximumAngle": -100
}
]
}
"Y": -13.83647,
"Z": -329.9288
},
- "MinimumAngle": -90,
- "MaximumAngle": 100
+ "MinimumAngle": -55,
+ "MaximumAngle": 70,
+ "MinimumDistance": 1.4,
+ "MaximumDistance": 3
},
{
"Position": {
"Y": -11.39756,
"Z": -323.1493
},
- "MinimumAngle": -90,
- "MaximumAngle": 125
+ "MinimumAngle": -65,
+ "MaximumAngle": 95
}
]
}
"Y": -8.5558,
"Z": -326.8167
},
- "MinimumAngle": -160,
- "MaximumAngle": 40
+ "MinimumAngle": -135,
+ "MaximumAngle": 5
},
{
"Position": {
"Y": -6.345774,
"Z": -325.4775
},
- "MinimumAngle": 95,
- "MaximumAngle": 290
+ "MinimumAngle": 135,
+ "MaximumAngle": 250,
+ "MinimumDistance": 1.4,
+ "MaximumDistance": 3
}
]
}
"Y": -5.395673,
"Z": -317.087
},
- "MinimumAngle": 145,
- "MaximumAngle": 305
+ "MinimumAngle": 180,
+ "MaximumAngle": 275
},
{
"Position": {
"Y": -5.140871,
"Z": -324.9326
},
- "MinimumAngle": -55,
- "MaximumAngle": 110
+ "MinimumAngle": -10,
+ "MaximumAngle": 60,
+ "MinimumDistance": 1.8,
+ "MaximumDistance": 3
}
]
}
]
}
]
-}
\ No newline at end of file
+}
{
"$schema": "https://git.carvel.li/liza/Questionable/raw/branch/master/GatheringPaths/gatheringlocation-v1.json",
"Author": "Redacted",
- "ExtraQuestItems": [
- 2001412,
- 2001413
- ],
"Steps": [
{
"TerritoryId": 156,
"InteractionType": "None",
- "AetheryteShortcut": "Mor Dhona"
+ "AetheryteShortcut": "Mor Dhona",
+ "SkipConditions": {
+ "AetheryteShortcutIf": {
+ "InSameTerritory": true
+ }
+ }
}
],
+ "ExtraQuestItems": [
+ 2001412,
+ 2001413
+ ],
"Groups": [
{
"Nodes": [
"Y": -15.86567,
"Z": -363.9182
},
- "MinimumAngle": -185,
- "MaximumAngle": -10
+ "MinimumAngle": -145,
+ "MaximumAngle": -35
},
{
"Position": {
"Y": -16.00947,
"Z": -351.6216
},
- "MinimumAngle": -160,
- "MaximumAngle": 45
+ "MinimumAngle": -125,
+ "MaximumAngle": 30
}
]
}
"Y": -16.46771,
"Z": -338.7833
},
- "MinimumAngle": -115,
- "MaximumAngle": 100
+ "MinimumAngle": -90,
+ "MaximumAngle": 75
},
{
"Position": {
"Y": -16.07329,
"Z": -337.0371
},
- "MinimumAngle": -80,
- "MaximumAngle": 130
+ "MinimumAngle": -65,
+ "MaximumAngle": 105
}
]
},
"Y": -16.18071,
"Z": -338.7262
},
- "MinimumAngle": -50,
+ "MinimumAngle": -35,
"MaximumAngle": 140
}
]
"Y": -15.12936,
"Z": -346.8752
},
- "MinimumAngle": -240,
- "MaximumAngle": -60
+ "MinimumAngle": -195,
+ "MaximumAngle": -110
},
{
"Position": {
"Y": -16.14678,
"Z": -363.7992
},
- "MinimumAngle": -50,
- "MaximumAngle": 175
+ "MinimumAngle": -20,
+ "MaximumAngle": 145
}
]
}
]
}
]
-}
\ No newline at end of file
+}
Wasshoi = 11499,
CollectMiner = 240,
+ LuckOfTheMountaineer = 4081,
ScourMiner = 22182,
MeticulousMiner = 22184,
ScrutinyMiner = 22185,
CollectBotanist = 815,
+ LuckOfThePioneer = 4095,
ScourBotanist = 22186,
MeticulousBotanist = 22188,
ScrutinyBotanist = 22189,
ILogger<GatherExecutor> logger) : TaskExecutor<Task>
{
private bool _wasGathering;
+ private bool _usedLuck;
private SlotInfo? _slotToGather;
private Queue<EAction>? _actionQueue;
}
_actionQueue = GetNextActions(nodeCondition, slots);
- if (_actionQueue.Count == 0)
+ if (_actionQueue == null)
{
- var slot = _slotToGather ?? slots.Single(x => x.ItemId == Task.Request.ItemId);
- addonGathering->FireCallbackInt(slot.Index);
+ logger.LogInformation("Skipping the rest of gathering...");
+ addonGathering->FireCallbackInt(-1);
+ return ETaskResult.TaskComplete;
+ }
+ else if (_actionQueue.Count == 0)
+ {
+ var slot = _slotToGather ?? slots.SingleOrDefault(x => x.ItemId == Task.Request.ItemId) ?? slots.MinBy(x => x.ItemId);
+ if (slot?.ItemId is >= 2 and <= 19)
+ {
+ InventoryManager* inventoryManager = InventoryManager.Instance();
+ if (inventoryManager->GetInventoryItemCount(slot.ItemId) == 9999)
+ slot = null;
+ }
+
+ if (slot != null)
+ addonGathering->FireCallbackInt(slot.Index);
+ else
+ addonGathering->FireCallbackInt(-1);
}
}
}
}
[SuppressMessage("ReSharper", "UnusedParameter.Local")]
- private Queue<EAction> GetNextActions(NodeCondition nodeCondition, List<SlotInfo> slots)
+ private Queue<EAction>? GetNextActions(NodeCondition nodeCondition, List<SlotInfo> slots)
{
+ // it's possible the item has disappeared
+ if (_slotToGather != null && slots.All(x => x.Index != _slotToGather.Index))
+ _slotToGather = null;
+
//uint gp = clientState.LocalPlayer!.CurrentGp;
Queue<EAction> actions = new();
}
}
- var slot = slots.Single(x => x.ItemId == Task.Request.ItemId);
- if (slot.GatheringChance > 0 && slot.GatheringChance < 100)
+ SlotInfo? slot = slots.SingleOrDefault(x => x.ItemId == Task.Request.ItemId);
+ if (slot == null)
+ {
+ if (!_usedLuck &&
+ nodeCondition.CurrentIntegrity == nodeCondition.MaxIntegrity &&
+ CanUseAction(EAction.LuckOfTheMountaineer, EAction.LuckOfThePioneer))
+ {
+ _usedLuck = true;
+ actions.Enqueue(PickAction(EAction.LuckOfTheMountaineer, EAction.LuckOfThePioneer));
+ return actions;
+ }
+ else if (_usedLuck)
+ {
+ // we still can't find the item, if this node has been hit at least once we just close it
+ if (nodeCondition.CurrentIntegrity != nodeCondition.MaxIntegrity)
+ return null;
+
+ // otherwise, there most likely is -any- other item available, probably a shard/crystal
+ _slotToGather = slots.MinBy(x => x.ItemId);
+ return actions;
+ }
+ }
+
+ slot = slots.SingleOrDefault(x => x.ItemId == Task.Request.ItemId);
+ if (slot is { GatheringChance: > 0 and < 100 })
{
if (slot.GatheringChance >= 95 &&
CanUseAction(EAction.SharpVision1, EAction.FieldMastery1))
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
+using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Component.GUI;
+using LLib.GameUI;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Shared;
using Questionable.Data;
return null;
}
}
+
+
+ internal sealed class CloseGatheringAddonFactory(IGameGui gameGui) : ITaskFactory
+ {
+ public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
+ {
+ if (IsAddonOpen("GatheringMasterpiece"))
+ yield return new CloseGatheringAddonTask("GatheringMasterpiece");
+
+ if (IsAddonOpen("Gathering"))
+ yield return new CloseGatheringAddonTask("Gathering");
+ }
+
+ private unsafe bool IsAddonOpen(string name)
+ {
+ return gameGui.TryGetAddonByName(name, out AtkUnitBase* addon) && addon->IsVisible;
+ }
+ }
+
+ internal sealed record CloseGatheringAddonTask(string AddonName) : ITask
+ {
+ public override string ToString() => $"CloseAddon({AddonName})";
+ }
+
+ internal sealed class DoCloseAddon(IGameGui gameGui) : TaskExecutor<CloseGatheringAddonTask>
+ {
+ protected override unsafe bool Start()
+ {
+ if (gameGui.TryGetAddonByName(Task.AddonName, out AtkUnitBase* addon))
+ {
+ addon->FireCallbackInt(-1);
+ return true;
+ }
+
+ return false;
+ }
+
+ public override ETaskResult Update() => ETaskResult.TaskComplete;
+
+ public override bool ShouldInterruptOnDamage() => false;
+ }
}
{
// individual tasks
serviceCollection.AddTaskFactory<QuestCleanUp.CheckAlliedSocietyMount>();
+ serviceCollection.AddTaskFactoryAndExecutor<QuestCleanUp.CloseGatheringAddonTask, QuestCleanUp.CloseGatheringAddonFactory, QuestCleanUp.DoCloseAddon>();
serviceCollection
.AddTaskExecutor<MoveToLandingLocation.Task, MoveToLandingLocation.MoveToLandingLocationExecutor>();
serviceCollection