Skip to content

Commit

Permalink
=Fixed targeting
Browse files Browse the repository at this point in the history
  • Loading branch information
vadash committed Feb 16, 2021
1 parent d9adc39 commit 3736ca1
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 78 deletions.
148 changes: 92 additions & 56 deletions EssenceDrainContagion.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using ExileCore;
using ExileCore.PoEMemory.Components;
using ExileCore.PoEMemory.FilesInMemory;
using ExileCore.PoEMemory.MemoryObjects;
using ExileCore.Shared;
using ExileCore.Shared.Enums;
using ExileCore.Shared.Helpers;
using SharpDX;

namespace EssenceDrainContagion
{
public class EssenceDrainContagion : BaseSettingsPlugin<EssenceDrainContagionSettings>
{
private readonly Stopwatch _aimTimer = Stopwatch.StartNew();
private readonly List<Entity> _entities = new List<Entity>();
private IDictionary<string, StatsDat.StatRecord> _statRecords;
private bool _aiming;
private Vector2 _oldMousePos;
private HashSet<string> _ignoredMonsters;
private Coroutine _mainCoroutine;
private Tuple<float, Entity> _bestTarget;

private readonly string[] _ignoredBuffs = {
"capture_monster_captured",
Expand Down Expand Up @@ -55,82 +54,119 @@ public class EssenceDrainContagion : BaseSettingsPlugin<EssenceDrainContagionSet
public override bool Initialise()
{
LoadIgnoredMonsters($@"{DirectoryFullName}\Ignored Monsters.txt");
_statRecords = GameController.Files.Stats.records;
Input.RegisterKey(Settings.AimKey);
_mainCoroutine = new Coroutine(
MainCoroutine(),
this,
"EDC");
Core.ParallelRunner.Run(_mainCoroutine);
return true;
}

private void LoadIgnoredMonsters(string fileName)
private IEnumerator MainCoroutine()
{
_ignoredMonsters = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
if (!File.Exists(fileName))
while (true)
{
LogError($@"Failed to find {fileName}", 10);
return;
}

foreach (var line in File.ReadAllLines(fileName))
if (!string.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))
_ignoredMonsters.Add(line.Trim().ToLower());
}

public override void Render()
{
if (_aimTimer.ElapsedMilliseconds < 100) return;
try
{
if (!ValidTarget(_bestTarget?.Item2)) _bestTarget = ScanValidMonsters()?.FirstOrDefault();
}
catch
{
// ignored
}

try
{
if (!Input.IsKeyDown(Keys.RButton))
if (!Input.IsKeyDown(Settings.AimKey))
_oldMousePos = Input.MousePosition;
if (Input.IsKeyDown(Keys.RButton)
if (Input.IsKeyDown(Settings.AimKey)
&& !GameController.Game.IngameState.IngameUi.InventoryPanel.IsVisible
&& !GameController.Game.IngameState.IngameUi.OpenLeftPanel.IsVisible)
{
_aiming = true;
var bestTarget = ScanValidMonsters()?.FirstOrDefault();
Attack(bestTarget);
yield return Attack();
}
if (!Input.IsKeyDown(Keys.RButton) && _aiming)

if (!Input.IsKeyDown(Settings.AimKey) && _aiming)
{
Input.SetCursorPos(_oldMousePos);
_aiming = false;
_aiming = false;
}

yield return new WaitTime(25);
}
catch (Exception e)
// ReSharper disable once IteratorNeverReturns
}

private bool ValidTarget(Entity entity)
{
try
{
return entity != null &&
entity.IsValid &&
entity.IsAlive &&
entity.IsHostile &&
entity.HasComponent<Monster>() &&
entity.HasComponent<Targetable>() &&
entity.HasComponent<Life>() &&
entity.GetComponent<Life>().CurHP / (float) entity.GetComponent<Life>().MaxHP > 0.25f &&
entity.DistancePlayer < Settings.AimRangeGrid &&
GameController.Window.GetWindowRectangleTimeCache.Contains(
GameController.Game.IngameState.Camera.WorldToScreen(entity.Pos));
}
catch
{
LogError("Something went wrong? " + e, 5);
return false;
}
}

_aimTimer.Restart();
public override void Render()
{
if (_bestTarget != null)
{
var position = GameController.Game.IngameState.Camera.WorldToScreen(_bestTarget.Item2.Pos);
Graphics.DrawFrame(position, position.Translate(20, 20), Color.Chocolate, 3);
}
base.Render();
}

public override void EntityAdded(Entity entityWrapper) { _entities.Add(entityWrapper); }
private void LoadIgnoredMonsters(string fileName)
{
_ignoredMonsters = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
if (!File.Exists(fileName))
{
LogError($@"Failed to find {fileName}", 10);
return;
}

public override void EntityRemoved(Entity entityWrapper) { _entities.Remove(entityWrapper); }
foreach (var line in File.ReadAllLines(fileName))
if (!string.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))
_ignoredMonsters.Add(line.Trim().ToLower());
}

private void Attack(Tuple<float, Entity> bestTarget)
private IEnumerator Attack()
{
if (bestTarget == null) return;
var position = GameController.Game.IngameState.Camera.WorldToScreen(bestTarget.Item2.Pos);
var windowRectangle = GameController.Window.GetWindowRectangle();
if (!position.IsInside(windowRectangle)) return;
var offset = GameController.Window.GetWindowRectangle().TopLeft;
Input.SetCursorPos(position + offset);
Input.KeyPressRelease(bestTarget.Item2.HasBuff("contagion", true) ? Settings.EssenceDrainKey.Value : Settings.ContagionKey.Value);
if (_bestTarget == null) yield break;
var position = GameController.Game.IngameState.Camera.WorldToScreen(_bestTarget.Item2.Pos);
Input.SetCursorPos(position);
yield return Input.KeyPress(_bestTarget.Item2.HasBuff("contagion", true) ? Settings.EssenceDrainKey.Value : Settings.ContagionKey.Value);
}

private IEnumerable<Tuple<float, Entity>> ScanValidMonsters()
{
return _entities?.Where(x =>
x.HasComponent<Monster>() &&
x.IsAlive &&
x.IsHostile &&
x.GetStatValue("ignored_by_enemy_target_selection", _statRecords) == 0 &&
x.GetStatValue("cannot_die", _statRecords) == 0 &&
x.GetStatValue("cannot_be_damaged", _statRecords) == 0 &&
!_ignoredBuffs.Any(b => x.HasBuff(b)) &&
!_ignoredMonsters.Any(im => x.Path.ToLower().Contains(im))
)
.Select(x => new Tuple<float, Entity>(ComputeWeight(x), x))
.Where(x => x.Item1 < Settings.AimRange)
.OrderByDescending(x => x.Item1);
var queue =
from entity in GameController.Entities
where ValidTarget(entity)
let stats = entity.GetComponent<Stats>()
where !Extensions.HaveStat(entity, GameStat.CannotDie) &&
!Extensions.HaveStat(entity, GameStat.CannotBeDamaged) &&
!Extensions.HaveStat(entity, GameStat.IgnoredByEnemyTargetSelection) &&
!_ignoredBuffs.Any(b => entity.HasBuff(b)) &&
!_ignoredMonsters.Any(im => entity.Path.ToLower().Contains(im))
let weight = ComputeWeight(entity)
orderby weight descending
select new Tuple<float, Entity>(weight, entity);

return queue;
}

private float ComputeWeight(Entity entity)
Expand Down
5 changes: 3 additions & 2 deletions EssenceDrainContagion.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
Expand All @@ -23,7 +23,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\PoeHelper\Plugins\Compiled\EssenceDrainContagion\</OutputPath>
Expand Down Expand Up @@ -62,6 +62,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<HintPath>..\..\..\..\PoEHelper\System.Numerics.Vectors.dll</HintPath>
</Reference>
Expand Down
4 changes: 4 additions & 0 deletions EssenceDrainContagion.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Huhu/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taniwha/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tukohama/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
6 changes: 3 additions & 3 deletions EssenceDrainContagionSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ namespace EssenceDrainContagion
public class EssenceDrainContagionSettings : ISettings
{
public HotkeyNode AimKey { get; set; } = Keys.RButton;
public HotkeyNode ContagionKey { get; set; } = Keys.Z;
public HotkeyNode EssenceDrainKey { get; set; } = Keys.R;
public RangeNode<int> AimRange { get; set; } = new RangeNode<int>(600, 1, 1000);
public HotkeyNode ContagionKey { get; set; } = Keys.Q;
public HotkeyNode EssenceDrainKey { get; set; } = Keys.W;
public RangeNode<int> AimRangeGrid { get; set; } = new RangeNode<int>(100, 40, 200);
public RangeNode<int> AimLoopDelay { get; set; } = new RangeNode<int>(124, 1, 200);
public ToggleNode RMousePos { get; set; } = new ToggleNode(false);
public ToggleNode AimPlayers { get; set; } = new ToggleNode(true);
Expand Down
30 changes: 13 additions & 17 deletions Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ExileCore.PoEMemory.Components;
using ExileCore.PoEMemory.FilesInMemory;
using ExileCore.PoEMemory.MemoryObjects;
using ExileCore.Shared.Enums;
using SharpDX;
Expand All @@ -19,6 +17,19 @@ public static bool HasBuff(this Entity entity, string buff, bool contains = fals
entity.GetComponent<Life>().Buffs.Any(b => contains ? b.Name.Contains(buff) : b.Name == buff);
}

public static bool HaveStat(Entity entity, GameStat stat)
{
try
{
var result = entity?.GetComponent<Stats>()?.StatDictionary?[stat];
return result > 0;
}
catch (Exception)
{
return false;
}
}

public static bool IsInside(this Vector2 position, RectangleF container)
{
return position.Y + PixelBorder < container.Bottom
Expand All @@ -39,20 +50,5 @@ public static int DistanceFrom(this Entity fromEntity, Entity toEntity)
return Int32.MaxValue;
}
}

public static int GetStatValue(this Entity entity, string playerStat, IDictionary<string, StatsDat.StatRecord> recordsByIdentifier)
{
if (!recordsByIdentifier.TryGetValue(playerStat, out var startRecord))
{
return 0;
}

if (!entity.GetComponent<Stats>().StatDictionary.TryGetValue((GameStat) startRecord.ID, out var statValue))
{
return 0;
}

return statValue;
}
}
}

0 comments on commit 3736ca1

Please sign in to comment.