//returns all valid mods for the given base item template, covering all possible influences public static IDictionary <PoEModData, int> FindBaseValidMods(PoEBaseItemData baseitem, ICollection <PoEModData> db, bool ignoredomain = false) { IDictionary <PoEModData, int> mods = new Dictionary <PoEModData, int>(); if (baseitem == null) { return(mods); } //extend tags to allow mods of any influence and special mods enabled by convoking wand's implicit ISet <string> extendedtags = new HashSet <string>(baseitem.tags) { "weapon_can_roll_minion_modifiers" }; foreach (ItemInfluence inf in Enum.GetValues(typeof(ItemInfluence))) { extendedtags.Add(baseitem.item_class_properties[EnumConverter.InfToTag(inf)]); } foreach (string s in CraftingDatabase.afflictionmods) { extendedtags.Add(s); } foreach (PoEModData mod in db) { if (ignoredomain || mod.domain == baseitem.domain) { int w = CalcGenWeight(mod, extendedtags); if (w > 0) { mods.Add(mod, w); } } } return(mods); }
public void GenerateName() { PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[SourceData]; ItemName = itemtemplate.name; if (Rarity == ItemRarity.Rare) { ItemName = GenRareName() + "\n" + itemtemplate.name; } else if (Rarity == ItemRarity.Magic) { foreach (ModCraft m in LiveMods) { PoEModData modtemplate = CraftingDatabase.AllMods[m.SourceData]; if (modtemplate.generation_type == ModLogic.Prefix) { ItemName = modtemplate.name + " " + ItemName; } else if (modtemplate.generation_type == ModLogic.Suffix) { ItemName = ItemName + " " + modtemplate.name; } } } }
public ItemCraft(PoEBaseItemData data, int level = 100, ISet <ItemInfluence> influences = null) { SourceData = data.key; _basequality = DefaultQuality; QualityType = null; ItemLevel = level; Rarity = ItemRarity.Normal; ItemName = data.name; LiveTags = new HashSet <string>(data.tags); if (influences != null) { foreach (ItemInfluence inf in influences) { string s = data.item_class_properties[EnumConverter.InfToTag(inf)]; if (s != null) { LiveTags.Add(s); } } } LiveMods = new List <ModCraft>(); LiveImplicits = new List <ModCraft>(); LiveEnchantments = new List <ModCraft>(); foreach (string s in data.implicits) { AddImplicit(CraftingDatabase.AllMods[s]); } }
private void PostCraftButton_Click(object sender, RoutedEventArgs e) { BigBox.Text = ""; if (Bench.BenchItem == null) { BigBox.Text = "Bench is empty"; return; } PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[Bench.BenchItem.SourceData]; PostCraftDialog d = new PostCraftDialog(ModLogic.FindValidBenchMods(itemtemplate, CraftingDatabase.BenchOptions, CraftingDatabase.AllMods), Bench.PostRoll) { Owner = this }; bool?res = d.ShowDialog(); if (!res.HasValue || !res.Value) { return; } PostRollOptions ops = d.GetPostRollOptions(); if (!ops.Maximize && ops.TryCrafts.Count == 0) { PostCraftButton.ClearValue(Button.BackgroundProperty); } else { PostCraftButton.Background = Brushes.Green; } Bench.PostRoll = ops; }
public static ItemProperties ParseProperties(ItemCraft item) { IDictionary <string, int> mods = new Dictionary <string, int>(); IList <string> keys = new List <string>() { "arp", "arf", "evp", "evf", "esp", "esf", "blf", "dp", "mindf", "maxdf", "crp", "asp", "qf" }; //all possible property modifiers foreach (string s in keys) { mods.Add(s, 0); } foreach (ModCraft m in item.LiveMods) { ParsePropMods(m, mods); } PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[item.SourceData]; int qual = item.BaseQuality + mods["qf"]; //zero out quality if item class is mismatched if (CraftingDatabase.ItemClassNoQuality.Contains(itemtemplate.item_class)) { qual = 0; } else if (CraftingDatabase.ItemClassCatalyst.Contains(itemtemplate.item_class)) { if (item.QualityType == null) { qual = 0; } } else { if (item.QualityType != null) { qual = 0; } } int propqual = item.QualityType == null ? qual : 0; return(new ItemProperties() { quality = qual, armour = (itemtemplate.properties.armour + mods["arf"]) * (100 + mods["arp"] + propqual) / 100, evasion = (itemtemplate.properties.evasion + mods["evf"]) * (100 + mods["evp"] + propqual) / 100, energy_shield = (itemtemplate.properties.energy_shield + mods["esf"]) * (100 + mods["esp"] + propqual) / 100, block = itemtemplate.properties.block + mods["blf"], physical_damage_min = (itemtemplate.properties.physical_damage_min + mods["mindf"]) * (100 + mods["dp"] + propqual) / 100, physical_damage_max = (itemtemplate.properties.physical_damage_max + mods["maxdf"]) * (100 + mods["dp"] + propqual) / 100, critical_strike_chance = itemtemplate.properties.critical_strike_chance * (100 + mods["crp"]) / 100, attack_time = itemtemplate.properties.attack_time * 100 / (100 + mods["asp"]) }); }
public ISet <ItemInfluence> GetInfluences() { ISet <ItemInfluence> infs = new HashSet <ItemInfluence>(); PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[SourceData]; foreach (ItemInfluence inf in Enum.GetValues(typeof(ItemInfluence))) { if (LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(inf)])) { infs.Add(inf); } } return(infs); }
private bool NameFilter(object item) { if (string.IsNullOrEmpty(ItemFilter.Text)) { return(true); } else { KeyValuePair <string, PoEBaseItemData>?kv = item as KeyValuePair <string, PoEBaseItemData>?; PoEBaseItemData d = kv?.Value; if (d == null) { return(false); } return(d.name.IndexOf(ItemFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0); } }
public static IDictionary <PoEModData, int> FindValidEnchantments(PoEBaseItemData baseitem, IDictionary <string, PoEModData> db) { IDictionary <PoEModData, int> mods = new Dictionary <PoEModData, int>(); if (baseitem == null) { return(mods); } foreach (PoEModData mod in db.Values) { int w = CalcGenWeight(mod, baseitem.tags); if (w > 0) { mods.Add(mod, w); } } return(mods); }
public void UpdateEnchantments() { if (Bench == null || Bench.BenchItem == null) { EnchantmentsView.ItemsSource = new Dictionary <PoEModData, int>(); //EnchantmentsDisplay.UpdateData(new Dictionary<PoEModData, int>()); return; } PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[Bench.BenchItem.SourceData]; IDictionary <PoEModData, int> enchs = ModLogic.FindValidEnchantments(itemtemplate, CraftingDatabase.Enchantments); IDictionary <PoEModData, object> mods = new Dictionary <PoEModData, object>(); foreach (PoEModData d in enchs.Keys) { mods.Add(d, enchs[d]); } CollectionViewSource.GetDefaultView(mods).Filter = FilterMods; EnchantmentsView.ItemsSource = mods; }
private void ItemNameView_Select(object sender, RoutedEventArgs e) { KeyValuePair <string, PoEBaseItemData>?kv = (sender as ListView).SelectedItem as KeyValuePair <string, PoEBaseItemData>?; PoEBaseItemData d = kv?.Value; if (d != null) { SelectedBase = d; OKButton.IsEnabled = true; ItemInfoBox.Text = JsonSerializer.Serialize(d, new JsonSerializerOptions() { WriteIndented = true }); } else { OKButton.IsEnabled = false; } }
public int GetAffixLimit(bool ignorerarity = false) { PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[SourceData]; if (ignorerarity) { return(itemtemplate.item_class.Contains("Jewel") ? 2 : 3); } switch (Rarity) { case ItemRarity.Rare: return(itemtemplate.item_class.Contains("Jewel") ? 2 : 3); case ItemRarity.Magic: return(1); default: return(0); } }
public void UpdateCrafts() { if (Bench == null || Bench.BenchItem == null) { CraftedModsDisplay.UpdateData(new Dictionary <PoEModData, object>()); SpecialModsDisplay.UpdateData(new Dictionary <PoEModData, object>()); return; } PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[Bench.BenchItem.SourceData]; IDictionary <PoEModData, IDictionary <string, int> > results = ModLogic.FindValidBenchMods(itemtemplate, CraftingDatabase.BenchOptions, CraftingDatabase.AllMods); Dictionary <PoEModData, object> mods = new Dictionary <PoEModData, object>(); foreach (PoEModData d in results.Keys) { mods.Add(d, results[d]); } CraftedModsDisplay.UpdateData(mods); IDictionary <PoEModData, object> specresults = new Dictionary <PoEModData, object>(); if (CraftingDatabase.DelveDroponlyMods.ContainsKey(itemtemplate.item_class)) { foreach (string modid in CraftingDatabase.DelveDroponlyMods[itemtemplate.item_class]) { if (CraftingDatabase.AllMods.ContainsKey(modid)) { specresults.Add(CraftingDatabase.AllMods[modid], "Drop-only: Delve"); } } } if (CraftingDatabase.IncursionDroponlyMods.ContainsKey(itemtemplate.item_class)) { foreach (string modid in CraftingDatabase.IncursionDroponlyMods[itemtemplate.item_class]) { if (CraftingDatabase.AllMods.ContainsKey(modid)) { specresults.Add(CraftingDatabase.AllMods[modid], "Drop-only: Incursion"); } } } SpecialModsDisplay.UpdateData(specresults); }
private string GenRareName() { PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[SourceData]; if (namesuffix.Keys.Contains(itemtemplate.item_class)) { string key; if (itemtemplate.item_class == "Shield" && itemtemplate.properties.energy_shield > 0 && itemtemplate.properties.armour == 0 && itemtemplate.properties.evasion == 0) { key = "Spirit Shield"; } else { key = itemtemplate.item_class; } IList <string> suf = namesuffix[key]; return(nameprefix[RNG.Gen.Next(nameprefix.Count)] + " " + suf[RNG.Gen.Next(suf.Count)]); } else { return(fnames[RNG.Gen.Next(fnames.Count)] + " " + snames[RNG.Gen.Next(snames.Count)]); } }
public string ApplyCurrency(PoECurrencyData currency, int tries = 1) { if (BenchItem == null) { return("Bench is empty"); } string c = currency.name; string res; switch (c) { case "Chaos Orb": if (BenchItem.Rarity != ItemRarity.Rare) { return("Invalid item rarity for selected currency"); } DoReroll(null, BaseValidMods, ItemRarity.Rare, false, tries); break; case "Orb of Alteration": if (BenchItem.Rarity != ItemRarity.Magic) { return("Invalid item rarity for selected currency"); } DoReroll(null, BaseValidMods, ItemRarity.Magic, false, tries); break; case "Orb of Alchemy": if (BenchItem.Rarity != ItemRarity.Normal) { return("Invalid item rarity for selected currency"); } DoReroll(null, BaseValidMods, ItemRarity.Rare, false, tries); break; case "Orb of Transmutation": if (BenchItem.Rarity != ItemRarity.Normal) { return("Invalid item rarity for selected currency"); } DoReroll(null, BaseValidMods, ItemRarity.Magic, false, tries); break; case "Exalted Orb": if (BenchItem.Rarity != ItemRarity.Rare) { return("Invalid item rarity for selected currency"); } if (BenchItem.LiveMods.Count >= 2 * BenchItem.GetAffixLimit()) { return("Item cannot have another mod"); } res = DoAddMod(ItemRarity.Rare, false, tries, 20) ? null : "Item has no valid rollable mods"; if (res != null) { return(res); } break; case "Regal Orb": if (BenchItem.Rarity != ItemRarity.Magic) { return("Invalid item rarity for selected currency"); } DoAddMod(ItemRarity.Rare, true, tries, 5); break; case "Orb of Augmentation": if (BenchItem.Rarity != ItemRarity.Magic) { return("Invalid item rarity for selected currency"); } if (BenchItem.LiveMods.Count >= 2 * BenchItem.GetAffixLimit()) { return("Item cannot have another mod"); } DoAddMod(ItemRarity.Magic, true, tries, 2); break; case "Redeemer's Exalted Orb": res = ApplyInfExalt(ItemInfluence.Redeemer, tries); if (res != null) { return(res); } break; case "Hunter's Exalted Orb": res = ApplyInfExalt(ItemInfluence.Hunter, tries); if (res != null) { return(res); } break; case "Warlord's Exalted Orb": res = ApplyInfExalt(ItemInfluence.Warlord, tries); if (res != null) { return(res); } break; case "Crusader's Exalted Orb": res = ApplyInfExalt(ItemInfluence.Crusader, tries); if (res != null) { return(res); } break; case "Orb of Annulment": if (BenchItem.Rarity == ItemRarity.Normal) { return("Invalid item rarity for selected currency"); } DoCurrencyRolls((item) => { item.RemoveRandomMod(); if (item.QualityType != null) { item.BaseQuality -= 20; } }, tries); break; case "Divine Orb": if (BenchItem.Rarity == ItemRarity.Normal) { return("Invalid item rarity for selected currency"); } DoCurrencyRolls((item) => { item.RerollExplicits(); }, tries); break; case "Blessed Orb": DoCurrencyRolls((item) => { item.RerollImplicits(); }, tries); break; case "Orb of Scouring": if (BenchItem.Rarity == ItemRarity.Normal) { return("Invalid item rarity for selected currency"); } DoCurrencyRolls((item) => { item.ClearMods(); item.Rarity = item.GetMinimumRarity(); item.GenerateName(); }, tries); break; case "Remove Crafted Mods": DoCurrencyRolls((item) => { item.ClearCraftedMods(); }, tries); break; case "Do Nothing": IDictionary <PoEModData, int> validatedpool = ModLogic.FindValidMods(BenchItem, BaseValidMods); DoCurrencyRolls((item) => { DoPostRoll(item, new Dictionary <PoEModData, int>(validatedpool)); }, tries); break; case "Abrasive Catalyst": case "Fertile Catalyst": case "Imbued Catalyst": case "Intrinsic Catalyst": case "Prismatic Catalyst": case "Tempering Catalyst": case "Turbulent Catalyst": PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[BenchItem.SourceData]; if (!CraftingDatabase.ItemClassCatalyst.Contains(itemtemplate.item_class)) { return("Invalid item type for catalysts"); } if (BenchItem.QualityType == c && BenchItem.BaseQuality >= 20) { return("Item already has max catalyst quality"); } DoCurrencyRolls((item) => { item.ApplyCatalyst(c); }, tries); break; default: return("Unrecognized currency selected"); } if (tries == 1) { string currencykey = currency.key; if (currencykey == "RemoveCraftedMods") { currencykey = "Metadata/Items/Currency/CurrencyConvertToNormal"; } if (currencykey != "DoNothing") { TallyCurrency(currency.key, 1); } } return(null); }
//Adds a mod directly to target item (or bench item) if legal; updates costs if provided; modifies mod pool accordingly if provided public string ForceAddMod(PoEModData mod, ItemCraft target = null, IDictionary <string, int> costs = null, IDictionary <PoEModData, int> pool = null) { target = target ?? BenchItem; if (mod.generation_type == ModLogic.Prefix) { if (target.ModCountByType(ModLogic.Prefix) >= target.GetAffixLimit(true)) { return("Item cannot have another prefix"); } } else { if (target.ModCountByType(ModLogic.Suffix) >= target.GetAffixLimit(true)) { return("Item cannot have another suffix"); } } foreach (ModCraft livemod in target.LiveMods) { PoEModData modtemplate = CraftingDatabase.AllMods[livemod.SourceData]; if (modtemplate.group == mod.group) { return("Item already has a mod in this mod group"); } } if (mod.domain == "crafted") //if crafted check the specific cases of quality craft on item w/ quality mod, and conversion glove mod { if (target.LiveTags.Contains("local_item_quality")) { foreach (PoEModWeight w in mod.spawn_weights) { if (w.tag == "local_item_quality" && w.weight == 0) { return("Cannot craft quality on an item with another quality mod"); } } } if (target.LiveTags.Contains("has_physical_conversion_mod") && mod.adds_tags.Contains("has_physical_conversion_mod")) { return("Item already has a physical conversion mod"); } //This check turned out to the too restrictive. Many crafted mods have 0 spawn weight on item types they should be craftable on. //if (ModLogic.CalcGenWeight(mod, target.LiveTags) <= 0) // return "Invalid craft for current item and/or item mods"; } PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[target.SourceData]; //if it's an influenced mod, add the appropriate tag foreach (ItemInfluence inf in Enum.GetValues(typeof(ItemInfluence))) { if (EnumConverter.InfToNames(inf).Contains(mod.name)) { string inftag = itemtemplate.item_class_properties[EnumConverter.InfToTag((ItemInfluence)inf)]; if (inftag != null) { target.LiveTags.Add(inftag); } break; } } //if a mod pool is provided, updated it accordingly, otherwise just add the mod directly if (pool != null) { ModLogic.AddModAndTrim(target, pool, mod); } else { target.AddMod(mod); } ItemRarity newrarity = target.GetMinimumRarity(); if (newrarity > target.Rarity) { target.Rarity = newrarity; } if (costs != null && target == BenchItem) { foreach (string s in costs.Keys) { TallyCurrency(s, costs[s]); } } return(null); }
public void UpdatePreviews() { if (Bench == null || Bench.BenchItem == null || Currency == null) { WeightedModsDisplay.UpdateData(new Dictionary <PoEModData, object>()); return; } ItemCraft itemcopy = Bench.BenchItem.Copy(); RollOptions ops = new RollOptions(); IDictionary <PoEModData, int> extendedpool = new Dictionary <PoEModData, int>(Bench.BaseValidMods); PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[itemcopy.SourceData]; //Shaper = null/invalid; inf and temp tags used for the 4 conquerors' exalts ItemInfluence inf = ItemInfluence.Shaper; IList <PoEModData> forcedmods = new List <PoEModData>(); int cesscount = 0; object c = Currency.GetSelected(); if (c is PoEEssenceData e) { string itemclass = itemtemplate.item_class; if (itemclass == "Rune Dagger") { itemclass = "Dagger"; } if (itemclass == "Warstaff") { itemclass = "Staff"; } if (e.mods.Keys.Contains(itemclass)) { forcedmods.Add(CraftingDatabase.CoreMods[e.mods[itemclass]]); } ops.ILvlCap = e.item_level_restriction ?? 200; itemcopy.ClearCraftedMods(); itemcopy.ClearMods(); } else if (c is PoECurrencyData) { string currency = ((PoECurrencyData)c).name; if (itemcopy.GetInfluences().Count == 0) { if (currency == "Redeemer's Exalted Orb") { inf = ItemInfluence.Redeemer; } else if (currency == "Hunter's Exalted Orb") { inf = ItemInfluence.Hunter; } else if (currency == "Warlord's Exalted Orb") { inf = ItemInfluence.Warlord; } else if (currency == "Crusader's Exalted Orb") { inf = ItemInfluence.Crusader; } if (inf != ItemInfluence.Shaper) { string tag = itemtemplate.item_class_properties[Utils.EnumConverter.InfToTag(inf)]; if (tag != null) //temporarily add influence tag { itemcopy.LiveTags.Add(tag); } } } if (inf == ItemInfluence.Shaper) //if selected item isn't a conq exalt { //if it's a reroll currency, preview as if the item has been scoured if (currency == "Chaos Orb" || currency == "Orb of Alchemy" || currency == "Orb of Transmutation" || currency == "Orb of Alteration") { itemcopy.ClearMods(); } } } else if (c != null) { IList <PoEFossilData> fossils = ((System.Collections.IList)c).Cast <PoEFossilData>().ToList(); ISet <IList <PoEModWeight> > modweightgroups = new HashSet <IList <PoEModWeight> >(); foreach (PoEFossilData fossil in fossils) { foreach (string t in fossil.added_mods) { if (!extendedpool.ContainsKey(CraftingDatabase.AllMods[t])) { extendedpool.Add(CraftingDatabase.AllMods[t], 0); } } foreach (string t in fossil.forced_mods) { forcedmods.Add(CraftingDatabase.AllMods[t]); } forcedmods = new List <PoEModData>(ModLogic.FindBaseValidMods(itemtemplate, forcedmods, true).Keys); if (fossil.corrupted_essence_chance > 0) { cesscount += fossil.corrupted_essence_chance; } modweightgroups.Add(fossil.negative_mod_weights); modweightgroups.Add(fossil.positive_mod_weights); } ops.ModWeightGroups = modweightgroups; itemcopy.ClearCraftedMods(); itemcopy.ClearMods(); } foreach (PoEModData d in forcedmods) { itemcopy.AddMod(d); } IDictionary <PoEModData, int> validmods = ModLogic.FindValidMods(itemcopy, extendedpool, true, ops); if (inf != ItemInfluence.Shaper) //if a conq exalt is selected, only show influenced mods { validmods = ModLogic.FilterForInfluence(validmods, inf); } IDictionary <PoEModData, object> mods = new Dictionary <PoEModData, object>(); foreach (PoEModData d in validmods.Keys) { mods.Add(d, validmods[d]); } foreach (PoEModData d in forcedmods) { mods.Add(d, "Always"); } if (cesscount > 0) { IDictionary <PoEModData, int> glyphicmods = ModLogic.FindGlyphicMods(itemcopy, ops.ModWeightGroups); if (glyphicmods.Count > 0) { int weightsum = 0; foreach (PoEModData d in glyphicmods.Keys) { weightsum += glyphicmods[d]; } foreach (PoEModData d in glyphicmods.Keys) { mods.Add(d, "Special: " + ((double)cesscount / 100).ToString("0.#") + " x " + ((double)glyphicmods[d] * 100 / weightsum).ToString("N0") + "%"); } } } WeightedModsDisplay.UpdateData(mods); }
public string GetClipboardString() { string s = "Rarity: "; if (Rarity == ItemRarity.Rare) { s += "Rare"; } else if (Rarity == ItemRarity.Magic) { s += "Magic"; } else { s += "Normal"; } s += "\n" + ItemName; s += "\n--------"; PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[SourceData]; s += "\n" + itemtemplate.item_class; ItemProperties props = ItemParser.ParseProperties(this); int q = props.quality; if (q > 0) { string t; switch (QualityType) { case "Prismatic Catalyst": t = "Quality (Resistance Modifiers): "; break; case "Fertile Catalyst": t = "Quality (Life and Mana Modifiers): "; break; case "Intrinsic Catalyst": t = "Quality (Attribute Modifiers): "; break; case "Tempering Catalyst": t = "Quality (Defence Modifiers): "; break; case "Abrasive Catalyst": t = "Quality (Attack Modifiers): "; break; case "Imbued Catalyst": t = "Quality (Caster Modifiers): "; break; case "Turbulent Catalyst": t = "Quality (Elemental Damage): "; break; default: t = "Quality: "; break; } s += "\n" + t + q + "%"; } if (props.block > 0) { s += "\nChance to Block: " + props.block + "%"; } if (props.armour > 0) { s += "\nArmour: " + props.armour; } if (props.evasion > 0) { s += "\nEvasion: " + props.evasion; } if (props.energy_shield > 0) { s += "\nEnergy Shield: " + props.energy_shield; } if (props.physical_damage_max > 0) { s += "\nPhysical Damage: " + props.physical_damage_min + "-" + props.physical_damage_max; } if (props.critical_strike_chance > 0) { s += "\nCritical Strike Chance: " + ((double)props.critical_strike_chance / 100).ToString("N2") + "%"; } if (props.attack_time > 0) { s += "\nAttacks per Second: " + ((double)1000 / props.attack_time).ToString("N2"); } s += "\n--------"; s += "\nItem Level: " + ItemLevel; if (LiveImplicits.Count > 0) { s += "\n--------"; foreach (ModCraft m in LiveImplicits) { s += "\n" + m; } } if (LiveMods.Count > 0) { s += "\n--------"; foreach (ModCraft m in LiveMods) { s += "\n" + m; } } s += "\n"; return(s); }
public string ApplyFossils(IList <PoEFossilData> fossils, int tries = 1) { if (BenchItem == null) { return("Bench is empty"); } if (BenchItem.Rarity == ItemRarity.Magic) { return("Cannot apply fossils to a magic item"); } ISet <IList <PoEModWeight> > modweightgroups = new HashSet <IList <PoEModWeight> >(); ISet <PoEModData> fossilmods = new HashSet <PoEModData>(); //forced mods from fossils int cesscount = 0; //glyphic/tangled corrupted mod count IDictionary <PoEModData, int> extendedpool = new Dictionary <PoEModData, int>(BaseValidMods); //extra rollable mods PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[BenchItem.SourceData]; foreach (PoEFossilData fossil in fossils) { foreach (string t in fossil.forbidden_tags) { if (BenchItem.LiveTags.Contains(t)) { return("Invalid item class for one or more selected fossils"); } } if (fossil.allowed_tags.Count > 0) { bool allowed = false; foreach (string t in fossil.allowed_tags) { if (BenchItem.LiveTags.Contains(t)) { allowed = true; break; } } if (!allowed) { return("Invalid item class for one or more selected fossils"); } } foreach (string t in fossil.added_mods) { if (!extendedpool.ContainsKey(CraftingDatabase.AllMods[t])) { extendedpool.Add(CraftingDatabase.AllMods[t], 0); } } foreach (string t in fossil.forced_mods) { fossilmods.Add(CraftingDatabase.AllMods[t]); } if (fossil.corrupted_essence_chance > 0) { cesscount += fossil.corrupted_essence_chance; } modweightgroups.Add(fossil.negative_mod_weights); modweightgroups.Add(fossil.positive_mod_weights); } IList <PoEModData> forcedmods = new List <PoEModData>(ModLogic.FindBaseValidMods(itemtemplate, fossilmods, true).Keys); //filter by spawn_weight first int fprefix = 0; int fsuffix = 0; foreach (PoEModData m in forcedmods) { if (m.generation_type == ModLogic.Prefix) { fprefix++; } else { fsuffix++; } } if (BenchItem.ModCountByType(ModLogic.Prefix, true) + fprefix > BenchItem.GetAffixLimit(true)) { return("Item does not have space for forced prefix"); } else if (BenchItem.ModCountByType(ModLogic.Suffix, true) + fsuffix > BenchItem.GetAffixLimit(true)) { return("Item does not have space for forced suffix"); } if (cesscount > 0) { //check that the item can roll a corrupted ess mod ItemCraft clone = BenchItem.Copy(); clone.ClearMods(); IDictionary <PoEModData, int> glyphicmods = ModLogic.FindGlyphicMods(clone, modweightgroups); if (glyphicmods.Count == 0) { return("Item cannot roll forced corrupted essence mods"); } } RollOptions ops = new RollOptions() { ForceMods = forcedmods, ModWeightGroups = modweightgroups, GlyphicCount = cesscount }; if (tries == 1) { foreach (PoEFossilData fossil in fossils) { TallyCurrency(fossil.key, 1); } } DoReroll(ops, extendedpool, ItemRarity.Rare, true, tries); return(null); }
//Uses benchops to find relevant mod templates in db for the item base public static IDictionary <PoEModData, IDictionary <string, int> > FindValidBenchMods(PoEBaseItemData item, ISet <PoEBenchOption> benchops, IDictionary <string, PoEModData> db) { IDictionary <PoEModData, IDictionary <string, int> > mods = new Dictionary <PoEModData, IDictionary <string, int> >(); if (item == null) { return(mods); } foreach (PoEBenchOption b in benchops) { if (b.mod_id == null || !b.item_classes.Contains(item.item_class)) { continue; } PoEModData mod = db[b.mod_id]; mods.Add(mod, b.cost); } return(mods); }
public void UpdateData(ItemCraft item) { SourceItem = item; PoEBaseItemData itemtemplate = CraftingDatabase.AllBaseItems[item.SourceData]; if (item != null) { ItemNameBox.ToolTip = "tags: " + string.Join(", ", item.LiveTags); ItemNameBox.Foreground = new SolidColorBrush(EnumConverter.RarityToColor(item.Rarity)); ItemNameBox.Text = item.ItemName; ItemDataBox.Text = "ilvl: " + item.ItemLevel + " "; if (item.LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(ItemInfluence.Shaper)])) { ItemDataBox.Text += " Shaper"; } if (item.LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(ItemInfluence.Elder)])) { ItemDataBox.Text += " Elder"; } if (item.LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(ItemInfluence.Redeemer)])) { ItemDataBox.Text += " Redeemer"; } if (item.LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(ItemInfluence.Hunter)])) { ItemDataBox.Text += " Hunter"; } if (item.LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(ItemInfluence.Warlord)])) { ItemDataBox.Text += " Warlord"; } if (item.LiveTags.Contains(itemtemplate.item_class_properties[EnumConverter.InfToTag(ItemInfluence.Crusader)])) { ItemDataBox.Text += " Crusader"; } EnchantmentBox.Children.Clear(); foreach (ModCraft m in item.LiveEnchantments) { TextBlock tb = new TextBlock() { TextWrapping = TextWrapping.Wrap, FontWeight = FontWeights.Bold, Foreground = new SolidColorBrush(Color.FromRgb(184, 218, 242)) }; tb.Text = m.ToString(); tb.ToolTip = CraftingDatabase.AllMods[m.SourceData].ToString(); //HookEvents(tb); EnchantmentBox.Children.Add(tb); } ImplicitBox.Children.Clear(); foreach (ModCraft m in item.LiveImplicits) { TextBlock tb = new TextBlock() { TextWrapping = TextWrapping.Wrap, FontWeight = FontWeights.Bold, Foreground = new SolidColorBrush(Color.FromRgb(184, 218, 242)) }; tb.Text = m.ToString(); tb.ToolTip = CraftingDatabase.AllMods[m.SourceData].ToString(); HookEvents(tb); ImplicitBox.Children.Add(tb); } ItemModBox.Children.Clear(); foreach (ModCraft m in item.LiveMods) { PoEModData modtemplate = CraftingDatabase.AllMods[m.SourceData]; DockPanel dock = new DockPanel(); string header = ""; if (modtemplate.generation_type == ModLogic.Prefix) { header = "[P] "; } else if (modtemplate.generation_type == ModLogic.Suffix) { header = "[S] "; } TextBlock affix = new TextBlock() { FontWeight = FontWeights.Bold, Foreground = Brushes.DarkGray, Text = header }; DockPanel.SetDock(affix, Dock.Right); dock.Children.Add(affix); if (AllowEdit) { Button lockbutton = new Button() { Width = 20, Tag = m }; Image lockimg = new Image { Source = m.IsLocked ? Icons.Lock : Icons.Unlock }; lockbutton.Content = lockimg; lockbutton.Background = m.IsLocked ? Brushes.Red : Brushes.Green; lockbutton.Click += LockButton_Click; DockPanel.SetDock(lockbutton, Dock.Left); dock.Children.Add(lockbutton); } StackPanel sp = new StackPanel(); IList <string> statlines = m.ToString().Split('\n'); foreach (string s in statlines) { TextBlock tb = new TextBlock() { TextWrapping = TextWrapping.Wrap, FontWeight = FontWeights.Bold, Text = s, ToolTip = modtemplate.name + ": " + modtemplate }; if (modtemplate.domain == "crafted") { tb.Foreground = new SolidColorBrush(Color.FromRgb(184, 218, 242)); } else { tb.Foreground = new SolidColorBrush(Color.FromRgb(136, 136, 255)); } HookEvents(tb); sp.Children.Add(tb); } dock.Children.Add(sp); ItemModBox.Children.Add(dock); } FillPropertyBox(item); if (item.TempProps != null) { foreach (string tp in item.TempProps.Keys) { TextBlock tb = new TextBlock() { TextWrapping = TextWrapping.Wrap, FontWeight = FontWeights.Bold, Foreground = Brushes.DarkGray, Text = tp + ": " + item.TempProps[tp], Tag = tp }; HookEvents(tb); TempPropBox.Children.Add(tb); } } } else { ItemNameBox.Foreground = Brushes.White; ItemNameBox.Text = ""; ItemDataBox.Text = ""; PropertyBox.Children.Clear(); ImplicitBox.Children.Clear(); ItemModBox.Children.Clear(); TempPropBox.Children.Clear(); } }