No need to track network condition changes, use the UI for everything
This commit is contained in:
+25
-46
@@ -1,72 +1,51 @@
|
|||||||
using Craftimizer.Simulator;
|
using Craftimizer.Simulator.Actions;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using System;
|
using System;
|
||||||
|
using ActionType = Craftimizer.Simulator.Actions.ActionType;
|
||||||
|
using CSActionType = FFXIVClientStructs.FFXIV.Client.Game.ActionType;
|
||||||
|
using Condition = Craftimizer.Simulator.Condition;
|
||||||
|
using Craftimizer.Plugin;
|
||||||
|
using ActionUtils = Craftimizer.Plugin.ActionUtils;
|
||||||
|
|
||||||
namespace Craftimizer.Utils;
|
namespace Craftimizer.Utils;
|
||||||
|
|
||||||
public sealed class Hooks : IDisposable
|
public sealed unsafe class Hooks : IDisposable
|
||||||
{
|
{
|
||||||
public class ConditionUpdatedEventArgs : EventArgs
|
public delegate void OnActionUsedDelegate(ActionType action);
|
||||||
{
|
|
||||||
public Condition Condition { get; }
|
|
||||||
|
|
||||||
public ConditionUpdatedEventArgs(Condition condition)
|
public event OnActionUsedDelegate? OnActionUsed;
|
||||||
{
|
|
||||||
Condition = condition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler<ConditionUpdatedEventArgs>? OnConditionUpdated;
|
public delegate bool UseActionDelegate(ActionManager* manager, CSActionType actionType, uint actionId, ulong targetId, uint param, uint useType, int pvp, nint a8);
|
||||||
|
|
||||||
public delegate void ActorControlSelfPrototype(uint entityId, uint type, uint a3, uint a4, uint a5, uint source, uint a7, uint a8, ulong a9, byte flag);
|
public readonly Hook<UseActionDelegate> UseActionHook = null!;
|
||||||
|
|
||||||
// https://github.com/Kouzukii/ffxiv-deathrecap/blob/1298e75c5e15a6596e8678e85b8f1bde926051bf/Events/CombatEventCapture.cs#L82
|
|
||||||
[Signature("E8 ?? ?? ?? ?? 0F B7 0B 83 E9 64", DetourName = nameof(ActorControlSelfDetour))]
|
|
||||||
public readonly Hook<ActorControlSelfPrototype> ActorControlSelfHook = null!;
|
|
||||||
|
|
||||||
public Hooks()
|
public Hooks()
|
||||||
{
|
{
|
||||||
SignatureHelper.Initialise(this);
|
UseActionHook = Hook<UseActionDelegate>.FromAddress((nint)ActionManager.MemberFunctionPointers.UseAction, UseActionDetour);
|
||||||
ActorControlSelfHook.Enable();
|
UseActionHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandleCondition(uint type, uint a3, uint a4)
|
private bool UseActionDetour(ActionManager* manager, CSActionType actionType, uint actionId, ulong targetId, uint param, uint useType, int pvp, nint a8)
|
||||||
{
|
{
|
||||||
// Crafting related or something?
|
var canCast = manager->GetActionStatus(actionType, actionId) == 0;
|
||||||
if (type != 300)
|
var ret = UseActionHook.Original(manager, actionType, actionId, targetId, param, useType, pvp, a8);
|
||||||
return false;
|
if (canCast && ret && (actionType == CSActionType.CraftAction || actionType == CSActionType.Spell))
|
||||||
|
|
||||||
// Condition update
|
|
||||||
if (a3 != 9)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Invalid condition
|
|
||||||
if (a4 < 2)
|
|
||||||
{
|
{
|
||||||
PluginLog.LogError($"Invalid condition {a4}");
|
var classJob = ClassJobUtils.GetClassJobFromIdx((byte)(Service.ClientState.LocalPlayer?.ClassJob.Id ?? 0));
|
||||||
return false;
|
if (classJob != null) {
|
||||||
|
var simActionType = ActionUtils.GetActionTypeFromId(actionId, classJob.Value, actionType == CSActionType.CraftAction);
|
||||||
|
if (simActionType != null)
|
||||||
|
OnActionUsed?.Invoke(simActionType.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var condition = (Condition)(1 << ((int)a4 - 2));
|
|
||||||
|
|
||||||
OnConditionUpdated?.Invoke(this, new(condition));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
private void ActorControlSelfDetour(uint entityId, uint type, uint a3, uint a4, uint a5, uint source, uint a7, uint a8, ulong a9, byte flag)
|
|
||||||
{
|
|
||||||
ActorControlSelfHook.Original(entityId, type, a3, a4, a5, source, a7, a8, a9, flag);
|
|
||||||
|
|
||||||
if (HandleCondition(type, a3, a4))
|
|
||||||
return;
|
|
||||||
|
|
||||||
//PluginLog.LogDebug($"{entityId} {type} {a3} {a4} {a5} {a7} {a8} {a9} {flag}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ActorControlSelfHook.Dispose();
|
UseActionHook.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user