Add Health% as combat item use condition

This commit is contained in:
Liza 2024-10-13 01:51:44 +02:00
parent 7a3bab3d51
commit 368b119b6d
Signed by: liza
GPG Key ID: 7199F8D727D55F67
8 changed files with 56 additions and 12 deletions

View File

@ -55,7 +55,7 @@
"Steps": [ "Steps": [
{ {
"TerritoryId": 351, "TerritoryId": 351,
"InteractionType": "WaitForManualProgress", "InteractionType": "None",
"Comment": "Credits" "Comment": "Credits"
} }
] ]

View File

@ -37,10 +37,23 @@
"Sequence": 2, "Sequence": 2,
"Steps": [ "Steps": [
{ {
"Position": {
"X": 206.0426,
"Y": 20.561113,
"Z": 629.14465
},
"DataId": 1039998, "DataId": 1039998,
"TerritoryId": 961, "TerritoryId": 961,
"InteractionType": "WaitForManualProgress", "InteractionType": "Combat",
"Comment": "Capture Mobs with less than 50% HP" "EnemySpawnType": "OverworldEnemies",
"KillEnemyDataIds": [
13447, 13448, 13449
],
"CombatItemUse": {
"ItemId": 2003232,
"Condition": "Health%",
"Value": 50
}
} }
] ]
}, },

View File

@ -21,15 +21,23 @@
"Sequence": 1, "Sequence": 1,
"Steps": [ "Steps": [
{ {
"DataId": 13468,
"Position": { "Position": {
"X": -159.59418, "X": -159.59418,
"Y": 10.8, "Y": 10.8,
"Z": -468.8335 "Z": -468.8335
}, },
"StopDistance": 0.5,
"TerritoryId": 958, "TerritoryId": 958,
"InteractionType": "WaitForManualProgress", "InteractionType": "Combat",
"Comment": "Use item 2003202 on 13468 after \"weakening\"", "EnemySpawnType": "OverworldEnemies",
"KillEnemyDataIds": [
13468
],
"CombatItemUse": {
"ItemId": 2003202,
"Condition": "Health%",
"Value": 40
},
"Fly": true "Fly": true
} }
] ]

View File

@ -627,8 +627,12 @@
"Condition": { "Condition": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Incapacitated" "Incapacitated",
"Health%"
] ]
},
"Value": {
"type": "integer"
} }
}, },
"required": [ "required": [

View File

@ -9,4 +9,6 @@ public sealed class CombatItemUse
[JsonConverter(typeof(CombatItemUseConditionConverter))] [JsonConverter(typeof(CombatItemUseConditionConverter))]
public ECombatItemUseCondition Condition { get; set; } public ECombatItemUseCondition Condition { get; set; }
public int Value { get; set; }
} }

View File

@ -8,5 +8,6 @@ public sealed class CombatItemUseConditionConverter() : EnumConverter<ECombatIte
private static readonly Dictionary<ECombatItemUseCondition, string> Values = new() private static readonly Dictionary<ECombatItemUseCondition, string> Values = new()
{ {
{ ECombatItemUseCondition.Incapacitated, "Incapacitated" }, { ECombatItemUseCondition.Incapacitated, "Incapacitated" },
{ ECombatItemUseCondition.HealthPercent, "Health%" },
}; };
} }

View File

@ -4,4 +4,5 @@ public enum ECombatItemUseCondition
{ {
None, None,
Incapacitated, Incapacitated,
HealthPercent,
} }

View File

@ -6,6 +6,7 @@ using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Questionable.Functions; using Questionable.Functions;
@ -16,19 +17,17 @@ namespace Questionable.Controller.CombatModules;
internal sealed class ItemUseModule : ICombatModule internal sealed class ItemUseModule : ICombatModule
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly GameFunctions _gameFunctions;
private readonly ICondition _condition; private readonly ICondition _condition;
private readonly ILogger<ItemUseModule> _logger; private readonly ILogger<ItemUseModule> _logger;
private ICombatModule? _delegate; private ICombatModule? _delegate;
private CombatController.CombatData? _combatData; private CombatController.CombatData? _combatData;
private bool _isDoingRotation; private bool _isDoingRotation;
private DateTime _continueAt;
public ItemUseModule(IServiceProvider serviceProvider, GameFunctions gameFunctions, ICondition condition, public ItemUseModule(IServiceProvider serviceProvider, ICondition condition, ILogger<ItemUseModule> logger)
ILogger<ItemUseModule> logger)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_gameFunctions = gameFunctions;
_condition = condition; _condition = condition;
_logger = logger; _logger = logger;
} }
@ -51,6 +50,7 @@ internal sealed class ItemUseModule : ICombatModule
{ {
_combatData = combatData; _combatData = combatData;
_isDoingRotation = true; _isDoingRotation = true;
_continueAt = DateTime.Now;
return true; return true;
} }
@ -65,6 +65,7 @@ internal sealed class ItemUseModule : ICombatModule
_isDoingRotation = false; _isDoingRotation = false;
_combatData = null; _combatData = null;
_delegate = null; _delegate = null;
_continueAt = DateTime.Now;
} }
return true; return true;
@ -75,6 +76,9 @@ internal sealed class ItemUseModule : ICombatModule
if (_delegate == null) if (_delegate == null)
return; return;
if (_continueAt > DateTime.Now)
return;
if (_combatData?.CombatItemUse == null) if (_combatData?.CombatItemUse == null)
{ {
_delegate.Update(nextTarget); _delegate.Update(nextTarget);
@ -93,6 +97,7 @@ internal sealed class ItemUseModule : ICombatModule
{ {
_isDoingRotation = false; _isDoingRotation = false;
_delegate.Stop(); _delegate.Stop();
return;
} }
} }
@ -100,7 +105,11 @@ internal sealed class ItemUseModule : ICombatModule
{ {
_isDoingRotation = false; _isDoingRotation = false;
_delegate.Stop(); _delegate.Stop();
_gameFunctions.UseItem(nextTarget.DataId, _combatData.CombatItemUse.ItemId); unsafe
{
AgentInventoryContext.Instance()->UseItem(_combatData.CombatItemUse.ItemId);
}
_continueAt = DateTime.Now.AddSeconds(2);
} }
else else
_delegate.Update(nextTarget); _delegate.Update(nextTarget);
@ -108,6 +117,9 @@ internal sealed class ItemUseModule : ICombatModule
else if (_condition[ConditionFlag.Casting]) else if (_condition[ConditionFlag.Casting])
{ {
// do nothing // do nothing
DateTime alternativeContinueAt = DateTime.Now.AddSeconds(0.5);
if (alternativeContinueAt > _continueAt)
_continueAt = alternativeContinueAt;
} }
else else
{ {
@ -131,6 +143,9 @@ internal sealed class ItemUseModule : ICombatModule
BattleChara* battleChara = (BattleChara*)gameObject.Address; BattleChara* battleChara = (BattleChara*)gameObject.Address;
if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.Incapacitated) if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.Incapacitated)
return (battleChara->Flags2 & 128u) != 0; return (battleChara->Flags2 & 128u) != 0;
if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.HealthPercent)
return (100f * battleChara->Health / battleChara->MaxHealth) < _combatData.CombatItemUse.Value;
} }
return false; return false;