Skip to content

Commit

Permalink
Merge pull request #458 from FFXIV-CombatReborn/targettingstuff
Browse files Browse the repository at this point in the history
Enhance target checks and add PriorityTargetHelper
  • Loading branch information
LTS-FFXIV authored Dec 3, 2024
2 parents d365f6b + 8af285c commit e46ac3d
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
15 changes: 10 additions & 5 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,17 +377,22 @@ public static IBattleChara[] AllHostileTargets
{
get
{
var strongOfShieldPositional = EnemyPositional.Front;

return AllTargets.Where(b =>
{
// Check if the target is an enemy.
if (!b.IsEnemy()) return false;

// Check if the target is targetable.
if (!b.IsTargetable) return false;
// Check if the target is an enemy and targetable.
if (!b.IsEnemy() || !b.IsTargetable) return false;

// Check if the target is invincible.
if (b.StatusList.Any(StatusHelper.IsInvincible)) return false;

// Special exception for Jeuno raid Ark Angels.
if (b.IsWrongEpicFatedVaunted()) return false;

// Special exception for the Strong of Shield status on Hansel and Gretel.
if (b.HasStatus(true, StatusID.StrongOfShield) && strongOfShieldPositional != b.FindEnemyPositional()) return false;

// If all checks pass, the target is considered hostile.
return true;
}).ToArray();
Expand Down
28 changes: 26 additions & 2 deletions RotationSolver.Basic/Helpers/ObjectHelper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds;
using ECommons;
using ECommons.DalamudServices;
using ECommons.GameFunctions;
using ECommons.GameHelpers;
using ECommons.Reflection;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Event;
Expand Down Expand Up @@ -44,7 +46,7 @@ internal static bool CanProvoke(this IGameObject target)
//Removed the listed names.
if (OtherConfiguration.NoProvokeNames.TryGetValue(Svc.ClientState.TerritoryType, out var ns1))
{
var names = ns1.Where(n => !string.IsNullOrEmpty(n) && new Regex(n).Match(target.Name.ToString()).Success);
var names = ns1.Where(n => !string.IsNullOrEmpty(n) && new Regex(n).Match(target.Name.ExtractText()).Success);
if (names.Any()) return false;
}

Expand All @@ -65,7 +67,7 @@ internal static bool CanProvoke(this IGameObject target)

internal static bool HasPositional(this IGameObject obj)
{
return obj != null && !(obj.GetObjectNPC()?.IsOmnidirectional ?? false); // Unknown10 used to be the flag for no positional, believe this was changed to IsOmnidirectional
return obj != null && !(obj.GetObjectNPC()?.IsOmnidirectional ?? false) && !obj.HasStatus(true, StatusID.DirectionalDisregard); // Unknown10 used to be the flag for no positional, believe this was changed to IsOmnidirectional
}

internal static unsafe bool IsOthersPlayers(this IGameObject obj)
Expand Down Expand Up @@ -279,6 +281,24 @@ internal static bool IsAlive(this IGameObject obj)
/// <returns></returns>
public static unsafe ObjectKind GetObjectKind(this IGameObject obj) => (ObjectKind)obj.Struct()->ObjectKind;

/// <summary>
/// Determines whether the specified game object is a valid target for a player with the Epic Hero, Fated Hero, or Vaunted hero status.
/// </summary>
/// <param name="obj">The game object to check.</param>
/// <returns>
/// <c>true</c> if the game object does not have the appropriate status, target; otherwise, <c>false</c>.
/// </returns>
internal static bool IsWrongEpicFatedVaunted(this IGameObject obj)
{
if (obj == null || Player.Object == null) return false;

var player = Player.Object;

return (player.HasStatus(true, StatusID.EpicHero) && !obj.HasStatus(true, StatusID.EpicVillain)) ||
(player.HasStatus(true, StatusID.FatedHero) && !obj.HasStatus(true, StatusID.FatedVillain)) ||
(player.HasStatus(true, StatusID.VauntedHero) && !obj.HasStatus(true, StatusID.VauntedVillain));
}

/// <summary>
/// Determines whether the specified game object is a top priority hostile target based on its name being listed.
/// </summary>
Expand Down Expand Up @@ -318,8 +338,12 @@ internal static bool IsTopPriorityHostile(this IGameObject obj)

var fateId = DataCenter.FateId;


if (obj is IBattleChara b)
{
if (Player.Object == null) return false;
// Check IBattleChara against the priority target list of OIDs
if (PriorityTargetHelper.IsPriorityTarget(b.DataId)) return true;
// Ensure StatusList is not null before calling Any
if (b.StatusList != null && b.StatusList.Any(StatusHelper.IsPriority)) return true;
}
Expand Down
27 changes: 27 additions & 0 deletions RotationSolver.Basic/Helpers/PriorityTargetHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace RotationSolver.Basic.Helpers
{
internal class PriorityTargetHelper
{
// List of OIDs (DataId)
private static readonly HashSet<uint> priorityOids = new HashSet<uint>
{
0x415E, // Example OID
// Add more OIDs here
};

// Method to check if the given DataId is a priority target
public static bool IsPriorityTarget(uint dataId)
{
return priorityOids.Contains(dataId);
}

// Method to add a DataId to the priority list
public static void AddPriorityTarget(uint dataId)
{
if (!priorityOids.Contains(dataId))
{
priorityOids.Add(dataId);
}
}
}
}

0 comments on commit e46ac3d

Please sign in to comment.