exuals reacted to
Matenia in Walking into multiple mobs to target far away, pulls 3+
Gonna dump some code here I've used to experiment, you can adjust it for your own needs:
public class SmartPulls
{
private static WoWLocalPlayer Me = ObjectManager.Me;
private static int _checkDistance = 22;
private static int _frontDistance = 15;
public static void Start()
{
if (PluginSettings.CurrentSetting.SmartPulls)
{
FightEvents.OnFightStart += FightValidityCheck;
Radar3D.OnDrawEvent += Radar3DOnOnDrawEvent;
}
}
private static void Radar3DOnOnDrawEvent()
{
if (Radar3D.IsLaunched)
{
Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position,
-Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), -_checkDistance);
Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position,
-Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), _checkDistance);
Vector3 rightTargetVector = Helper.CalculatePosition(rightPlayerVector,
-Helper.Atan2Rotation(Me.Position, rightPlayerVector, 0), _checkDistance + _frontDistance);
Vector3 leftTargetVector = Helper.CalculatePosition(leftPlayerVector,
-Helper.Atan2Rotation(Me.Position, leftPlayerVector, 0), -(_checkDistance + _frontDistance));
Radar3D.DrawCircle(rightPlayerVector, 2.5f, Color.Blue);
Radar3D.DrawCircle(leftPlayerVector, 2.5f, Color.Green);
Radar3D.DrawCircle(rightTargetVector, 2.5f, Color.Yellow);
Radar3D.DrawCircle(leftTargetVector, 2.5f, Color.DarkRed);
Radar3D.DrawLine(rightPlayerVector, leftPlayerVector, Color.Gold);
Radar3D.DrawLine(leftPlayerVector, leftTargetVector, Color.Gold);
Radar3D.DrawLine(leftTargetVector, rightTargetVector, Color.Gold);
Radar3D.DrawLine(rightTargetVector, rightPlayerVector, Color.Gold);
}
}
public static void Stop()
{
FightEvents.OnFightStart -= FightValidityCheck;
Radar3D.OnDrawEvent -= Radar3DOnOnDrawEvent;
}
public static void Pulse()
{
if (PluginSettings.CurrentSetting.SmartPulls && !Escape.IsEscaping && Me.Target > 0 && !Fight.InFight && !Me.InCombatFlagOnly && Logging.Status != "Regeneration" && !Me.HaveBuff("Resurrection Sickness"))
{
Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position,
-Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), -_checkDistance);
Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position,
-Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), _checkDistance);
Vector3 rightTargetVector = Helper.CalculatePosition(rightPlayerVector,
-Helper.Atan2Rotation(Me.Position, rightPlayerVector, 0), _checkDistance + _frontDistance);
Vector3 leftTargetVector = Helper.CalculatePosition(leftPlayerVector,
-Helper.Atan2Rotation(Me.Position, leftPlayerVector, 0), -(_checkDistance + _frontDistance));
List<Vector3> boundBox = new List<Vector3>
{
rightPlayerVector,
leftPlayerVector,
rightTargetVector,
leftTargetVector
};
WoWUnit unit = ObjectManager.GetObjectWoWUnit()
.Where(o => o.IsAlive && o.Reaction == Reaction.Hostile && !o.IsPet && !o.IsPlayer() && o.Guid != Me.Target &&
(o.Level >= Me.Level ? o.Level - Me.Level <= 3 : Me.Level - o.Level <= 6)
&& VectorHelper.PointInPolygon2D(boundBox, o.Position)
&& !TraceLine.TraceLineGo(Me.Position, o.Position, CGWorldFrameHitFlags.HitTestSpellLoS)
&& !wManagerSetting.IsBlackListed(o.Guid))
.OrderBy(o => o.GetDistance)
.FirstOrDefault();
if (unit != null)
{
PluginLog.Log($"{unit.Name} is in our way, attacking!");
MovementManager.StopMoveTo(false, 500);
ObjectManager.Me.Target = unit.Guid;
Fight.StartFight(unit.Guid);
ObjectManager.Me.Target = unit.Guid;
}
}
}
//don't pull another target if we are already in combat with anyone (e.g. body pulled mobs)
private static void FightValidityCheck(WoWUnit unit, CancelEventArgs cancelable)
{
if (Escape.IsEscaping || ObjectManager.GetObjectWoWUnit().Count(u => u.IsTargetingMeOrMyPet && u.Reaction == Reaction.Hostile) > 0)
{
return;
}
if (CheckForGroup(unit, cancelable))
{
MovementManager.StopMoveTo(false, 500);
cancelable.Cancel = true;
return;
}
if (CheckForClearPath(unit, cancelable))
{
MovementManager.StopMoveTo(false, 500);
cancelable.Cancel = true;
return;
}
}
private static bool CheckForGroup(WoWUnit unit, CancelEventArgs cancelable)
{
// group too large, nothing we can do, stop fight and go away
int addAmount = ObjectManager.GetObjectWoWUnit().Count(o =>
o.IsAlive && o.Reaction == Reaction.Hostile && o.Guid != unit.Guid &&
o.Position.DistanceTo(unit.Position) <= 12 && !o.IsTargetingMeOrMyPetOrPartyMember);
if (addAmount > 1)
{
wManagerSetting.AddBlackList(unit.Guid, 60000);
Fight.StopFight();
Lua.LuaDoString("ClearTarget()");
wManagerSetting.AddBlackListZone(unit.Position, 30 + addAmount * 5);
PathFinder.ReportBigDangerArea(unit.Position, 30 + addAmount * 5);
PluginLog.Log("Stopping pull on large group!");
return true;
}
return false;
}
private static bool CheckForClearPath(WoWUnit unit, CancelEventArgs cancelable)
{
if (Me.InCombatFlagOnly)
{
return false;
}
Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position, -Helper.Atan2Rotation(unit.Position, Me.Position, 0), _checkDistance);
Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position, -Helper.Atan2Rotation(unit.Position, Me.Position, 0), -_checkDistance);
Vector3 rightTargetVector = Helper.CalculatePosition(unit.Position, -Helper.Atan2Rotation(Me.Position, unit.Position, 0), -_checkDistance);
Vector3 leftTargetVector = Helper.CalculatePosition(unit.Position, -Helper.Atan2Rotation(Me.Position, unit.Position, 0), _checkDistance);
List<Vector3> boundingBox = new List<Vector3>{rightPlayerVector, leftPlayerVector, rightTargetVector, leftTargetVector};
if (ObjectManager.GetObjectWoWUnit().FirstOrDefault(o =>
o.IsAlive && o.Reaction == Reaction.Hostile && o.Guid != unit.Guid &&
VectorHelper.PointInPolygon2D(boundingBox, o.Position)) != null)
{
WoWUnit newEnemy = ObjectManager.GetObjectWoWUnit()
.Where(o => o.IsAlive && o.Reaction == Reaction.Hostile && o.SummonedBy <= 0 && !o.IsPlayer() && o.Guid != unit.Guid && !wManagerSetting.IsBlackListed(o.Guid) && !wManagerSetting.IsBlackListedNpcEntry(o.Entry))
.OrderBy(o => o.GetDistance)
.FirstOrDefault();
if (newEnemy != null)
{
wManagerSetting.AddBlackList(unit.Guid, 60000);
Fight.StopFight();
Fight.StartFight(newEnemy.Guid);
PluginLog.Log($"Enemy in the way, can't pull here - pulling {newEnemy.Name} instead");
}
return true;
}
return false;
}
}