using System;
using System.Linq;
using System.Threading.Tasks;
using AdvancedItemFilter.Extensions;
using Loki.Bot;
using Loki.Common;
using Loki.Game;
using Loki.Game.Objects;
using CommunityLib;
using Stash = CommunityLib.Stash;
namespace AdvancedItemFilter.Tasks
{
public class IdentifyItems : ITask
{
private bool _enabled = true;
private bool _skip;
private bool _chanskip;
private MyItemEvaluator _mie => AdvancedItemFilter.ItemEvaluator;
#region Implementation of IAuthored
/// <summary>
/// The name of this authored object.
/// </summary>
public string Name => "IdentifyItemsTask";
/// <summary>
/// The author of this object.
/// </summary>
public string Author => "Alcor75 & toNyx";
/// <summary>
/// The description of this object.
/// </summary>
public string Description => "Custom identify items task";
string IAuthored.Version => "1.0.0.0";
#endregion
#region Implementation of IEnableable
/// <summary>
/// The object is being enabled.
/// </summary>
public void Enable()
{
_enabled = true;
}
/// <summary>
/// The object is being disabled.
/// </summary>
public void Disable()
{
_enabled = false;
}
/// <summary>
/// Is this object currently enabled?
/// </summary>
public bool IsEnabled => _enabled;
#endregion
#region Implementation of IRunnable
/// <summary>
/// The object start callback. Do any initialization here.
/// </summary>
public void Start()
{
}
/// <summary>
/// The object tick callback. Do any update logic here.
/// </summary>
public void Tick()
{
}
/// <summary>
/// The object stop callback. Do any pre-dispose cleanup here.
/// </summary>
public void Stop()
{
}
#endregion
#region Implementation of ILogic
public async Task<bool> Logic(string type, params dynamic[] param)
{
if (type == "core_area_changed_event")
{
_skip = false;
_chanskip = false;
return true;
}
if (type != "task_execute")
return false;
//adding Chancing
if (_chanskip) {
return false;
}
var chanitems = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.Items.Where(item => item.Name == "Sorcerer Boots" && item.Rarity == 0).ToList();
if (chanitems.Any()) {
var chanOrbs = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.FindItemByFullName("Orb of Chance");
if (chanOrbs == null) {
AdvancedItemFilter.Log.ErrorFormat("[{0}] We have no chance orbs in main inventory and we're not in town, abort this task !", Name);
_chanskip = true;
return false;
}
AdvancedItemFilter.Log.DebugFormat("We have boots and orbs!");
if (!LokiPoe.InGameState.InventoryUi.IsOpened)
{
await Coroutines.LatencyWait(3);
if (!await LibCoroutines.OpenInventoryPanel())
{
AdvancedItemFilter.Log.DebugFormat("[{0}] Inventory isn't opened, returning true to retry", Name);
_chanskip = true;
return true;
}
}
foreach (var booter in chanitems) {
var applied = await CommunityLib.Inventory.UseItemOnItem(
LokiPoe.InGameState.InventoryUi.InventoryControl_Main,
chanOrbs,
LokiPoe.InGameState.InventoryUi.InventoryControl_Main,
booter);
}
if (LokiPoe.InGameState.InventoryUi.IsOpened)
await Coroutines.CloseBlockingWindows();
return true;
}
// on-the-fly handling
if (_skip) return false;
if (!AdvancedItemFilter.AdvSettings.EnableOnTheFlyIdentification && !LokiPoe.Me.IsInHideout && !LokiPoe.Me.IsInTown) return false;
if (AdvancedItemFilter.AdvSettings.EnableOnTheFlyIdentification && !AdvancedItemFilter.AdvSettings.TriggerOnTheFlyIdentification) return false;
if (AdvancedItemFilter.ExecuteSellingRecipesLogic)
{
AdvancedItemFilter.Log.DebugFormat("[{0}] Seems like we were on a Recipe logic not long ago, skipping this process because security matters...", Name);
return true;
}
// This is to avoid identifying recipe items h3h3h3
IItemFilter myFilter;
// A Valid item to identify should : Not be identified already, not protected from identification by the plugin, and match a condition in any of our evaluators
Func<Item, bool> identifyRule = i => !i.IsIdentified && !i.IsProtectedFromIdentification() && _mie.Match(i, EvaluationType.Id, out myFilter);
if (!LokiPoe.InGameState.InventoryUi.IsOpened)
{
await Coroutines.LatencyWait(3);
if (!await LibCoroutines.OpenInventoryPanel())
{
AdvancedItemFilter.Log.DebugFormat("[{0}] Inventory isn't opened, returning true to retry", Name);
return true;
}
}
var cachedUnidItemListInInventory = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.Items.Where(item => !item.IsIdentified && !item.IsCorrupted).ToList();
if (!cachedUnidItemListInInventory.Any())
{
AdvancedItemFilter.Log.DebugFormat("[{0}] Nothing to id, KEEP ON GOING BITCHES", Name);
_skip = true;
return false;
}
foreach (var uItem in cachedUnidItemListInInventory)
{
await Coroutines.LatencyWait(2);
// Process item to protect it if needed
await AdvancedItemFilter.GearRecipeObject.CheckProtectionNeeds(uItem);
if (uItem.IsProtectedFromIdentification())
{
if (uItem.IsQuiverType || uItem.IsShieldType || uItem.IsOneHandWeaponType)
{
AdvancedItemFilter.Log.DebugFormat("[{0}] {1} is protected but shouldn't be, removing it from blacklist...", Name, uItem.Name);
AdvancedItemFilter.AdvSettings.ItemsBlackListedFromIdentificationForRecipes.Remove(uItem.LocationTopLeft);
}
else
{
AdvancedItemFilter.Log.DebugFormat("[{0}] {1} is protected from identification, passing by...", Name, uItem.Name);
continue;
}
}
if (AdvancedItemFilter.AdvSettings.NeverIdItems)
{
if (cachedUnidItemListInInventory.Last() == uItem)
{
AdvancedItemFilter.Log.DebugFormat("[{0}] NeverIdItems is checked, We processed items for recipe(s) just in case", Name);
_skip = true;
return false;
}
continue;
}
// Verify if it has to be identified
if (!identifyRule.Invoke(uItem))
{
AdvancedItemFilter.Log.DebugFormat("[{0}] The item shouldn't be identified, skipping it", Name);
continue;
}
int itemlocalid = uItem.LocalId;
int idAttempts = 0;
Vector2i itemLocation = uItem.LocationTopLeft;
var scrollsInMainInventory = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.FindItemByFullName("Scroll of Wisdom");
// If we need to use stash, use stash (SOUNDS LEGIT HE????)
if (scrollsInMainInventory == null)
{
if (!LokiPoe.Me.IsInTown && !LokiPoe.Me.IsInHideout)
{
AdvancedItemFilter.Log.ErrorFormat("[{0}] We have no scrolls in main inventory and we're not in town, abort this task !", Name);
_skip = true;
return false;
}
if (!LokiPoe.InGameState.StashUi.IsOpened)
{
var isOpenedErr = await LibCoroutines.OpenStash();
await Dialog.WaitForPanel(Dialog.PanelType.Stash);
if (isOpenedErr != Results.OpenStashError.None)
{
AdvancedItemFilter.Log.ErrorFormat("[{0}] Fail to open the stash.", Name);
return false;
}
}
var sItem = Stash.FindItemInStashTab("Scroll of Wisdom");
if (sItem == null)
{
var it = await Stash.FindTabContainingItem("Scroll of Wisdom");
if (it.Item1 == Results.FindItemInTabResult.ItemNotFoundInTab)
{
AdvancedItemFilter.Log.ErrorFormat("[{0}] We have no scrolls in stash either, rekityrekt skip this task !", Name);
_skip = true;
return false;
}
sItem = it.Item2;
}
while (true)
{
if (idAttempts > 2)
{
AdvancedItemFilter.Log.DebugFormat("[{0}] We tried 3 times to id an item but it failed, stopping bot for security reasons", Name);
BotManager.Stop();
}
AdvancedItemFilter.Log.DebugFormat("[{0}] Attempt to ID an item located at ({1},{2})", Name, itemLocation.X, itemLocation.Y);
var applied = await sItem.UseOnItem(
LokiPoe.InGameState.InventoryUi.InventoryControl_Main,
uItem);
idAttempts++;
if (applied != ApplyCursorResult.None)
{
if (applied == ApplyCursorResult.ItemNotFound)
{
AdvancedItemFilter.Log.DebugFormat($"[{Name}] Seems like the item at location {itemLocation} cannot be found, supposing he's identified");
break;
}
AdvancedItemFilter.Log.ErrorFormat("[{0}] Something went wrong when identifying an item, Error : {1}", Name, applied);
var cc = await Inputs.ClearCursorTask();
AdvancedItemFilter.Log.Debug($"[{Name}] CCTask returned {cc}");
continue;
}
var hasBeenIdentified = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.GetItemById(itemlocalid) == null;
if (!hasBeenIdentified)
{
AdvancedItemFilter.Log.ErrorFormat("[{0}] Seems like the item at location ({1},{2}) is still not identified, retrying", Name, itemLocation.X, itemLocation.Y);
var cc = await Inputs.ClearCursorTask();
AdvancedItemFilter.Log.Debug($"[{Name}] CCTask returned {cc}");
continue;
}
break;
}
continue;
}
idAttempts = 0;
itemLocation = uItem.LocationTopLeft;
while (true)
{
if (idAttempts > 2)
{
AdvancedItemFilter.Log.DebugFormat("[{0}] We tried 3 times to id an item but it failed, stopping bot for security reasons", Name);
BotManager.Stop();
}
AdvancedItemFilter.Log.DebugFormat("[{0}] Attempt to ID an item located at ({1},{2})", Name, itemLocation.X, itemLocation.Y);
var applied = await CommunityLib.Inventory.UseItemOnItem(
LokiPoe.InGameState.InventoryUi.InventoryControl_Main,
scrollsInMainInventory,
LokiPoe.InGameState.InventoryUi.InventoryControl_Main,
uItem);
idAttempts++;
if (applied != ApplyCursorResult.None)
{
if (applied == ApplyCursorResult.ItemNotFound)
{
AdvancedItemFilter.Log.DebugFormat($"[{Name}] Seems like the item at location {itemLocation} cannot be found, supposing he's identified");
break;
}
AdvancedItemFilter.Log.ErrorFormat("[{0}] Something went wrong when identifying an item, Error : {1}", Name, applied);
continue;
}
var hasBeenIdentified = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.GetItemById(itemlocalid) == null;
if (!hasBeenIdentified)
{
AdvancedItemFilter.Log.ErrorFormat("[{0}] Seems like the item at location ({1},{2}) is still not identified, retrying", Name, itemLocation.X, itemLocation.Y);
continue;
}
break;
}
}
if (!AdvancedItemFilter.AdvSettings.NeverIdItems)
{
var remainingUnidItems = LokiPoe.InGameState.InventoryUi.InventoryControl_Main.Inventory.Items.Where(identifyRule).ToList();
if (remainingUnidItems.Any())
{
AdvancedItemFilter.Log.DebugFormat("[{0}] We still have {1} remaining unid items, keep iding", Name, remainingUnidItems.Count);
return true;
}
_skip = true;
}
if (LokiPoe.InGameState.InventoryUi.IsOpened)
await Coroutines.CloseBlockingWindows();
if (AdvancedItemFilter.AdvSettings.TriggerOnTheFlyIdentification)
AdvancedItemFilter.AdvSettings.TriggerOnTheFlyIdentification = false;
return false;
}
public object Execute(string name, params dynamic[] param)
{
return null;
}
#endregion
}
}