Skip to content

Commit

Permalink
Merge pull request #411 from FFXIV-CombatReborn/Raise-settings-galore
Browse files Browse the repository at this point in the history
Refactor angle calculations and enhance configurations
  • Loading branch information
LTS-FFXIV authored Sep 26, 2024
2 parents dfd8e43 + 7579893 commit 0d1da36
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 57 deletions.
27 changes: 16 additions & 11 deletions RotationSolver.Basic/Actions/ActionTargetInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using RotationSolver.Basic.Configuration;
using RotationSolver.Basic.Helpers;
using static FFXIVClientStructs.FFXIV.Client.Game.Character.ActionEffectHandler;
using static RotationSolver.Basic.Configuration.ConfigTypes;

namespace RotationSolver.Basic.Actions;
Expand Down Expand Up @@ -129,8 +131,14 @@ private static bool InViewTarget(IBattleChara gameObject)
if (Service.Config.OnlyAttackInVisionCone && Player.Object != null)
{
Vector3 dir = gameObject.Position - Player.Object.Position;
Vector2 dirVec = new(dir.Z, dir.X);
double angle = Player.Object.GetFaceVector().AngleTo(dirVec);
Vector3 faceVec = Player.Object.GetFaceVector();
dir = Vector3.Normalize(dir);
faceVec = Vector3.Normalize(faceVec);

// Calculate the angle between the direction vector and the facing vector
double dotProduct = Vector3.Dot(faceVec, dir);
double angle = Math.Acos(dotProduct);

if (angle > Math.PI * Service.Config.AngleOfVisionCone / 360)
{
return false;
Expand Down Expand Up @@ -183,7 +191,7 @@ public bool GeneralCheck(IBattleChara gameObject, bool skipStatusProvideCheck)
{
if (!gameObject.IsTargetable) return false;

if (!Service.Config.TargetAllForFriendly && gameObject.IsAlliance() && !gameObject.IsParty())
if (Service.Config.RaiseType == RaiseType.PartyOnly && gameObject.IsAlliance() && !gameObject.IsParty())
{
return false;
}
Expand Down Expand Up @@ -709,7 +717,7 @@ private readonly bool CanGetTarget(IGameObject target, IGameObject subTarget)
}
else if (IGameObjects != null)
{
IGameObjects = IGameObjects.Where(t => t.DistanceToPlayer() < 1);
IGameObjects = IGameObjects.Where(t => t.DistanceToPlayer() < Service.Config.DistanceForMoving);
}
}
break;
Expand Down Expand Up @@ -811,8 +819,6 @@ private readonly bool CanGetTarget(IGameObject target, IGameObject subTarget)

IBattleChara? FindTargetForMoving()
{
const float DISTANCE_TO_MOVE = 3;

if (Service.Config == null || Player.Object == null || IGameObjects == null)
{
return null;
Expand All @@ -827,7 +833,7 @@ private readonly bool CanGetTarget(IGameObject target, IGameObject subTarget)

var tars = IGameObjects.Where(t =>
{
if (t.DistanceToPlayer() < DISTANCE_TO_MOVE) return false;
if (t.DistanceToPlayer() > Service.Config.DistanceForMoving) return false;

if (!Svc.GameGui.WorldToScreen(t.Position, out var scrPos)) return false;

Expand All @@ -848,12 +854,11 @@ private readonly bool CanGetTarget(IGameObject target, IGameObject subTarget)

var tars = IGameObjects.Where(t =>
{
if (t.DistanceToPlayer() < DISTANCE_TO_MOVE) return false;
if (t.DistanceToPlayer() > Service.Config.DistanceForMoving) return false;

var dir = t.Position - pPosition;
var dirVec = new Vector2(dir.Z, dir.X);
var angle = faceVec.AngleTo(dirVec);
return angle <= Math.PI * Service.Config.MoveTargetAngle / 360;
var angle = Vector3.Dot(faceVec, Vector3.Normalize(dir));
return angle >= Math.Cos(Math.PI * Service.Config.MoveTargetAngle / 360);
}).OrderByDescending(ObjectHelper.DistanceToPlayer);

return tars.FirstOrDefault();
Expand Down
13 changes: 2 additions & 11 deletions RotationSolver.Basic/Configuration/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,6 @@ public const string
[ConditionBool, UI("Use beneficial AoE actions when moving.", Parent = nameof(UseGroundBeneficialAbility))]
private static readonly bool _useGroundBeneficialAbilityWhenMoving = false;

[ConditionBool, UI("Heal/Rez players in other alliances.",
Filter = TargetConfig, Section = 3)]
private static readonly bool _targetAllForFriendly = false;

[ConditionBool, UI("Show Cooldown Window", Filter = UiWindows)]
private static readonly bool _showCooldownWindow = false;

Expand Down Expand Up @@ -432,10 +428,10 @@ public const string
PvEFilter = JobFilterType.None)]
private static readonly bool _raisePlayerBySwift = true;

[ConditionBool, UI("Raise any player in range in Alliance Raids",
[JobConfig, UI("Raise styles",
Filter = HealingActionCondition, Section = 2,
PvEFilter = JobFilterType.Raise, PvPFilter = JobFilterType.NoJob)]
private static readonly bool _raiseAll = false;
private readonly RaiseType _RaiseType = RaiseType.PartyOnly;

[ConditionBool, UI("Raise players that have the Brink of Death debuff",
Filter = HealingActionCondition, Section = 2,
Expand Down Expand Up @@ -527,11 +523,6 @@ public const string
[Range(0, 3, ConfigUnitType.Seconds, 0.002f)]
public Vector2 HealDelay { get; set; } = new(0.5f, 1);

[UI("How soon before countdown is finished to start casting or attacking.",
Filter = BasicTimer, Section = 1, PvPFilter = JobFilterType.NoJob)]
[Range(0, 0.7f, ConfigUnitType.Seconds, 0.002f)]
public float CountDownAhead { get; set; } = 0.4f;

[UI("The size of the sector angle that can be selected as the moveable target",
Description = "If the selection mode is based on character facing, i.e., targets within the character's viewpoint are moveable targets. \nIf the selection mode is screen-centered, i.e., targets within a sector drawn upward from the character's point are movable targets.",
Filter = TargetConfig, Section = 2)]
Expand Down
25 changes: 25 additions & 0 deletions RotationSolver.Basic/Data/RaiseType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace RotationSolver.Basic.Data;

/// <summary>
/// Specifies who to raise.
/// </summary>
public enum RaiseType : byte
{
/// <summary>
/// Raise only party members.
/// </summary>
[Description("Raise only party members.")]
PartyOnly,

/// <summary>
/// Raise party and alliance members.
/// </summary>
[Description("Raise party and alliance members.")]
PartyAndAlliance,

/// <summary>
/// Raise party members and alliance healers.
/// </summary>
[Description("Raise party members and alliance healers.")]
PartyAndAllianceHealers,
}
37 changes: 19 additions & 18 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,47 +381,48 @@ public static IBattleChara? DeathTarget
var deathParty = PartyMembers.GetDeath();
var deathNPC = FriendlyNPCMembers.GetDeath();

// Check death in party members
if (deathParty.Any())
{
var deathT = deathParty.GetJobCategory(JobRole.Tank).ToList();
var deathH = deathParty.GetJobCategory(JobRole.Healer).ToList();

if (deathT.Count > 1)
{
return deathT.FirstOrDefault();
}

if (deathT.Count > 1) return deathT.FirstOrDefault();
if (deathH.Any()) return deathH.FirstOrDefault();

if (deathT.Any()) return deathT.FirstOrDefault();

return deathParty.FirstOrDefault();
}

if (deathAll.Any() && Service.Config.RaiseAll)
// Check death in alliance members
if (deathAll.Any())
{
var deathAllH = deathAll.GetJobCategory(JobRole.Healer).ToList();
var deathAllT = deathAll.GetJobCategory(JobRole.Tank).ToList();
if (Service.Config.RaiseType == RaiseType.PartyAndAllianceHealers)
{
var deathAllH = deathAll.GetJobCategory(JobRole.Healer).ToList();
if (deathAllH.Any()) return deathAllH.FirstOrDefault();
}

if (deathAllH.Any()) return deathAllH.FirstOrDefault();
if (Service.Config.RaiseType == RaiseType.PartyAndAlliance)
{
var deathAllH = deathAll.GetJobCategory(JobRole.Healer).ToList();
var deathAllT = deathAll.GetJobCategory(JobRole.Tank).ToList();

if (deathAllT.Any()) return deathAllT.FirstOrDefault();
if (deathAllH.Any()) return deathAllH.FirstOrDefault();
if (deathAllT.Any()) return deathAllT.FirstOrDefault();

return deathAll.FirstOrDefault();
return deathAll.FirstOrDefault();
}
}

// Check death in friendly NPC members
if (deathNPC.Any() && Service.Config.FriendlyPartyNpcHealRaise)
{
var deathNPCT = deathNPC.GetJobCategory(JobRole.Tank).ToList();
var deathNPCH = deathNPC.GetJobCategory(JobRole.Healer).ToList();

if (deathNPCT.Count > 1)
{
return deathNPCT.FirstOrDefault();
}

if (deathNPCT.Count > 1) return deathNPCT.FirstOrDefault();
if (deathNPCH.Any()) return deathNPCH.FirstOrDefault();

if (deathNPCT.Any()) return deathNPCT.FirstOrDefault();

return deathNPC.FirstOrDefault();
Expand Down
23 changes: 13 additions & 10 deletions RotationSolver.Basic/Helpers/ObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ internal static unsafe bool IsAlliance(this IGameObject obj)
&& (!(DataCenter.IsPvP) && obj is IPlayerCharacter
|| ActionManager.CanUseActionOnTarget((uint)ActionID.CurePvE, obj.Struct()));


private static readonly object _lock = new object();

internal static bool IsParty(this IGameObject gameObject)
Expand Down Expand Up @@ -469,12 +470,15 @@ public static EnemyPositional FindEnemyPositional(this IGameObject enemy)
if (enemy == null || Player.Object == null) return EnemyPositional.None;

Vector3 pPosition = enemy.Position;
Vector2 faceVec = enemy.GetFaceVector();
Vector3 faceVec = enemy.GetFaceVector();

Vector3 dir = Player.Object.Position - pPosition;
Vector2 dirVec = new Vector2(dir.Z, dir.X);
dir = Vector3.Normalize(dir);
faceVec = Vector3.Normalize(faceVec);

double angle = faceVec.AngleTo(dirVec);
// Calculate the angle between the direction vector and the facing vector
double dotProduct = Vector3.Dot(faceVec, dir);
double angle = Math.Acos(dotProduct);

const double frontAngle = Math.PI / 4;
const double rearAngle = Math.PI * 3 / 4;
Expand All @@ -489,14 +493,14 @@ public static EnemyPositional FindEnemyPositional(this IGameObject enemy)
/// </summary>
/// <param name="obj">The game object.</param>
/// <returns>
/// A <see cref="Vector2"/> representing the facing direction of the game object.
/// A <see cref="Vector3"/> representing the facing direction of the game object.
/// </returns>
internal static Vector2 GetFaceVector(this IGameObject obj)
internal static Vector3 GetFaceVector(this IGameObject obj)
{
if (obj == null) return Vector2.Zero;
if (obj == null) return Vector3.Zero;

float rotation = obj.Rotation;
return new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
return new Vector3((float)Math.Sin(rotation), 0, (float)Math.Cos(rotation));
}

/// <summary>
Expand All @@ -507,12 +511,12 @@ internal static Vector2 GetFaceVector(this IGameObject obj)
/// <returns>
/// The angle in radians between the two vectors.
/// </returns>
internal static double AngleTo(this Vector2 vec1, Vector2 vec2)
internal static double AngleTo(this Vector3 vec1, Vector3 vec2)
{
double lengthProduct = vec1.Length() * vec2.Length();
if (lengthProduct == 0) return 0;

double dotProduct = Vector2.Dot(vec1, vec2);
double dotProduct = Vector3.Dot(vec1, vec2);
return Math.Acos(dotProduct / lengthProduct);
}

Expand All @@ -529,5 +533,4 @@ public static float DistanceToPlayer(this IGameObject? obj)
var distance = Vector3.Distance(player.Position, obj.Position) - (player.HitboxRadius + obj.HitboxRadius);
return distance;
}

}
6 changes: 0 additions & 6 deletions RotationSolver.Basic/Rotations/CustomRotation_OtherInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -566,12 +566,6 @@ protected static float GCDTime(uint gcdCount = 0, float offset = 0)
=> DataCenter.GCDTime(gcdCount, offset);

#region Service
/// <summary>
/// The count down ahead.
/// </summary>
[Description("Count Down ahead")]
public static float CountDownAhead => Service.Config.CountDownAhead;

/// <summary>
///
/// </summary>
Expand Down
4 changes: 3 additions & 1 deletion RotationSolver/UI/RotationConfigWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using ExCSS;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Fate;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Common.Component.BGCollision;
using Lumina.Excel.GeneratedSheets;
Expand Down Expand Up @@ -2771,7 +2770,10 @@ private static unsafe void DrawTargetData()
ImGui.Text($"Is Dying: {battleChara.IsDying()}");
ImGui.Text($"Is Alive: {battleChara.IsAlive()}");
ImGui.Text($"Is Party: {battleChara.IsParty()}");
ImGui.Text($"Is Healer: {battleChara.IsJobCategory(JobRole.Healer)}");
ImGui.Text($"Is Alliance: {battleChara.IsAlliance()}");
ImGui.Text($"Is Enemy: {battleChara.IsEnemy()}");
ImGui.Text($"Distance To Player: {battleChara.DistanceToPlayer()}");
ImGui.Text($"Is In EnemiesList: {battleChara.IsInEnemiesList()}");
ImGui.Text($"Is Attackable: {battleChara.IsAttackable()}");
ImGui.Text($"CanProvoke: {battleChara.CanProvoke()}");
Expand Down

0 comments on commit 0d1da36

Please sign in to comment.