diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/129_Spirithold Broken.json b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/129_Spirithold Broken.json index 8c7b51e1..cdb594ab 100644 --- a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/129_Spirithold Broken.json +++ b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/129_Spirithold Broken.json @@ -35,18 +35,6 @@ { "Sequence": 2, "Steps": [ - { - "DataId": 1000465, - "Position": { - "X": 298.63428, - "Y": 9.999997, - "Z": 119.035645 - }, - "TerritoryId": 148, - "InteractionType": "WaitForManualProgress", - "Comment": "Manual Quest Progress (very combat heavy)", - "$": "TODO Remove later" - }, { "DataId": 1000512, "Position": { @@ -56,7 +44,6 @@ }, "TerritoryId": 148, "InteractionType": "Interact", - "Disabled": true, "CompletionQuestVariablesFlags": [ null, null, @@ -75,7 +62,6 @@ }, "TerritoryId": 148, "InteractionType": "Interact", - "Disabled": true, "CompletionQuestVariablesFlags": [ null, null, @@ -94,7 +80,6 @@ }, "TerritoryId": 148, "InteractionType": "Interact", - "Disabled": true, "CompletionQuestVariablesFlags": [ null, null, @@ -113,7 +98,6 @@ }, "TerritoryId": 148, "InteractionType": "Interact", - "Disabled": true, "CompletionQuestVariablesFlags": [ null, null, @@ -132,7 +116,6 @@ }, "TerritoryId": 148, "InteractionType": "Interact", - "Disabled": true, "CompletionQuestVariablesFlags": [ null, null, diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/175_Surveying the Damage.json b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/175_Surveying the Damage.json index e62a1b0c..a254f620 100644 --- a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/175_Surveying the Damage.json +++ b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/175_Surveying the Damage.json @@ -21,6 +21,26 @@ "Sequence": 1, "Comment": "Very likely this needs manual combat and/or manual continues", "Steps": [ + { + "Position": { + "X": 192.07129, + "Y": -12.000001, + "Z": 38.204 + }, + "TerritoryId": 148, + "InteractionType": "WalkTo" + }, + { + "Position": { + "X": 190.28528, + "Y": -12, + "Z": 77.53861 + }, + "TerritoryId": 148, + "InteractionType": "Combat", + "EnemySpawnType": "FinishCombatIfAny", + "KillEnemyDataIds": [] + }, { "DataId": 2000141, "Position": { diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/201_Passing Muster.json b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/201_Passing Muster.json index d9a568be..266df28e 100644 --- a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/201_Passing Muster.json +++ b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/201_Passing Muster.json @@ -24,6 +24,75 @@ "TerritoryId": 148, "InteractionType": "EquipRecommended" }, + { + "DataId": 1000396, + "Position": { + "X": 82.597046, + "Y": -7.893894, + "Z": -103.349365 + }, + "TerritoryId": 148, + "InteractionType": "PurchaseItem", + "PurchaseMenu": { + "ExcelSheet": "GilShop", + "Key": 262186 + }, + "ItemId": 2653, + "ItemCount": 1, + "RequiredCurrentJob": [ + "DoW" + ], + "SkipConditions": { + "StepIf": { + "Item": { + "NotInInventory": false + } + } + } + }, + { + "DataId": 1000396, + "Position": { + "X": 82.597046, + "Y": -7.893894, + "Z": -103.349365 + }, + "TerritoryId": 148, + "InteractionType": "PurchaseItem", + "PurchaseMenu": { + "ExcelSheet": "GilShop", + "Key": 262186 + }, + "ItemId": 2655, + "ItemCount": 1, + "RequiredCurrentJob": [ + "DoM" + ] + }, + { + "TerritoryId": 148, + "InteractionType": "EquipItem", + "ItemId": 2653, + "SkipConditions": { + "StepIf": { + "Item": { + "NotInInventory": true + } + } + } + }, + { + "TerritoryId": 148, + "InteractionType": "EquipItem", + "ItemId": 2655, + "SkipConditions": { + "StepIf": { + "Item": { + "NotInInventory": true + } + } + } + }, { "DataId": 1000421, "Position": { diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/3855_A Soldier's Breakfast.json b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/3855_A Soldier's Breakfast.json index 64af3a34..dd2e59d1 100644 --- a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/3855_A Soldier's Breakfast.json +++ b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Gridania/3855_A Soldier's Breakfast.json @@ -20,6 +20,17 @@ { "Sequence": 1, "Steps": [ + { + "Position": { + "X": 486.40424, + "Y": 24.968294, + "Z": -88.684456 + }, + "TerritoryId": 148, + "InteractionType": "Combat", + "EnemySpawnType": "FinishCombatIfAny", + "KillEnemyDataIds": [] + }, { "DataId": 2000010, "Position": { diff --git a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Limsa/463_Dressed to Call.json b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Limsa/463_Dressed to Call.json index 2911b4e9..db9debe7 100644 --- a/QuestPaths/2.x - A Realm Reborn/MSQ-1/Limsa/463_Dressed to Call.json +++ b/QuestPaths/2.x - A Realm Reborn/MSQ-1/Limsa/463_Dressed to Call.json @@ -24,6 +24,75 @@ "TerritoryId": 134, "InteractionType": "EquipRecommended" }, + { + "DataId": 1003257, + "Position": { + "X": 201.70898, + "Y": 98.422874, + "Z": -206.10364 + }, + "TerritoryId": 134, + "InteractionType": "PurchaseItem", + "PurchaseMenu": { + "ExcelSheet": "GilShop", + "Key": 262186 + }, + "ItemId": 2653, + "ItemCount": 1, + "RequiredCurrentJob": [ + "DoW" + ], + "SkipConditions": { + "StepIf": { + "Item": { + "NotInInventory": false + } + } + } + }, + { + "DataId": 1003257, + "Position": { + "X": 201.70898, + "Y": 98.422874, + "Z": -206.10364 + }, + "TerritoryId": 134, + "InteractionType": "PurchaseItem", + "PurchaseMenu": { + "ExcelSheet": "GilShop", + "Key": 262186 + }, + "ItemId": 2655, + "ItemCount": 1, + "RequiredCurrentJob": [ + "DoM" + ] + }, + { + "TerritoryId": 134, + "InteractionType": "EquipItem", + "ItemId": 2653, + "SkipConditions": { + "StepIf": { + "Item": { + "NotInInventory": true + } + } + } + }, + { + "TerritoryId": 134, + "InteractionType": "EquipItem", + "ItemId": 2655, + "SkipConditions": { + "StepIf": { + "Item": { + "NotInInventory": true + } + } + } + }, { "DataId": 1002626, "Position": { diff --git a/QuestPaths/quest-v1.json b/QuestPaths/quest-v1.json index 134b1c60..7511bc27 100644 --- a/QuestPaths/quest-v1.json +++ b/QuestPaths/quest-v1.json @@ -593,7 +593,8 @@ "AfterAction", "AfterEmote", "OverworldEnemies", - "FateEnemies" + "FateEnemies", + "FinishCombatIfAny" ] }, "KillEnemyDataIds": { diff --git a/Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs b/Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs index 1b43eaf4..58b292f3 100644 --- a/Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs +++ b/Questionable.Model/Questing/Converter/EnemySpawnTypeConverter.cs @@ -14,5 +14,6 @@ public sealed class EnemySpawnTypeConverter() : EnumConverter(V { EEnemySpawnType.AutoOnEnterArea, "AutoOnEnterArea" }, { EEnemySpawnType.OverworldEnemies, "OverworldEnemies" }, { EEnemySpawnType.FateEnemies, "FateEnemies" }, + { EEnemySpawnType.FinishCombatIfAny, "FinishCombatIfAny" } }; } diff --git a/Questionable.Model/Questing/EEnemySpawnType.cs b/Questionable.Model/Questing/EEnemySpawnType.cs index e4f49433..49f44bf1 100644 --- a/Questionable.Model/Questing/EEnemySpawnType.cs +++ b/Questionable.Model/Questing/EEnemySpawnType.cs @@ -14,5 +14,6 @@ public enum EEnemySpawnType AutoOnEnterArea, OverworldEnemies, FateEnemies, + FinishCombatIfAny, QuestInterruption, } diff --git a/Questionable/Controller/CombatController.cs b/Questionable/Controller/CombatController.cs index 9cdf3bcf..91eca6c1 100644 --- a/Questionable/Controller/CombatController.cs +++ b/Questionable/Controller/CombatController.cs @@ -76,7 +76,7 @@ internal sealed class CombatController : IDisposable Module = combatModule, Data = combatData, }; - _wasInCombat = combatData.SpawnType == EEnemySpawnType.QuestInterruption; + _wasInCombat = combatData.SpawnType is EEnemySpawnType.QuestInterruption or EEnemySpawnType.FinishCombatIfAny; return true; } else diff --git a/Questionable/Controller/GameUi/InteractionUiController.cs b/Questionable/Controller/GameUi/InteractionUiController.cs index 20148073..c5aa27c3 100644 --- a/Questionable/Controller/GameUi/InteractionUiController.cs +++ b/Questionable/Controller/GameUi/InteractionUiController.cs @@ -51,6 +51,7 @@ internal sealed class InteractionUiController : IDisposable private readonly ShopController _shopController; private readonly ILogger _logger; private readonly Regex _returnRegex; + private readonly Regex _purchaseItemRegex; private bool _isInitialCheck; @@ -91,6 +92,7 @@ internal sealed class InteractionUiController : IDisposable _logger = logger; _returnRegex = _dataManager.GetExcelSheet().GetRow(196).GetRegex(addon => addon.Text, pluginLog)!; + _purchaseItemRegex = _dataManager.GetRegex(3406, addon => addon.Text, pluginLog)!; _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectString", SelectStringPostSetup); _addonLifecycle.RegisterListener(AddonEvent.PostSetup, "CutSceneSelectString", CutsceneSelectStringPostSetup); @@ -560,7 +562,7 @@ internal sealed class InteractionUiController : IDisposable return; _logger.LogTrace("Prompt: '{Prompt}'", actualPrompt); - if (_shopController.IsAutoBuyEnabled && _shopController.IsAwaitingYesNo) + if (_shopController.IsAwaitingYesNo && _purchaseItemRegex.IsMatch(actualPrompt)) { addonSelectYesno->AtkUnitBase.FireCallbackInt(0); _shopController.IsAwaitingYesNo = false; diff --git a/Questionable/Controller/Steps/Interactions/Combat.cs b/Questionable/Controller/Steps/Interactions/Combat.cs index c670e3bc..f0b7ff15 100644 --- a/Questionable/Controller/Steps/Interactions/Combat.cs +++ b/Questionable/Controller/Steps/Interactions/Combat.cs @@ -83,6 +83,7 @@ internal static class Combat case EEnemySpawnType.OverworldEnemies: case EEnemySpawnType.FateEnemies: + case EEnemySpawnType.FinishCombatIfAny: yield return CreateTask(quest, sequence, step); break; @@ -122,17 +123,18 @@ internal static class Combat { public override string ToString() { + if (CombatData.SpawnType == EEnemySpawnType.FinishCombatIfAny) + return "HandleCombat(wait: not in combat, optional)"; if (QuestWorkUtils.HasCompletionFlags(CompletionQuestVariableFlags)) - return $"HandleCombat(wait: QW flags)"; + return "HandleCombat(wait: QW flags)"; else if (IsLastStep) - return $"HandleCombat(wait: next sequence)"; + return "HandleCombat(wait: next sequence)"; else - return $"HandleCombat(wait: not in combat)"; + return "HandleCombat(wait: not in combat)"; } } internal sealed class HandleCombat( - CombatController combatController, QuestFunctions questFunctions) : TaskExecutor { diff --git a/Questionable/Controller/Steps/QuestCleanUp.cs b/Questionable/Controller/Steps/QuestCleanUp.cs index b3cd5b50..e5e56055 100644 --- a/Questionable/Controller/Steps/QuestCleanUp.cs +++ b/Questionable/Controller/Steps/QuestCleanUp.cs @@ -14,7 +14,8 @@ internal static class QuestCleanUp { private static readonly Dictionary AlliedSocietyMountConfiguration = new() { - { 369, new(1051798, EAetheryteLocation.KozamaukaDockPoga) } + { 79, new(1017031, EAetheryteLocation.DravanianForelandsAnyxTrine) }, + { 369, new(1051798, EAetheryteLocation.KozamaukaDockPoga) }, }; internal sealed class CheckAlliedSocietyMount(GameFunctions gameFunctions, AetheryteData aetheryteData, ILogger logger) : SimpleTaskFactory diff --git a/Questionable/Functions/QuestFunctions.cs b/Questionable/Functions/QuestFunctions.cs index 1ef56c4e..067e0e77 100644 --- a/Questionable/Functions/QuestFunctions.cs +++ b/Questionable/Functions/QuestFunctions.cs @@ -243,6 +243,8 @@ internal sealed unsafe class QuestFunctions { return questId.Value switch { + >= 2171 and <= 2200 => EAlliedSociety.VanuVanu, + >= 2261 and <= 2280 => EAlliedSociety.Vath, >= 5199 and <= 5226 => EAlliedSociety.Pelupelu, _ => EAlliedSociety.None, };