private void DoReroll(RollOptions ops, IDictionary <PoEModData, int> pool, ItemRarity targetrarity, bool ignoremeta, int count) { ItemCraft dummy = BenchItem.Copy(); if (ignoremeta) { dummy.ClearCraftedMods(); } dummy.ClearMods(); dummy.Rarity = targetrarity; IDictionary <PoEModData, int> validatedpool = ModLogic.FindValidMods(dummy, pool, op: ops); DoCurrencyRolls((item) => { if (ignoremeta) { item.ClearCraftedMods(); } item.ClearMods(); item.Rarity = targetrarity; IDictionary <PoEModData, int> poolcopy = new Dictionary <PoEModData, int>(validatedpool); ModLogic.RollItem(item, poolcopy, ops); DoPostRoll(item, poolcopy); item.GenerateName(); }, count); }
//deep copy everything private ItemCraft(ItemCraft item) { SourceData = item.SourceData; _basequality = item.BaseQuality; QualityType = item.QualityType; LiveTags = new HashSet <string>(item.LiveTags); ItemLevel = item.ItemLevel; Rarity = item.Rarity; LiveMods = new List <ModCraft>(); foreach (ModCraft m in item.LiveMods) { LiveMods.Add(m.Copy()); } LiveImplicits = new List <ModCraft>(); foreach (ModCraft m in item.LiveImplicits) { LiveImplicits.Add(m.Copy()); } LiveEnchantments = new List <ModCraft>(); foreach (ModCraft m in item.LiveEnchantments) { LiveEnchantments.Add(m.Copy()); } ItemName = item.ItemName; }
//Performs an action once on BenchItem, or many times on copies of it to build mass results private void DoCurrencyRolls(CurrencyAction action, int count) { if (count == 1) { action(BenchItem); } else { MassResults.Clear(); if (count >= Properties.Settings.Default.ProgressBarThreshold) { ProgressDialog p = new ProgressDialog() { Title = "Rolling...", Steps = count, ReportStep = Math.Max(count / 100, 1) }; p.Increment = () => { ItemCraft copy = BenchItem.Copy(); action(copy); MassResults.Add(copy); }; p.ShowDialog(); } else { for (int n = 0; n < count; n++) { ItemCraft copy = BenchItem.Copy(); action(copy); MassResults.Add(copy); } } } }
private void BenchMove_Click(object sender, EventArgs e) { ItemCraft item = ((MenuItem)sender).Tag as ItemCraft; bool samebase = item != null && Bench.BenchItem != null && item.SourceData == Bench.BenchItem.SourceData; Bench.BenchItem = item.Copy(); ItemSlot.UpdateData(Bench.BenchItem); ModPreview.UpdatePreviews(); if (!samebase) { ModPreview.UpdateCrafts(); ModPreview.UpdateEnchantments(); Bench.PostRoll = new PostRollOptions(); PostCraftButton.ClearValue(Button.BackgroundProperty); } }
private bool DoAddMod(ItemRarity targetrarity, bool rename, int count, int qualityconsumed, ItemInfluence?inf = null) { string inftag = null; if (inf != null) { inftag = CraftingDatabase.AllBaseItems[BenchItem.SourceData].item_class_properties[EnumConverter.InfToTag(inf.Value)]; } ItemCraft dummy = BenchItem.Copy(); if (inftag != null) { dummy.LiveTags.Add(inftag); } dummy.Rarity = targetrarity; IDictionary <PoEModData, int> validatedpool = ModLogic.FindValidMods(dummy, BaseValidMods); if (inf != null) { validatedpool = ModLogic.FilterForInfluence(validatedpool, inf.Value); } if (validatedpool.Count == 0) { return(false); } DoCurrencyRolls((item) => { if (inftag != null) { item.LiveTags.Add(inftag); } item.Rarity = targetrarity; IDictionary <PoEModData, int> poolcopy = new Dictionary <PoEModData, int>(validatedpool); ModLogic.RollAddMod(item, poolcopy); if (item.QualityType != null) { item.BaseQuality -= qualityconsumed; } if (rename) { item.GenerateName(); } }, count); return(true); }
private void DoPostRoll(ItemCraft item, IDictionary <PoEModData, int> pool) { if (PostRoll.TryCrafts != null) { foreach (KeyValuePair <PoEModData, IDictionary <string, int> > kv in PostRoll.TryCrafts) { string ret = ForceAddMod(kv.Key, item, kv.Value, pool); if (ret == null) { break; } } } if (PostRoll.FillAffix) { while (item.LiveMods.Count < item.GetAffixLimit() * 2) { ModLogic.RollAddMod(item, pool); if (item.QualityType != null) { if (item.Rarity == ItemRarity.Rare) { item.BaseQuality -= 20; } else { item.BaseQuality -= 2; } } } } if (PostRoll.Maximize) { item.MaximizeMods(); } }
//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 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); }