Untitled diff
2 removals
291 lines
17 additions
304 lines
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics;
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Controls;
using log4net;
using log4net;
using System;
using System;
using Loki.Bot;
using Loki.Bot;
using Loki.Bot.v3;
using Loki.Bot.v3;
using Loki.Game;
using Loki.Game;
using Loki.Game.GameData;
using Loki.Game.GameData;
using Loki.Game.Objects;
using Loki.Game.Objects;
using Loki.Utilities;
using Loki.Utilities;
namespace OverwordAreaTweaks
namespace OverwordAreaTweaks
{
{
internal class OverwordAreaTweaks : IPlugin
internal class OverwordAreaTweaks : IPlugin
{
{
private static readonly ILog Log = Logger.GetLoggerInstanceForType();
private static readonly ILog Log = Logger.GetLoggerInstanceForType();
private bool _enabled;
private bool _enabled;
/// <summary> The name of the plugin. </summary>
/// <summary> The name of the plugin. </summary>
public string Name
public string Name
{
{
get { return "OverwordAreaTweaks"; }
get { return "OverwordAreaTweaks"; }
}
}
/// <summary> The description of the plugin. </summary>
/// <summary> The description of the plugin. </summary>
public string Description
public string Description
{
{
get
get
{
{
return "A plugin that provides some additional functionality in Overworld areas.";
return "A plugin that provides some additional functionality in Overworld areas.";
}
}
}
}
/// <summary>The author of the plugin.</summary>
/// <summary>The author of the plugin.</summary>
public string Author
public string Author
{
{
get { return "Bossland GmbH"; }
get { return "Bossland GmbH"; }
}
}
/// <summary>The version of the plugin.</summary>
/// <summary>The version of the plugin.</summary>
public Version Version
public Version Version
{
{
get { return new Version(0, 0, 1, 1); }
get { return new Version(0, 0, 1, 1); }
}
}
/// <summary>Initializes this plugin.</summary>
/// <summary>Initializes this plugin.</summary>
public void Initialize()
public void Initialize()
{
{
Log.DebugFormat("[OverwordAreaTweaks] Initialize");
Log.DebugFormat("[OverwordAreaTweaks] Initialize");
}
}
/// <summary> The plugin start callback. Do any initialization here. </summary>
/// <summary> The plugin start callback. Do any initialization here. </summary>
public void Start()
public void Start()
{
{
Log.DebugFormat("[OverwordAreaTweaks] Start");
Log.DebugFormat("[OverwordAreaTweaks] Start");
// We want to change the behavior before exploration, so we can travel to the bosses before exploration is finished.
// We want to change the behavior before exploration, so we can travel to the bosses before exploration is finished.
// This should avoid issues with other plugins that add tasks after exploration, such as DominusFight.
// This should avoid issues with other plugins that add tasks after exploration, such as DominusFight.
if (!TaskManager.AddBefore(new TrackMoreMobs(), "ExploreTask"))
if (!TaskManager.AddBefore(new TrackMoreMobs(), "ExploreTask"))
{
{
Log.ErrorFormat("[OverwordAreaTweaks] AddAfter failed.");
Log.ErrorFormat("[OverwordAreaTweaks] AddAfter failed.");
BotManager.Stop();
BotManager.Stop();
}
}
}
}
/// <summary> The plugin tick callback. Do any update logic here. </summary>
/// <summary> The plugin tick callback. Do any update logic here. </summary>
public void Tick()
public void Tick()
{
{
}
}
/// <summary> The plugin stop callback. Do any pre-dispose cleanup here. </summary>
/// <summary> The plugin stop callback. Do any pre-dispose cleanup here. </summary>
public void Stop()
public void Stop()
{
{
Log.DebugFormat("[OverwordAreaTweaks] Stop");
Log.DebugFormat("[OverwordAreaTweaks] Stop");
}
}
#region Implementation of IConfigurable
#region Implementation of IConfigurable
public JsonSettings Settings
public JsonSettings Settings
{
{
get { return null; }
get { return null; }
}
}
/// <summary> The plugin's settings control. This will be added to the Exilebuddy Settings tab.</summary>
/// <summary> The plugin's settings control. This will be added to the Exilebuddy Settings tab.</summary>
public UserControl Control
public UserControl Control
{
{
get { return null; }
get { return null; }
}
}
#endregion
#endregion
#region Implementation of IEnableable
#region Implementation of IEnableable
/// <summary>Is this plugin currently enabled?</summary>
/// <summary>Is this plugin currently enabled?</summary>
public bool IsEnabled
public bool IsEnabled
{
{
get { return _enabled; }
get { return _enabled; }
}
}
/// <summary> The plugin is being enabled.</summary>
/// <summary> The plugin is being enabled.</summary>
public void Enable()
public void Enable()
{
{
Log.DebugFormat("[OverwordAreaTweaks] Enable");
Log.DebugFormat("[OverwordAreaTweaks] Enable");
_enabled = true;
_enabled = true;
}
}
/// <summary> The plugin is being disabled.</summary>
/// <summary> The plugin is being disabled.</summary>
public void Disable()
public void Disable()
{
{
Log.DebugFormat("[OverwordAreaTweaks] Disable");
Log.DebugFormat("[OverwordAreaTweaks] Disable");
_enabled = false;
_enabled = false;
}
}
#endregion
#endregion
#region Implementation of IDisposable
#region Implementation of IDisposable
/// <summary> </summary>
/// <summary> </summary>
public void Dispose()
public void Dispose()
{
{
}
}
#endregion
#endregion
#region Override of Object
#region Override of Object
/// <summary>
/// <summary>
///
///
/// </summary>
/// </summary>
/// <returns></returns>
/// <returns></returns>
public override string ToString()
public override string ToString()
{
{
return Name + ": " + Description;
return Name + ": " + Description;
}
}
#endregion
#endregion
public class TrackMoreMobs : ITask
public class TrackMoreMobs : ITask
{
{
private readonly Stopwatch _sw = new Stopwatch();
private readonly Stopwatch _sw = new Stopwatch();
private readonly Dictionary<int, Vector2i> _mobs = new Dictionary<int, Vector2i>();
private readonly Dictionary<int, Vector2i> _mobs = new Dictionary<int, Vector2i>();
private readonly List<int> _processed = new List<int>();
private readonly List<int> _processed = new List<int>();
private KeyValuePair<int, Vector2i>? _currentEntry;
private bool _enabled = true;
private bool _enabled = true;
/// <summary>The name of this task.</summary>
/// <summary>The name of this task.</summary>
public string Name
public string Name
{
{
get { return "TrackMoreMobs"; }
get { return "TrackMoreMobs"; }
}
}
/// <summary>A description of what this task does.</summary>
/// <summary>A description of what this task does.</summary>
public string Description
public string Description
{
{
get { return "This task helps BasicGrindBot seek out as many mobs as possible in Overworld areas."; }
get { return "This task helps BasicGrindBot seek out as many mobs as possible in Overworld areas."; }
}
}
/// <summary>The author of this task.</summary>
/// <summary>The author of this task.</summary>
public string Author
public string Author
{
{
get { return "Bossland GmbH"; }
get { return "Bossland GmbH"; }
}
}
/// <summary>The version of this task.</summary>
/// <summary>The version of this task.</summary>
public Version Version
public Version Version
{
{
get { return new Version(0, 0, 1, 1); }
get { return new Version(0, 0, 1, 1); }
}
}
/// <summary>
/// <summary>
/// The tasks's execution logic.
/// The tasks's execution logic.
/// </summary>
/// </summary>
/// <returns>true if the TaskManager should not execute any other tasks, and false if it should.</returns>
/// <returns>true if the TaskManager should not execute any other tasks, and false if it should.</returns>
public async Task<bool> Execute()
public async Task<bool> Execute()
{
{
if (!LokiPoe.CurrentWorldArea.IsOverworldArea)
if (!LokiPoe.CurrentWorldArea.IsOverworldArea)
return false;
return false;
// No uniques to process.
// No uniques to process.
if (_mobs.Count == 0)
if (_mobs.Count == 0)
return false;
return false;
var myPos = LokiPoe.Me.Position;
var myPos = LokiPoe.Me.Position;
// Get the closest mob to check the position of.
// Find a new location to move to.
var kvp = _mobs.OrderBy(mkvp => myPos.DistanceSqr(mkvp.Value)).First();
if (_currentEntry == null)
{
// Get the closest mob to check the position of.
_currentEntry = _mobs.OrderBy(mkvp => myPos.DistanceSqr(mkvp.Value)).First();
}
var kvp = _currentEntry.Value;
// If we aren't in range of it, move towards it so we can trigger it.
// If we aren't in range of it, move towards it so we can trigger it.
if (LokiPoe.Me.Position.Distance(kvp.Value) > 15)
if (myPos.Distance(kvp.Value) > 15)
{
{
if (!PlayerMover.MoveTowards(kvp.Value))
if (!PlayerMover.MoveTowards(kvp.Value))
{
{
Log.ErrorFormat("[TrackMoreMobs] MoveTowards failed for {0}.", kvp.Value);
Log.ErrorFormat("[TrackMoreMobs] MoveTowards failed for {0}.", kvp.Value);
_mobs.Remove(kvp.Key);
_mobs.Remove(kvp.Key);
_currentEntry = null;
}
}
return true;
return true;
}
}
// We are now close enough to the position, check to see if the object exists or is dead.
// We are now close enough to the position, check to see if the object exists or is dead.
var m = LokiPoe.ObjectManager.GetObjectById<Monster>(kvp.Key);
var m = LokiPoe.ObjectManager.GetObjectById<Monster>(kvp.Key);
if (m == null || m.IsDead)
if (m == null || m.IsDead)
{
{
_mobs.Remove(kvp.Key);
_mobs.Remove(kvp.Key);
_processed.Remove(kvp.Key);
_processed.Remove(kvp.Key);
_currentEntry = null;
}
}
else
else
{
{
// The mob has moved, so update the position we need to move to instead.
_mobs[kvp.Key] = m.Position;
_mobs[kvp.Key] = m.Position;
_currentEntry = null; // Find a new entry on the next run, since the mob has moved far away.
}
}
// We now are relying on the CR to kill the boss. If it doesn't, we'll just die or get
// We now are relying on the CR to kill the boss. If it doesn't, we'll just die or get
// stuck around where it spawns.
// stuck around where it spawns.
return true;
return true;
}
}
/// <summary>The bot Start event.</summary>
/// <summary>The bot Start event.</summary>
public void Start()
public void Start()
{
{
GameEventManager.AreaChanged += GameEventManagerOnAreaChanged;
GameEventManager.AreaChanged += GameEventManagerOnAreaChanged;
_currentEntry = null;
}
}
/// <summary>The bot Tick event.</summary>
/// <summary>The bot Tick event.</summary>
public void Tick()
public void Tick()
{
{
if (!LokiPoe.IsInGame || LokiPoe.Me.IsInTown || LokiPoe.Me.IsInHideout)
if (!LokiPoe.IsInGame || LokiPoe.Me.IsInTown || LokiPoe.Me.IsInHideout)
return;
return;
if (!_sw.IsRunning)
if (!_sw.IsRunning)
{
{
_sw.Start();
_sw.Start();
}
}
else
else
{
{
if (_sw.ElapsedMilliseconds < 250)
if (_sw.ElapsedMilliseconds < 250)
return;
return;
}
}
var mobs =
var mobs =
LokiPoe.ObjectManager.Objects.OfType<Monster>()
LokiPoe.ObjectManager.Objects.OfType<Monster>()
.Where(m => !AreaStateCache.Current.IsBlacklisted(m.Id) && !m.IsDead && m.Reaction == Reaction.Enemy);
.Where(m => !AreaStateCache.Current.IsBlacklisted(m.Id) && !m.IsDead && m.Reaction == Reaction.Enemy);
foreach (var mob in mobs)
foreach (var mob in mobs)
{
{
if (!_mobs.ContainsKey(mob.Id) && !_processed.Contains(mob.Id))
if (!_mobs.ContainsKey(mob.Id) && !_processed.Contains(mob.Id))
{
{
Log.DebugFormat("[TrackMoreMobs] Now adding {0} at {1}.", mob.Name, mob.Position);
Log.DebugFormat("[TrackMoreMobs] Now adding {0} at {1}.", mob.Name, mob.Position);
_mobs.Add(mob.Id, mob.Position);
_mobs.Add(mob.Id, mob.Position);
_processed.Add(mob.Id);
_processed.Add(mob.Id);
}
}
}
}
_sw.Restart();
_sw.Restart();
}
}
/// <summary>The bot Stop event.</summary>
/// <summary>The bot Stop event.</summary>
public void Stop()
public void Stop()
{
{
GameEventManager.AreaChanged -= GameEventManagerOnAreaChanged;
GameEventManager.AreaChanged -= GameEventManagerOnAreaChanged;
}
}
/// <summary>Is this task currently enabled?</summary>
/// <summary>Is this task currently enabled?</summary>
public bool IsEnabled
public bool IsEnabled
{
{
get { return _enabled; }
get { return _enabled; }
}
}
/// <summary>Called when the task should be enabled.</summary>
/// <summary>Called when the task should be enabled.</summary>
public void Enable()
public void Enable()
{
{
_enabled = true;
_enabled = true;
}
}
/// <summary>Called when the task should be disabled.</summary>
/// <summary>Called when the task should be disabled.</summary>
public void Disable()
public void Disable()
{
{
_enabled = false;
_enabled = false;
}
}
private void GameEventManagerOnAreaChanged(object sender, AreaChangedEventArgs areaChangedEventArgs)
private void GameEventManagerOnAreaChanged(object sender, AreaChangedEventArgs areaChangedEventArgs)
{
{
_mobs.Clear();
_mobs.Clear();
_processed.Clear();
_processed.Clear();
_currentEntry = null;
}
}
}
}
}
}
}
}