public void LootedItemLog(GilesItemType thisgilesitemtype, GilesBaseItemType thisgilesbasetype, ItemQuality itemQuality) { if (thisgilesitemtype == GilesItemType.HealthPotion) { return; } //No profile set.. because new game? //if (Bot.BotStatistics.ProfileStats.CurrentProfile == null) // return; switch (thisgilesbasetype) { case GilesBaseItemType.WeaponOneHand: case GilesBaseItemType.WeaponTwoHand: case GilesBaseItemType.WeaponRange: case GilesBaseItemType.Offhand: case GilesBaseItemType.Armor: case GilesBaseItemType.Jewelry: case GilesBaseItemType.FollowerItem: if (itemQuality > ItemQuality.Rare6) { //Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[3]++; //Statistics.ItemStats.CurrentGame.lootedItemTotals[3]++; Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Legendary.Looted++; } else if (itemQuality > ItemQuality.Magic3) { //Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[2]++; Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Rare.Looted++; } else { //Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[1]++; Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Magical.Looted++; } break; case GilesBaseItemType.Unknown: case GilesBaseItemType.Misc: if (thisgilesitemtype == GilesItemType.CraftingMaterial || thisgilesitemtype == GilesItemType.CraftingPlan || thisgilesitemtype == GilesItemType.CraftTome) { // Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[(int)LootIndex.Crafting]++; Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Crafting.Looted++; } else if (thisgilesitemtype == GilesItemType.InfernalKey) { // Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[(int)LootIndex.Key]++; Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Keys.Looted++; } break; case GilesBaseItemType.Gem: // Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[(int)LootIndex.Gem]++; Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Gems.Looted++; break; } }
internal static void LogItemInformation() { // Store item pickup stats //if (!_hashsetItemPicksLookedAt.Contains(Bot.Targeting.Cache.CurrentTarget.RAGUID)) //{ CacheItem thisCacheItem = (CacheItem)Bot.Targeting.Cache.CurrentTarget; GilesItemType thisgilesitemtype = Backpack.DetermineItemType(thisCacheItem.InternalName, thisCacheItem.BalanceData.thisItemType, thisCacheItem.BalanceData.thisFollowerType); GilesBaseItemType thisgilesbasetype = Backpack.DetermineBaseType(thisgilesitemtype); //Herbfunk -- Live loot stats keeping. Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.LootedItemLog(thisgilesitemtype, thisgilesbasetype, thisCacheItem.Itemquality.Value); //} }
private static void LootedItemLog(GilesItemType thisgilesitemtype, GilesBaseItemType thisgilesbasetype, ItemQuality itemQuality) { if (thisgilesitemtype == GilesItemType.HealthPotion) return; //No profile set.. because new game? if (Bot.BotStatistics.ProfileStats.CurrentProfile==null) return; switch (thisgilesbasetype) { case GilesBaseItemType.WeaponOneHand: case GilesBaseItemType.WeaponTwoHand: case GilesBaseItemType.WeaponRange: case GilesBaseItemType.Offhand: case GilesBaseItemType.Armor: case GilesBaseItemType.Jewelry: case GilesBaseItemType.FollowerItem: if (itemQuality > ItemQuality.Rare6) { Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[3]++; //Statistics.ItemStats.CurrentGame.lootedItemTotals[3]++; } else if (itemQuality > ItemQuality.Magic3) { Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[2]++; } else Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[1]++; break; case GilesBaseItemType.Unknown: case GilesBaseItemType.Misc: if (thisgilesitemtype== GilesItemType.CraftingMaterial||thisgilesitemtype== GilesItemType.CraftingPlan||thisgilesitemtype== GilesItemType.CraftTome) Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[(int)LootIndex.Crafting]++; else if (thisgilesitemtype==GilesItemType.InfernalKey) Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[(int)LootIndex.Key]++; else Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[0]++; break; case GilesBaseItemType.Gem: Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.lootedItemTotals[(int)LootIndex.Gem]++; break; } }
internal static void LogJunkItems(CacheACDItem thisgooditem, GilesBaseItemType thisgilesbaseitemtype, GilesItemType thisgilesitemtype, double ithisitemvalue) { FileStream LogStream = null; try { LogStream = File.Open(LoggingFolderPath + LoggingPrefixString + " -- JunkLog.log", FileMode.Append, FileAccess.Write, FileShare.Read); using (StreamWriter LogWriter = new StreamWriter(LogStream)) { if (!TownRunManager.bLoggedJunkThisStash) { TownRunManager.bLoggedJunkThisStash = true; LogWriter.WriteLine(DateTime.Now.ToString() + ":"); LogWriter.WriteLine("===================="); } string sLegendaryString = ""; if (thisgooditem.ThisQuality >= ItemQuality.Legendary) { sLegendaryString = " {legendary item}"; } LogWriter.WriteLine(thisgilesbaseitemtype.ToString() + " - " + thisgilesitemtype.ToString() + " '" + thisgooditem.ThisRealName + "'. Score = " + Math.Round(ithisitemvalue).ToString() + sLegendaryString); if (!String.IsNullOrEmpty(TownRunManager.sJunkItemStatString)) { LogWriter.WriteLine(" " + TownRunManager.sJunkItemStatString); } else { LogWriter.WriteLine(" (no scorable attributes)"); } LogWriter.WriteLine(""); } } catch (IOException) { DBLog.Info("Fatal Error: File access error for junk log file."); } }
// ********************************************************************************************** // ***** Nice smooth one-at-a-time salvaging replacement ***** // ********************************************************************************************** internal static RunStatus GilesOptimisedSalvage(object ret) { DiaUnit objBlacksmith = ZetaDia.Actors.GetActorsOfType <DiaUnit>(true).FirstOrDefault <DiaUnit>(u => u.IsSalvageShortcut); Vector3 vectorPlayerPosition = ZetaDia.Me.Position; Vector3 vectorSalvageLocation = new Vector3(0f, 0f, 0f); if (objBlacksmith == null || objBlacksmith.Distance > 20f) { switch (ZetaDia.CurrentAct) { case Act.A1: vectorSalvageLocation = new Vector3(2958.418f, 2823.037f, 24.04533f); break; case Act.A2: vectorSalvageLocation = new Vector3(289.6358f, 232.1146f, 0.1f); break; case Act.A3: case Act.A4: vectorSalvageLocation = new Vector3(379.6096f, 415.6198f, 0.3321424f); break; } } else { vectorSalvageLocation = objBlacksmith.Position; } Bot.NavigationCache.RefreshMovementCache(); //Wait until we are not moving if (Bot.NavigationCache.IsMoving) { return(RunStatus.Running); } float iDistanceFromSell = Vector3.Distance(vectorPlayerPosition, vectorSalvageLocation); //Out-Of-Range... if (objBlacksmith == null || iDistanceFromSell > 12f) //|| !GilesCanRayCast(vectorPlayerPosition, vectorSalvageLocation, Zeta.Internals.SNO.NavCellFlags.AllowWalk)) { //Use our click movement Bot.NavigationCache.RefreshMovementCache(); //Wait until we are not moving to send click again.. if (Bot.NavigationCache.IsMoving) { return(RunStatus.Running); } Navigator.PlayerMover.MoveTowards(vectorSalvageLocation); return(RunStatus.Running); } if (!UIElements.SalvageWindow.IsVisible) { objBlacksmith.Interact(); return(RunStatus.Running); } if (!UIElements.InventoryWindow.IsVisible) { Bot.Character.Data.BackPack.InventoryBackPackToggle(true); return(RunStatus.Running); } iCurrentItemLoops++; if (iCurrentItemLoops < iItemDelayLoopLimit * 1.15) { return(RunStatus.Running); } iCurrentItemLoops = 0; RandomizeTheTimer(); if (Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSalvageItems.Count > 0) { CacheACDItem thisitem = Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSalvageItems.FirstOrDefault(); if (thisitem != null) { // Item log for cool stuff stashed GilesItemType OriginalGilesItemType = Backpack.DetermineItemType(thisitem.ThisInternalName, thisitem.ThisDBItemType, thisitem.ThisFollowerType); GilesBaseItemType thisGilesBaseType = Backpack.DetermineBaseType(OriginalGilesItemType); if (thisGilesBaseType == GilesBaseItemType.WeaponTwoHand || thisGilesBaseType == GilesBaseItemType.WeaponOneHand || thisGilesBaseType == GilesBaseItemType.WeaponRange || thisGilesBaseType == GilesBaseItemType.Armor || thisGilesBaseType == GilesBaseItemType.Jewelry || thisGilesBaseType == GilesBaseItemType.Offhand || thisGilesBaseType == GilesBaseItemType.FollowerItem) { double iThisItemValue = Backpack.ValueThisItem(thisitem, OriginalGilesItemType); Logger.LogJunkItems(thisitem, thisGilesBaseType, OriginalGilesItemType, iThisItemValue); } Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.SalvagedItemLog(thisitem); ZetaDia.Me.Inventory.SalvageItem(thisitem.ThisDynamicID); } Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSalvageItems.Remove(thisitem); if (Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSalvageItems.Count > 0) { thisitem = Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSalvageItems.FirstOrDefault(); if (thisitem != null) { return(RunStatus.Running); } } else { iCurrentItemLoops = 0; return(RunStatus.Running); } } bReachedSafety = false; bCurrentlyMoving = false; return(RunStatus.Success); }
internal static void LogGoodItems(CacheACDItem thisgooditem, GilesBaseItemType thisgilesbaseitemtype, GilesItemType thisgilesitemtype) { try { //Update this item using (ZetaDia.Memory.AcquireFrame()) { thisgooditem = new CacheACDItem(thisgooditem.ACDItem); } } catch { DBLog.DebugFormat("Failure to update CacheACDItem during Logging"); } double iThisItemValue = Backpack.ValueThisItem(thisgooditem, thisgilesitemtype); FileStream LogStream = null; try { LogStream = File.Open(LoggingFolderPath + LoggingPrefixString + " -- StashLog.log", FileMode.Append, FileAccess.Write, FileShare.Read); using (StreamWriter LogWriter = new StreamWriter(LogStream)) { if (!TownRunManager.bLoggedAnythingThisStash) { TownRunManager.bLoggedAnythingThisStash = true; LogWriter.WriteLine(DateTime.Now.ToString() + ":"); LogWriter.WriteLine("===================="); } string sLegendaryString = ""; if (thisgooditem.ThisQuality >= ItemQuality.Legendary) { if (!thisgooditem.IsUnidentified) { Funky.AddNotificationToQueue(thisgooditem.ThisRealName + " [" + thisgilesitemtype.ToString() + "] (Score=" + iThisItemValue.ToString() + ". " + TownRunManager.sValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new legendary!", Funky.ProwlNotificationPriority.Emergency); sLegendaryString = " {legendary item}"; // Change made by bombastic DBLog.Info("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+"); DBLog.Info("+ Name: " + thisgooditem.ThisRealName + " (" + thisgilesitemtype.ToString() + ")"); DBLog.Info("+ Score: " + Math.Round(iThisItemValue).ToString()); DBLog.Info("+ Attributes: " + thisgooditem.ItemStatString); DBLog.Info("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); } else { DBLog.Info("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+"); DBLog.Info("+ Unid: " + thisgilesitemtype.ToString()); DBLog.Info("+ Level: " + thisgooditem.ThisLevel.ToString()); DBLog.Info("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); } } else { // Check for non-legendary notifications bool bShouldNotify = false; switch (thisgilesbaseitemtype) { case GilesBaseItemType.WeaponOneHand: case GilesBaseItemType.WeaponRange: case GilesBaseItemType.WeaponTwoHand: //if (ithisitemvalue >= settings.iNeedPointsToNotifyWeapon) // bShouldNotify = true; break; case GilesBaseItemType.Armor: case GilesBaseItemType.Offhand: //if (ithisitemvalue >= settings.iNeedPointsToNotifyArmor) //bShouldNotify = true; break; case GilesBaseItemType.Jewelry: //if (ithisitemvalue >= settings.iNeedPointsToNotifyJewelry) //bShouldNotify = true; break; } if (bShouldNotify) { Funky.AddNotificationToQueue(thisgooditem.ThisRealName + " [" + thisgilesitemtype.ToString() + "] (Score=" + iThisItemValue.ToString() + ". " + TownRunManager.sValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new item!", Funky.ProwlNotificationPriority.Emergency); } } if (!thisgooditem.IsUnidentified) { LogWriter.WriteLine(thisgilesbaseitemtype.ToString() + " - " + thisgilesitemtype.ToString() + " '" + thisgooditem.ThisRealName + "'. Score = " + Math.Round(iThisItemValue).ToString() + sLegendaryString); LogWriter.WriteLine(" " + thisgooditem.ItemStatString); LogWriter.WriteLine(""); } else { LogWriter.WriteLine(thisgilesbaseitemtype.ToString() + " - " + thisgilesitemtype.ToString() + " '" + sLegendaryString); LogWriter.WriteLine(" " + thisgooditem.ThisLevel.ToString()); LogWriter.WriteLine(""); } } } catch (IOException) { DBLog.Info("Fatal Error: File access error for stash log file."); } }
// ***** DetermineBaseType - Calculates a more generic, "basic" type of item ***** private GilesBaseItemType DetermineBaseType(GilesItemType thisGilesItemType) { GilesBaseItemType thisGilesBaseType = GilesBaseItemType.Unknown; if (thisGilesItemType == GilesItemType.Axe || thisGilesItemType == GilesItemType.CeremonialKnife || thisGilesItemType == GilesItemType.Dagger || thisGilesItemType == GilesItemType.FistWeapon || thisGilesItemType == GilesItemType.Mace || thisGilesItemType == GilesItemType.MightyWeapon || thisGilesItemType == GilesItemType.Spear || thisGilesItemType == GilesItemType.Sword || thisGilesItemType == GilesItemType.Wand) { thisGilesBaseType = GilesBaseItemType.WeaponOneHand; } else if (thisGilesItemType == GilesItemType.TwoHandDaibo || thisGilesItemType == GilesItemType.TwoHandMace || thisGilesItemType == GilesItemType.TwoHandMighty || thisGilesItemType == GilesItemType.TwoHandPolearm || thisGilesItemType == GilesItemType.TwoHandStaff || thisGilesItemType == GilesItemType.TwoHandSword || thisGilesItemType == GilesItemType.TwoHandAxe) { thisGilesBaseType = GilesBaseItemType.WeaponTwoHand; } else if (thisGilesItemType == GilesItemType.TwoHandCrossbow || thisGilesItemType == GilesItemType.HandCrossbow || thisGilesItemType == GilesItemType.TwoHandBow) { thisGilesBaseType = GilesBaseItemType.WeaponRange; } else if (thisGilesItemType == GilesItemType.Mojo || thisGilesItemType == GilesItemType.Source || thisGilesItemType == GilesItemType.Quiver || thisGilesItemType == GilesItemType.Shield) { thisGilesBaseType = GilesBaseItemType.Offhand; } else if (thisGilesItemType == GilesItemType.Boots || thisGilesItemType == GilesItemType.Bracers || thisGilesItemType == GilesItemType.Chest || thisGilesItemType == GilesItemType.Cloak || thisGilesItemType == GilesItemType.Gloves || thisGilesItemType == GilesItemType.Helm || thisGilesItemType == GilesItemType.Pants || thisGilesItemType == GilesItemType.Shoulders || thisGilesItemType == GilesItemType.SpiritStone || thisGilesItemType == GilesItemType.VoodooMask || thisGilesItemType == GilesItemType.WizardHat || thisGilesItemType == GilesItemType.Belt || thisGilesItemType == GilesItemType.MightyBelt) { thisGilesBaseType = GilesBaseItemType.Armor; } else if (thisGilesItemType == GilesItemType.Amulet || thisGilesItemType == GilesItemType.Ring) { thisGilesBaseType = GilesBaseItemType.Jewelry; } else if (thisGilesItemType == GilesItemType.FollowerEnchantress || thisGilesItemType == GilesItemType.FollowerScoundrel || thisGilesItemType == GilesItemType.FollowerTemplar) { thisGilesBaseType = GilesBaseItemType.FollowerItem; } else if (thisGilesItemType == GilesItemType.CraftingMaterial || thisGilesItemType == GilesItemType.LoreBook || thisGilesItemType == GilesItemType.SpecialItem || thisGilesItemType == GilesItemType.CraftingPlan || thisGilesItemType == GilesItemType.Dye || thisGilesItemType == GilesItemType.StaffOfHerding) { thisGilesBaseType = GilesBaseItemType.Misc; } else if (thisGilesItemType == GilesItemType.HealthPotion) { thisGilesBaseType = GilesBaseItemType.Potion; } else if (thisGilesItemType == GilesItemType.Ruby || thisGilesItemType == GilesItemType.Emerald || thisGilesItemType == GilesItemType.Topaz || thisGilesItemType == GilesItemType.Amethyst) { thisGilesBaseType = GilesBaseItemType.Gem; } else if (thisGilesItemType == GilesItemType.HealthGlobe) { thisGilesBaseType = GilesBaseItemType.HealthGlobe; } return(thisGilesBaseType); }
// ********************************************************************************************** // ***** Sell Routine replacement for smooth one-at-a-time item selling and handling ***** // ********************************************************************************************** internal static RunStatus GilesOptimisedSell(object ret) { string sVendorName = ""; switch (ZetaDia.CurrentAct) { case Act.A1: sVendorName = "a1_uniquevendor_miner"; break; case Act.A2: sVendorName = "a2_uniquevendor_peddler"; break; case Act.A3: sVendorName = "a3_uniquevendor_collector"; break; case Act.A4: sVendorName = "a4_uniquevendor_collector"; break; } #region Navigation DiaUnit objSellNavigation = ZetaDia.Actors.GetActorsOfType <DiaUnit>(true).FirstOrDefault <DiaUnit>(u => u.Name.ToLower().StartsWith(sVendorName)); Vector3 vectorPlayerPosition = ZetaDia.Me.Position; Vector3 vectorSellLocation = new Vector3(0f, 0f, 0f); if (objSellNavigation == null) { switch (ZetaDia.CurrentAct) { case Act.A1: vectorSellLocation = new Vector3(2901.399f, 2809.826f, 24.04533f); break; case Act.A2: vectorSellLocation = new Vector3(295.2101f, 265.1436f, 0.1000002f); break; case Act.A3: case Act.A4: vectorSellLocation = new Vector3(410.6073f, 355.8762f, 0.1000005f); break; } } else { vectorSellLocation = objSellNavigation.Position; } float iDistanceFromSell = Vector3.Distance(vectorPlayerPosition, vectorSellLocation); //Out-Of-Range... if (objSellNavigation == null) //!GilesCanRayCast(vectorPlayerPosition, vectorSellLocation, NavCellFlags.AllowWalk)) { Logger.DBLog.InfoFormat("Vendor Obj is Null or Raycast Failed.. using Navigator to move!"); Navigator.PlayerMover.MoveTowards(vectorSellLocation); return(RunStatus.Running); } if (iDistanceFromSell > 40f) { Navigator.MoveTo(vectorSellLocation, "Vendor", true); //ZetaDia.Me.UsePower(SNOPower.Walk, vectorSellLocation, ZetaDia.Me.WorldDynamicId); return(RunStatus.Running); } if (iDistanceFromSell > 7.5f && !UIElements.VendorWindow.IsValid) { //Use our click movement Bot.NavigationCache.RefreshMovementCache(); //Wait until we are not moving to send click again.. if (Bot.NavigationCache.IsMoving) { return(RunStatus.Running); } objSellNavigation.Interact(); //ZetaDia.Me.UsePower(SNOPower.Axe_Operate_Gizmo, vectorSellLocation, ZetaDia.Me.WorldDynamicId, objSellNavigation.ACDGuid); return(RunStatus.Running); } if (!UIElements.VendorWindow.IsVisible) { objSellNavigation.Interact(); return(RunStatus.Running); } if (!UIElements.InventoryWindow.IsVisible) { Bot.Character.Data.BackPack.InventoryBackPackToggle(true); return(RunStatus.Running); } #endregion #region SellItem if (Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSellItems.Count > 0) { iCurrentItemLoops++; if (iCurrentItemLoops < iItemDelayLoopLimit) { return(RunStatus.Running); } iCurrentItemLoops = 0; RandomizeTheTimer(); CacheACDItem thisitem = Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSellItems.FirstOrDefault(); // Item log for cool stuff sold if (thisitem != null) { GilesItemType OriginalGilesItemType = Backpack.DetermineItemType(thisitem.ThisInternalName, thisitem.ThisDBItemType, thisitem.ThisFollowerType); GilesBaseItemType thisGilesBaseType = Backpack.DetermineBaseType(OriginalGilesItemType); if (thisGilesBaseType == GilesBaseItemType.WeaponTwoHand || thisGilesBaseType == GilesBaseItemType.WeaponOneHand || thisGilesBaseType == GilesBaseItemType.WeaponRange || thisGilesBaseType == GilesBaseItemType.Armor || thisGilesBaseType == GilesBaseItemType.Jewelry || thisGilesBaseType == GilesBaseItemType.Offhand || thisGilesBaseType == GilesBaseItemType.FollowerItem) { double iThisItemValue = Backpack.ValueThisItem(thisitem, OriginalGilesItemType); Logger.LogJunkItems(thisitem, thisGilesBaseType, OriginalGilesItemType, iThisItemValue); } Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.VendoredItemLog(thisitem); ZetaDia.Me.Inventory.SellItem(thisitem.ACDItem); } if (thisitem != null) { Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSellItems.Remove(thisitem); } if (Bot.Character.Data.BackPack.townRunCache.hashGilesCachedSellItems.Count > 0) { return(RunStatus.Running); } } #endregion #region BuyPotion //Check if settings for potion buy is enabled, with less than 99 potions existing! if (Bot.Settings.BuyPotionsDuringTownRun && Bot.Character.Data.iTotalPotions < Bot.Settings.Loot.MaximumHealthPotions && !PotionCheck) { //Obey the timer, so we don't buy 100 potions in 3 seconds. iCurrentItemLoops++; if (iCurrentItemLoops < iItemDelayLoopLimit) { return(RunStatus.Running); } iCurrentItemLoops = 0; RandomizeTheTimer(); //Buy Potions int BestPotionID = 0; int LastHPValue = 0; foreach (ACDItem item in ZetaDia.Me.Inventory.MerchantItems) { if (item.ItemType == ItemType.Potion && item.HitpointsGranted > LastHPValue && item.RequiredLevel <= Bot.Character.Data.iMyLevel && item.Gold < ZetaDia.Me.Inventory.Coinage) { LastHPValue = item.HitpointsGranted; BestPotionID = item.DynamicId; } } if (BestPotionID != 0) { ZetaDia.Me.Inventory.BuyItem(BestPotionID); //Update counter Bot.Character.Data.iTotalPotions++; return(RunStatus.Running); } PotionCheck = true; } else { PotionCheck = true; } #endregion if (bNeedsEquipmentRepairs) { iCurrentItemLoops++; if (iCurrentItemLoops < iItemDelayLoopLimit) { return(RunStatus.Running); } iCurrentItemLoops = 0; RandomizeTheTimer(); if (ZetaDia.Me.Inventory.Coinage < 40000) { Logger.DBLog.InfoFormat("Emergency Stop: You need repairs but don't have enough money. Stopping the bot to prevent infinite death loop."); BotMain.Stop(false, "Not enough gold to repair item(s)!"); } ZetaDia.Me.Inventory.RepairEquippedItems(); bNeedsEquipmentRepairs = false; } bCurrentlyMoving = false; bReachedSafety = false; return(RunStatus.Success); }
// ********************************************************************************************** // ***** Stash replacement accurately and neatly finds a free stash location ***** // ********************************************************************************************** private static bool GilesStashAttempt(CacheACDItem item, out int[] XY, out int StashPage) { XY = new[] { -1, -1 }; StashPage = -1; int iPlayerDynamicID = ZetaDia.Me.CommonData.DynamicId; int iOriginalGameBalanceId = item.ThisBalanceID; int iOriginalDynamicID = item.ThisDynamicID; int iOriginalStackQuantity = item.ThisItemStackQuantity; string sOriginalItemName = item.ThisRealName; string sOriginalInternalName = item.ThisInternalName; GilesItemType OriginalGilesItemType = Backpack.DetermineItemType(item.ThisInternalName, item.ThisDBItemType, item.ThisFollowerType); GilesBaseItemType thisGilesBaseType = Backpack.DetermineBaseType(OriginalGilesItemType); bool bOriginalTwoSlot = Backpack.DetermineIsTwoSlot(OriginalGilesItemType); bool bOriginalIsStackable = Backpack.DetermineIsStackable(OriginalGilesItemType); int iAttempts; if (_dictItemStashAttempted.TryGetValue(iOriginalDynamicID, out iAttempts)) { Logger.DBLog.InfoFormat("GSError: Detected a duplicate stash attempt, DB item mis-read error, now forcing this item as a 2-slot item"); _dictItemStashAttempted[iOriginalDynamicID] = iAttempts + 1; bOriginalTwoSlot = true; bOriginalIsStackable = false; if (iAttempts > 6) { Logger.DBLog.InfoFormat("GSError: Detected an item stash loop risk, now re-mapping stash treating everything as 2-slot and re-attempting"); // Array for what blocks are or are not blocked for (int iRow = 0; iRow <= 29; iRow++) { for (int iColumn = 0; iColumn <= 6; iColumn++) { GilesStashSlotBlocked[iColumn, iRow] = false; } } // Block off the entire of any "protected stash pages" foreach (int iProtPage in CharacterSettings.Instance.ProtectedStashPages) { for (int iProtRow = 0; iProtRow <= 9; iProtRow++) { for (int iProtColumn = 0; iProtColumn <= 6; iProtColumn++) { GilesStashSlotBlocked[iProtColumn, iProtRow + (iProtPage * 10)] = true; } } } // Remove rows we don't have for (int iRow = (ZetaDia.Me.NumSharedStashSlots / 7); iRow <= 29; iRow++) { for (int iColumn = 0; iColumn <= 6; iColumn++) { GilesStashSlotBlocked[iColumn, iRow] = true; } } // Map out all the items already in the stash foreach (ACDItem tempitem in ZetaDia.Me.Inventory.StashItems) { if (tempitem.BaseAddress != IntPtr.Zero) { int inventoryRow = tempitem.InventoryRow; int inventoryColumn = tempitem.InventoryColumn; // Mark this slot as not-free GilesStashSlotBlocked[inventoryColumn, inventoryRow] = true; // Try and reliably find out if this is a two slot item or not GilesStashSlotBlocked[inventoryColumn, inventoryRow + 1] = true; if (inventoryRow != 19 && inventoryRow != 9 && inventoryRow != 29) { GilesStashSlotBlocked[inventoryColumn, inventoryRow + 1] = true; } } } } if (iAttempts > 15) { Logger.DBLog.InfoFormat("***************************"); Logger.DBLog.InfoFormat("GSError: Emergency Stop: No matter what we tried, we couldn't prevent an infinite stash loop. Sorry. Now stopping the bot."); BotMain.Stop(); return(false); } } else { _dictItemStashAttempted.Add(iOriginalDynamicID, 1); } // Safety incase it's not actually in the backpack anymore /*if (item.InventorySlot != InventorySlot.PlayerBackpack) * { * Logger.DBLog.InfoFormat("GSError: Diablo 3 memory read error, or item became invalid [StashAttempt-4]", true); * return false; * }*/ int iLeftoverStackQuantity; // Item log for cool stuff stashed if (thisGilesBaseType == GilesBaseItemType.WeaponTwoHand || thisGilesBaseType == GilesBaseItemType.WeaponOneHand || thisGilesBaseType == GilesBaseItemType.WeaponRange || thisGilesBaseType == GilesBaseItemType.Armor || thisGilesBaseType == GilesBaseItemType.Jewelry || thisGilesBaseType == GilesBaseItemType.Offhand || thisGilesBaseType == GilesBaseItemType.FollowerItem) { Logger.LogGoodItems(item, thisGilesBaseType, OriginalGilesItemType); } int iPointX = -1; int iPointY = -1; // First check if we can top-up any already-existing stacks in the stash if (bOriginalIsStackable) { foreach (ACDItem tempitem in ZetaDia.Me.Inventory.StashItems) { if (tempitem.BaseAddress == IntPtr.Zero) { Logger.DBLog.InfoFormat("GSError: Diablo 3 memory read error, or stash item became invalid [StashAttempt-5]"); return(false); } // Check if we combine the stacks, we won't overfill them if ((tempitem.GameBalanceId == iOriginalGameBalanceId) && (tempitem.ItemStackQuantity < tempitem.MaxStackCount)) { iLeftoverStackQuantity = (tempitem.ItemStackQuantity + iOriginalStackQuantity) - tempitem.MaxStackCount; iPointX = tempitem.InventoryColumn; iPointY = tempitem.InventoryRow; // Will we have leftovers? if (iLeftoverStackQuantity <= 0) { goto FoundStashLocation; } goto HandleStackMovement; } } HandleStackMovement: if ((iPointX >= 0) && (iPointY >= 0)) { ZetaDia.Me.Inventory.MoveItem(iOriginalDynamicID, iPlayerDynamicID, InventorySlot.SharedStash, iPointX, iPointY); } } iPointX = -1; iPointY = -1; // If it's a 2-square item, find a double-slot free if (bOriginalTwoSlot) { for (int iRow = 0; iRow <= 29; iRow++) { bool bBottomPageRow = (iRow == 9 || iRow == 19 || iRow == 29); for (int iColumn = 0; iColumn <= 6; iColumn++) { // If nothing in the 1st row if (!GilesStashSlotBlocked[iColumn, iRow]) { bool bNotEnoughSpace = false; // Bottom row of a page = no room if (bBottomPageRow) { bNotEnoughSpace = true; } // Already something in the stash in the 2nd row) else if (GilesStashSlotBlocked[iColumn, iRow + 1]) { bNotEnoughSpace = true; } if (!bNotEnoughSpace) { iPointX = iColumn; iPointY = iRow; goto FoundStashLocation; } } } } } // 2 slot item? // Now deal with any leftover 1-slot items else { // First we try and find somewhere "sensible" for (int iRow = 0; iRow <= 29; iRow++) { bool bTopPageRow = (iRow == 0 || iRow == 10 || iRow == 20); bool bBottomPageRow = (iRow == 9 || iRow == 19 || iRow == 29); for (int iColumn = 0; iColumn <= 6; iColumn++) { // Nothing in this slot if (!GilesStashSlotBlocked[iColumn, iRow]) { bool bSensibleLocation = false; if (!bTopPageRow && !bBottomPageRow) { // Something above and below this slot, or an odd-numbered row, so put something here if ((GilesStashSlotBlocked[iColumn, iRow + 1] && GilesStashSlotBlocked[iColumn, iRow - 1]) || (iRow) % 2 != 0) { bSensibleLocation = true; } } // Top page row with something directly underneath already blocking else if (bTopPageRow) { if (GilesStashSlotBlocked[iColumn, iRow + 1]) { bSensibleLocation = true; } } // Bottom page row with something directly over already blocking else { bSensibleLocation = true; } // Sensible location? Yay, stash it here! if (bSensibleLocation) { iPointX = iColumn; iPointY = iRow; // Keep looking for places if it's a stackable to try to stick it at the end if (!bOriginalIsStackable) { goto FoundStashLocation; } } } } } // Didn't find a "sensible" place, let's try and force it in absolutely anywhere if ((iPointX < 0) || (iPointY < 0)) { for (int iRow = 0; iRow <= 29; iRow++) { for (int iColumn = 0; iColumn <= 6; iColumn++) { // Nothing in this spot, we're good! if (!GilesStashSlotBlocked[iColumn, iRow]) { iPointX = iColumn; iPointY = iRow; // Keep looking for places if it's a stackable to try to stick it at the end if (!bOriginalIsStackable) { goto FoundStashLocation; } } } } } } FoundStashLocation: if ((iPointX < 0) || (iPointY < 0)) { Logger.DBLog.DebugFormat("Fatal Error: No valid stash location found for '" + sOriginalItemName + "' [" + sOriginalInternalName + " - " + OriginalGilesItemType.ToString() + "]"); Logger.DBLog.InfoFormat("***************************"); Logger.DBLog.InfoFormat("GSError: Emergency Stop: You need to stash an item but no valid space could be found. Stash is full? Stopping the bot to prevent infinite town-run loop."); OutOfGame.MuleBehavior = true; ZetaDia.Service.Party.LeaveGame(); return(false); } // We have two valid points that are empty, move the object here! GilesStashSlotBlocked[iPointX, iPointY] = true; if (bOriginalTwoSlot) { GilesStashSlotBlocked[iPointX, iPointY + 1] = true; } XY = new[] { iPointX, iPointY }; if (iPointY < 10) { StashPage = 0; } else if (iPointY < 20) { StashPage = 1; } else { StashPage = 2; } return(true); } // Custom stashing routine
// ********************************************************************************************** // ***** Log the nice items we found and stashed ***** // ********************************************************************************************** internal static void LogGoodItems(CacheACDItem thisgooditem, GilesBaseItemType thisgilesbaseitemtype, GilesItemType thisgilesitemtype, double ithisitemvalue) { FileStream LogStream=null; try { LogStream=File.Open(LoggingFolderPath+LoggingPrefixString+" -- StashLog.log", FileMode.Append, FileAccess.Write, FileShare.Read); using (StreamWriter LogWriter=new StreamWriter(LogStream)) { if (!TownRunManager.bLoggedAnythingThisStash) { TownRunManager.bLoggedAnythingThisStash=true; LogWriter.WriteLine(DateTime.Now.ToString()+":"); LogWriter.WriteLine("===================="); } string sLegendaryString=""; if (thisgooditem.ThisQuality>=ItemQuality.Legendary) { if (!thisgooditem.IsUnidentified) { AddNotificationToQueue(thisgooditem.ThisRealName+" ["+thisgilesitemtype.ToString()+"] (Score="+ithisitemvalue.ToString()+". "+TownRunManager.sValueItemStatString+")", ZetaDia.Service.CurrentHero.Name+" new legendary!", ProwlNotificationPriority.Emergency); sLegendaryString=" {legendary item}"; // Change made by bombastic Logging.Write("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+"); Logging.Write("+ Name: "+thisgooditem.ThisRealName+" ("+thisgilesitemtype.ToString()+")"); Logging.Write("+ Score: "+Math.Round(ithisitemvalue).ToString()); Logging.Write("+ Attributes: "+ thisgooditem.ItemStatString); Logging.Write("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); } else { Logging.Write("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+"); Logging.Write("+ Unid: "+thisgilesitemtype.ToString()); Logging.Write("+ Level: "+thisgooditem.ThisLevel.ToString()); Logging.Write("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); } } else { // Check for non-legendary notifications bool bShouldNotify=false; switch (thisgilesbaseitemtype) { case GilesBaseItemType.WeaponOneHand: case GilesBaseItemType.WeaponRange: case GilesBaseItemType.WeaponTwoHand: //if (ithisitemvalue >= settings.iNeedPointsToNotifyWeapon) // bShouldNotify = true; break; case GilesBaseItemType.Armor: case GilesBaseItemType.Offhand: //if (ithisitemvalue >= settings.iNeedPointsToNotifyArmor) //bShouldNotify = true; break; case GilesBaseItemType.Jewelry: //if (ithisitemvalue >= settings.iNeedPointsToNotifyJewelry) //bShouldNotify = true; break; } if (bShouldNotify) AddNotificationToQueue(thisgooditem.ThisRealName+" ["+thisgilesitemtype.ToString()+"] (Score="+ithisitemvalue.ToString()+". "+TownRunManager.sValueItemStatString+")", ZetaDia.Service.CurrentHero.Name+" new item!", ProwlNotificationPriority.Emergency); } if (!thisgooditem.IsUnidentified) { LogWriter.WriteLine(thisgilesbaseitemtype.ToString()+" - "+thisgilesitemtype.ToString()+" '"+thisgooditem.ThisRealName+"'. Score = "+Math.Round(ithisitemvalue).ToString()+sLegendaryString); LogWriter.WriteLine(" "+thisgooditem.ItemStatString); LogWriter.WriteLine(""); } else { LogWriter.WriteLine(thisgilesbaseitemtype.ToString()+" - "+thisgilesitemtype.ToString()+" '"+sLegendaryString); LogWriter.WriteLine(" "+thisgooditem.ThisLevel.ToString()); LogWriter.WriteLine(""); } } } catch (IOException) { Log("Fatal Error: File access error for stash log file."); } }
// ********************************************************************************************** // ***** Log the rubbish junk items we salvaged or sold ***** // ********************************************************************************************** internal static void LogJunkItems(CacheACDItem thisgooditem, GilesBaseItemType thisgilesbaseitemtype, GilesItemType thisgilesitemtype, double ithisitemvalue) { FileStream LogStream=null; try { LogStream=File.Open(LoggingFolderPath+LoggingPrefixString+" -- JunkLog.log", FileMode.Append, FileAccess.Write, FileShare.Read); using (StreamWriter LogWriter=new StreamWriter(LogStream)) { if (!TownRunManager.bLoggedJunkThisStash) { TownRunManager.bLoggedJunkThisStash=true; LogWriter.WriteLine(DateTime.Now.ToString()+":"); LogWriter.WriteLine("===================="); } string sLegendaryString=""; if (thisgooditem.ThisQuality>=ItemQuality.Legendary) sLegendaryString=" {legendary item}"; LogWriter.WriteLine(thisgilesbaseitemtype.ToString()+" - "+thisgilesitemtype.ToString()+" '"+thisgooditem.ThisRealName+"'. Score = "+Math.Round(ithisitemvalue).ToString()+sLegendaryString); if (!String.IsNullOrEmpty(TownRunManager.sJunkItemStatString)) LogWriter.WriteLine(" "+TownRunManager.sJunkItemStatString); else LogWriter.WriteLine(" (no scorable attributes)"); LogWriter.WriteLine(""); } } catch (IOException) { Log("Fatal Error: File access error for junk log file."); } }