Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
fix: add target effect condition. Thanks Splatoon!
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchiDog1998 committed Oct 31, 2023
1 parent f05db68 commit e9e7e02
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 15 deletions.
22 changes: 20 additions & 2 deletions RotationSolver.Basic/Configuration/Conditions/TargetCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ internal class TargetCondition : DelayCondition
public bool IsTarget;
public TargetConditionType TargetConditionType;

public float DistanceOrTime;
public int GCD;
public float DistanceOrTime, TimeEnd;
public int GCD, Param2;

public string CastingActionName = string.Empty;

Expand Down Expand Up @@ -117,6 +117,23 @@ protected override bool IsTrueInside(ICustomRotation rotation)
}
result = tar.Name.TextValue == CastingActionName;
break;

case TargetConditionType.ObjectEffect:
foreach (var effect in DataCenter.ObjectEffects.Reverse())
{
var time = effect.TimeDuration.TotalSeconds;
if (time > DistanceOrTime && time < TimeEnd
&& effect.Param1 == GCD
&& effect.Param2 == Param2)
{
if (!FromSelf || effect.ObjectId == tar.ObjectId)
{
result = true;
break;
}
}
}
break;
}

return Condition ? !result : result;
Expand All @@ -139,4 +156,5 @@ internal enum TargetConditionType : byte
HPRatio,
MP,
TargetName,
ObjectEffect,
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ internal class TerritoryCondition : DelayCondition

public int Position = 0;
public int Param1 = 0, Param2 = 0;
public string Name = "Not Chosen";
public int Condition;
public string Name = "Not Chosen";
public float TimeStart, TimeEnd;

protected override bool IsTrueInside(ICustomRotation rotation)
Expand All @@ -24,14 +24,14 @@ protected override bool IsTrueInside(ICustomRotation rotation)
break;

case TerritoryConditionType.TerritoryName:
result= Name == DataCenter.TerritoryName;
result = Name == DataCenter.TerritoryName;
break;

case TerritoryConditionType.MapEffect:
foreach (var effect in DataCenter.MapEffects.Reverse())
{
var time = effect.TimeDuration.TotalSeconds;
if ( time > TimeStart && time < TimeEnd
if (time > TimeStart && time < TimeEnd
&& effect.Position == Position
&& effect.Param1 == Param1
&& effect.Param2 == Param2)
Expand All @@ -40,7 +40,7 @@ protected override bool IsTrueInside(ICustomRotation rotation)
break;
}
}

break;
}
return Condition > 0 ? !result : result;
Expand Down
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Data/MapEffectData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace RotationSolver.Basic.Data;

public readonly struct MapEffectData
internal readonly struct MapEffectData
{
public readonly uint Position;

Expand Down
20 changes: 20 additions & 0 deletions RotationSolver.Basic/Data/ObjectEffectData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace RotationSolver.Basic.Data;

internal readonly struct ObjectEffectData
{
public readonly uint ObjectId;

public readonly ushort Param1, Param2;

public readonly DateTime Time;

public readonly TimeSpan TimeDuration => DateTime.Now - Time;

public ObjectEffectData(uint objectId, ushort param1, ushort param2)
{
Time = DateTime.Now;
ObjectId = objectId;
Param1 = param1;
Param2 = param2;
}
}
4 changes: 3 additions & 1 deletion RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace RotationSolver.Basic;
internal static class DataCenter
{
internal static Queue<MapEffectData> MapEffects { get; } = new(64);
internal static Queue<ObjectEffectData> ObjectEffects { get; } = new(64);

/// <summary>
/// This one never be null.
Expand Down Expand Up @@ -459,7 +460,8 @@ internal static void ResetAllRecords()
_timeLastActionUsed = DateTime.Now;
_actions.Clear();

DataCenter.MapEffects.Clear();
MapEffects.Clear();
ObjectEffects.Clear();
}

internal static void AddDamageRec(float damageRatio)
Expand Down
3 changes: 1 addition & 2 deletions RotationSolver.Basic/Helpers/ObjectHelper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds;
using ECommons.GameFunctions;
using ECommons.GameHelpers;
using FFXIVClientStructs.FFXIV.Client.Game;
Expand Down Expand Up @@ -67,7 +66,7 @@ public static unsafe bool IsNPCEnemy(this GameObject obj)
/// <param name="obj"></param>
/// <returns></returns>
public static unsafe bool IsAlliance(this GameObject obj)
=> obj != null
=> obj != null
&& ActionManager.CanUseActionOnTarget((uint)ActionID.Cure, obj.Struct());

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions RotationSolver/Localization/EnumTranslations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal static class EnumTranslations
TargetConditionType.HPRatio => LocalizationManager.RightLang.TargetConditionType_HPRatio,
TargetConditionType.MP => LocalizationManager.RightLang.TargetConditionType_MP,
TargetConditionType.TargetName => LocalizationManager.RightLang.TargetConditionType_TargetName,
TargetConditionType.ObjectEffect => LocalizationManager.RightLang.TargetConditionType_ObjectEffect,
_ => string.Empty,
};

Expand Down
1 change: 1 addition & 0 deletions RotationSolver/Localization/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ internal class Strings
public string TargetConditionType_HPRatio { get; set; } = "HP%";
public string TargetConditionType_MP { get; set; } = "MP";
public string TargetConditionType_TargetName { get; set; } = "Target Name";
public string TargetConditionType_ObjectEffect { get; set; } = "Object Effect";

#endregion

Expand Down
41 changes: 40 additions & 1 deletion RotationSolver/UI/ConditionDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using ECommons.DalamudServices;
using ECommons.ImGuiMethods;
using Lumina.Excel.GeneratedSheets;
using RotationSolver.Basic.Configuration.Conditions;
Expand Down Expand Up @@ -923,6 +922,46 @@ void DrawStatusIcon()
ImGuiHelper.SetNextWidthWithName(targetCondition.CastingActionName);
ImGui.InputText($"Name##TargetName{targetCondition.GetHashCode()}", ref targetCondition.CastingActionName, 128);
break;

case TargetConditionType.ObjectEffect:
ImGui.SameLine();

ImGui.Text("Param1:");
ImGui.SameLine();
ImGui.SetNextItemWidth(Math.Max(150 * ImGuiHelpers.GlobalScale, ImGui.CalcTextSize(targetCondition.GCD.ToString()).X));
ImGui.DragInt($"##Param1{targetCondition.GetHashCode()}", ref targetCondition.GCD, .1f);

ImGui.SameLine();

ImGui.Text("Param2:");
ImGui.SameLine();
ImGui.SetNextItemWidth(Math.Max(150 * ImGuiHelpers.GlobalScale, ImGui.CalcTextSize(targetCondition.Param2.ToString()).X));
ImGui.DragInt($"##Param2{targetCondition.GetHashCode()}", ref targetCondition.Param2, .1f);

ImGui.SameLine();

ImGui.Text("Time Offset:");
ImGui.SameLine();
const float MIN = 0, MAX = 60;

ImGui.SetNextItemWidth(150 * ImGuiHelpers.GlobalScale);
if (ImGui.DragFloatRange2($"##TimeOffset {targetCondition.GetHashCode()}", ref targetCondition.DistanceOrTime, ref targetCondition.TimeEnd, 0.1f, MIN, MAX))
{
targetCondition.DistanceOrTime = Math.Max(Math.Min(targetCondition.DistanceOrTime, targetCondition.TimeEnd), MIN);
targetCondition.TimeEnd = Math.Min(Math.Max(targetCondition.DistanceOrTime, targetCondition.TimeEnd), MAX);
}

ImGui.SameLine();
check = targetCondition.FromSelf ? 1 : 0;
if (ImGuiHelper.SelectableCombo($"From Self {targetCondition.GetHashCode()}", new string[]
{
LocalizationManager.RightLang.ActionSequencer_StatusAll,
LocalizationManager.RightLang.ActionSequencer_StatusSelf,
}, ref check))
{
targetCondition.FromSelf = check != 0;
}
break;
}
}

Expand Down
40 changes: 36 additions & 4 deletions RotationSolver/Watcher.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Hooking;
using Dalamud.Memory;
using Dalamud.Plugin.Ipc;
using ECommons;
using ECommons.DalamudServices;
using ECommons.GameHelpers;
using ECommons.Hooks;
Expand All @@ -8,35 +11,44 @@
using Lumina.Excel.GeneratedSheets;
using RotationSolver.Basic.Configuration;
using System.Text.RegularExpressions;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;

namespace RotationSolver;

public static class Watcher
{
#if DEBUG
private unsafe delegate bool OnUseAction(ActionManager* manager, ActionType actionType, uint actionID, ulong targetID, uint a4, uint a5, uint a6, void* a7);
private static Dalamud.Hooking.Hook<OnUseAction> _useActionHook;
private static Hook<OnUseAction> _useActionHook;
#endif

private unsafe delegate long ProcessObjectEffect(GameObject* a1, ushort a2, ushort a3, long a4);
private static Hook<ProcessObjectEffect> _processObjectEffectHook;


private static ICallGateSubscriber<object, object> IpcSubscriber;

public static void Enable()
{
#if DEBUG
unsafe
{
#if DEBUG

_useActionHook = Svc.Hook.HookFromSignature<OnUseAction>("E8 ?? ?? ?? ?? EB 64 B1 01", UseActionDetour);
//_useActionHook.Enable();
}
#endif
//From https://github.com/PunishXIV/Splatoon/blob/main/Splatoon/Memory/ObjectEffectProcessor.cs#L14
_processObjectEffectHook = Svc.Hook.HookFromSignature<ProcessObjectEffect>("40 53 55 56 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 0F B7 FA", ProcessObjectEffectDetour);
_processObjectEffectHook.Enable();
}
IpcSubscriber = Svc.PluginInterface.GetIpcSubscriber<object, object>("PingPlugin.Ipc");
IpcSubscriber.Subscribe(UpdateRTTDetour);

ActionEffect.ActionEffectEvent += ActionFromEnemy;
ActionEffect.ActionEffectEvent += ActionFromSelf;
MapEffect.Init((a1, position, param1, param2) =>
{
if(DataCenter.MapEffects.Count >= 64)
if (DataCenter.MapEffects.Count >= 64)
{
DataCenter.MapEffects.TryDequeue(out _);
}
Expand All @@ -50,11 +62,31 @@ public static void Disable()
#if DEBUG
_useActionHook?.Dispose();
#endif
_processObjectEffectHook?.Disable();
IpcSubscriber.Unsubscribe(UpdateRTTDetour);
MapEffect.Dispose();
ActionEffect.ActionEffectEvent -= ActionFromEnemy;
ActionEffect.ActionEffectEvent -= ActionFromSelf;
}

private static unsafe long ProcessObjectEffectDetour(GameObject* a1, ushort a2, ushort a3, long a4)
{
try
{
if (DataCenter.ObjectEffects.Count >= 64)
{
DataCenter.ObjectEffects.TryDequeue(out _);
}

DataCenter.ObjectEffects.Enqueue(new ObjectEffectData(a1->ObjectID, a2, a3));
}
catch (Exception e)
{
Svc.Log.Warning(e, "Failed to execute the object effect!");
}
return _processObjectEffectHook.Original(a1, a2, a3, a4);
}

#if DEBUG
private static unsafe bool UseActionDetour(ActionManager* manager, ActionType actionType, uint actionID, ulong targetID, uint a4, uint a5, uint a6, void* a7)
{
Expand Down

0 comments on commit e9e7e02

Please sign in to comment.