using System.Collections.Generic;
using System.Speech.Synthesis;
using System.Windows.Controls;
using log4net;
using Loki.Bot;
using Loki.Bot.Settings;
using Loki.Game;
using Loki.Game.GameData;
using Loki.Game.Objects;
using Loki.Utilities;
using System;
//!CompilerOption|AddRef|C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Speech.dll
namespace AlertBot
{
/// <summary> </summary>
public class AlertBot : IBot
{
private static readonly ILog Log = Logger.GetLoggerInstanceForType();
private readonly List<int> _alertedMasters = new List<int>();
private readonly List<int> _alertedStrongboxes = new List<int>();
private readonly Dictionary<Vector2i, int> _alertedItems = new Dictionary<Vector2i, int>();
#region Implementation of IAuthored
/// <summary> The name of this bot. </summary>
public string Name
{
get { return "AlertBot"; }
}
/// <summary> The description of this bot. </summary>
public string Description
{
get { return "An example bot for Exilebuddy."; }
}
/// <summary>The author of this bot.</summary>
public string Author
{
get { return "Bossland GmbH"; }
}
/// <summary>The version of this bot's implementation.</summary>
public Version Version
{
get { return new Version(0, 0, 1, 1); }
}
#endregion
#region Implementation of IBase
/// <summary>Initializes this object. This is called when the object is loaded into the bot.</summary>
public void Initialize()
{
}
#endregion
#region Implementation of IRunnable
/// <summary> The bot start callback. Do any initialization here. </summary>
public void Start()
{
Log.DebugFormat("[AlertBot] Start");
// Reset the default MsBetweenTicks on start.
Log.DebugFormat("[Start] MsBetweenTicks: {0}.", MainSettings.Instance.MsBetweenTicks);
Log.DebugFormat("[Start] InputEventMsDelay: {0}.", MainSettings.Instance.InputEventMsDelay);
GameEventManager.Start();
GameEventManager.AreaChanged += GameEventManagerOnAreaChanged;
}
/// <summary> The bot tick callback. Do any update logic here. </summary>
public void Tick()
{
// We don't want to do anything when we're not in game!
if (!LokiPoe.IsInGame)
return;
GameEventManager.Tick();
foreach (var obj in LokiPoe.ObjectManager.Objects)
{
if (obj.IsMaster)
{
if (!_alertedMasters.Contains(obj.Id))
{
_alertedMasters.Add(obj.Id);
Log.InfoFormat("[Tick] The master {0} was detected at {1}.", obj.Name, obj.Position);
var tts = string.Format("{0} was detected.", obj.Name);
Say(tts);
// Let the next Tick handle others, as we left the frame, and then returned.
return;
}
}
var wi = obj as WorldItem;
if (wi != null)
{
int id;
if (_alertedItems.TryGetValue(wi.Position, out id))
{
if (id != wi.Id)
{
_alertedItems.Remove(wi.Position);
}
else
{
continue;
}
}
var item = wi.Item;
if (item.Rarity == Rarity.Currency && item.Name != "Portal Scroll" &&
item.Name != "Scroll of Wisdom")
{
_alertedItems.Add(obj.Position, obj.Id);
Log.InfoFormat("[Tick] The item {0} was detected at {1}.", item.Name, obj.Position);
var tts = string.Format("{0} was detected.", item.Name);
Say(tts);
// Let the next Tick handle others, as we left the frame, and then returned.
return;
}
}
var chest = obj as Chest;
if (chest != null)
{
if (chest.IsStrongBox && !chest.IsOpened)
{
if (!_alertedStrongboxes.Contains(chest.Id))
{
_alertedStrongboxes.Add(obj.Id);
Log.InfoFormat("[Tick] The strongbox {0} was detected at {1}.", obj.Name, obj.Position);
var tts = string.Format("{0} was detected.", obj.Name);
Say(tts);
// Let the next Tick handle others, as we left the frame, and then returned.
return;
}
}
}
}
}
/// <summary> The bot stop callback. Do any pre-dispose cleanup here. </summary>
public void Stop()
{
Log.DebugFormat("[AlertBot] OnStop");
GameEventManager.Stop();
GameEventManager.AreaChanged -= GameEventManagerOnAreaChanged;
}
#endregion
#region Implementation of IConfigurable
public JsonSettings Settings
{
get { return null; }
}
/// <summary> The bot's settings control. This will be added to the Exilebuddy Settings tab.</summary>
public UserControl Control
{
get { return null; }
}
#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
#region Coroutine Logic
#endregion
private void GameEventManagerOnAreaChanged(object sender, AreaChangedEventArgs areaChangedEventArgs)
{
_alertedMasters.Clear();
_alertedStrongboxes.Clear();
_alertedItems.Clear();
}
private static void Say(string tts)
{
using (LokiPoe.Memory.ReleaseFrame(LokiPoe.UseHardlock))
{
using (var synth = new SpeechSynthesizer())
{
synth.SetOutputToDefaultAudioDevice();
synth.Speak(tts);
}
}
}
}
}