diff --git a/QuestPaths/5.x - Shadowbringers/MSQ/L-5.55/4066_Death Unto Dawn.json b/QuestPaths/5.x - Shadowbringers/MSQ/L-5.55/4066_Death Unto Dawn.json index dee4eaec..2e796799 100644 --- a/QuestPaths/5.x - Shadowbringers/MSQ/L-5.55/4066_Death Unto Dawn.json +++ b/QuestPaths/5.x - Shadowbringers/MSQ/L-5.55/4066_Death Unto Dawn.json @@ -55,7 +55,7 @@ "Steps": [ { "TerritoryId": 351, - "InteractionType": "WaitForManualProgress", + "InteractionType": "None", "Comment": "Credits" } ] diff --git a/QuestPaths/6.x - Endwalker/MSQ/E-Elpis/4421_Petalouda Hunt.json b/QuestPaths/6.x - Endwalker/MSQ/E-Elpis/4421_Petalouda Hunt.json index 04c452c5..c11ebd1d 100644 --- a/QuestPaths/6.x - Endwalker/MSQ/E-Elpis/4421_Petalouda Hunt.json +++ b/QuestPaths/6.x - Endwalker/MSQ/E-Elpis/4421_Petalouda Hunt.json @@ -37,10 +37,23 @@ "Sequence": 2, "Steps": [ { + "Position": { + "X": 206.0426, + "Y": 20.561113, + "Z": 629.14465 + }, "DataId": 1039998, "TerritoryId": 961, - "InteractionType": "WaitForManualProgress", - "Comment": "Capture Mobs with less than 50% HP" + "InteractionType": "Combat", + "EnemySpawnType": "OverworldEnemies", + "KillEnemyDataIds": [ + 13447, 13448, 13449 + ], + "CombatItemUse": { + "ItemId": 2003232, + "Condition": "Health%", + "Value": 50 + } } ] }, diff --git a/QuestPaths/6.x - Endwalker/Side Quests/Garlemald/4226_With Folded Hands.json b/QuestPaths/6.x - Endwalker/Side Quests/Garlemald/4226_With Folded Hands.json index dff6a220..0001cbe9 100644 --- a/QuestPaths/6.x - Endwalker/Side Quests/Garlemald/4226_With Folded Hands.json +++ b/QuestPaths/6.x - Endwalker/Side Quests/Garlemald/4226_With Folded Hands.json @@ -21,15 +21,23 @@ "Sequence": 1, "Steps": [ { - "DataId": 13468, "Position": { "X": -159.59418, "Y": 10.8, "Z": -468.8335 }, + "StopDistance": 0.5, "TerritoryId": 958, - "InteractionType": "WaitForManualProgress", - "Comment": "Use item 2003202 on 13468 after \"weakening\"", + "InteractionType": "Combat", + "EnemySpawnType": "OverworldEnemies", + "KillEnemyDataIds": [ + 13468 + ], + "CombatItemUse": { + "ItemId": 2003202, + "Condition": "Health%", + "Value": 40 + }, "Fly": true } ] diff --git a/QuestPaths/quest-v1.json b/QuestPaths/quest-v1.json index 50d39d05..eefbf1eb 100644 --- a/QuestPaths/quest-v1.json +++ b/QuestPaths/quest-v1.json @@ -627,8 +627,12 @@ "Condition": { "type": "string", "enum": [ - "Incapacitated" + "Incapacitated", + "Health%" ] + }, + "Value": { + "type": "integer" } }, "required": [ diff --git a/Questionable.Model/Questing/CombatItemUse.cs b/Questionable.Model/Questing/CombatItemUse.cs index bbcfd100..565a0c77 100644 --- a/Questionable.Model/Questing/CombatItemUse.cs +++ b/Questionable.Model/Questing/CombatItemUse.cs @@ -9,4 +9,6 @@ public sealed class CombatItemUse [JsonConverter(typeof(CombatItemUseConditionConverter))] public ECombatItemUseCondition Condition { get; set; } + + public int Value { get; set; } } diff --git a/Questionable.Model/Questing/Converter/CombatItemUseConditionConverter.cs b/Questionable.Model/Questing/Converter/CombatItemUseConditionConverter.cs index d2bca66a..1b4086ff 100644 --- a/Questionable.Model/Questing/Converter/CombatItemUseConditionConverter.cs +++ b/Questionable.Model/Questing/Converter/CombatItemUseConditionConverter.cs @@ -8,5 +8,6 @@ public sealed class CombatItemUseConditionConverter() : EnumConverter Values = new() { { ECombatItemUseCondition.Incapacitated, "Incapacitated" }, + { ECombatItemUseCondition.HealthPercent, "Health%" }, }; } diff --git a/Questionable.Model/Questing/ECombatItemUseCondition.cs b/Questionable.Model/Questing/ECombatItemUseCondition.cs index dab191e6..7bb4e2b2 100644 --- a/Questionable.Model/Questing/ECombatItemUseCondition.cs +++ b/Questionable.Model/Questing/ECombatItemUseCondition.cs @@ -4,4 +4,5 @@ public enum ECombatItemUseCondition { None, Incapacitated, + HealthPercent, } diff --git a/Questionable/Controller/CombatModules/ItemUseModule.cs b/Questionable/Controller/CombatModules/ItemUseModule.cs index cff43161..91b4ca1d 100644 --- a/Questionable/Controller/CombatModules/ItemUseModule.cs +++ b/Questionable/Controller/CombatModules/ItemUseModule.cs @@ -6,6 +6,7 @@ using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Character; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Questionable.Functions; @@ -16,19 +17,17 @@ namespace Questionable.Controller.CombatModules; internal sealed class ItemUseModule : ICombatModule { private readonly IServiceProvider _serviceProvider; - private readonly GameFunctions _gameFunctions; private readonly ICondition _condition; private readonly ILogger _logger; private ICombatModule? _delegate; private CombatController.CombatData? _combatData; private bool _isDoingRotation; + private DateTime _continueAt; - public ItemUseModule(IServiceProvider serviceProvider, GameFunctions gameFunctions, ICondition condition, - ILogger logger) + public ItemUseModule(IServiceProvider serviceProvider, ICondition condition, ILogger logger) { _serviceProvider = serviceProvider; - _gameFunctions = gameFunctions; _condition = condition; _logger = logger; } @@ -51,6 +50,7 @@ internal sealed class ItemUseModule : ICombatModule { _combatData = combatData; _isDoingRotation = true; + _continueAt = DateTime.Now; return true; } @@ -65,6 +65,7 @@ internal sealed class ItemUseModule : ICombatModule _isDoingRotation = false; _combatData = null; _delegate = null; + _continueAt = DateTime.Now; } return true; @@ -75,6 +76,9 @@ internal sealed class ItemUseModule : ICombatModule if (_delegate == null) return; + if (_continueAt > DateTime.Now) + return; + if (_combatData?.CombatItemUse == null) { _delegate.Update(nextTarget); @@ -93,6 +97,7 @@ internal sealed class ItemUseModule : ICombatModule { _isDoingRotation = false; _delegate.Stop(); + return; } } @@ -100,7 +105,11 @@ internal sealed class ItemUseModule : ICombatModule { _isDoingRotation = false; _delegate.Stop(); - _gameFunctions.UseItem(nextTarget.DataId, _combatData.CombatItemUse.ItemId); + unsafe + { + AgentInventoryContext.Instance()->UseItem(_combatData.CombatItemUse.ItemId); + } + _continueAt = DateTime.Now.AddSeconds(2); } else _delegate.Update(nextTarget); @@ -108,6 +117,9 @@ internal sealed class ItemUseModule : ICombatModule else if (_condition[ConditionFlag.Casting]) { // do nothing + DateTime alternativeContinueAt = DateTime.Now.AddSeconds(0.5); + if (alternativeContinueAt > _continueAt) + _continueAt = alternativeContinueAt; } else { @@ -131,6 +143,9 @@ internal sealed class ItemUseModule : ICombatModule BattleChara* battleChara = (BattleChara*)gameObject.Address; if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.Incapacitated) return (battleChara->Flags2 & 128u) != 0; + + if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.HealthPercent) + return (100f * battleChara->Health / battleChara->MaxHealth) < _combatData.CombatItemUse.Value; } return false;