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); }
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 CommandHandler(CommandService commands, DiscordSocketClient client, IMessageTriggerService msgTrgSrvs, MediaProcessor mediaProcessor, MessageTriggers messageTriggers, ModLogic modLogic, PunishLogic punishLogic, NotifyLogic notifyLogic, EventLogic eventLogic, CustomCommandLogic customCommandLogic, IActivityLogService activityLogService) { _commands = commands; _client = client; _msgTrgSrvs = msgTrgSrvs; _modLogic = modLogic; _punishLogic = punishLogic; _notifyLogic = notifyLogic; _eventLogic = eventLogic; _customCommandLogic = customCommandLogic; _mediaProcessor = mediaProcessor; _messageTriggers = messageTriggers; _tokenSource = new CancellationTokenSource(); _activityLogService = activityLogService; }
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); }
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; }
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 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(); } }
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); }
//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 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); }
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); }