// NYI comparison public EquipCompare CompareTo(Monster rhs) { if (Loadout.CompareSets(Current.sets, rhs.Current.sets) == 0) return EquipCompare.Unknown; Stats a = GetStats(); Stats b = rhs.GetStats(); if (a.Health <= b.Health) return EquipCompare.Worse; if (a.Attack <= b.Attack) return EquipCompare.Worse; if (a.Defense <= b.Defense) return EquipCompare.Worse; if (a.Speed <= b.Speed) return EquipCompare.Worse; if (a.CritRate <= b.CritRate) return EquipCompare.Worse; if (a.CritDamage <= b.CritDamage) return EquipCompare.Worse; if (a.Accuracy <= b.Accuracy) return EquipCompare.Worse; if (a.Resistance <= b.Resistance) return EquipCompare.Worse; return EquipCompare.Better; }
// copy down! public Monster(Monster rhs) : base(rhs) { Name = rhs.Name; ID = rhs.ID; level = rhs.level; }
public Rune(Rune rhs) { ID = rhs.ID; Set = rhs.Set; Grade = rhs.Grade; Slot = rhs.Slot; Level = rhs.Level; //FakeLevel = rhs.FakeLevel; //PredictSubs = rhs.PredictSubs; Locked = rhs.Locked; AssignedId = rhs.AssignedId; AssignedName = rhs.AssignedName; Assigned = rhs.Assigned; Swapped = rhs.Swapped; MainType = rhs.MainType; MainValue = rhs.MainValue; InnateType = rhs.InnateType; InnateValue = rhs.InnateValue; Sub1Type = rhs.Sub1Type; Sub1Value = rhs.Sub1Value; Sub2Type = rhs.Sub2Type; Sub2Value = rhs.Sub2Value; Sub3Type = rhs.Sub3Type; Sub3Value = rhs.Sub3Value; Sub4Type = rhs.Sub4Type; Sub4Value = rhs.Sub4Value; Parent = rhs; }
/// <summary> /// Generates builds based on the instances variables. /// </summary> /// <param name="top">If non-zero, runs until N builds are generated</param> /// <param name="time">If non-zero, runs for N seconds</param> /// <param name="printTo">Periodically gives progress% and if it failed</param> /// <param name="progTo">Periodically gives the progress% as a double</param> /// <param name="dumpBads">If true, will only track new builds if they score higher than an other found builds</param> public void GenBuilds(int top = 0, int time = 0, Action<string> printTo = null, Action<double> progTo = null, bool dumpBads = false, bool saveStats = false) { if (runes.Any(r => r == null)) return; // if to get awakened if (DownloadAwake && !mon.downloaded) { var mref = MonsterStat.FindMon(mon); if (mref != null) { // download the current (unawakened monster) var mstat = mref.Download(); // if the retrieved mon is unawakened, get the awakened if (!mstat.Awakened && mstat.AwakenRef != null) { mon = mstat.AwakenRef.Download().GetMon(mon); } } } // getting awakened also gets level 40, so... // only get lvl 40 stats if the monster isn't 40, wants to download AND isn't already downloaded (first and last are about the same) else if (mon.level < 40 && DownloadStats && !mon.downloaded) { var mref = MonsterStat.FindMon(mon); if (mref != null) { mon = mref.Download().GetMon(mon); } } try { Best = null; SynchronizedCollection<Monster> tests = new SynchronizedCollection<Monster>(); long count = 0; long total = runes[0].Count(); total *= runes[1].Count(); total *= runes[2].Count(); total *= runes[3].Count(); total *= runes[4].Count(); total *= runes[5].Count(); long complete = total; if (total == 0) { if (printTo != null) printTo.Invoke("0 perms"); Console.WriteLine("Zero permuations"); return; } if (!AllowBroken && BuildSets.Count == 1 && Rune.SetRequired(BuildSets[0]) == 4) { if (printTo != null) printTo.Invoke("Bad sets"); Console.WriteLine("Cannot use 4 set with no broken"); return; } bool hasSort = false; foreach (string stat in statNames) { if (Sort[stat] != 0) { hasSort = true; break; } } foreach (string extra in extraNames) { if (Sort.ExtraGet(extra) != 0) { hasSort = true; break; } } if (top == 0 && !hasSort) { if (printTo != null) printTo.Invoke("No sort"); Console.WriteLine("No method of determining best"); return; } DateTime begin = DateTime.Now; DateTime timer = DateTime.Now; Console.WriteLine(count + "/" + total + " " + string.Format("{0:P2}", (count + complete - total) / (double)complete)); // build the scoring function Func<Stats, double> sort = (m) => { double pts = 0; foreach (string stat in statNames) { // if this stat is used for sorting if (Sort[stat] != 0) { // sum points for the stat pts += m[stat] / Sort[stat]; // if exceeding max, subtracted the gained points and then some if (Threshold[stat] != 0) pts -= Math.Max(0, m[stat] - Threshold[stat]) / Sort[stat]; } } // look, cool metrics! foreach (string extra in extraNames) { if (Sort.ExtraGet(extra) != 0) { pts += m.ExtraValue(extra) / Sort.ExtraGet(extra); if (Threshold.ExtraGet(extra) != 0) pts -= Math.Max(0, m.ExtraValue(extra) - Threshold.ExtraGet(extra)) / Sort.ExtraGet(extra); } } return pts; }; int[] slotFakes = new int[6]; bool[] slotPred = new bool[6]; // crank the rune prediction for (int i = 0; i < 6; i++) { Rune[] rs = runes[i]; int raiseTo = 0; bool predictSubs = false; // find the largest number to raise to // if any along the tree say to predict, do it if (runePrediction.ContainsKey("g")) { int glevel = runePrediction["g"].Key; if (glevel > raiseTo) raiseTo = glevel; predictSubs |= runePrediction["g"].Value; } if (runePrediction.ContainsKey(((i % 2 == 0) ? "o" : "e"))) { int mlevel = runePrediction[((i % 2 == 0) ? "o" : "e")].Key; if (mlevel > raiseTo) raiseTo = mlevel; predictSubs |= runePrediction[((i % 2 == 0) ? "o" : "e")].Value; } if (runePrediction.ContainsKey((i + 1).ToString())) { int slevel = runePrediction[(i + 1).ToString()].Key; if (slevel > raiseTo) raiseTo = slevel; predictSubs |= runePrediction[(i + 1).ToString()].Value; } slotFakes[i] = raiseTo; slotPred[i] = predictSubs; } // set to running isRun = true; // Parallel the outer loop var loopRes = Parallel.ForEach<Rune>(runes[0], (r0, loopState) => { if (!isRun) //break; loopState.Break(); // number of builds ruled out since last sync int kill = 0; // number of builds added since last sync int plus = 0; foreach (Rune r1 in runes[1]) { if (!isRun) // Can't break to a lable, don't want to goto break; foreach (Rune r2 in runes[2]) { if (!isRun) break; foreach (Rune r3 in runes[3]) { if (!isRun) break; foreach (Rune r4 in runes[4]) { if (!isRun) break; foreach (Rune r5 in runes[5]) { if (!isRun) break; Monster test = new Monster(mon); test.Current.shrines = shrines; test.Current.leader = leader; test.Current.FakeLevel = slotFakes; test.Current.PredictSubs = slotPred; test.ApplyRune(r0); test.ApplyRune(r1); test.ApplyRune(r2); test.ApplyRune(r3); test.ApplyRune(r4); test.ApplyRune(r5); if (saveStats) { foreach (Rune r in test.Current.runes) { r.manageStats_LoadGen++; } } var cstats = test.GetStats(); bool maxdead = false; if (Maximum != null) { foreach (var stat in statNames) { if (Maximum[stat] > 0 && cstats[stat] > Maximum[stat]) { maxdead = true; break; } } } // check if build meets minimum if (Minimum != null && !(cstats > Minimum)) { kill++; } else if (maxdead) { kill++; } // if no broken sets, check for broken sets else if (!AllowBroken && !test.Current.SetsFull) { kill++; } // if there are required sets, ensure we have them else if (RequiredSets != null && RequiredSets.Count > 0 // this Linq adds no overhead compared to GetStats() and ApplyRune() && !RequiredSets.All(s => test.Current.sets.Count(q => q == s) >= RequiredSets.Count(q => q == s))) { kill++; } else { // we found an okay build! plus++; if (saveStats) { foreach (Rune r in test.Current.runes) { r.manageStats_LoadFilt++; } } // if we are to track all good builds, keep it if (!dumpBads) { tests.Add(test); } // if we only want to track really good builds else { // if there are currently no good builds, keep it if (tests.FirstOrDefault() == null) { tests.Add(test); Best = test; } else { // if this build is better than the best, keep it if (sort(Best.GetStats()) < sort(test.GetStats())) { Best = test; tests.Add(test); } } } } // every second, give a bit of feedback to those watching if (DateTime.Now > timer.AddSeconds(1)) { timer = DateTime.Now; Console.WriteLine(count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); if (printTo != null) printTo.Invoke(String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); if (progTo != null) progTo.Invoke((double)(count + complete - total) / (double)complete); if (time > 0) { if (DateTime.Now > begin.AddSeconds(time)) { isRun = false; break; } } } } // sum up what work we've done Interlocked.Add(ref total, -kill); kill = 0; Interlocked.Add(ref count, plus); plus = 0; // if we've got enough, stop if (top > 0 && count >= top) { isRun = false; break; } } } } } }); // write out completion Console.WriteLine(isRun + " " + count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); if (printTo != null) printTo.Invoke("100%"); if (progTo != null) progTo.Invoke(1); // sort *all* the builds loads = tests.Where(t => t != null).OrderByDescending(r => sort(r.GetStats())).Take((top > 0 ? top : 1)); // dump everything to console, if nothing to print to if (printTo == null) foreach (var l in loads) { Console.WriteLine(l.GetStats().Health + " " + l.GetStats().Attack + " " + l.GetStats().Defense + " " + l.GetStats().Speed + " " + l.GetStats().CritRate + "%" + " " + l.GetStats().CritDamage + "%" + " " + l.GetStats().Resistance + "%" + " " + l.GetStats().Accuracy + "%"); } // sadface if no builds if (loads.Count() == 0) { Console.WriteLine("No builds :("); if (printTo != null) printTo.Invoke("Zero :("); } else { // remember the good one Best = loads.First(); foreach (Rune r in Best.Current.runes) { r.manageStats_In = true; } for (int i = 0; i < 6; i++) { if (mon.Current.runes[i] != null && mon.Current.runes[i].ID != Best.Current.runes[i].ID) mon.Current.runes[i].Swapped = true; } } } catch (Exception e) { Console.WriteLine("Error " + e); if (printTo != null) printTo.Invoke(e.ToString()); } }
public Monster GetMon(Monster mon) { return new Monster() { ID = mon.ID, priority = mon.priority, Current = mon.Current, Accuracy = Accuracy, Attack = Attack, CritDamage = CritDamage, CritRate = CritRate, Defense = Defense, Health = Health, level = 40, Resistance = Resistance, Speed = Speed, Name = (Awakened ? name : name + " (" + element.ToString() + ")"), downloaded = true }; }
public Monster GetMon(StatReference mref, Monster mon) { var mstat = mref.Download(); return GetMon(mon); }
public static StatReference FindMon(Monster mon) { return FindMon(mon.Name); }
private void ShowMon(Monster mon) { Stats cur = mon.GetStats(); statName.Text = mon.Name; statID.Text = mon.ID.ToString(); statLevel.Text = mon.level.ToString(); ShowStats(cur, mon); ShowRunes(mon.Current.runes); }
/// <summary> /// Generates builds based on the instances variables. /// </summary> /// <param name="top">If non-zero, runs until N builds are generated</param> /// <param name="time">If non-zero, runs for N seconds</param> /// <param name="printTo">Periodically gives progress% and if it failed</param> /// <param name="progTo">Periodically gives the progress% as a double</param> /// <param name="dumpBads">If true, will only track new builds if they score higher than an other found builds</param> public void GenBuilds(int top = 0, int time = 0, Action <string> printTo = null, Action <double> progTo = null, bool dumpBads = false, bool saveStats = false) { if (runes.Any(r => r == null)) { return; } try { Best = null; SynchronizedCollection <Monster> tests = new SynchronizedCollection <Monster>(); long count = 0; long total = runes[0].Count(); total *= runes[1].Count(); total *= runes[2].Count(); total *= runes[3].Count(); total *= runes[4].Count(); total *= runes[5].Count(); long complete = total; if (total == 0) { if (printTo != null) { printTo.Invoke("0 perms"); } Console.WriteLine("Zero permuations"); return; } if (!AllowBroken && BuildSets.Count == 1 && Rune.SetRequired(BuildSets[0]) == 4) { if (printTo != null) { printTo.Invoke("Bad sets"); } Console.WriteLine("Cannot use 4 set with no broken"); return; } bool hasSort = false; foreach (string stat in statNames) { if (Sort[stat] != 0) { hasSort = true; break; } } foreach (string extra in extraNames) { if (Sort.ExtraGet(extra) != 0) { hasSort = true; break; } } if (top == 0 && !hasSort) { if (printTo != null) { printTo.Invoke("No sort"); } Console.WriteLine("No method of determining best"); return; } DateTime begin = DateTime.Now; DateTime timer = DateTime.Now; Console.WriteLine(count + "/" + total + " " + string.Format("{0:P2}", (count + complete - total) / (double)complete)); // build the scoring function Func <Stats, double> sort = (m) => { double pts = 0; foreach (string stat in statNames) { // if this stat is used for sorting if (Sort[stat] != 0) { // sum points for the stat pts += m[stat] / Sort[stat]; // if exceeding max, subtracted the gained points and then some if (Threshold[stat] != 0) { pts -= Math.Max(0, m[stat] - Threshold[stat]) / Sort[stat]; } } } // look, cool metrics! foreach (string extra in extraNames) { if (Sort.ExtraGet(extra) != 0) { pts += m.ExtraValue(extra) / Sort.ExtraGet(extra); if (Threshold.ExtraGet(extra) != 0) { pts -= Math.Max(0, m.ExtraValue(extra) - Threshold.ExtraGet(extra)) / Sort.ExtraGet(extra); } } } return(pts); }; int[] slotFakes = new int[6]; bool[] slotPred = new bool[6]; // crank the rune prediction for (int i = 0; i < 6; i++) { Rune[] rs = runes[i]; int raiseTo = 0; bool predictSubs = false; // find the largest number to raise to // if any along the tree say to predict, do it if (runePrediction.ContainsKey("g")) { int glevel = runePrediction["g"].Key; if (glevel > raiseTo) { raiseTo = glevel; } predictSubs |= runePrediction["g"].Value; } if (runePrediction.ContainsKey(((i % 2 == 0) ? "o" : "e"))) { int mlevel = runePrediction[((i % 2 == 0) ? "o" : "e")].Key; if (mlevel > raiseTo) { raiseTo = mlevel; } predictSubs |= runePrediction[((i % 2 == 0) ? "o" : "e")].Value; } if (runePrediction.ContainsKey((i + 1).ToString())) { int slevel = runePrediction[(i + 1).ToString()].Key; if (slevel > raiseTo) { raiseTo = slevel; } predictSubs |= runePrediction[(i + 1).ToString()].Value; } slotFakes[i] = raiseTo; slotPred[i] = predictSubs; } // set to running isRun = true; // Parallel the outer loop var loopRes = Parallel.ForEach <Rune>(runes[0], (r0, loopState) => { if (!isRun) { //break; loopState.Break(); } // number of builds ruled out since last sync int kill = 0; // number of builds added since last sync int plus = 0; foreach (Rune r1 in runes[1]) { if (!isRun) // Can't break to a lable, don't want to goto { break; } foreach (Rune r2 in runes[2]) { if (!isRun) { break; } foreach (Rune r3 in runes[3]) { if (!isRun) { break; } foreach (Rune r4 in runes[4]) { if (!isRun) { break; } foreach (Rune r5 in runes[5]) { if (!isRun) { break; } Monster test = new Monster(mon); test.Current.shrines = shrines; test.Current.leader = leader; test.Current.FakeLevel = slotFakes; test.Current.PredictSubs = slotPred; test.ApplyRune(r0); test.ApplyRune(r1); test.ApplyRune(r2); test.ApplyRune(r3); test.ApplyRune(r4); test.ApplyRune(r5); if (saveStats) { foreach (Rune r in test.Current.runes) { r.manageStats_LoadGen++; } } var cstats = test.GetStats(); bool maxdead = false; if (Maximum != null) { foreach (var stat in statNames) { if (Maximum[stat] > 0 && cstats[stat] > Maximum[stat]) { maxdead = true; break; } } } // check if build meets minimum if (Minimum != null && !(cstats > Minimum)) { kill++; } else if (maxdead) { kill++; } // if no broken sets, check for broken sets else if (!AllowBroken && !test.Current.SetsFull) { kill++; } // if there are required sets, ensure we have them else if (RequiredSets != null && RequiredSets.Count > 0 && !RequiredSets.All(s => test.Current.sets.Contains(s))) { kill++; } else { // we found an okay build! plus++; if (saveStats) { foreach (Rune r in test.Current.runes) { r.manageStats_LoadFilt++; } } // if we are to track all good builds, keep it if (!dumpBads) { tests.Add(test); } else { //lock (tests) //{ // if there are currently no good builds, keep it if (tests.FirstOrDefault() == null) { tests.Add(test); Best = test; } else { if (Best.GetStats() < test.GetStats()) { Best = test; tests.Add(test); } // take a snapshot of the builds (multithread /may/ cause a "collection modified" excepion in next step) /*var tt = tests.ToList(); * // if this build is better than any other build, keep it * // can't just keep a copy of Max becaues of threading * if (tt.Max(t => sort(t.GetStats())) < sort(test.GetStats())) * { * tests.Add(test); * }*/ } //} } } // every second, give a bit of feedback to those watching if (DateTime.Now > timer.AddSeconds(1)) { timer = DateTime.Now; Console.WriteLine(count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); if (printTo != null) { printTo.Invoke(String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); } if (progTo != null) { progTo.Invoke((double)(count + complete - total) / (double)complete); } if (time > 0) { if (DateTime.Now > begin.AddSeconds(time)) { isRun = false; break; } } } } // sum up what work we've done Interlocked.Add(ref total, -kill); kill = 0; Interlocked.Add(ref count, plus); plus = 0; // if we've got enough, stop if (top > 0 && count >= top) { isRun = false; break; } } } } } }); // write out completion Console.WriteLine(isRun + " " + count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); if (printTo != null) { printTo.Invoke("100%"); } if (progTo != null) { progTo.Invoke(1); } // sort *all* the builds loads = tests.Where(t => t != null).OrderByDescending(r => sort(r.GetStats())).Take((top > 0 ? top : 1)); // dump everything to console, if nothing to print to if (printTo == null) { foreach (var l in loads) { Console.WriteLine(l.GetStats().Health + " " + l.GetStats().Attack + " " + l.GetStats().Defense + " " + l.GetStats().Speed + " " + l.GetStats().CritRate + "%" + " " + l.GetStats().CritDamage + "%" + " " + l.GetStats().Resistance + "%" + " " + l.GetStats().Accuracy + "%"); } } // sadface if no builds if (loads.Count() == 0) { Console.WriteLine("No builds :("); if (printTo != null) { printTo.Invoke("Zero :("); } } else { // remember the good one Best = loads.First(); foreach (Rune r in Best.Current.runes) { r.manageStats_In = true; } } } catch (Exception e) { Console.WriteLine("Error " + e); if (printTo != null) { printTo.Invoke(e.ToString()); } } }
public static Loadout MakeBuild(Monster mon, IEnumerable<Rune>[] runesSlot, Func<Stats, double> sort, Predicate<RuneSet[]> reqsets = null, Predicate<Stats> minimum = null) { System.Collections.Generic.SynchronizedCollection<Monster> tests = new SynchronizedCollection<Monster>();//new List<Monster>(); long count = 0; long total = runesSlot[0].Count(); total *= runesSlot[1].Count(); total *= runesSlot[2].Count(); total *= runesSlot[3].Count(); total *= runesSlot[4].Count(); total *= runesSlot[5].Count(); long complete = total; DateTime timer = DateTime.Now; Console.WriteLine(count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); Parallel.ForEach<Rune>(runesSlot[0], r0 => { int kill = 0; int plus = 0; foreach (Rune r1 in runesSlot[1]) { foreach (Rune r2 in runesSlot[2]) { foreach (Rune r3 in runesSlot[3]) { foreach (Rune r4 in runesSlot[4]) { foreach (Rune r5 in runesSlot[5]) { Monster test = new Monster(mon); test.ApplyRune(r0); test.ApplyRune(r1); test.ApplyRune(r2); test.ApplyRune(r3); test.ApplyRune(r4); test.ApplyRune(r5); if (minimum != null && !minimum.Invoke(test.GetStats())) { //total--; kill++; //Interlocked.Decrement(ref total); } else if (reqsets != null && !reqsets.Invoke(test.Current.sets)) { kill++; //Interlocked.Decrement(ref total); } else { plus++; tests.Add(test); //Interlocked.Increment(ref count); //count++; } if (DateTime.Now > timer.AddSeconds(1)) { timer = DateTime.Now; Console.WriteLine(count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); } } Interlocked.Add(ref total, -kill); kill = 0; Interlocked.Add(ref count, plus); plus = 0; } } } } }); Console.WriteLine(count + "/" + total + " " + String.Format("{0:P2}", (double)(count + complete - total) / (double)complete)); var desc = tests.Where(t => t != null).OrderByDescending(r => sort(r.GetStats())).Take(10).ToArray(); foreach (var l in desc) { Console.WriteLine(l.GetStats().Health + " " + l.GetStats().Attack + " " + l.GetStats().Defense + " " + l.GetStats().Speed + " " + l.GetStats().CritRate + "%" + " " + l.GetStats().CritDamage + "%" + " " + l.GetStats().Resistance + "%" + " " + l.GetStats().Accuracy + "%"); } if (desc.Count() == 0) { Console.WriteLine("No builds :("); return null; } var best = desc.First().Current; foreach (Rune r in best.runes) { r.Locked = true; } return best; }
private void refreshStats(Monster mon, Stats cur) { statName.Text = mon.Name; statID.Text = mon.ID.ToString(); statLevel.Text = mon.level.ToString(); // read a bunch of numbers foreach (var stat in statNames) { var ctrlBase = (Label)groupBox1.Controls.Find(stat + "Base", true).FirstOrDefault(); ctrlBase.Text = mon[stat].ToString(); var ctrlBonus = (Label)groupBox1.Controls.Find(stat + "Bonus", true).FirstOrDefault(); var ctrlTotal = (TextBox)groupBox1.Controls.Find(stat + "Total", true).FirstOrDefault(); ctrlTotal.Tag = new KeyValuePair<Label, Label>(ctrlBase, ctrlBonus); var ctrlCurrent = groupBox1.Controls.Find(stat + "Current", true).FirstOrDefault(); ctrlCurrent.Text = cur[stat].ToString(); var ctrlWorth = groupBox1.Controls.Find(stat + "Worth", true).FirstOrDefault(); var ctrlThresh = groupBox1.Controls.Find(stat + "Thresh", true).FirstOrDefault(); var ctrlMax = groupBox1.Controls.Find(stat + "Max", true).FirstOrDefault(); if (build.Minimum[stat] > 0) ctrlTotal.Text = build.Minimum[stat].ToString(); if (build.Sort[stat] != 0) ctrlWorth.Text = build.Sort[stat].ToString(); if (build.Maximum[stat] != 0) ctrlMax.Text = build.Maximum[stat].ToString(); if (build.Threshold[stat] != 0) ctrlThresh.Text = build.Threshold[stat].ToString(); } foreach (var extra in extraNames) { var ctrlBase = (Label)groupBox1.Controls.Find(extra + "Base", true).FirstOrDefault(); ctrlBase.Text = mon.ExtraValue(extra).ToString(); var ctrlBonus = (Label)groupBox1.Controls.Find(extra + "Bonus", true).FirstOrDefault(); var ctrlTotal = (TextBox)groupBox1.Controls.Find(extra + "Total", true).FirstOrDefault(); ctrlTotal.Tag = new KeyValuePair<Label, Label>(ctrlBase, ctrlBonus); var ctrlCurrent = groupBox1.Controls.Find(extra + "Current", true).FirstOrDefault(); ctrlCurrent.Text = cur.ExtraValue(extra).ToString(); var ctrlWorth = groupBox1.Controls.Find(extra + "Worth", true).FirstOrDefault(); var ctrlThresh = groupBox1.Controls.Find(extra + "Thresh", true).FirstOrDefault(); var ctrlMax = groupBox1.Controls.Find(extra + "Max", true).FirstOrDefault(); if (build.Minimum.ExtraGet(extra) > 0) ctrlTotal.Text = build.Minimum.ExtraGet(extra).ToString(); if (build.Sort.ExtraGet(extra) != 0) ctrlWorth.Text = build.Sort.ExtraGet(extra).ToString(); if (build.Maximum.ExtraGet(extra) != 0) ctrlMax.Text = build.Maximum.ExtraGet(extra).ToString(); if (build.Threshold.ExtraGet(extra) != 0) ctrlThresh.Text = build.Threshold.ExtraGet(extra).ToString(); } }