punish v6.8.18.0
This commit is contained in:
commit
e786325cda
322 changed files with 554232 additions and 0 deletions
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.External;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class BossModModule : ICombatModule, IDisposable
|
||||
{
|
||||
private readonly ILogger<BossModModule> _logger;
|
||||
|
||||
private readonly BossModIpc _bossModIpc;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
public BossModModule(ILogger<BossModModule> logger, BossModIpc bossModIpc, Configuration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_bossModIpc = bossModIpc;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
if (_configuration.General.CombatModule != Configuration.ECombatModule.BossMod)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _bossModIpc.IsSupported();
|
||||
}
|
||||
|
||||
public bool Start(CombatController.CombatData combatData)
|
||||
{
|
||||
try
|
||||
{
|
||||
_bossModIpc.SetPreset(BossModIpc.EPreset.Overworld);
|
||||
return true;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not start combat");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
_bossModIpc.ClearPreset();
|
||||
return true;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not turn off combat");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(IGameObject gameObject)
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanAttack(IBattleNpc target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal interface ICombatModule
|
||||
{
|
||||
bool CanHandleFight(CombatController.CombatData combatData);
|
||||
|
||||
bool Start(CombatController.CombatData combatData);
|
||||
|
||||
bool Stop();
|
||||
|
||||
void Update(IGameObject nextTarget);
|
||||
|
||||
bool CanAttack(IBattleNpc target);
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
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.Model.Questing;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class ItemUseModule : ICombatModule
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
private readonly ICondition _condition;
|
||||
|
||||
private readonly ILogger<ItemUseModule> _logger;
|
||||
|
||||
private ICombatModule? _delegate;
|
||||
|
||||
private CombatController.CombatData? _combatData;
|
||||
|
||||
private bool _isDoingRotation;
|
||||
|
||||
private DateTime _continueAt;
|
||||
|
||||
public ItemUseModule(IServiceProvider serviceProvider, ICondition condition, ILogger<ItemUseModule> logger)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_condition = condition;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
if (combatData.CombatItemUse == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_delegate = (from x in _serviceProvider.GetRequiredService<IEnumerable<ICombatModule>>()
|
||||
where !(x is ItemUseModule)
|
||||
select x).FirstOrDefault((ICombatModule x) => x.CanHandleFight(combatData));
|
||||
_logger.LogInformation("ItemUse delegate: {Delegate}", _delegate?.GetType().Name);
|
||||
return _delegate != null;
|
||||
}
|
||||
|
||||
public bool Start(CombatController.CombatData combatData)
|
||||
{
|
||||
if (_delegate.Start(combatData))
|
||||
{
|
||||
_combatData = combatData;
|
||||
_isDoingRotation = true;
|
||||
_continueAt = DateTime.Now;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
if (_isDoingRotation)
|
||||
{
|
||||
_delegate.Stop();
|
||||
_isDoingRotation = false;
|
||||
_combatData = null;
|
||||
_delegate = null;
|
||||
_continueAt = DateTime.Now;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public unsafe void Update(IGameObject nextTarget)
|
||||
{
|
||||
if (_delegate == null || _continueAt > DateTime.Now)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_combatData?.CombatItemUse == null)
|
||||
{
|
||||
_delegate.Update(nextTarget);
|
||||
}
|
||||
else if (_combatData.KillEnemyDataIds.Contains(nextTarget.DataId) || _combatData.ComplexCombatDatas.Any((ComplexCombatData x) => x.DataId == nextTarget.DataId && (!x.NameId.HasValue || (nextTarget is ICharacter character && x.NameId == character.NameId))))
|
||||
{
|
||||
if (_isDoingRotation)
|
||||
{
|
||||
if (InventoryManager.Instance()->GetInventoryItemCount(_combatData.CombatItemUse.ItemId, isHq: false, checkEquipped: true, checkArmory: true, 0) == 0)
|
||||
{
|
||||
_isDoingRotation = false;
|
||||
_delegate.Stop();
|
||||
}
|
||||
else if (ShouldUseItem(nextTarget))
|
||||
{
|
||||
_isDoingRotation = false;
|
||||
_delegate.Stop();
|
||||
_logger.LogInformation("Using item {ItemId}", _combatData.CombatItemUse.ItemId);
|
||||
AgentInventoryContext.Instance()->UseItem(_combatData.CombatItemUse.ItemId, InventoryType.Invalid, 0u, 0);
|
||||
_continueAt = DateTime.Now.AddSeconds(2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_delegate.Update(nextTarget);
|
||||
}
|
||||
}
|
||||
else if (_condition[ConditionFlag.Casting])
|
||||
{
|
||||
DateTime dateTime = DateTime.Now.AddSeconds(0.5);
|
||||
if (dateTime > _continueAt)
|
||||
{
|
||||
_continueAt = dateTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_isDoingRotation = true;
|
||||
_delegate.Start(_combatData);
|
||||
}
|
||||
}
|
||||
else if (_isDoingRotation)
|
||||
{
|
||||
_delegate.Update(nextTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe bool ShouldUseItem(IGameObject gameObject)
|
||||
{
|
||||
if (_combatData?.CombatItemUse == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (gameObject is IBattleChara)
|
||||
{
|
||||
BattleChara* address = (BattleChara*)gameObject.Address;
|
||||
if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.Incapacitated)
|
||||
{
|
||||
return (address->ActorControlFlags & 0x40) != 0;
|
||||
}
|
||||
if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.HealthPercent)
|
||||
{
|
||||
return 100f * (float)address->Health / (float)address->MaxHealth < (float)_combatData.CombatItemUse.Value;
|
||||
}
|
||||
if (_combatData.CombatItemUse.Condition == ECombatItemUseCondition.MissingStatus)
|
||||
{
|
||||
return !address->StatusManager.HasStatus((uint)_combatData.CombatItemUse.Value);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanAttack(IBattleNpc target)
|
||||
{
|
||||
return _delegate.CanAttack(target);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class Mount128Module : ICombatModule
|
||||
{
|
||||
public const ushort MountId = 128;
|
||||
|
||||
private readonly EAction[] _actions = new EAction[2]
|
||||
{
|
||||
EAction.MagitekThunder,
|
||||
EAction.MagitekPulse
|
||||
};
|
||||
|
||||
private readonly GameFunctions _gameFunctions;
|
||||
|
||||
public Mount128Module(GameFunctions gameFunctions)
|
||||
{
|
||||
_gameFunctions = gameFunctions;
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
return _gameFunctions.GetMountId() == 128;
|
||||
}
|
||||
|
||||
public bool Start(CombatController.CombatData combatData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Update(IGameObject gameObject)
|
||||
{
|
||||
EAction[] actions = _actions;
|
||||
foreach (EAction action in actions)
|
||||
{
|
||||
if (_gameFunctions.UseAction(gameObject, action, checkCanUse: false))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanAttack(IBattleNpc target)
|
||||
{
|
||||
uint dataId = target.DataId;
|
||||
if (dataId - 7504 <= 1 || dataId == 14107)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Questionable.Functions;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class Mount147Module : ICombatModule
|
||||
{
|
||||
public const ushort MountId = 147;
|
||||
|
||||
private readonly EAction[] _actions = new EAction[1] { EAction.Trample };
|
||||
|
||||
private readonly GameFunctions _gameFunctions;
|
||||
|
||||
public Mount147Module(GameFunctions gameFunctions)
|
||||
{
|
||||
_gameFunctions = gameFunctions;
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
return _gameFunctions.GetMountId() == 147;
|
||||
}
|
||||
|
||||
public bool Start(CombatController.CombatData combatData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Update(IGameObject gameObject)
|
||||
{
|
||||
EAction[] actions = _actions;
|
||||
foreach (EAction action in actions)
|
||||
{
|
||||
if (_gameFunctions.UseAction(gameObject, action, checkCanUse: false))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanAttack(IBattleNpc target)
|
||||
{
|
||||
return target.DataId == 8593;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class RotationSolverRebornModule : ICombatModule, IDisposable
|
||||
{
|
||||
private enum StateCommandType : byte
|
||||
{
|
||||
Off,
|
||||
Auto,
|
||||
Manual
|
||||
}
|
||||
|
||||
private readonly ILogger<RotationSolverRebornModule> _logger;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
private readonly ICallGateSubscriber<string, object> _test;
|
||||
|
||||
private readonly ICallGateSubscriber<StateCommandType, object> _changeOperationMode;
|
||||
|
||||
public RotationSolverRebornModule(ILogger<RotationSolverRebornModule> logger, IDalamudPluginInterface pluginInterface, Configuration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
_test = pluginInterface.GetIpcSubscriber<string, object>("RotationSolverReborn.Test");
|
||||
_changeOperationMode = pluginInterface.GetIpcSubscriber<StateCommandType, object>("RotationSolverReborn.ChangeOperatingMode");
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
if (_configuration.General.CombatModule != Configuration.ECombatModule.RotationSolverReborn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
_test.InvokeAction("Validate RSR is callable from Questionable");
|
||||
return true;
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Start(CombatController.CombatData combatData)
|
||||
{
|
||||
try
|
||||
{
|
||||
_changeOperationMode.InvokeAction(StateCommandType.Manual);
|
||||
return true;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not start combat");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
if (!_changeOperationMode.HasAction)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
try
|
||||
{
|
||||
_changeOperationMode.InvokeAction(StateCommandType.Off);
|
||||
return true;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not turn off combat");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(IGameObject gameObject)
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanAttack(IBattleNpc target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
using System;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Controller.Steps;
|
||||
|
||||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal sealed class WrathComboModule : ICombatModule, IDisposable
|
||||
{
|
||||
public enum ESetResult
|
||||
{
|
||||
Okay = 0,
|
||||
OkayWorking = 1,
|
||||
IpcDisabled = 10,
|
||||
InvalidLease = 11,
|
||||
BlacklistedLease = 12,
|
||||
Duplicate = 13,
|
||||
PlayerNotAvailable = 14,
|
||||
InvalidConfiguration = 15,
|
||||
InvalidValue = 16
|
||||
}
|
||||
|
||||
public enum AutoRotationConfigOption
|
||||
{
|
||||
InCombatOnly,
|
||||
DPSRotationMode,
|
||||
HealerRotationMode,
|
||||
FATEPriority,
|
||||
QuestPriority,
|
||||
SingleTargetHPP,
|
||||
AoETargetHPP,
|
||||
SingleTargetRegenHPP,
|
||||
ManageKardia,
|
||||
AutoRez,
|
||||
AutoRezDPSJobs,
|
||||
AutoCleanse,
|
||||
IncludeNPCs,
|
||||
OnlyAttackInCombat,
|
||||
OrbwalkerIntegration,
|
||||
AutoRezOutOfParty,
|
||||
DPSAoETargets,
|
||||
SingleTargetExcogHPP
|
||||
}
|
||||
|
||||
public enum HealerRotationMode
|
||||
{
|
||||
Manual,
|
||||
Highest_Current,
|
||||
Lowest_Current
|
||||
}
|
||||
|
||||
private const string CallbackPrefix = "Questionable$Wrath";
|
||||
|
||||
private readonly ILogger<WrathComboModule> _logger;
|
||||
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
private readonly ICallGateSubscriber<object> _test;
|
||||
|
||||
private readonly ICallGateSubscriber<string, string, string, Guid?> _registerForLeaseWithCallback;
|
||||
|
||||
private readonly ICallGateSubscriber<Guid, object> _releaseControl;
|
||||
|
||||
private readonly ICallGateSubscriber<Guid, bool, ESetResult> _setAutoRotationState;
|
||||
|
||||
private readonly ICallGateSubscriber<Guid, object, object, ESetResult> _setAutoRotationConfigState;
|
||||
|
||||
private readonly ICallGateSubscriber<Guid, ESetResult> _setCurrentJobAutoRotationReady;
|
||||
|
||||
private readonly ICallGateProvider<int, string, object> _callback;
|
||||
|
||||
private Guid? _lease;
|
||||
|
||||
public WrathComboModule(ILogger<WrathComboModule> logger, Configuration configuration, IDalamudPluginInterface pluginInterface)
|
||||
{
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
_test = pluginInterface.GetIpcSubscriber<object>("WrathCombo.Test");
|
||||
_registerForLeaseWithCallback = pluginInterface.GetIpcSubscriber<string, string, string, Guid?>("WrathCombo.RegisterForLeaseWithCallback");
|
||||
_releaseControl = pluginInterface.GetIpcSubscriber<Guid, object>("WrathCombo.ReleaseControl");
|
||||
_setAutoRotationState = pluginInterface.GetIpcSubscriber<Guid, bool, ESetResult>("WrathCombo.SetAutoRotationState");
|
||||
_setAutoRotationConfigState = pluginInterface.GetIpcSubscriber<Guid, object, object, ESetResult>("WrathCombo.SetAutoRotationConfigState");
|
||||
_setCurrentJobAutoRotationReady = pluginInterface.GetIpcSubscriber<Guid, ESetResult>("WrathCombo.SetCurrentJobAutoRotationReady");
|
||||
_callback = pluginInterface.GetIpcProvider<int, string, object>("Questionable$Wrath.WrathComboCallback");
|
||||
_callback.RegisterAction(Callback);
|
||||
}
|
||||
|
||||
public bool CanHandleFight(CombatController.CombatData combatData)
|
||||
{
|
||||
if (_configuration.General.CombatModule != Configuration.ECombatModule.WrathCombo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
_test.InvokeAction();
|
||||
return true;
|
||||
}
|
||||
catch (IpcError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Start(CombatController.CombatData combatData)
|
||||
{
|
||||
try
|
||||
{
|
||||
_lease = _registerForLeaseWithCallback.InvokeFunc("Questionable", "Questionable", "Questionable$Wrath");
|
||||
if (_lease.HasValue)
|
||||
{
|
||||
_logger.LogDebug("Wrath combo lease: {Lease}", _lease.Value);
|
||||
if (!_setAutoRotationState.InvokeFunc(_lease.Value, arg2: true).IsSuccess())
|
||||
{
|
||||
_logger.LogError("Unable to set autorotation state");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
if (!_setCurrentJobAutoRotationReady.InvokeFunc(_lease.Value).IsSuccess())
|
||||
{
|
||||
_logger.LogError("Unable to set current job for autorotation");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
ESetResult eSetResult = _setAutoRotationConfigState.InvokeFunc(_lease.Value, AutoRotationConfigOption.HealerRotationMode, HealerRotationMode.Lowest_Current);
|
||||
if (!eSetResult.IsSuccess())
|
||||
{
|
||||
_logger.LogError("Unable to configure healing priority for autorotation: {Result}", eSetResult);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
_logger.LogError("Wrath combo did not return a lease");
|
||||
return false;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogError(exception, "Unable to use wrath combo for combat");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_lease.HasValue)
|
||||
{
|
||||
_releaseControl.InvokeAction(_lease.Value);
|
||||
_lease = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (IpcError exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Could not turn off wrath combo");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(IGameObject nextTarget)
|
||||
{
|
||||
if (!_lease.HasValue)
|
||||
{
|
||||
throw new TaskException("Wrath Combo Lease is cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanAttack(IBattleNpc target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Callback(int reason, string additionalInfo)
|
||||
{
|
||||
_logger.LogWarning("WrathCombo callback: {Reason} ({Info})", reason, additionalInfo);
|
||||
_lease = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
_callback.UnregisterAction();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
namespace Questionable.Controller.CombatModules;
|
||||
|
||||
internal static class WrathResultExtensions
|
||||
{
|
||||
public static bool IsSuccess(this WrathComboModule.ESetResult result)
|
||||
{
|
||||
if ((uint)result <= 1u)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue