using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Markup;
using log4net;
using System;
using Loki.Bot;
using Loki.Bot.Logic.Bots.BasicGrindBot;
using Loki.Bot.Pathfinding;
using Loki.Bot.v3;
using Loki.Game;
using Loki.Game.Objects;
using Loki.Utilities;
using Buddy.Coroutines;
namespace LibraryCorruptedHandler
{
internal class LibraryCorruptedHandler : IPlugin
{
private static readonly ILog Log = Logger.GetLoggerInstanceForType();
private bool _enabled;
private bool _skip;
/// <summary> The name of the plugin. </summary>
public string Name
{
get { return "LibraryCorruptedHandler"; }
}
/// <summary> The description of the plugin. </summary>
public string Description
{
get { return "A plugin that handles the logic required for fighting Library Corrupted Boss."; }
}
/// <summary>The author of the plugin.</summary>
public string Author
{
get { return "Bossland GmbH"; }
}
/// <summary>The version of the plugin.</summary>
public Version Version
{
get { return new Version(0, 0, 1, 1); }
}
/// <summary>Initializes this plugin.</summary>
public void Initialize()
{
Log.DebugFormat("[LibraryCorruptedHandler] Initialize");
}
/// <summary> The plugin start callback. Do any initialization here. </summary>
public void Start()
{
Log.DebugFormat("[LibraryCorruptedHandler] Start");
GameEventManager.AreaChanged += GameEventManagerOnAreaChanged;
Reset();
// Check to see if the current grind zone is for Dominus.
if (BasicGrindBotSettings.Instance.GrindZoneName != "The Library")
{
Log.InfoFormat("[LibraryCorruptedHandler] The area to grind is not The Library. Skipping execution until a restart or area change.");
_skip = true;
return;
}
// We want to change the behavior after exploration, so we can start the boss fight, and stay in it
// though different phases.
if (!TaskManager.AddAfter(new HandleLibraryCorruptedArea(), "ExploreTask"))
{
Log.ErrorFormat("[LibraryCorruptedHandler] AddBefore Explore Task failed.");
BotManager.Stop();
}
else
{
Log.ErrorFormat("[LibraryCorruptedHandler] AddBefore Explore Task Success.");
}
}
/// <summary> The plugin tick callback. Do any update logic here. </summary>
public void Tick()
{
if (_skip)
return;
if (!LokiPoe.IsInGame || LokiPoe.Me.IsInTown || LokiPoe.Me.IsDead)
return;
}
/// <summary> The plugin stop callback. Do any pre-dispose cleanup here. </summary>
public void Stop()
{
Log.DebugFormat("[LibraryCorruptedHandler] Stop");
GameEventManager.AreaChanged -= GameEventManagerOnAreaChanged;
}
#region Implementation of IConfigurable
public JsonSettings Settings
{
get { return null; }
}
/// <summary> The plugin's settings control. This will be added to the Exilebuddy Settings tab.</summary>
public UserControl Control
{
get { return null; }
}
#endregion
#region Implementation of IEnableable
/// <summary>Is this plugin currently enabled?</summary>
public bool IsEnabled
{
get { return _enabled; }
}
/// <summary> The plugin is being enabled.</summary>
public void Enable()
{
Log.DebugFormat("[LibraryCorruptedHandler] Enable");
_enabled = true;
}
/// <summary> The plugin is being disabled.</summary>
public void Disable()
{
Log.DebugFormat("[LibraryCorruptedHandler] Disable");
_enabled = false;
}
#endregion
#region Implementation of IDisposable
/// <summary> </summary>
public void Dispose()
{
}
#endregion
#region Override of Object
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Name + ": " + Description;
}
#endregion
private void GameEventManagerOnAreaChanged(object sender, AreaChangedEventArgs areaChangedEventArgs)
{
Reset();
}
private void Reset()
{
Log.DebugFormat("[LibraryCorruptedHandler] Now resetting task state.");
_skip = false;
}
/// <summary>
/// This task helps BasicGrindBot stay in the Dominus boss fight area, resetting exploration to
/// keep the bot moving around to trigger different phases.
/// </summary>
public class HandleLibraryCorruptedArea : ITask
{
private bool _enabled = true;
/// <summary>The name of this task.</summary>
public string Name
{
get { return "HandleLibraryCorruptedArea"; }
}
/// <summary>A description of what this task does.</summary>
public string Description
{
get { return "This task helps BasicGrindBot stay in the Dominus boss fight area, resetting exploration to keep the bot moving around to trigger different phases."; }
}
/// <summary>The author of this task.</summary>
public string Author
{
get { return "Bossland GmbH"; }
}
/// <summary>The version of this task.</summary>
public Version Version
{
get { return new Version(0, 0, 1, 1); }
}
private Vector2i _towerFightStarterPos;
private Vector2i __objectVaalChestPos;
/// <summary>
/// The tasks's execution logic.
/// </summary>
/// <returns>true if the TaskManager should not execute any other tasks, and false if it should.</returns>
public async Task<bool> Execute()
{
if(!LokiPoe.CurrentWorldArea.IsCorruptedArea)
{
Log.InfoFormat("[LibraryCorruptedHandler] Not Corrupted area");
return false;
}
else
{
Log.InfoFormat("[LibraryCorruptedHandler] Corrupted Area Found");
}
// When we first spawn into the area, exploration should take us within range of everything.
// Start out by triggering the fight itself.
if (_towerFightStarterPos == Vector2i.Zero)
{
var fightStarter =
LokiPoe.ObjectManager.GetObjectByName(
"Vaal Vessel");
if (fightStarter != null)
{
_towerFightStarterPos = ExilePather.WalkablePositionFor(fightStarter, 10);
Log.InfoFormat("[LibraryCorruptedHandler] _fightStarterPos: {0}.", _towerFightStarterPos);
if (!await Coroutines.MoveToLocation(_towerFightStarterPos, 10, 30000))
{
Log.ErrorFormat("[LibraryCorruptedHandler] MoveToLocation failed.");
}
return true;
}
}
// Simply move towards Dominus if nothing else is running.
var boss = LokiPoe.ObjectManager.GetObjectByName<Monster>("Ch'aska, Maker of Rain");
if (boss != null)
{
if (!boss.IsDead)
{
PlayerMover.MoveTowards(boss.Position);
Log.InfoFormat("[LibraryCorruptedHandler] {0} is Not Dead. Finding Him", boss.Name);
return true;
}
if(boss.IsDead)
{
Log.InfoFormat("[LibraryCorruptedHandler] Boss Dead. Triggering Town Run");
if (__objectVaalChestPos == Vector2i.Zero)
{
var _objectVaalChest =
LokiPoe.ObjectManager.GetObjectByName(
"Vaal Vessel");
if (_objectVaalChest != null)
{
if (_objectVaalChest.IsTargetable)
{
__objectVaalChestPos = ExilePather.WalkablePositionFor(_objectVaalChest, 10);
Log.InfoFormat("[LibraryCorruptedHandler] _fightStarterPos: {0}.", __objectVaalChestPos);
if (!await Coroutines.MoveToLocation(__objectVaalChestPos, 10, 30000))
{
Log.ErrorFormat("[LibraryCorruptedHandler] MoveToLocation failed.");
return true;
}
await Coroutine.Sleep(Utility.LatencySafeValue(500));
if (!LokiPoe.Input.HighlightObject(_objectVaalChest))
{
return true;
}
if (!await Coroutines.InteractWith(_objectVaalChest, false, 160))
{
return true;
}
BasicGrindBotSettings.Instance.TriggerTownRun();
}
else
{
BasicGrindBotSettings.Instance.NeedsTownRun = 2;
}
}
}
//BasicGrindBotSettings.Instance.TriggerTownRun();
}
return true;
}
// Reset the explorer, so we move around the area looking for things that might be out of view.
// It's up to the CR to avoid getting stuck killing Miscreations near their spawner.
if (AreaStateCache.Current.Explorer != null)
{
Log.InfoFormat("[LibraryCorruptedHandler] Now resetting the explorer.");
AreaStateCache.Current.Explorer.Reset();
}
// Don't execute any tasks afterwards. This forces the BasicGrindBot to say in the boss area.
return true;
}
/// <summary>The bot Start event.</summary>
public void Start()
{
}
/// <summary>The bot Tick event.</summary>
public void Tick()
{
}
/// <summary>The bot Stop event.</summary>
public void Stop()
{
}
public void RemoveMe()
{
if(!TaskManager.Remove("LibraryCorruptedHandler"))
{
Log.InfoFormat("[LibraryCorruptedHandler] Remove LibraryCorruptedHandler Task Failed");
}
}
/// <summary>Is this task currently enabled?</summary>
public bool IsEnabled
{
get { return _enabled; }
}
/// <summary>Called when the task should be enabled.</summary>
public void Enable()
{
_enabled = true;
}
/// <summary>Called when the task should be disabled.</summary>
public void Disable()
{
_enabled = false;
}
}
}
}