private bool TrinitySell(ACDItem item) { CachedACDItem cItem = CachedACDItem.GetCachedItem(item); // Vanity Items if (DataDictionary.VanityItems.Any(i => item.InternalName.StartsWith(i))) { return(false); } switch (cItem.TrinityItemBaseType) { case GItemBaseType.WeaponRange: case GItemBaseType.WeaponOneHand: case GItemBaseType.WeaponTwoHand: case GItemBaseType.Armor: case GItemBaseType.Offhand: case GItemBaseType.Jewelry: case GItemBaseType.FollowerItem: return(true); case GItemBaseType.Gem: case GItemBaseType.Misc: if (cItem.TrinityItemType == GItemType.CraftingPlan) { return(true); } return(false); case GItemBaseType.Unknown: return(false); } return(false); }
public static CachedACDItem GetCachedItem(ACDItem item) { CachedACDItem cItem = new CachedACDItem(item.Stats) { AcdItem = item, InternalName = item.InternalName, RealName = item.Name, Level = item.Level, Quality = item.ItemQualityLevel, GoldAmount = item.Gold, BalanceID = item.GameBalanceId, DynamicID = item.DynamicId, OneHanded = item.IsOneHand, TwoHanded = item.IsTwoHand, DyeType = item.DyeType, DBItemType = item.ItemType, DBBaseType = item.ItemBaseType, FollowerType = item.FollowerSpecialType, IsUnidentified = item.IsUnidentified, ItemStackQuantity = item.ItemStackQuantity, Row = item.InventoryRow, Column = item.InventoryColumn, ItemLink = item.ItemLink, TrinityItemType = Trinity.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType), TrinityItemBaseType = Trinity.DetermineBaseType(Trinity.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType)) }; cItem.ComputeUpgrade(); return(cItem); }
public static bool GetIsSalvageable(CachedACDItem cItem) { if (!cItem.IsEquipment) { return(false); } if (cItem.AcdItem.IsVendorBought) { return(false); } return(true); }
public static CachedACDItem GetCachedItem(ACDItem item) { try { if (!item.IsValid) { return(default(CachedACDItem)); } CachedACDItem cItem = new CachedACDItem(item.Stats) { AcdItem = item, InternalName = item.InternalName, RealName = item.Name, Level = item.Level, Quality = item.GetItemQuality(), GoldAmount = item.Gold, BalanceID = item.GameBalanceId, DynamicID = item.DynamicId, ActorSNO = item.ActorSNO, OneHanded = item.IsOneHand, TwoHanded = item.IsTwoHand, DyeType = item.DyeType, DBItemType = item.ItemType, DBBaseType = item.ItemBaseType, FollowerType = item.FollowerSpecialType, IsUnidentified = item.IsUnidentified, ItemStackQuantity = item.ItemStackQuantity, Row = item.InventoryRow, Column = item.InventoryColumn, ItemLink = item.ItemLink, GameBalanceId = item.GameBalanceId, TrinityItemType = TrinityItemManager.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType), IsAncient = item.GetAttribute <int>(ActorAttributeType.AncientRank) > 0, }; TrinityItemBaseType trinityItemBaseType = TrinityItemManager.DetermineBaseType(TrinityItemManager.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType)); cItem.TrinityItemBaseType = trinityItemBaseType; cItem.IsEquipment = GetIsEquipment(trinityItemBaseType); cItem.IsSalvageable = GetIsSalvageable(cItem); return(cItem); } catch (Exception ex) { Logger.LogError("Error getting CachedItem {0}", ex.Message); return(default(CachedACDItem)); } }
public int CompareTo(object obj) { CachedACDItem item = (CachedACDItem)obj; if (Row < item.Row) { return(-1); } if (Column < item.Column) { return(-1); } if (Column == item.Column && Row == item.Row) { return(0); } return(1); }
internal static void TrinityOnItemSalvaged(object sender, ItemEventArgs e) { ACDItem i = e.Item; var cachedItem = CachedACDItem.GetCachedItem(i); ResetTownRun(); switch (i.ItemBaseType) { case ItemBaseType.Gem: case ItemBaseType.Misc: break; default: TownRun.LogJunkItems(cachedItem, cachedItem.TrinityItemBaseType, cachedItem.TrinityItemType, ItemValuation.ValueThisItem(cachedItem, cachedItem.TrinityItemType)); break; } }
public static CachedACDItem GetCachedItem(ACDItem item) { try { if (!item.IsValid) { return(default(CachedACDItem)); } CachedACDItem cItem = new CachedACDItem(item.Stats) { AcdItem = item, InternalName = item.InternalName, RealName = item.Name, Level = item.Level, Quality = item.ItemQualityLevel, GoldAmount = item.Gold, BalanceID = item.GameBalanceId, DynamicID = item.DynamicId, OneHanded = item.IsOneHand, TwoHanded = item.IsTwoHand, DyeType = item.DyeType, DBItemType = item.ItemType, DBBaseType = item.ItemBaseType, FollowerType = item.FollowerSpecialType, IsUnidentified = item.IsUnidentified, ItemStackQuantity = item.ItemStackQuantity, Row = item.InventoryRow, Column = item.InventoryColumn, ItemLink = item.ItemLink, TrinityItemType = Trinity.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType), TrinityItemBaseType = Trinity.DetermineBaseType(Trinity.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType)) }; cItem.ComputeUpgrade(); return(cItem); } catch (Exception ex) { Logger.LogError("Error getting CachedItem {0}", ex.Message); return(default(CachedACDItem)); } }
/// <summary> /// Log the rubbish junk items we salvaged or sold /// </summary> internal static void LogJunkItems(CachedACDItem acdItem, GItemBaseType itemBaseType, GItemType itemType, double itemValue) { FileStream LogStream = null; try { string filePath = Path.Combine(FileManager.LoggingPath, "JunkLog - " + Trinity.Player.ActorClass.ToString() + ".log"); LogStream = File.Open(filePath, FileMode.Append, FileAccess.Write, FileShare.Read); using (StreamWriter LogWriter = new StreamWriter(LogStream)) { if (!_loggedJunkThisStash) { _loggedJunkThisStash = true; LogWriter.WriteLine(DateTime.Now.ToString() + ":"); LogWriter.WriteLine("===================="); } string isLegendaryItem = ""; if (acdItem.Quality >= ItemQuality.Legendary) { isLegendaryItem = " {legendary item}"; } LogWriter.WriteLine(itemBaseType.ToString() + " - " + itemType.ToString() + " '" + acdItem.RealName + "'. Score = " + itemValue.ToString("0") + isLegendaryItem); if (JunkItemStatString != "") { LogWriter.WriteLine(" " + JunkItemStatString); } else { LogWriter.WriteLine(" (no scorable attributes)"); } LogWriter.WriteLine(""); } LogStream.Close(); } catch (IOException) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Fatal Error: File access error for junk log file."); if (LogStream != null) { LogStream.Close(); } } }
public bool ShouldSellItem(ACDItem item, ItemEvaluationType evaluationType) { ItemEvents.ResetTownRun(); CachedACDItem cItem = CachedACDItem.GetCachedItem(item); if (Current.ItemIsProtected(cItem.AcdItem)) { return(false); } if (Trinity.Settings.Loot.ItemFilterMode == ItemFilterMode.DemonBuddy) { return(Current.ShouldSellItem(item)); } if (Trinity.Settings.Loot.ItemFilterMode == ItemFilterMode.TrinityWithItemRules) { return(ItemRulesSalvageSell(item, evaluationType)); } return(TrinitySell(item)); }
public int CompareTo(object obj) { CachedACDItem item = (CachedACDItem)obj; if (this.Row < item.Row) { return(-1); } else if (this.Column < item.Column) { return(-1); } else if (this.Column == item.Column && this.Row == item.Row) { return(0); } else { return(1); } }
public bool ShouldStashItem(ACDItem item, ItemEvaluationType evaluationType) { ItemEvents.ResetTownRun(); if (Current.ItemIsProtected(item)) { return(false); } // Vanity Items if (DataDictionary.VanityItems.Any(i => item.InternalName.StartsWith(i))) { return(false); } if (Trinity.Settings.Loot.ItemFilterMode == ItemFilterMode.DemonBuddy) { return(ItemManager.Current.ShouldStashItem(item)); } CachedACDItem cItem = CachedACDItem.GetCachedItem(item); // Now look for Misc items we might want to keep GItemType tItemType = cItem.TrinityItemType; // DetermineItemType(cItem.InternalName, cItem.DBItemType, cItem.FollowerType); GItemBaseType tBaseType = cItem.TrinityItemBaseType; // DetermineBaseType(trinityItemType); bool isEquipment = (tBaseType == GItemBaseType.Armor || tBaseType == GItemBaseType.Jewelry || tBaseType == GItemBaseType.Offhand || tBaseType == GItemBaseType.WeaponOneHand || tBaseType == GItemBaseType.WeaponRange || tBaseType == GItemBaseType.WeaponTwoHand); if (cItem.TrinityItemType == GItemType.HoradricCache && Trinity.Settings.Loot.TownRun.OpenHoradricCaches) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] = (ignoring Horadric Cache)", cItem.RealName, cItem.InternalName); return(false); } // Stash all unidentified items - assume we want to keep them since we are using an identifier over-ride if (cItem.IsUnidentified) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] = (autokeep unidentified items)", cItem.RealName, cItem.InternalName); } return(true); } if (tItemType == GItemType.StaffOfHerding) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep staff of herding)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } if (tItemType == GItemType.CraftingMaterial) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep craft materials)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } if (tItemType == GItemType.Emerald || tItemType == GItemType.Amethyst || tItemType == GItemType.Topaz || tItemType == GItemType.Ruby || tItemType == GItemType.Diamond) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep gems)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } if (tItemType == GItemType.CraftTome) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep tomes)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } if (tItemType == GItemType.InfernalKey) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep infernal key)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } if (tItemType == GItemType.HealthPotion) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (ignoring potions)", cItem.RealName, cItem.InternalName, tItemType); } return(false); } if (tItemType == GItemType.CraftingPlan && cItem.Quality >= ItemQuality.Legendary) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep legendary plans)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } if (Trinity.Settings.Loot.ItemFilterMode == ItemFilterMode.TrinityWithItemRules) { Interpreter.InterpreterAction action = Trinity.StashRule.checkItem(item, evaluationType); if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (" + action + ")", cItem.AcdItem.Name, cItem.AcdItem.InternalName, cItem.AcdItem.ItemType); } switch (action) { case Interpreter.InterpreterAction.KEEP: return(true); case Interpreter.InterpreterAction.TRASH: return(false); case Interpreter.InterpreterAction.SCORE: break; } } if (tItemType == GItemType.CraftingPlan) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep plans)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } // Stashing Whites, auto-keep if (Trinity.Settings.Loot.TownRun.StashWhites && isEquipment && cItem.Quality <= ItemQuality.Superior) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (stashing whites)", cItem.RealName, cItem.InternalName, tItemType); return(true); } // Else auto-trash if (cItem.Quality <= ItemQuality.Superior && (isEquipment || cItem.TrinityItemBaseType == GItemBaseType.FollowerItem)) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (trash whites)", cItem.RealName, cItem.InternalName, tItemType); return(false); } // Stashing blues, auto-keep if (Trinity.Settings.Loot.TownRun.StashBlues && isEquipment && cItem.Quality >= ItemQuality.Magic1 && cItem.Quality <= ItemQuality.Magic3) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (stashing blues)", cItem.RealName, cItem.InternalName, tItemType); return(true); } // Else auto trash if (cItem.Quality >= ItemQuality.Magic1 && cItem.Quality <= ItemQuality.Magic3 && (isEquipment || cItem.TrinityItemBaseType == GItemBaseType.FollowerItem)) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (trashing blues)", cItem.RealName, cItem.InternalName, tItemType); return(false); } // Force salvage Rares if (Trinity.Settings.Loot.TownRun.ForceSalvageRares && cItem.Quality >= ItemQuality.Rare4 && cItem.Quality <= ItemQuality.Rare6 && (isEquipment || cItem.TrinityItemBaseType == GItemBaseType.FollowerItem)) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (force salvage rare)", cItem.RealName, cItem.InternalName, tItemType); return(false); } if (cItem.Quality >= ItemQuality.Legendary) { if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep legendaries)", cItem.RealName, cItem.InternalName, tItemType); } return(true); } // Ok now try to do some decent item scoring based on item types double iNeedScore = Trinity.ScoreNeeded(item.ItemBaseType); double iMyScore = ItemValuation.ValueThisItem(cItem, tItemType); if (evaluationType == ItemEvaluationType.Keep) { Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "{0} [{1}] [{2}] = {3}", cItem.RealName, cItem.InternalName, tItemType, iMyScore); } if (iMyScore >= iNeedScore) { return(true); } // If we reached this point, then we found no reason to keep the item! return(false); }
public static CachedACDItem GetCachedItem(ACDItem item) { try { if (!item.IsValid) return default(CachedACDItem); CachedACDItem cItem = new CachedACDItem(item.Stats) { AcdItem = item, InternalName = item.InternalName, RealName = item.Name, Level = item.Level, Quality = item.ItemLinkColorQuality(), GoldAmount = item.Gold, BalanceID = item.GameBalanceId, DynamicID = item.DynamicId, ActorSNO = item.ActorSNO, OneHanded = item.IsOneHand, TwoHanded = item.IsTwoHand, DyeType = item.DyeType, DBItemType = item.ItemType, DBBaseType = item.ItemBaseType, FollowerType = item.FollowerSpecialType, IsUnidentified = item.IsUnidentified, ItemStackQuantity = item.ItemStackQuantity, Row = item.InventoryRow, Column = item.InventoryColumn, ItemLink = item.ItemLink, TrinityItemType = TrinityItemManager.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType), IsAncient = item.GetAttribute<int>(ActorAttributeType.AncientRank) > 0, }; TrinityItemBaseType trinityItemBaseType = TrinityItemManager.DetermineBaseType(TrinityItemManager.DetermineItemType(item.InternalName, item.ItemType, item.FollowerSpecialType)); cItem.TrinityItemBaseType = trinityItemBaseType; cItem.IsEquipment = GetIsEquipment(trinityItemBaseType); cItem.IsSalvageable = GetIsSalvageable(cItem); return cItem; } catch (Exception ex) { Logger.LogError("Error getting CachedItem {0}", ex.Message); return default(CachedACDItem); } }
/// <summary> /// The bizarre mystery function to score your lovely items! /// </summary> /// <param name="item"></param> /// <param name="itemType"></param> /// <returns></returns> internal static double ValueThisItem(CachedACDItem item, TrinityItemType itemType) { // Reset static variables TotalItemPoints = 0; IsInvalidItem = true; ItemMaxStats = new double[Constants.TOTALSTATS]; ItemMaxPoints = new double[Constants.TOTALSTATS]; baseItemType = TrinityItemManager.DetermineBaseType(itemType); BestFinalBonus = 1d; HadStat = new double[Constants.TOTALSTATS] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; HadPoints = new double[Constants.TOTALSTATS] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; SafeLifePercentage = 0; SocketsCanReplacePrimaries = false; HighestScoringPrimary = 0; WhichPrimaryIsHighest = 0; AmountHighestScoringPrimary = 0; TotalRequirements = 0; GlobalMultiplier = 1; TownRun.JunkItemStatString = ""; TownRun.ValueItemStatString = ""; // Checks for Invalid Item Types CheckForInvalidItemType(itemType); // Double safety check for unidentified items if (item.IsUnidentified) IsInvalidItem = true; // Make sure we got a valid item here, otherwise score it a big fat 0 if (IsInvalidItem) { Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "-- Invalid Item Type or Unidentified?"); return 0; } Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "NEXT ITEM= " + item.RealName + " - " + item.InternalName + " [" + baseItemType.ToString() + " - " + itemType.ToString() + "]"); ResetValuationStatStrings(); // We loop through all of the stats, in a particular order. The order *IS* important, because it pulls up primary stats first, BEFORE other stats for (int i = 0; i <= (Constants.TOTALSTATS - 1); i++) { double TempStatistic = 0; // Now we lookup each stat on this item we are scoring, and store it in the variable "iTempStatistic" - which is used for calculations further down switch (i) { case Constants.DEXTERITY: TempStatistic = item.Dexterity; break; case Constants.INTELLIGENCE: TempStatistic = item.Intelligence; break; case Constants.STRENGTH: TempStatistic = item.Strength; break; case Constants.VITALITY: TempStatistic = item.Vitality; break; case Constants.LIFEPERCENT: TempStatistic = item.LifePercent; break; case Constants.LIFEONHIT: TempStatistic = item.LifeOnHit; break; case Constants.LIFESTEAL: TempStatistic = item.LifeSteal; break; case Constants.LIFEREGEN: TempStatistic = item.HealthPerSecond; break; case Constants.MAGICFIND: TempStatistic = item.MagicFind; break; case Constants.GOLDFIND: TempStatistic = item.GoldFind; break; case Constants.MOVEMENTSPEED: TempStatistic = item.MovementSpeed; break; case Constants.PICKUPRADIUS: TempStatistic = item.PickUpRadius; break; case Constants.SOCKETS: TempStatistic = item.Sockets; break; case Constants.CRITCHANCE: TempStatistic = item.CritPercent; break; case Constants.CRITDAMAGE: TempStatistic = item.CritDamagePercent; break; case Constants.ATTACKSPEED: TempStatistic = item.AttackSpeedPercent; break; case Constants.MINDAMAGE: TempStatistic = item.MinDamage; break; case Constants.MAXDAMAGE: TempStatistic = item.MaxDamage; break; case Constants.BLOCKCHANCE: TempStatistic = item.BlockChance; break; case Constants.THORNS: TempStatistic = item.Thorns; break; case Constants.ALLRESIST: TempStatistic = item.ResistAll; break; case Constants.RANDOMRESIST: if (item.ResistArcane > TempStatistic) TempStatistic = item.ResistArcane; if (item.ResistCold > TempStatistic) TempStatistic = 0; //thisitem.ResistCold; if (item.ResistFire > TempStatistic) TempStatistic = item.ResistFire; if (item.ResistHoly > TempStatistic) TempStatistic = item.ResistHoly; if (item.ResistLightning > TempStatistic) TempStatistic = 0; //thisitem.ResistLightning; if (item.ResistPhysical > TempStatistic) TempStatistic = item.ResistPhysical; if (item.ResistPoison > TempStatistic) TempStatistic = 0; //thisitem.ResistPoison; break; case Constants.TOTALDPS: TempStatistic = item.WeaponDamagePerSecond; break; case Constants.ARMOR: TempStatistic = item.ArmorBonus; break; case Constants.MAXDISCIPLINE: TempStatistic = item.MaxDiscipline; break; case Constants.MAXMANA: TempStatistic = item.MaxMana; break; case Constants.ARCANECRIT: TempStatistic = item.ArcaneOnCrit; break; case Constants.MANAREGEN: TempStatistic = item.ManaRegen; break; case Constants.GLOBEBONUS: TempStatistic = item.GlobeBonus; break; } HadStat[i] = TempStatistic; HadPoints[i] = 0; // Now we check that the current statistic in the "for" loop, actually exists on this item, and is a stat we are measuring (has >0 in the "max stats" array) if (ItemMaxStats[i] > 0 && TempStatistic > 0) { // Final bonus granted is an end-of-score multiplier. 1 = 100%, so all items start off with 100%, of course! double FinalBonusGranted = 1; // Item Stat Ratio is what PERCENTAGE of the *MAXIMUM POSSIBLE STAT*, this stat is at. // Note that stats OVER the max will get a natural score boost, since this value will be over 1! double itemStatRatio = TempStatistic / ItemMaxStats[i]; // Now multiply the "max points" value, by that percentage, as the start/basis of the scoring for this statistic double iTempPoints = ItemMaxPoints[i] * itemStatRatio; Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "--- " + Constants.StatNames[i] + ": " + TempStatistic.ToString("0") + " out of " + ItemMaxStats[i].ToString() + " (" + ItemMaxPoints[i].ToString() + " * " + itemStatRatio.ToString("0.000") + " = " + iTempPoints.ToString("0") + ")"); // Check if this statistic is over the "bonus threshold" array value for this stat - if it is, then it gets a score bonus when over a certain % of max-stat if (itemStatRatio > Constants.BonusThreshold[i] && Constants.BonusThreshold[i] > 0f) { FinalBonusGranted += ((itemStatRatio - Constants.BonusThreshold[i]) * 0.9); } // We're going to store the life % stat here for quick-calculations against other stats. Don't edit this bit! if (i == Constants.LIFEPERCENT) { if (ItemMaxStats[Constants.LIFEPERCENT] > 0) { SafeLifePercentage = (TempStatistic / ItemMaxStats[Constants.LIFEPERCENT]); } else { SafeLifePercentage = 0; } } // This *REMOVES* score from follower items for stats that followers don't care about if (baseItemType == TrinityItemBaseType.FollowerItem && (i == Constants.CRITDAMAGE || i == Constants.LIFEONHIT || i == Constants.ALLRESIST)) FinalBonusGranted -= 0.9; // Bonus 15% for being *at* the stat cap (ie - completely maxed out, or very very close to), but not for the socket stat (since sockets are usually 0 or 1!) if (i != Constants.SOCKETS) { if ((TempStatistic / ItemMaxStats[i]) >= 0.99) FinalBonusGranted += 0.15; // Else bonus 10% for being in final 95% else if ((TempStatistic / ItemMaxStats[i]) >= 0.95) FinalBonusGranted += 0.10; } // Socket handling // Sockets give special bonuses for certain items, depending how close to the max-socket-count it is for that item // It also enables bonus scoring for stats which usually rely on a high primary stat - since a socket can make up for a lack of a high primary (you can socket a +primary stat!) if (i == Constants.SOCKETS) { // Off-handers get less value from sockets if (baseItemType == TrinityItemBaseType.Offhand) { FinalBonusGranted -= 0.35; } // Chest if (itemType == TrinityItemType.Chest || itemType == TrinityItemType.Cloak) { if (TempStatistic >= 2) { SocketsCanReplacePrimaries = true; if (TempStatistic >= 3) FinalBonusGranted += 0.25; } } // Pants if (itemType == TrinityItemType.Legs) { if (TempStatistic >= 2) { SocketsCanReplacePrimaries = true; FinalBonusGranted += 0.25; } } // Helmets can have a bonus for a socket since it gives amazing MF/GF if (TempStatistic >= 1 && (itemType == TrinityItemType.Helm || itemType == TrinityItemType.WizardHat || itemType == TrinityItemType.VoodooMask || itemType == TrinityItemType.SpiritStone)) { SocketsCanReplacePrimaries = true; } // And rings and amulets too if (TempStatistic >= 1 && (itemType == TrinityItemType.Ring || itemType == TrinityItemType.Amulet)) { SocketsCanReplacePrimaries = true; } } // Right, here's quite a long bit of code, but this is basically all about granting all sorts of bonuses based on primary stat values of all different ranges // For all item types *EXCEPT* weapons if (baseItemType != TrinityItemBaseType.WeaponRange && baseItemType != TrinityItemBaseType.WeaponOneHand && baseItemType != TrinityItemBaseType.WeaponTwoHand) { double SpecialBonus = 0; if (i > Constants.LIFEPERCENT) { // Knock off points for being particularly low if ((TempStatistic / ItemMaxStats[i]) < 0.2 && (Constants.BonusThreshold[i] <= 0f || Constants.BonusThreshold[i] >= 0.2)) FinalBonusGranted -= 0.35; else if ((TempStatistic / ItemMaxStats[i]) < 0.4 && (Constants.BonusThreshold[i] <= 0f || Constants.BonusThreshold[i] >= 0.4)) FinalBonusGranted -= 0.15; // Remove 80% if below minimum threshold if ((TempStatistic / ItemMaxStats[i]) < Constants.MinimumThreshold[i] && Constants.MinimumThreshold[i] > 0f) FinalBonusGranted -= 0.8; // Primary stat/vitality minimums or zero-check reductions on other stats if (Constants.StatMinimumPrimary[i] > 0) { // Remove 40% from all stats if there is no prime stat present or vitality/life present and this is below 90% of max if (((TempStatistic / ItemMaxStats[i]) < .90) && ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) < Constants.StatMinimumPrimary[i]) && ((HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) < (Constants.StatMinimumPrimary[i] + 0.1)) && ((HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) < Constants.StatMinimumPrimary[i]) && ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) < Constants.StatMinimumPrimary[i]) && (SafeLifePercentage < (Constants.StatMinimumPrimary[i] * 2.5)) && !SocketsCanReplacePrimaries) { if (itemType != TrinityItemType.Ring && itemType != TrinityItemType.Amulet) FinalBonusGranted -= 0.4; else FinalBonusGranted -= 0.3; // And another 25% off for armor and all resist which are more useful with primaries, as long as not jewelry if ((i == Constants.ARMOR || i == Constants.ALLRESIST || i == Constants.RANDOMRESIST) && itemType != TrinityItemType.Ring && itemType != TrinityItemType.Amulet && !SocketsCanReplacePrimaries) FinalBonusGranted -= 0.15; } } else { // Almost no primary stats or health at all if (HadStat[Constants.DEXTERITY] <= 60 && HadStat[Constants.STRENGTH] <= 60 && HadStat[Constants.INTELLIGENCE] <= 60 && HadStat[Constants.VITALITY] <= 60 && SafeLifePercentage < 0.9 && !SocketsCanReplacePrimaries) { // So 35% off for all items except jewelry which is 20% off if (itemType != TrinityItemType.Ring && itemType != TrinityItemType.Amulet) { FinalBonusGranted -= 0.35; // And another 25% off for armor and all resist which are more useful with primaries if (i == Constants.ARMOR || i == Constants.ALLRESIST) FinalBonusGranted -= 0.15; } else { FinalBonusGranted -= 0.20; } } } if (baseItemType == TrinityItemBaseType.Armor || baseItemType == TrinityItemBaseType.Jewelry) { // Grant a 50% bonus to stats if a primary is above 200 AND (vitality above 200 or life% within 90% max) if ((HadStat[Constants.DEXTERITY] > 200 || HadStat[Constants.STRENGTH] > 200 || HadStat[Constants.INTELLIGENCE] > 200) && (HadStat[Constants.VITALITY] > 200 || SafeLifePercentage > .97)) { if (0.5 > SpecialBonus) SpecialBonus = 0.5; } // Else grant a 40% bonus to stats if a primary is above 200 if (HadStat[Constants.DEXTERITY] > 200 || HadStat[Constants.STRENGTH] > 200 || HadStat[Constants.INTELLIGENCE] > 200) { if (0.4 > SpecialBonus) SpecialBonus = 0.4; } // Grant a 30% bonus if vitality > 200 or life percent within 90% of max if (HadStat[Constants.VITALITY] > 200 || SafeLifePercentage > .97) { if (0.3 > SpecialBonus) SpecialBonus = 0.3; } } // Checks for various primary & health levels if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > .85 || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > .85 || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > .85) { if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .90) { if (0.5 > SpecialBonus) SpecialBonus = 0.5; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .35 || SafeLifePercentage > .85) { if (0.4 > SpecialBonus) SpecialBonus = 0.4; } else { if (0.2 > SpecialBonus) SpecialBonus = 0.2; } } if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > .75 || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > .75 || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > .75) { if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .90) { if (0.35 > SpecialBonus) SpecialBonus = 0.35; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .35 || SafeLifePercentage > .85) { if (0.30 > SpecialBonus) SpecialBonus = 0.30; } else { if (0.15 > SpecialBonus) SpecialBonus = 0.15; } } if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > .65 || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > .65 || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > .65) { if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .90) { if (0.26 > SpecialBonus) SpecialBonus = 0.26; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .35 || SafeLifePercentage > .85) { if (0.22 > SpecialBonus) SpecialBonus = 0.22; } else { if (0.11 > SpecialBonus) SpecialBonus = 0.11; } } if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > .55 || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > .55 || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > .55) { if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .90) { if (0.18 > SpecialBonus) SpecialBonus = 0.18; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .35 || SafeLifePercentage > .85) { if (0.14 > SpecialBonus) SpecialBonus = 0.14; } else { if (0.08 > SpecialBonus) SpecialBonus = 0.08; } } if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > .5 || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > .5 || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > .5) { if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .90) { if (0.12 > SpecialBonus) SpecialBonus = 0.12; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .35 || SafeLifePercentage > .85) { if (0.05 > SpecialBonus) SpecialBonus = 0.05; } else { if (0.03 > SpecialBonus) SpecialBonus = 0.03; } } if (itemType == TrinityItemType.Ring || itemType == TrinityItemType.Amulet) { if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > .4 || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > .4 || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > .4) { if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .90) { if (0.10 > SpecialBonus) SpecialBonus = 0.10; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .35 || SafeLifePercentage > .85) { if (0.08 > SpecialBonus) SpecialBonus = 0.08; } else { if (0.05 > SpecialBonus) SpecialBonus = 0.05; } } } if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .8 || SafeLifePercentage > .98) { if (0.20 > SpecialBonus) SpecialBonus = 0.20; } if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .7 || SafeLifePercentage > .95) { if (0.16 > SpecialBonus) SpecialBonus = 0.16; } if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .6 || SafeLifePercentage > .92) { if (0.12 > SpecialBonus) SpecialBonus = 0.12; } if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .55 || SafeLifePercentage > .89) { if (0.07 > SpecialBonus) SpecialBonus = 0.07; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .5 || SafeLifePercentage > .87) { if (0.05 > SpecialBonus) SpecialBonus = 0.05; } else if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > .45 || SafeLifePercentage > .86) { if (0.02 > SpecialBonus) SpecialBonus = 0.02; } } // This stat is one after life percent stat // Shields get less of a special bonus from high prime stats if (itemType == TrinityItemType.Shield) SpecialBonus *= 0.7; if (SpecialBonus > 0) Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "------- special bonus =" + SpecialBonus.ToString(), true); FinalBonusGranted += SpecialBonus; } if (i == Constants.LIFESTEAL && itemType == TrinityItemType.MightyBelt) FinalBonusGranted += 0.3; if (i == Constants.TOTALDPS) { // Knock off points for being particularly low if ((TempStatistic / ItemMaxStats[i]) < Constants.MinimumThreshold[i] && Constants.MinimumThreshold[i] > 0f) FinalBonusGranted -= 0.5; } else { // Knock off points for being particularly low if ((TempStatistic / ItemMaxStats[i]) < Constants.MinimumThreshold[i] && Constants.MinimumThreshold[i] > 0f) FinalBonusGranted -= 0.35; } // Grant a 20% bonus to vitality or Life%, for being paired with any prime stat above minimum threshold +.1 if (((i == Constants.VITALITY && (TempStatistic / ItemMaxStats[Constants.VITALITY]) > Constants.MinimumThreshold[Constants.VITALITY]) || i == Constants.LIFEPERCENT && (TempStatistic / ItemMaxStats[Constants.LIFEPERCENT]) > Constants.MinimumThreshold[Constants.LIFEPERCENT]) && ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > (Constants.MinimumThreshold[Constants.DEXTERITY] + 0.1) || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > (Constants.MinimumThreshold[Constants.STRENGTH] + 0.1) || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > (Constants.MinimumThreshold[Constants.INTELLIGENCE] + 0.1))) FinalBonusGranted += 0.2; // Blue item point reduction for non-weapons if (item.Quality < ItemQuality.Rare4 && (baseItemType == TrinityItemBaseType.Armor || baseItemType == TrinityItemBaseType.Offhand || baseItemType == TrinityItemBaseType.Jewelry || baseItemType == TrinityItemBaseType.FollowerItem) && ((TempStatistic / ItemMaxStats[i]) < 0.88)) FinalBonusGranted -= 0.9; // Special all-resist bonuses if (i == Constants.ALLRESIST) { // Shields with < 60% max all resist, lost some all resist score if (itemType == TrinityItemType.Shield && (TempStatistic / ItemMaxStats[i]) <= 0.6) FinalBonusGranted -= 0.30; double iSpecialBonus = 0; // All resist gets a special bonus if paired with good strength and some vitality if ((HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > 0.7 && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > 0.3) if (0.45 > iSpecialBonus) iSpecialBonus = 0.45; // All resist gets a smaller special bonus if paired with good dexterity and some vitality if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > 0.7 && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > 0.3) if (0.35 > iSpecialBonus) iSpecialBonus = 0.35; // All resist gets a slight special bonus if paired with good intelligence and some vitality if ((HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > 0.7 && (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > 0.3) if (0.25 > iSpecialBonus) iSpecialBonus = 0.25; // Smaller bonuses for smaller stats // All resist gets a special bonus if paired with good strength and some vitality if ((HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > 0.55 && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > 0.3) if (0.45 > iSpecialBonus) iSpecialBonus = 0.20; // All resist gets a smaller special bonus if paired with good dexterity and some vitality if ((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > 0.55 && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > 0.3) if (0.35 > iSpecialBonus) iSpecialBonus = 0.15; // All resist gets a slight special bonus if paired with good intelligence and some vitality if ((HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > 0.55 && (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > 0.3) if (0.25 > iSpecialBonus) iSpecialBonus = 0.10; // This stat is one after life percent stat FinalBonusGranted += iSpecialBonus; // Global bonus to everything //if ((ItemMaxStats[i] - TempStatistic) < 10.2f) // GlobalMultiplier += 0.05; } // All resist special bonuses if (itemType != TrinityItemType.Ring && itemType != TrinityItemType.Amulet) { // Shields get 10% less on everything if (itemType == TrinityItemType.Shield) FinalBonusGranted -= 0.10; // Prime stat gets a 20% bonus if 50 from max possible if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE || i == Constants.VITALITY) && (ItemMaxStats[i] - TempStatistic) < 50.5f) FinalBonusGranted += 0.25; // Reduce a prime stat by 75% if less than 100 *OR* less than 50% max if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE) && (TempStatistic < 100 || ((TempStatistic / ItemMaxStats[i]) < 0.5))) FinalBonusGranted -= 0.75; // Reduce a vitality/life% stat by 60% if less than 80 vitality/less than 60% max possible life% if ((i == Constants.VITALITY && TempStatistic < 80) || (i == Constants.LIFEPERCENT && ((TempStatistic / ItemMaxStats[Constants.LIFEPERCENT]) < 0.6))) FinalBonusGranted -= 0.6; // Grant 10% to any 4 main stat above 200 if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE || i == Constants.VITALITY) && TempStatistic > 200) FinalBonusGranted += 0.1; // Special stat handling stuff for non-jewelry types // Within 2 block chance if (i == Constants.BLOCKCHANCE && (ItemMaxStats[i] - TempStatistic) < 2.3f) FinalBonusGranted += 1; // Within final 5 gold find if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) < 5.3f) { FinalBonusGranted += 0.04; // Even bigger bonus if got prime stat & vit if (((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > Constants.MinimumThreshold[Constants.DEXTERITY] || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > Constants.MinimumThreshold[Constants.STRENGTH] || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > Constants.MinimumThreshold[Constants.INTELLIGENCE]) && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > Constants.MinimumThreshold[Constants.VITALITY]) FinalBonusGranted += 0.02; } // Within final 3 gold find if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) < 3.3f) { FinalBonusGranted += 0.04; } // Within final 2 gold find if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) < 2.3f) { FinalBonusGranted += 0.05; } // Within final 3 magic find if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) < 3.3f) FinalBonusGranted += 0.08; // Within final 2 magic find if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) < 2.3f) { FinalBonusGranted += 0.04; // Even bigger bonus if got prime stat & vit if (((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > Constants.MinimumThreshold[Constants.DEXTERITY] || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > Constants.MinimumThreshold[Constants.STRENGTH] || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > Constants.MinimumThreshold[Constants.INTELLIGENCE]) && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > Constants.MinimumThreshold[Constants.VITALITY]) FinalBonusGranted += 0.03; } // Within final magic find if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) < 1.3f) { FinalBonusGranted += 0.05; } // Within final 10 all resist if (i == Constants.ALLRESIST && (ItemMaxStats[i] - TempStatistic) < 10.2f) { FinalBonusGranted += 0.05; // Even bigger bonus if got prime stat & vit if (((HadStat[Constants.DEXTERITY] / ItemMaxStats[Constants.DEXTERITY]) > Constants.MinimumThreshold[Constants.DEXTERITY] || (HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > Constants.MinimumThreshold[Constants.STRENGTH] || (HadStat[Constants.INTELLIGENCE] / ItemMaxStats[Constants.INTELLIGENCE]) > Constants.MinimumThreshold[Constants.INTELLIGENCE]) && (HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY]) > Constants.MinimumThreshold[Constants.VITALITY]) FinalBonusGranted += 0.20; } // Within final 50 armor if (i == Constants.ARMOR && (ItemMaxStats[i] - TempStatistic) < 50.2f) { FinalBonusGranted += 0.10; if ((HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > Constants.MinimumThreshold[Constants.STRENGTH]) FinalBonusGranted += 0.10; } // Within final 15 armor if (i == Constants.ARMOR && (ItemMaxStats[i] - TempStatistic) < 15.2f) FinalBonusGranted += 0.15; // Within final 5 critical hit damage if (i == Constants.CRITDAMAGE && (ItemMaxStats[i] - TempStatistic) < 5.2f) FinalBonusGranted += 0.25; // More than 2.5 crit chance out if (i == Constants.CRITCHANCE && (ItemMaxStats[i] - TempStatistic) > 2.45f) FinalBonusGranted -= 0.35; // More than 20 crit damage out if (i == Constants.CRITDAMAGE && (ItemMaxStats[i] - TempStatistic) > 19.95f) FinalBonusGranted -= 0.35; // More than 2 attack speed out if (i == Constants.ATTACKSPEED && (ItemMaxStats[i] - TempStatistic) > 1.95f) FinalBonusGranted -= 0.35; // More than 2 move speed if (i == Constants.MOVEMENTSPEED && (ItemMaxStats[i] - TempStatistic) > 1.95f) FinalBonusGranted -= 0.35; // More than 5 gold find out if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) > 5.2f) FinalBonusGranted -= 0.40; // More than 8 gold find out if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) > 8.2f) FinalBonusGranted -= 0.1; // More than 5 magic find out if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) > 5.2f) FinalBonusGranted -= 0.40; // More than 7 magic find out if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) > 7.2f) FinalBonusGranted -= 0.1; // More than 20 all resist out if (i == Constants.ALLRESIST && (ItemMaxStats[i] - TempStatistic) > 20.2f) FinalBonusGranted -= 0.50; // More than 30 all resist out if (i == Constants.ALLRESIST && (ItemMaxStats[i] - TempStatistic) > 30.2f) FinalBonusGranted -= 0.20; } // And now for jewelry checks... if (itemType == TrinityItemType.Ring || itemType == TrinityItemType.Amulet) { // Global bonus to everything if jewelry has an all resist above 50% if (i == Constants.ALLRESIST && (TempStatistic / ItemMaxStats[i]) > 0.5) GlobalMultiplier += 0.08; // Within final 10 all resist if (i == Constants.ALLRESIST && (ItemMaxStats[i] - TempStatistic) < 10.2f) FinalBonusGranted += 0.10; // Within final 5 critical hit damage if (i == Constants.CRITDAMAGE && (ItemMaxStats[i] - TempStatistic) < 5.2f) FinalBonusGranted += 0.25; // Within 3 block chance if (i == Constants.BLOCKCHANCE && (ItemMaxStats[i] - TempStatistic) < 3.3f) FinalBonusGranted += 0.15; // Reduce a prime stat by 60% if less than 60 if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE) && (TempStatistic < 60 || ((TempStatistic / ItemMaxStats[i]) < 0.3))) FinalBonusGranted -= 0.6; // Reduce a vitality/life% stat by 50% if less than 50 vitality/less than 40% max possible life% if ((i == Constants.VITALITY && TempStatistic < 50) || (i == Constants.LIFEPERCENT && ((TempStatistic / ItemMaxStats[Constants.LIFEPERCENT]) < 0.4))) FinalBonusGranted -= 0.5; // Grant 20% to any 4 main stat above 150 if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE || i == Constants.VITALITY) && TempStatistic > 150) FinalBonusGranted += 0.2; // Special stat handling stuff for jewelry if (itemType == TrinityItemType.Ring) { // Prime stat gets a 25% bonus if 30 from max possible if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE || i == Constants.VITALITY) && (ItemMaxStats[i] - TempStatistic) < 30.5f) FinalBonusGranted += 0.25; // Within final 5 magic find if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) < 5.2f) FinalBonusGranted += 0.4; // Within final 5 gold find if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) < 5.2f) FinalBonusGranted += 0.35; // Within final 45 life on hit if (i == Constants.LIFEONHIT && (ItemMaxStats[i] - TempStatistic) < 45.2f) FinalBonusGranted += 1.2; } else { // Prime stat gets a 25% bonus if 60 from max possible if ((i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE || i == Constants.VITALITY) && (ItemMaxStats[i] - TempStatistic) < 60.5f) FinalBonusGranted += 0.25; // Within final 10 magic find if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) < 10.2f) FinalBonusGranted += 0.4; // Within final 10 gold find if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) < 10.2f) FinalBonusGranted += 0.35; // Within final 40 life on hit if (i == Constants.LIFEONHIT && (ItemMaxStats[i] - TempStatistic) < 40.2f) FinalBonusGranted += 1.2; } // Within final 50 armor if (i == Constants.ARMOR && (ItemMaxStats[i] - TempStatistic) < 50.2f) { FinalBonusGranted += 0.30; if ((HadStat[Constants.STRENGTH] / ItemMaxStats[Constants.STRENGTH]) > Constants.MinimumThreshold[Constants.STRENGTH]) FinalBonusGranted += 0.30; } // Within final 15 armor if (i == Constants.ARMOR && (ItemMaxStats[i] - TempStatistic) < 15.2f) FinalBonusGranted += 0.20; // More than 2.5 crit chance out if (i == Constants.CRITCHANCE && (ItemMaxStats[i] - TempStatistic) > 5.55f) FinalBonusGranted -= 0.20; // More than 20 crit damage out if (i == Constants.CRITDAMAGE && (ItemMaxStats[i] - TempStatistic) > 19.95f) FinalBonusGranted -= 0.20; // More than 2 attack speed out if (i == Constants.ATTACKSPEED && (ItemMaxStats[i] - TempStatistic) > 1.95f) FinalBonusGranted -= 0.20; // More than 15 gold find out if (i == Constants.GOLDFIND && (ItemMaxStats[i] - TempStatistic) > 15.2f) FinalBonusGranted -= 0.1; // More than 15 magic find out if (i == Constants.MAGICFIND && (ItemMaxStats[i] - TempStatistic) > 15.2f) FinalBonusGranted -= 0.1; // More than 30 all resist out if (i == Constants.ALLRESIST && (ItemMaxStats[i] - TempStatistic) > 20.2f) FinalBonusGranted -= 0.1; // More than 40 all resist out if (i == Constants.ALLRESIST && (ItemMaxStats[i] - TempStatistic) > 30.2f) FinalBonusGranted -= 0.1; } // All the "set to 0" checks now // Disable specific primary stat scoring for certain class-specific item types if ((itemType == TrinityItemType.VoodooMask || itemType == TrinityItemType.WizardHat || itemType == TrinityItemType.Wand || itemType == TrinityItemType.CeremonialKnife || itemType == TrinityItemType.Mojo || itemType == TrinityItemType.Orb) && (i == Constants.STRENGTH || i == Constants.DEXTERITY)) FinalBonusGranted = 0; if ((itemType == TrinityItemType.Quiver || itemType == TrinityItemType.HandCrossbow || itemType == TrinityItemType.Cloak || itemType == TrinityItemType.SpiritStone || itemType == TrinityItemType.TwoHandDaibo || itemType == TrinityItemType.FistWeapon) && (i == Constants.STRENGTH || i == Constants.INTELLIGENCE)) FinalBonusGranted = 0; if ((itemType == TrinityItemType.MightyBelt || itemType == TrinityItemType.MightyWeapon || itemType == TrinityItemType.TwoHandMighty) && (i == Constants.DEXTERITY || i == Constants.INTELLIGENCE)) FinalBonusGranted = 0; // Remove unwanted follower stats for specific follower types if (itemType == TrinityItemType.FollowerEnchantress && (i == Constants.STRENGTH || i == Constants.DEXTERITY)) FinalBonusGranted = 0; if (itemType == TrinityItemType.FollowerEnchantress && (i == Constants.INTELLIGENCE || i == Constants.VITALITY)) FinalBonusGranted -= 0.4; if (itemType == TrinityItemType.FollowerScoundrel && (i == Constants.STRENGTH || i == Constants.INTELLIGENCE)) FinalBonusGranted = 0; if (itemType == TrinityItemType.FollowerScoundrel && (i == Constants.DEXTERITY || i == Constants.VITALITY)) FinalBonusGranted -= 0.4; if (itemType == TrinityItemType.FollowerTemplar && (i == Constants.DEXTERITY || i == Constants.INTELLIGENCE)) FinalBonusGranted = 0; if (itemType == TrinityItemType.FollowerTemplar && (i == Constants.STRENGTH || i == Constants.VITALITY)) FinalBonusGranted -= 0.4; // Attack speed is always on a quiver so forget it if ((itemType == TrinityItemType.Quiver) && (i == Constants.ATTACKSPEED)) FinalBonusGranted = 0; // Single resists worth nothing without all-resist if (i == Constants.RANDOMRESIST && (HadStat[Constants.ALLRESIST] / ItemMaxStats[Constants.ALLRESIST]) < Constants.MinimumThreshold[Constants.ALLRESIST]) FinalBonusGranted = 0; if (FinalBonusGranted < 0) FinalBonusGranted = 0; // Grant the final bonus total iTempPoints *= FinalBonusGranted; // If it's a primary stat, log the highest scoring primary... else add these points to the running total if (i == Constants.DEXTERITY || i == Constants.STRENGTH || i == Constants.INTELLIGENCE) { Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "---- +" + iTempPoints.ToString("0") + " (*" + FinalBonusGranted.ToString("0.00") + " multiplier) [MUST BE MAX STAT SCORE TO COUNT]", true); if (iTempPoints > HighestScoringPrimary) { HighestScoringPrimary = iTempPoints; WhichPrimaryIsHighest = i; AmountHighestScoringPrimary = TempStatistic; } } else { Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "---- +" + iTempPoints.ToString("0") + " score (*" + FinalBonusGranted.ToString("0.00") + " multiplier)", true); TotalItemPoints += iTempPoints; } HadPoints[i] = iTempPoints; // For item logs if (i != Constants.DEXTERITY && i != Constants.STRENGTH && i != Constants.INTELLIGENCE) { if (TownRun.ValueItemStatString != "") TownRun.ValueItemStatString += ". "; TownRun.ValueItemStatString += Constants.StatNames[i] + "=" + Math.Round(TempStatistic).ToString(); if (TownRun.JunkItemStatString != "") TownRun.JunkItemStatString += ". "; TownRun.JunkItemStatString += Constants.StatNames[i] + "=" + Math.Round(TempStatistic).ToString(); } } } // Now add on one of the three primary stat scores, whichever was higher if (HighestScoringPrimary > 0) { // Give a 30% of primary-stat-score-possible bonus to the primary scoring if paired with a good amount of life % or vitality if ((HadStat[Constants.VITALITY] / ItemMaxStats[Constants.VITALITY] > (Constants.MinimumThreshold[Constants.VITALITY] + 0.1)) || SafeLifePercentage > 0.85) HighestScoringPrimary += ItemMaxPoints[WhichPrimaryIsHighest] * 0.3; // Reduce a primary a little if there is no vitality or life if ((HadStat[Constants.VITALITY] < 40) || SafeLifePercentage < 0.7) HighestScoringPrimary *= 0.8; TotalItemPoints += HighestScoringPrimary; TownRun.ValueItemStatString = Constants.StatNames[WhichPrimaryIsHighest] + "=" + Math.Round(AmountHighestScoringPrimary).ToString() + ". " + TownRun.ValueItemStatString; TownRun.JunkItemStatString = Constants.StatNames[WhichPrimaryIsHighest] + "=" + Math.Round(AmountHighestScoringPrimary).ToString() + ". " + TownRun.JunkItemStatString; } Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "--- +" + TotalItemPoints.ToString("0") + " total score pre-special reductions. (GlobalMultiplier=" + GlobalMultiplier.ToString("0.000") + ")", true); // Global multiplier TotalItemPoints *= GlobalMultiplier; // 2 handed weapons and ranged weapons lose a large score for low DPS if (baseItemType == TrinityItemBaseType.WeaponRange || baseItemType == TrinityItemBaseType.WeaponTwoHand) { if ((HadStat[Constants.TOTALDPS] / ItemMaxStats[Constants.TOTALDPS]) <= 0.7) TotalItemPoints *= 0.75; } // Weapons should get a nice 15% bonus score for having very high primaries if (baseItemType == TrinityItemBaseType.WeaponRange || baseItemType == TrinityItemBaseType.WeaponOneHand || baseItemType == TrinityItemBaseType.WeaponTwoHand) { if (HighestScoringPrimary > 0 && (HighestScoringPrimary >= ItemMaxPoints[WhichPrimaryIsHighest] * 0.9)) { TotalItemPoints *= 1.15; } // And an extra 15% for a very high vitality if (HadStat[Constants.VITALITY] > 0 && (HadStat[Constants.VITALITY] >= ItemMaxPoints[Constants.VITALITY] * 0.9)) { TotalItemPoints *= 1.15; } // And an extra 15% for a very high life-on-hit if (HadStat[Constants.LIFEONHIT] > 0 && (HadStat[Constants.LIFEONHIT] >= ItemMaxPoints[Constants.LIFEONHIT] * 0.9)) { TotalItemPoints *= 1.15; } } // Shields if (itemType == TrinityItemType.Shield) { // Strength/Dex based shield calculations if (WhichPrimaryIsHighest == Constants.STRENGTH || WhichPrimaryIsHighest == Constants.DEXTERITY) { if (HadStat[Constants.BLOCKCHANCE] < 20) { TotalItemPoints *= 0.7; } else if (HadStat[Constants.BLOCKCHANCE] < 25) { TotalItemPoints *= 0.9; } } // Intelligence/no primary based shields else { if (HadStat[Constants.BLOCKCHANCE] < 28) TotalItemPoints -= HadPoints[Constants.BLOCKCHANCE]; } } // Quivers if (itemType == TrinityItemType.Quiver) { TotalRequirements = 0; if (HadStat[Constants.DEXTERITY] >= 100) TotalRequirements++; else TotalRequirements -= 3; if (HadStat[Constants.DEXTERITY] >= 160) TotalRequirements++; if (HadStat[Constants.DEXTERITY] >= 250) TotalRequirements++; if (HadStat[Constants.ATTACKSPEED] < 14) TotalRequirements -= 2; if (HadStat[Constants.VITALITY] >= 70 || SafeLifePercentage >= 0.85) TotalRequirements++; else TotalRequirements--; if (HadStat[Constants.VITALITY] >= 260) TotalRequirements++; if (HadStat[Constants.MAXDISCIPLINE] >= 8) TotalRequirements++; if (HadStat[Constants.MAXDISCIPLINE] >= 10) TotalRequirements++; if (HadStat[Constants.SOCKETS] >= 1) TotalRequirements++; if (HadStat[Constants.CRITCHANCE] >= 6) TotalRequirements++; if (HadStat[Constants.CRITCHANCE] >= 8) TotalRequirements++; if (HadStat[Constants.LIFEPERCENT] >= 8) TotalRequirements++; if (HadStat[Constants.MAGICFIND] >= 18) TotalRequirements++; if (TotalRequirements < 4) TotalItemPoints *= 0.4; else if (TotalRequirements < 5) TotalItemPoints *= 0.5; if (TotalRequirements >= 7) TotalItemPoints *= 1.2; } // Mojos and Sources if (itemType == TrinityItemType.Orb || itemType == TrinityItemType.Mojo) { TotalRequirements = 0; if (HadStat[Constants.INTELLIGENCE] >= 100) TotalRequirements++; else if (HadStat[Constants.INTELLIGENCE] < 80) TotalRequirements -= 3; else if (HadStat[Constants.INTELLIGENCE] < 100) TotalRequirements -= 1; if (HadStat[Constants.INTELLIGENCE] >= 160) TotalRequirements++; if (HadStat[Constants.MAXDAMAGE] >= 250) TotalRequirements++; else TotalRequirements -= 2; if (HadStat[Constants.MAXDAMAGE] >= 340) TotalRequirements++; if (HadStat[Constants.MINDAMAGE] >= 50) TotalRequirements++; else TotalRequirements--; if (HadStat[Constants.MINDAMAGE] >= 85) TotalRequirements++; if (HadStat[Constants.VITALITY] >= 70) TotalRequirements++; if (HadStat[Constants.SOCKETS] >= 1) TotalRequirements++; if (HadStat[Constants.CRITCHANCE] >= 6) TotalRequirements++; if (HadStat[Constants.CRITCHANCE] >= 8) TotalRequirements++; if (HadStat[Constants.LIFEPERCENT] >= 8) TotalRequirements++; if (HadStat[Constants.MAGICFIND] >= 15) TotalRequirements++; if (HadStat[Constants.MAXMANA] >= 60) TotalRequirements++; if (HadStat[Constants.ARCANECRIT] >= 8) TotalRequirements++; if (HadStat[Constants.ARCANECRIT] >= 10) TotalRequirements++; if (TotalRequirements < 4) TotalItemPoints *= 0.4; else if (TotalRequirements < 5) TotalItemPoints *= 0.5; if (TotalRequirements >= 8) TotalItemPoints *= 1.2; } // Chests/cloaks/pants without a socket lose 17% of total score if ((itemType == TrinityItemType.Chest || itemType == TrinityItemType.Cloak || itemType == TrinityItemType.Legs) && HadStat[Constants.SOCKETS] == 0) TotalItemPoints *= 0.83; // Boots with no movement speed get reduced score if ((itemType == TrinityItemType.Boots) && HadStat[Constants.MOVEMENTSPEED] <= 6) TotalItemPoints *= 0.75; // Helmets if (itemType == TrinityItemType.Helm || itemType == TrinityItemType.WizardHat || itemType == TrinityItemType.VoodooMask || itemType == TrinityItemType.SpiritStone) { // Helmets without a socket lose 20% of total score, and most of any MF/GF bonus if (HadStat[Constants.SOCKETS] == 0) { TotalItemPoints *= 0.8; if (HadStat[Constants.MAGICFIND] > 0 || HadStat[Constants.GOLDFIND] > 0) { if (HadStat[Constants.MAGICFIND] > 0 && HadStat[Constants.GOLDFIND] > 0) TotalItemPoints -= ((HadPoints[Constants.MAGICFIND] * 0.25) + (HadPoints[Constants.GOLDFIND] * 0.25)); else TotalItemPoints -= ((HadPoints[Constants.MAGICFIND] * 0.65) + (HadPoints[Constants.GOLDFIND] * 0.65)); } } } Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "--- +" + TotalItemPoints.ToString("0") + " total score after special reductions. (TotalRequirements=" + TotalRequirements + ")", true); GetBestFinalPoints(itemType); TotalItemPoints *= BestFinalBonus; Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "TOTAL: " + TotalItemPoints.ToString("0") + "(Final Bonus=" + BestFinalBonus.ToString("0.00") + ")"); Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, ""); return Math.Round(TotalItemPoints); }
internal static bool IsWeaponArmorJewlery(CachedACDItem thisitem) { return (thisitem.DBBaseType == Zeta.Game.Internals.Actors.ItemBaseType.Armor || thisitem.DBBaseType == Zeta.Game.Internals.Actors.ItemBaseType.Jewelry || thisitem.DBBaseType == Zeta.Game.Internals.Actors.ItemBaseType.Weapon); }
/// <summary> /// Output test scores for everything in the backpack /// </summary> internal static void TestScoring() { using (new PerformanceLogger("TestScoring")) { using (var helper = new Helpers.ZetaCacheHelper()) { try { if (TownRun.TestingBackpack) return; TownRun.TestingBackpack = true; //ZetaDia.Actors.Update(); if (ZetaDia.Actors.Me == null) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Error testing scores - not in game world?"); return; } if (ZetaDia.IsInGame && !ZetaDia.IsLoadingWorld) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "===== Outputting Test Scores ====="); foreach (ACDItem item in ZetaDia.Me.Inventory.Backpack) { if (item.BaseAddress == IntPtr.Zero) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "GSError: Diablo 3 memory read error, or item became invalid [TestScore-1]"); } else { CachedACDItem cItem = new CachedACDItem(item, item.InternalName, item.Name, item.Level, item.ItemQualityLevel, item.Gold, item.GameBalanceId, item.DynamicId, item.Stats.WeaponDamagePerSecond, item.IsOneHand, item.IsTwoHand, item.DyeType, item.ItemType, item.ItemBaseType, item.FollowerSpecialType, item.IsUnidentified, item.ItemStackQuantity, item.Stats); bool bShouldStashTest = TrinityItemManager.Current.ShouldStashItem(item); Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, bShouldStashTest ? "* KEEP *" : "-- TRASH --"); } } Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "===== Finished Test Score Outputs ====="); //Logger.Log(TrinityLogLevel.Normal, LogCategory.UserInformation, "Note: See bad scores? Wrong item types? Known DB bug - restart DB before using the test button!"); } else { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Error testing scores - not in game world?"); } TownRun.TestingBackpack = false; } catch (Exception ex) { Logger.LogNormal("Exception in TestScoring(): {0}", ex); TownRun.TestingBackpack = false; } } } }
/// <summary> /// Log the nice items we found and stashed /// </summary> internal static void LogGoodItems(CachedACDItem acdItem, GItemBaseType itemBaseType, GItemType itemType, double itemValue) { FileStream LogStream = null; try { string filePath = Path.Combine(FileManager.LoggingPath, "StashLog - " + Trinity.Player.ActorClass.ToString() + ".log"); LogStream = File.Open(filePath, FileMode.Append, FileAccess.Write, FileShare.Read); //TODO : Change File Log writing using (StreamWriter LogWriter = new StreamWriter(LogStream)) { if (!_loggedAnythingThisStash) { _loggedAnythingThisStash = true; LogWriter.WriteLine(DateTime.Now.ToString() + ":"); LogWriter.WriteLine("===================="); } string sLegendaryString = ""; bool shouldSendNotifications = false; if (acdItem.Quality >= ItemQuality.Legendary) { if (!Trinity.Settings.Notification.LegendaryScoring) { shouldSendNotifications = true; } else if (Trinity.Settings.Notification.LegendaryScoring && Trinity.CheckScoreForNotification(itemBaseType, itemValue)) { shouldSendNotifications = true; } if (shouldSendNotifications) { NotificationManager.AddNotificationToQueue(acdItem.RealName + " [" + itemType.ToString() + "] (Score=" + itemValue.ToString() + ". " + ValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new legendary!", ProwlNotificationPriority.Emergency); } sLegendaryString = " {legendary item}"; // Change made by bombastic Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+"); Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "+ Name: {0} ({1})", acdItem.RealName, itemType); Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "+ Score: {0:0}", itemValue); Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "+ Attributes: {0}", ValueItemStatString); Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); } else { // Check for non-legendary notifications shouldSendNotifications = Trinity.CheckScoreForNotification(itemBaseType, itemValue); if (shouldSendNotifications) { NotificationManager.AddNotificationToQueue(acdItem.RealName + " [" + itemType.ToString() + "] (Score=" + itemValue.ToString() + ". " + ValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new item!", ProwlNotificationPriority.Emergency); } } if (shouldSendNotifications) { NotificationManager.EmailMessage.AppendLine(itemBaseType.ToString() + " - " + itemType.ToString() + " '" + acdItem.RealName + "'. Score = " + Math.Round(itemValue).ToString() + sLegendaryString) .AppendLine(" " + ValueItemStatString) .AppendLine(); } LogWriter.WriteLine(itemBaseType.ToString() + " - " + itemType.ToString() + " '" + acdItem.RealName + "'. Score = " + Math.Round(itemValue).ToString() + sLegendaryString); LogWriter.WriteLine(" " + ValueItemStatString); LogWriter.WriteLine(""); } LogStream.Close(); } catch (IOException) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Fatal Error: File access error for stash log file."); if (LogStream != null) { LogStream.Close(); } } }
private bool TrinitySalvage(ACDItem item) { CachedACDItem cItem = CachedACDItem.GetCachedItem(item); if (cItem.AcdItem.IsVendorBought) { return(false); } // Vanity Items if (DataDictionary.VanityItems.Any(i => item.InternalName.StartsWith(i))) { return(false); } GItemType trinityItemType = Trinity.DetermineItemType(cItem.InternalName, cItem.DBItemType, cItem.FollowerType); GItemBaseType trinityItemBaseType = Trinity.DetermineBaseType(trinityItemType); // Take Salvage Option corresponding to ItemLevel SalvageOption salvageOption = GetSalvageOption(cItem.Quality); // Stashing Whites if (Trinity.Settings.Loot.TownRun.StashWhites && cItem.Quality < ItemQuality.Magic1) { return(false); } // Stashing Blues if (Trinity.Settings.Loot.TownRun.StashBlues && cItem.Quality > ItemQuality.Superior && cItem.Quality < ItemQuality.Rare4) { return(false); } if (cItem.Quality >= ItemQuality.Legendary && salvageOption == SalvageOption.InfernoOnly && cItem.Level >= 60) { return(true); } switch (trinityItemBaseType) { case GItemBaseType.WeaponRange: case GItemBaseType.WeaponOneHand: case GItemBaseType.WeaponTwoHand: case GItemBaseType.Armor: case GItemBaseType.Offhand: return((cItem.Level >= 61 && salvageOption == SalvageOption.InfernoOnly) || salvageOption == SalvageOption.All); case GItemBaseType.Jewelry: return((cItem.Level >= 59 && salvageOption == SalvageOption.InfernoOnly) || salvageOption == SalvageOption.All); case GItemBaseType.FollowerItem: return((cItem.Level >= 60 && salvageOption == SalvageOption.InfernoOnly) || salvageOption == SalvageOption.All); case GItemBaseType.Gem: case GItemBaseType.Misc: case GItemBaseType.Unknown: return(false); default: return(false); } }
public static bool GetIsSalvageable(CachedACDItem cItem) { if (!cItem.IsEquipment) return false; if (cItem.AcdItem.IsVendorBought) return false; return true; }