// return the selected rune private void listView2_DoubleClick(object sender, EventArgs e) { if (listView2.SelectedItems.Count > 0) { returnedRune = (Rune)listView2.SelectedItems[0].Tag; DialogResult = DialogResult.OK; Close(); } }
/// <summary> /// Original test program. /// Do not use /// </summary> /// <param name="args"></param> static void Main(string[] args) { string save = System.IO.File.ReadAllText("..\\..\\save.json"); Save data = JsonConvert.DeserializeObject <Save>(save); foreach (Monster mon in data.Monsters) { var equipedRunes = data.Runes.Where(r => r.AssignedId == mon.ID); foreach (Rune rune in equipedRunes) { mon.ApplyRune(rune); } var stats = mon.GetStats(); } var rsets = new Rune[(int)RuneSet.Destroy + 1][][]; foreach (RuneSet r in Enum.GetValues(typeof(RuneSet))) { rsets[(int)r] = new Rune[6][]; for (int i = 0; i < 6; ++i) { rsets[(int)r][i] = data.Runes.Where(t => t.Set.Equals(r) && t.Slot == i).ToArray(); } } var veromos = data.GetMonster("Veromos"); var belladeon = data.GetMonster("Belladeon"); var sath = data.GetMonster("Sath"); var verdehile = data.GetMonster("Verdehile"); var acasis = data.GetMonster("Acasis (In Storage)"); var shannon = data.GetMonster("Shannon"); var bernard = data.GetMonster("Bernard"); var chasun = data.GetMonster("Chasun"); var arnold = data.GetMonster("Arnold"); var fuco = data.GetMonster("Fuco"); var ahman = data.GetMonster("Ahman"); var orochi = data.GetMonster("Orochi"); var theomars = data.GetMonster("Theomars"); var basalt = data.GetMonster("Basalt"); var baretta = data.GetMonster("Baretta"); var briand = data.GetMonster("Briand"); var lapis = data.GetMonster("Lapis"); var megan = data.GetMonster("Megan"); var lyn = data.GetMonster("Lyn"); var garoche = data.GetMonster("Garoche (In Storage)"); var lushen1 = data.GetMonster(20); var lushen2 = data.GetMonster(21); var mav = data.GetMonster("Mav"); var darion = data.GetMonster("Darion"); var gina = data.GetMonster("Gina"); var xing = data.GetMonster("Xing Zhe"); foreach (Rune r in data.Runes) { r.Locked = false; } Loadout best; best = MakeBuild(veromos, MakeSets(data.Runes, r => r.MainType == Attr.HealthPercent || r.MainType == Attr.Speed || r.MainType == Attr.Accuracy, r => r.HealthPercent > 0 && r.Speed > 0, new RuneSet[] { RuneSet.Swift, RuneSet.Energy }), s => s.Health, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Energy), s => s.Accuracy >= 60 && s.Speed > 200 && s.Health > 22000); Console.WriteLine("vero: " + best); best.Lock(); best = MakeBuild(belladeon, MakeSets(data.Runes, Attr.Speed, Attr.HealthPercent, Attr.Accuracy, r => r.HealthPercent > 10 || r.Accuracy > 5, new RuneSet[] { RuneSet.Swift, RuneSet.Focus }), s => s.Speed / 3 + s.Defense / 50 + s.Health / 300 - s.CritRate + s.Accuracy / 2, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Focus), s => s.Accuracy >= 70 && s.Speed >= 170 && s.Health >= 15000 && s.Defense >= 950); Console.WriteLine("bella: " + best); best.Lock(); best = MakeBuild(sath, MakeSets(data.Runes, Attr.AttackPercent, Attr.CritRate, Attr.AttackPercent, r => r.Speed > 0 && (r.AttackPercent > 0 || r.CritRate > 0), new RuneSet[] { RuneSet.Swift, RuneSet.Blade }), s => s.Speed + s.CritDamage * 2 + s.Attack / 10 + s.CritRate * 3 - Math.Max(0, s.CritRate - 100) * 3, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Blade), s => s.Attack >= 1900 && s.Speed >= 143 && s.CritRate >= 95); Console.WriteLine("sath: " + best); best.Lock(); best = MakeBuild(verdehile, MakeSets(data.Runes, Attr.Speed, Attr.CritRate, Attr.AttackPercent, r => r.Speed > 0 && (r.HealthPercent > 0 || r.CritRate > 0), new RuneSet[] { RuneSet.Violent, RuneSet.Blade }), s => s.Speed + s.Health / 500 + s.CritRate + s.Attack / 50 + s.Defense / 50, s => s.Contains(RuneSet.Violent) && s.Contains(RuneSet.Blade), s => s.Health >= 10000 && s.Speed >= 120 && s.CritRate >= 95); Console.WriteLine("verd: " + best); best.Lock(); best = MakeBuild(acasis, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.Accuracy, r => r.Accuracy > 0, new RuneSet[] { RuneSet.Despair, RuneSet.Focus }), s => s.Speed + s.Health / 500 + s.Accuracy, s => s.Contains(RuneSet.Despair) && s.Contains(RuneSet.Focus), s => s.Health >= 13000 && s.Speed >= 110 && s.Accuracy >= 80);/**/ Console.WriteLine("acas: " + best); best.Lock(); best = MakeBuild(shannon, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.Accuracy, r => r.Accuracy > 0, new RuneSet[] { RuneSet.Energy, RuneSet.Focus, RuneSet.Focus }), s => s.Defense / 40 + s.Health / 100 + s.Accuracy, s => s.Contains(RuneSet.Energy) && s.Count(r => r == RuneSet.Focus) == 2, s => s.Health >= 12000 && s.Accuracy >= 60);/**/ Console.WriteLine("shann: " + best); best.Lock(); best = MakeBuild(bernard, MakeSets(data.Runes, Attr.Speed, Attr.HealthPercent, Attr.Accuracy, r => r.Accuracy + r.Speed / 2 > 6, new RuneSet[] { RuneSet.Energy, RuneSet.Swift }), s => s.Defense / 40 + s.Health / 100 + s.Accuracy + s.Speed, s => s.Contains(RuneSet.Energy) && s.Contains(RuneSet.Swift), s => s.Health >= 13000 && s.Speed >= 170 && s.Accuracy >= 60);/**/ Console.WriteLine("bern: " + best); best.Lock(); best = MakeBuild(chasun, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.HealthPercent, r => r.HealthPercent >= 10, new RuneSet[] { RuneSet.Energy, RuneSet.Energy, RuneSet.Guard }), s => s.Health / 300 + s.Resistance + s.Speed / 2 - s.CritRate / 2 + s.Accuracy / 2, s => s.Contains(RuneSet.Guard) && s.Count(r => r == RuneSet.Energy) == 2, s => s.Health >= 30000 && s.Resistance >= 80);/**/ Console.WriteLine("chas: " + best); best.Lock(); best = MakeBuild(arnold, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.HealthPercent, r => r.HealthPercent * 2 + r.DefensePercent + r.Speed / 2 >= 8, new RuneSet[] { RuneSet.Guard, RuneSet.Shield, RuneSet.Energy }), s => s.Health / 300 + s.Resistance + s.Speed / 2 - s.CritRate / 2 + s.Accuracy / 2, s => true, //s.Contains(RuneSet.Guard) && s.Contains(RuneSet.Shield), s => s.Health >= 20000); /**/ Console.WriteLine("arn: " + best); best.Lock(); best = MakeBuild(fuco, MakeSets(data.Runes, Attr.Speed, Attr.AttackPercent, Attr.AttackPercent, r => r.Speed > 6 | r.AttackPercent > 6, new RuneSet[] { RuneSet.Swift, RuneSet.Guard }), s => s.Health / 300 + s.Defense + s.Speed + s.Defense / 20 + s.Accuracy / 2, s => s.Contains(RuneSet.Guard) && s.Contains(RuneSet.Swift), s => s.Speed >= 170);/**/ Console.WriteLine("fuco: " + best); best.Lock(); best = MakeBuild(ahman, MakeSets(data.Runes, Attr.HealthPercent, Attr.CritRate, Attr.HealthPercent, r => r.HealthPercent > 0 | r.CritRate > 0, new RuneSet[] { RuneSet.Energy, RuneSet.Blade, RuneSet.Blade }), s => s.CritRate + s.Health / 250 + s.Speed / 3, s => s.Contains(RuneSet.Energy) && s.Count(r => r == RuneSet.Blade) == 2, s => s.Health >= 15000 && s.CritRate >= 90);/**/ Console.WriteLine("ahm: " + best); best.Lock(); best = MakeBuild(orochi, MakeSets(data.Runes, Attr.Speed, Attr.CritRate, Attr.Accuracy, r => r.Accuracy + r.CritRate + r.AttackPercent / 2 + r.HealthPercent / 2 >= 10, new RuneSet[] { RuneSet.Focus, RuneSet.Blade }), s => s.CritRate + s.Health / 500 + s.Speed / 2 + s.Accuracy, s => s.Contains(RuneSet.Focus) && s.Contains(RuneSet.Blade), s => s.Health >= 8000 && s.CritRate >= 90 && s.Accuracy >= 60);/**/ Console.WriteLine("oro: " + best); best.Lock(); best = MakeBuild(theomars, MakeSets(data.Runes, Attr.Speed, Attr.CritDamage, Attr.AttackPercent, r => r.Speed + r.CritRate + r.CritDamage + r.AttackPercent >= 10, new RuneSet[] { RuneSet.Violent, RuneSet.Blade }), s => s.CritRate + s.Health / 500 + s.Speed + s.CritDamage - Math.Max(0, s.CritRate - 61), s => s.Contains(RuneSet.Violent) && s.Contains(RuneSet.Blade), s => s.Health >= 8000 && s.CritRate >= 61 && s.CritDamage >= 100);/**/ Console.WriteLine("theo: " + best); best.Lock(); best = MakeBuild(basalt, MakeSets(data.Runes, Attr.DefensePercent, Attr.DefensePercent, Attr.DefensePercent, r => r.Speed + r.CritRate + r.CritDamage + r.Accuracy + r.DefensePercent >= 10, new RuneSet[] { RuneSet.Violent, RuneSet.Energy }), s => s.Defense / 20 + s.Health / 500 + s.Speed + s.CritDamage, s => s.Contains(RuneSet.Violent) && s.Contains(RuneSet.Energy), s => s.Health >= 9000 && s.Defense >= 1000);/**/ Console.WriteLine("basa: " + best); best.Lock(); best = MakeBuild(baretta, MakeSets(data.Runes, Attr.AttackPercent, Attr.HealthPercent, Attr.Accuracy, r => r.Speed + r.Accuracy + r.HealthPercent >= 10, new RuneSet[] { RuneSet.Swift, RuneSet.Energy }), s => s.Health / 500 + s.Speed + s.Accuracy, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Energy), s => s.Health >= 14000 && s.Speed > 140);/**/ Console.WriteLine("baretta: " + best); best.Lock(); best = MakeBuild(briand, MakeSets(data.Runes, Attr.HealthPercent, Attr.Null, Attr.Null, r => r.Speed + r.Resistance + r.HealthPercent + r.Accuracy >= 5, new RuneSet[] { RuneSet.Despair, RuneSet.Energy }), s => s.Health / 400 + s.Speed / 3 + s.Accuracy / 2, s => s.Contains(RuneSet.Despair) && s.Contains(RuneSet.Energy), s => s.Health >= 20000);/**/ Console.WriteLine("briand: " + best); best.Lock(); best = MakeBuild(lapis, MakeSets(data.Runes, Attr.AttackPercent, Attr.AttackPercent, Attr.AttackPercent, r => r.Speed + r.AttackPercent * 2 + r.CritRate / 2 + r.CritDamage / 2 >= 5, new RuneSet[] { RuneSet.Vampire, RuneSet.Revenge }), s => s.Attack / 40 + s.Speed / 2, s => s.Contains(RuneSet.Vampire) && s.Contains(RuneSet.Revenge), s => s.Attack >= 1900);/**/ Console.WriteLine("lapis: " + best); best.Lock(); best = MakeBuild(megan, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.Null, r => r.Speed + r.HealthPercent + r.Accuracy >= 5, new RuneSet[] { RuneSet.Swift, RuneSet.Energy }), s => s.Health / 400 + s.Speed / 2 + s.Accuracy, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Energy));/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("megan: " + best); best.Lock(); best = MakeBuild(lyn, MakeSets(data.Runes, Attr.Null, Attr.CritDamage, Attr.Null, r => r.CritRate + r.CritDamage + r.HealthPercent + r.Speed >= 10, new RuneSet[] { RuneSet.Violent, RuneSet.Blade }), s => s.Health / 200 + s.Speed / 2 + s.CritRate * 3 + s.CritDamage * 2 + s.Attack / 80 + s.Defense / 30, s => s.Contains(RuneSet.Violent) && s.Count(r => r == RuneSet.Null) == 1);/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("lyn: " + best); best.Lock(); best = MakeBuild(garoche, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.HealthPercent, r => r.HealthFlat + r.HealthPercent + r.Accuracy + r.Speed >= 12, new RuneSet[] { RuneSet.Focus, RuneSet.Blade, RuneSet.Shield }), s => s.Health / 400 + s.Speed / 2 + s.Accuracy, s => s.Count(q => q == RuneSet.Null) == 0, s => s.Accuracy >= 40 && s.Health >= 13000);/**/ Console.WriteLine("garoche: " + best); best.Lock(); var qq = data.Runes.Where(r => r.Locked == false && r.MainType == Attr.CritDamage && (r.Set == RuneSet.Fatal || r.Set == RuneSet.Blade)).OrderByDescending(r => r.CritDamage).ToArray(); if (qq.Length > 0) { Console.WriteLine(qq[0].ID); } if (qq.Length > 1) { Console.WriteLine(qq[1].ID); } best = MakeBuild(lushen1, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed + r.AttackPercent + r.CritRate + r.CritDamage >= 5, new RuneSet[] { RuneSet.Fatal, RuneSet.Blade }), s => s.Health / 300 + s.Attack / 20 + s.Speed + s.CritRate * 3 + s.CritDamage * 2, s => s.Contains(RuneSet.Fatal) && s.Contains(RuneSet.Blade));/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("lushen1: " + best); best.Lock(); best = MakeBuild(lushen2, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed + r.AttackPercent + r.CritRate + r.CritDamage >= 5, new RuneSet[] { RuneSet.Fatal, RuneSet.Blade }), s => s.Health / 300 + s.Attack / 20 + s.Speed + s.CritRate * 3 + s.CritDamage * 2, s => s.Contains(RuneSet.Fatal) && s.Contains(RuneSet.Blade));/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("lushen2: " + best); best.Lock(); best = MakeBuild(xing, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed + r.AttackPercent + r.CritRate + r.CritDamage + r.HealthPercent >= 10, new RuneSet[] { RuneSet.Energy }), s => s.Health / 100 + s.Attack / 8 + s.Speed + s.CritRate * 4 + s.CritDamage * 3 + s.Defense / 10, s => !s.Contains(RuneSet.Null));/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("xing: " + best); best.Lock(); best = MakeBuild(darion, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed / 2 + r.DefensePercent + r.AttackPercent + r.HealthFlat + r.HealthPercent * 2 >= 10, new RuneSet[] { RuneSet.Energy }), s => s.Health / 200 + s.Attack / 40 + s.Speed / 2 + s.Defense / 30, s => true, s => s.Health >= 15000);/**/ Console.WriteLine("darion: " + best); /* * best = MakeBuild(darion, MakeSets(data.Runes, * r => r.AttackPercent + r.DefensePercent + r.HealthPercent >= 18, * r => r.AttackPercent + r.DefensePercent + r.HealthPercent + r.HealthFlat >= 12), * s => s.Health / 200 + s.Attack / 50 + s.Speed + s.Defense / 25, * s => !s.Contains(RuneSet.Null));/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/** * * Console.WriteLine("darion: " + best); * best.Lock(); */ /* * best = MakeBuild(gina, MakeSets(data.Runes, * r => r.MainType != Attr.CritRate && r.MainType != Attr.CritDamage && r.MainType != Attr.Resistance && (r.Speed + r.HealthPercent > 0), * r => r.Accuracy + r.Speed + r.HealthPercent + r.HealthFlat >= 10), * s => s.Health / 200 + s.Accuracy + s.Speed / 2 + s.Defense / 30, * s => !s.Contains(RuneSet.Null));/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/** * * Console.WriteLine("gina: " + best); * best.Lock(); */ /* * best = MakeBuild(mav, MakeSets(data.Runes, * r => true, * r => true), * s => s.Health, * s => !s.Contains(RuneSet.Null), null);/*, * s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/ * * Console.WriteLine("mav: " + best); * best.Lock(); */ Console.ReadKey(); }
public RuneStat(Rune p, Attr s) { parent = p; stat = s; }
/// <summary> /// Fills the instance with acceptable runes from save /// </summary> /// <param name="save">The Save data that contais the runes</param> /// <param name="useLocked">If it should include locked runes</param> /// <param name="useEquipped">If it should include equipped runes (other than the current monster)</param> public void GenRunes(Save save, bool useLocked = false, bool useEquipped = false, bool saveStats = false) { if (save == null) { return; } if (save.Runes == null) { return; } IEnumerable <Rune> rsGlobal = save.Runes; // Only using 'inventory' or runes on mon if (!useEquipped) { rsGlobal = rsGlobal.Where(r => (r.AssignedName == "Unknown name" || r.AssignedName == mon.Name)); } // only if the rune isn't currently locked for another purpose if (!useLocked) { rsGlobal = rsGlobal.Where(r => r.Locked == false); } // Only runes which we've included rsGlobal = rsGlobal.Where(r => BuildSets.Contains(r.Set)); if (saveStats) { foreach (Rune r in rsGlobal) { r.manageStats_Set++; } } int[] slotFakes = new int[6]; bool[] slotPred = new bool[6]; // For each runeslot for (int i = 0; i < 6; i++) { // put the right ones in runes[i] = rsGlobal.Where(r => r.Slot == i + 1).ToArray(); // crank the rune prediction 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; // default fail OR Predicate <Rune> slotTest = r => false; int and = 0; // this means that runes won't get in unless they meet at least 1 criteria // which tab we pulled the filter from string gotScore = ""; // the value to test SUM against int testVal = 0; // TODO: check what inheriting SUM (eg. Odd and 3) does // TODO: check what inheriting AND/OR then SUM (or visa versa) // find the most significant operatand of joining checks if (runeScoring.ContainsKey("g") && runeFilters.ContainsKey("g") && runeFilters["g"].Any(r => r.Value.NonZero)) { var kv = runeScoring["g"]; gotScore = "g"; and = kv.Key; if (kv.Key == 1) { slotTest = r => true; } else if (kv.Key == 2) { testVal = kv.Value; } } // is it and odd or even slot? string tmk = (i % 2 == 1 ? "e" : "o"); if (runeScoring.ContainsKey(tmk) && runeFilters.ContainsKey(tmk) && runeFilters[tmk].Any(r => r.Value.NonZero)) { var kv = runeScoring[tmk]; gotScore = tmk; and = kv.Key; if (kv.Key == 1) { slotTest = r => true; } else if (kv.Key == 2) { testVal = kv.Value; } } // turn the 0-5 to a 1-6 tmk = (i + 1).ToString(); if (runeScoring.ContainsKey(tmk) && runeFilters.ContainsKey(tmk) && runeFilters[tmk].Any(r => r.Value.NonZero)) { var kv = runeScoring[tmk]; gotScore = tmk; and = kv.Key; if (kv.Key == 1) { slotTest = r => true; } else if (kv.Key == 2) { testVal = kv.Value; } } // if an operand was found, ensure the tab contains filter data if (gotScore != "") { if (runeFilters.ContainsKey(gotScore)) { // if all the filters for the tab are zero if (runeFilters[gotScore].All(r => !r.Value.NonZero)) { // set to OR TRUE slotTest = r => true; and = 0; } } } else { // if there wasn't any relevant data for how to pick runes, just take 'em all! slotTest = r => true; } // pull the filters (flat, perc, test) for all the tabs and stats Dictionary <string, RuneFilter> rfG = new Dictionary <string, RuneFilter>(); if (runeFilters.ContainsKey("g")) { rfG = runeFilters["g"]; } Dictionary <string, RuneFilter> rfM = new Dictionary <string, RuneFilter>(); if (runeFilters.ContainsKey((i % 2 == 1 ? "e" : "o"))) { rfM = runeFilters[(i % 2 == 1 ? "e" : "o")]; } Dictionary <string, RuneFilter> rfS = new Dictionary <string, RuneFilter>(); if (runeFilters.ContainsKey((i + 1).ToString())) { rfS = runeFilters[(i + 1).ToString()]; } // if there where no filters with data bool blank = true; Stats rFlat = new Stats(); Stats rPerc = new Stats(); Stats rTest = new Stats(); foreach (string stat in statNames) { RuneFilter rf = new RuneFilter(); if (rfS.ContainsKey(stat)) { rf = rfS[stat]; if (rfM.ContainsKey(stat)) { rf = RuneFilter.Min(rf, rfM[stat]); } if (rfG.ContainsKey(stat)) { rf = RuneFilter.Min(rf, rfG[stat]); } } else { if (rfM.ContainsKey(stat)) { rf = rfM[stat]; if (rfG.ContainsKey(stat)) { rf = RuneFilter.Min(rf, rfG[stat]); } } else { if (rfG.ContainsKey(stat)) { rf = rfG[stat]; } } } if (rf.NonZero) { // put the most relevant divisor in? rFlat[stat] = rf.Flat; rPerc[stat] = rf.Percent; rTest[stat] = rf.Test; blank = false; } } // TODO: seems like it just ignores all the slotTesting before now // no filter data = use all if (blank) { slotTest = r => true; } else { // Set the test based on the type found if (and == 0) { slotTest = r => r.Or(rFlat, rPerc, rTest, raiseTo, predictSubs); } else if (and == 1) { slotTest = r => r.And(rFlat, rPerc, rTest, raiseTo, predictSubs); } else if (and == 2) { slotTest = r => r.Test(rFlat, rPerc, raiseTo, predictSubs) >= testVal; } } runes[i] = runes[i].Where(r => slotTest.Invoke(r)).ToArray(); if (saveStats) { foreach (Rune r in runes[i]) { r.manageStats_RuneFilt++; } } if (i % 2 == 1) // actually evens because off by 1 { // makes sure that the primary stat type is in the selection if (slotStats[i].Count > 0) { runes[i] = runes[i].Where(r => slotStats[i].Contains(r.MainType.ToForms())).ToArray(); } } if (saveStats) { foreach (Rune r in runes[i]) { r.manageStats_TypeFilt++; } } } // Make sure that for each set type, there are enough slots with runes in them // Eg. if only 1,4,5 have Violent, remove all violent runes because you need 4 // for each included set foreach (RuneSet s in BuildSets) { // find how many slots have acceptable runes for it int slots = 0; for (int i = 0; i < 6; i++) { if (runes[i].Any(r => r.Set == s)) { slots += 1; } } // if there isn't enough slots if (slots < Rune.SetRequired(s)) { // remove that set for (int i = 0; i < 6; i++) { runes[i] = runes[i].Where(r => r.Set != s).ToArray(); } } } }
// Check what sets are completed in this build public void CheckSets() { SetsFull = false; // If there are an odd number of runes, don't bother (maybe even check < 6?) if (runeCount % 2 == 1) { return; } // can only have 3 sets max (eg. energy / energy / blade) sets = new RuneSet[3]; // which set we are looking for int setInd = 0; // what slot we are looking at int slotInd = 0; // if we have used this slot in a set yet bool[] used = new bool[6]; // how many runes are in sets int setNums = 0; // Check slots 1 - 5, minimum set size is 2. // Because it will search forward for sets, can't find more from 6 // Eg. starting from 6, working around, find 2 runes? for (; slotInd < 5; slotInd++) { //if there is a uncounted rune in this slot Rune rune = runes[slotInd]; if (rune != null && used[slotInd] == false) { // look for more in the set RuneSet set = rune.Set; // how many runes we need to get int getNum = Rune.SetRequired(set); // how many we got int gotNum = 1; // we have now used this slot used[slotInd] = true; // for the runes after this rune for (int ind = slotInd + 1; ind < 6; ind++) { // if there is a rune in this slot if (runes[ind] != null) { // that hasn't been counted if (used[ind] == false) { // that is the type I want if (runes[ind].Set == set) { used[ind] = true; gotNum++; } } } // if we have more than 1 rune if (gotNum > 1) { // if we have enough runes for a set if (gotNum == getNum) { // log this set sets[setInd] = set; // increase the number of runes in sets setNums += getNum; // look for the next set setInd++; // stop looking forward break; } } } } } // if all runes are in sets if (setNums == 6) { SetsFull = true; } // notify hackers their attempt has failed else if (setNums > 6) { throw new Exception("Wut"); } }
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; }
// Show the little preview window of the given rune private void ShowRune(Rune rune) { runeBox2.Show(); runeInventory.SetRune(rune); IRuneMain.Text = Rune.StringIt(rune.MainType, rune.MainValue); IRuneInnate.Text = Rune.StringIt(rune.InnateType, rune.InnateValue); IRuneSub1.Text = Rune.StringIt(rune.Sub1Type, rune.Sub1Value); IRuneSub2.Text = Rune.StringIt(rune.Sub2Type, rune.Sub2Value); IRuneSub3.Text = Rune.StringIt(rune.Sub3Type, rune.Sub3Value); IRuneSub4.Text = Rune.StringIt(rune.Sub4Type, rune.Sub4Value); IRuneMon.Text = rune.AssignedName; }
// put this rune on the current build public void ApplyRune(Rune rune) { Current.AddRune(rune); }
private bool GetPts(Rune rune, string tab, string stat, ref int points, int fake, bool pred) { int pts = 0; PropertyInfo[] props = typeof(Rune).GetProperties(); foreach (var prop in props) { } pts += DivCtrl(rune[stat + "flat", fake, pred], tab, stat, "flat"); pts += DivCtrl(rune[stat + "perc", fake, pred], tab, stat, "perc"); points += pts; var lCtrls = this.Controls.Find(tab + "r" + stat + "test", true); var tbCtrls = this.Controls.Find(tab + stat + "test", true); if (lCtrls.Length != 0 && tbCtrls.Length != 0) { var tLab = (Label)lCtrls[0]; var tBox = (TextBox)tbCtrls[0]; tLab.Text = pts.ToString(); tLab.ForeColor = Color.Black; int vs = 1; if (int.TryParse(tBox.Text, out vs)) { if (pts >= vs) { tLab.ForeColor = Color.Green; return true; } else { tLab.ForeColor = Color.Red; return false; } } return true; } return false; }
private void button1_Click(object sender, EventArgs e) { build.GenRunes(Main.data, false, true); using (var ff = new RuneSelect()) { ff.returnedRune = runeTest; ff.build = build; switch (tabControl1.SelectedTab.Text) { case "Evens": ff.runes = Main.data.Runes.Where(r => r.Slot % 2 == 0); List<Rune> fr = new List<Rune>(); fr.AddRange(ff.runes.Where(r => r.Slot == 2 && build.slotStats[1].Contains(r.MainType.ToForms()))); fr.AddRange(ff.runes.Where(r => r.Slot == 4 && build.slotStats[3].Contains(r.MainType.ToForms()))); fr.AddRange(ff.runes.Where(r => r.Slot == 6 && build.slotStats[5].Contains(r.MainType.ToForms()))); ff.runes = fr; break; case "Odds": ff.runes = Main.data.Runes.Where(r => r.Slot % 2 == 1); break; case "Global": ff.runes = Main.data.Runes; break; default: int slot = int.Parse(tabControl1.SelectedTab.Text); ff.runes = Main.data.Runes.Where(r => r.Slot == slot); break; } ff.slot = tabControl1.SelectedTab.Text; ff.runes = ff.runes.Where(r => build.BuildSets.Contains(r.Set)); var res = ff.ShowDialog(); if (res == System.Windows.Forms.DialogResult.OK) { Rune rune = ff.returnedRune; if (rune != null) { runeTest = rune; TestRune(rune); } } } }
private void TestRuneTab(Rune rune, string tab) { bool res = false; if (!build.runeScoring.ContainsKey(tab)) return; int fake = 0; bool pred = false; if (build.runePrediction.ContainsKey(tab)) { fake = build.runePrediction[tab].Key; pred = build.runePrediction[tab].Value; } var kv = build.runeScoring[tab]; int scoring = kv.Key; if (scoring == 1) res = true; int points = 0; foreach (var stat in statNames) { bool s = GetPts(rune, tab, stat, ref points, fake, pred); if (scoring == 1) res &= s; else if (scoring == 0) res |= s; } var ctrl = Controls.Find(tab + "Check", true).FirstOrDefault(); ctrl.Text = res.ToString(); if (scoring == 2) { ctrl.Text = points.ToString(); ctrl.ForeColor = Color.Red; if (points >= build.runeScoring[tab].Value) ctrl.ForeColor = Color.Green; } }
private void TestRune(Rune rune) { if (rune == null) return; // consider moving to the slot tab for the rune foreach (var tab in tabNames) { TestRuneTab(rune, tab); } }
private void rune_Stats(Rune rune) { SRuneMain.Text = Rune.StringIt(rune.MainType, rune.MainValue) + " " + rune.ID; SRuneInnate.Text = Rune.StringIt(rune.InnateType, rune.InnateValue); SRuneSub1.Text = Rune.StringIt(rune.Sub1Type, rune.Sub1Value); SRuneSub2.Text = Rune.StringIt(rune.Sub2Type, rune.Sub2Value); SRuneSub3.Text = Rune.StringIt(rune.Sub3Type, rune.Sub3Value); SRuneSub4.Text = Rune.StringIt(rune.Sub4Type, rune.Sub4Value); SRuneLevel.Text = rune.Level.ToString(); SRuneMon.Text = rune.AssignedName; }
private void ShowRunes(Rune[] rune) { runeControl1.SetRune(rune[0]); runeControl2.SetRune(rune[1]); runeControl3.SetRune(rune[2]); runeControl4.SetRune(rune[3]); runeControl5.SetRune(rune[4]); runeControl6.SetRune(rune[5]); foreach (RuneControl tc in runes) { if (tc.Tag != null) { tc.Show(); } else { tc.Hide(); } } }
public static IEnumerable<Rune>[] MakeSets(IList<Rune> runes, Attr slot2, Attr slot4, Attr slot6, Predicate<Rune> odds, RuneSet[] reqsets = null) { Rune[][] runesSlot = new Rune[6][]; Predicate<Rune> set = r => true; if (reqsets != null) { int reqCount = 0; foreach (RuneSet s in reqsets) reqCount += Rune.SetRequired(s); if (reqCount == 6) set = r => reqsets.Any(s => s == r.Set); } var unlocked = runes.Where(r => !r.Locked).ToArray(); var sets = unlocked.Where(r => set.Invoke(r)).ToArray(); var odd = sets.Where(r => odds.Invoke(r)).ToArray(); runesSlot[0] = odd.Where(r => r.Slot == 1).ToArray(); runesSlot[1] = sets.Where(r => r.Slot == 2 && (r.MainType == slot2 || slot2 == Attr.Null)).ToArray(); runesSlot[2] = odd.Where(r => r.Slot == 3).ToArray(); runesSlot[3] = sets.Where(r => r.Slot == 4 && (r.MainType == slot4 || slot4 == Attr.Null)).ToArray(); runesSlot[4] = odd.Where(r => r.Slot == 5).ToArray(); runesSlot[5] = sets.Where(r => r.Slot == 6 && (r.MainType == slot6 || slot6 == Attr.Null)).ToArray(); foreach (Rune[] rs in runesSlot.Where(r => r.Length == 0)) Console.WriteLine("No runes for slot " + (runesSlot.ToList().IndexOf(rs) + 1) + ":("); return runesSlot; }
/// <summary> /// Original test program. /// Do not use /// </summary> /// <param name="args"></param> static void Main(string[] args) { string save = System.IO.File.ReadAllText("..\\..\\save.json"); Save data = JsonConvert.DeserializeObject<Save>(save); foreach (Monster mon in data.Monsters) { var equipedRunes = data.Runes.Where(r => r.AssignedId == mon.ID); foreach (Rune rune in equipedRunes) { mon.ApplyRune(rune); } var stats = mon.GetStats(); } var rsets = new Rune[(int)RuneSet.Destroy + 1][][]; foreach (RuneSet r in Enum.GetValues(typeof(RuneSet))) { rsets[(int)r] = new Rune[6][]; for (int i = 0; i < 6; ++i) { rsets[(int)r][i] = data.Runes.Where(t => t.Set.Equals(r) && t.Slot == i).ToArray(); } } var veromos = data.GetMonster("Veromos"); var belladeon = data.GetMonster("Belladeon"); var sath = data.GetMonster("Sath"); var verdehile = data.GetMonster("Verdehile"); var acasis = data.GetMonster("Acasis (In Storage)"); var shannon = data.GetMonster("Shannon"); var bernard = data.GetMonster("Bernard"); var chasun = data.GetMonster("Chasun"); var arnold = data.GetMonster("Arnold"); var fuco = data.GetMonster("Fuco"); var ahman = data.GetMonster("Ahman"); var orochi = data.GetMonster("Orochi"); var theomars = data.GetMonster("Theomars"); var basalt = data.GetMonster("Basalt"); var baretta = data.GetMonster("Baretta"); var briand = data.GetMonster("Briand"); var lapis = data.GetMonster("Lapis"); var megan = data.GetMonster("Megan"); var lyn = data.GetMonster("Lyn"); var garoche = data.GetMonster("Garoche (In Storage)"); var lushen1 = data.GetMonster(20); var lushen2 = data.GetMonster(21); var mav = data.GetMonster("Mav"); var darion = data.GetMonster("Darion"); var gina = data.GetMonster("Gina"); var xing = data.GetMonster("Xing Zhe"); foreach (Rune r in data.Runes) { r.Locked = false; } Loadout best; best = MakeBuild(veromos, MakeSets(data.Runes, r => r.MainType == Attr.HealthPercent || r.MainType == Attr.Speed || r.MainType == Attr.Accuracy, r => r.HealthPercent > 0 && r.Speed > 0, new RuneSet[]{RuneSet.Swift, RuneSet.Energy}), s => s.Health, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Energy), s => s.Accuracy >= 60 && s.Speed > 200 && s.Health > 22000); Console.WriteLine("vero: " + best); best.Lock(); best = MakeBuild(belladeon, MakeSets(data.Runes, Attr.Speed, Attr.HealthPercent, Attr.Accuracy, r => r.HealthPercent > 10 || r.Accuracy > 5, new RuneSet[]{RuneSet.Swift, RuneSet.Focus}), s => s.Speed / 3 + s.Defense / 50 + s.Health / 300 - s.CritRate + s.Accuracy / 2, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Focus), s => s.Accuracy >= 70 && s.Speed >= 170 && s.Health >= 15000 && s.Defense >= 950); Console.WriteLine("bella: " + best); best.Lock(); best = MakeBuild(sath, MakeSets(data.Runes, Attr.AttackPercent, Attr.CritRate, Attr.AttackPercent, r => r.Speed > 0 && (r.AttackPercent > 0 || r.CritRate > 0), new RuneSet[] { RuneSet.Swift, RuneSet.Blade }), s => s.Speed + s.CritDamage * 2 + s.Attack / 10 + s.CritRate * 3 - Math.Max(0, s.CritRate - 100) * 3, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Blade), s => s.Attack >= 1900 && s.Speed >= 143 && s.CritRate >= 95); Console.WriteLine("sath: " + best); best.Lock(); best = MakeBuild(verdehile, MakeSets(data.Runes, Attr.Speed, Attr.CritRate, Attr.AttackPercent, r => r.Speed > 0 && (r.HealthPercent > 0 || r.CritRate > 0), new RuneSet[] { RuneSet.Violent, RuneSet.Blade }), s => s.Speed + s.Health / 500 + s.CritRate + s.Attack / 50 + s.Defense / 50, s => s.Contains(RuneSet.Violent) && s.Contains(RuneSet.Blade), s => s.Health >= 10000 && s.Speed >= 120 && s.CritRate >= 95); Console.WriteLine("verd: " + best); best.Lock(); best = MakeBuild(acasis, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.Accuracy, r => r.Accuracy > 0, new RuneSet[] { RuneSet.Despair, RuneSet.Focus }), s => s.Speed + s.Health / 500 + s.Accuracy, s => s.Contains(RuneSet.Despair) && s.Contains(RuneSet.Focus), s => s.Health >= 13000 && s.Speed >= 110 && s.Accuracy >= 80);/**/ Console.WriteLine("acas: " + best); best.Lock(); best = MakeBuild(shannon, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.Accuracy, r => r.Accuracy > 0, new RuneSet[] { RuneSet.Energy, RuneSet.Focus, RuneSet.Focus }), s => s.Defense / 40 + s.Health / 100 + s.Accuracy, s => s.Contains(RuneSet.Energy) && s.Count(r => r == RuneSet.Focus) == 2, s => s.Health >= 12000 && s.Accuracy >= 60);/**/ Console.WriteLine("shann: " + best); best.Lock(); best = MakeBuild(bernard, MakeSets(data.Runes, Attr.Speed, Attr.HealthPercent, Attr.Accuracy, r => r.Accuracy + r.Speed / 2 > 6, new RuneSet[] { RuneSet.Energy, RuneSet.Swift }), s => s.Defense / 40 + s.Health / 100 + s.Accuracy + s.Speed, s => s.Contains(RuneSet.Energy) && s.Contains(RuneSet.Swift), s => s.Health >= 13000 && s.Speed >= 170 && s.Accuracy >= 60);/**/ Console.WriteLine("bern: " + best); best.Lock(); best = MakeBuild(chasun, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.HealthPercent, r => r.HealthPercent >= 10, new RuneSet[] { RuneSet.Energy, RuneSet.Energy, RuneSet.Guard }), s => s.Health / 300 + s.Resistance + s.Speed / 2 - s.CritRate / 2 + s.Accuracy / 2, s => s.Contains(RuneSet.Guard) && s.Count(r => r == RuneSet.Energy) == 2, s => s.Health >= 30000 && s.Resistance >= 80);/**/ Console.WriteLine("chas: " + best); best.Lock(); best = MakeBuild(arnold, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.HealthPercent, r => r.HealthPercent * 2 + r.DefensePercent + r.Speed / 2 >= 8, new RuneSet[] { RuneSet.Guard, RuneSet.Shield, RuneSet.Energy}), s => s.Health / 300 + s.Resistance + s.Speed / 2 - s.CritRate / 2 + s.Accuracy / 2, s => true,//s.Contains(RuneSet.Guard) && s.Contains(RuneSet.Shield), s => s.Health >= 20000);/**/ Console.WriteLine("arn: " + best); best.Lock(); best = MakeBuild(fuco, MakeSets(data.Runes, Attr.Speed, Attr.AttackPercent, Attr.AttackPercent, r => r.Speed > 6 | r.AttackPercent > 6, new RuneSet[] { RuneSet.Swift, RuneSet.Guard }), s => s.Health / 300 + s.Defense + s.Speed + s.Defense / 20 + s.Accuracy / 2, s => s.Contains(RuneSet.Guard) && s.Contains(RuneSet.Swift), s => s.Speed >= 170);/**/ Console.WriteLine("fuco: " + best); best.Lock(); best = MakeBuild(ahman, MakeSets(data.Runes, Attr.HealthPercent, Attr.CritRate, Attr.HealthPercent, r => r.HealthPercent > 0 | r.CritRate > 0, new RuneSet[] { RuneSet.Energy, RuneSet.Blade, RuneSet.Blade }), s => s.CritRate + s.Health / 250 + s.Speed / 3, s => s.Contains(RuneSet.Energy) && s.Count(r => r == RuneSet.Blade) == 2, s => s.Health >= 15000 && s.CritRate >= 90);/**/ Console.WriteLine("ahm: " + best); best.Lock(); best = MakeBuild(orochi, MakeSets(data.Runes, Attr.Speed, Attr.CritRate, Attr.Accuracy, r => r.Accuracy + r.CritRate + r.AttackPercent / 2 + r.HealthPercent / 2 >= 10, new RuneSet[] { RuneSet.Focus, RuneSet.Blade }), s => s.CritRate + s.Health / 500 + s.Speed / 2 + s.Accuracy, s => s.Contains(RuneSet.Focus) && s.Contains(RuneSet.Blade), s => s.Health >= 8000 && s.CritRate >= 90 && s.Accuracy >= 60);/**/ Console.WriteLine("oro: " + best); best.Lock(); best = MakeBuild(theomars, MakeSets(data.Runes, Attr.Speed, Attr.CritDamage, Attr.AttackPercent, r => r.Speed + r.CritRate + r.CritDamage + r.AttackPercent >= 10, new RuneSet[] { RuneSet.Violent, RuneSet.Blade }), s => s.CritRate + s.Health / 500 + s.Speed + s.CritDamage - Math.Max(0, s.CritRate - 61), s => s.Contains(RuneSet.Violent) && s.Contains(RuneSet.Blade), s => s.Health >= 8000 && s.CritRate >= 61 && s.CritDamage >= 100);/**/ Console.WriteLine("theo: " + best); best.Lock(); best = MakeBuild(basalt, MakeSets(data.Runes, Attr.DefensePercent, Attr.DefensePercent, Attr.DefensePercent, r => r.Speed + r.CritRate + r.CritDamage + r.Accuracy + r.DefensePercent >= 10, new RuneSet[] { RuneSet.Violent, RuneSet.Energy }), s => s.Defense / 20 + s.Health / 500 + s.Speed + s.CritDamage, s => s.Contains(RuneSet.Violent) && s.Contains(RuneSet.Energy), s => s.Health >= 9000 && s.Defense >= 1000);/**/ Console.WriteLine("basa: " + best); best.Lock(); best = MakeBuild(baretta, MakeSets(data.Runes, Attr.AttackPercent, Attr.HealthPercent, Attr.Accuracy, r => r.Speed + r.Accuracy + r.HealthPercent >= 10, new RuneSet[] { RuneSet.Swift, RuneSet.Energy }), s => s.Health / 500 + s.Speed + s.Accuracy, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Energy), s => s.Health >= 14000 && s.Speed > 140);/**/ Console.WriteLine("baretta: " + best); best.Lock(); best = MakeBuild(briand, MakeSets(data.Runes, Attr.HealthPercent, Attr.Null, Attr.Null, r => r.Speed + r.Resistance + r.HealthPercent + r.Accuracy >= 5, new RuneSet[] { RuneSet.Despair, RuneSet.Energy }), s => s.Health / 400 + s.Speed / 3 + s.Accuracy / 2, s => s.Contains(RuneSet.Despair) && s.Contains(RuneSet.Energy), s => s.Health >= 20000);/**/ Console.WriteLine("briand: " + best); best.Lock(); best = MakeBuild(lapis, MakeSets(data.Runes, Attr.AttackPercent, Attr.AttackPercent, Attr.AttackPercent, r => r.Speed + r.AttackPercent * 2 + r.CritRate / 2 + r.CritDamage / 2 >= 5, new RuneSet[] { RuneSet.Vampire, RuneSet.Revenge }), s => s.Attack / 40 + s.Speed / 2, s => s.Contains(RuneSet.Vampire) && s.Contains(RuneSet.Revenge), s => s.Attack >= 1900);/**/ Console.WriteLine("lapis: " + best); best.Lock(); best = MakeBuild(megan, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.Null, r => r.Speed + r.HealthPercent + r.Accuracy >= 5, new RuneSet[] { RuneSet.Swift, RuneSet.Energy }), s => s.Health / 400 + s.Speed / 2 + s.Accuracy, s => s.Contains(RuneSet.Swift) && s.Contains(RuneSet.Energy));/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("megan: " + best); best.Lock(); best = MakeBuild(lyn, MakeSets(data.Runes, Attr.Null, Attr.CritDamage, Attr.Null, r => r.CritRate + r.CritDamage + r.HealthPercent + r.Speed >= 10, new RuneSet[] { RuneSet.Violent, RuneSet.Blade }), s => s.Health / 200 + s.Speed / 2 + s.CritRate * 3 + s.CritDamage * 2 + s.Attack / 80 + s.Defense / 30, s => s.Contains(RuneSet.Violent) && s.Count(r => r == RuneSet.Null) == 1);/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("lyn: " + best); best.Lock(); best = MakeBuild(garoche, MakeSets(data.Runes, Attr.HealthPercent, Attr.HealthPercent, Attr.HealthPercent, r => r.HealthFlat + r.HealthPercent + r.Accuracy + r.Speed >= 12, new RuneSet[] { RuneSet.Focus, RuneSet.Blade, RuneSet.Shield }), s => s.Health / 400 + s.Speed / 2 + s.Accuracy, s => s.Count(q => q == RuneSet.Null) == 0, s => s.Accuracy >= 40 && s.Health >= 13000);/**/ Console.WriteLine("garoche: " + best); best.Lock(); var qq = data.Runes.Where(r => r.Locked == false && r.MainType == Attr.CritDamage && (r.Set == RuneSet.Fatal || r.Set == RuneSet.Blade)).OrderByDescending(r => r.CritDamage).ToArray(); if (qq.Length > 0) Console.WriteLine(qq[0].ID); if (qq.Length > 1) Console.WriteLine(qq[1].ID); best = MakeBuild(lushen1, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed + r.AttackPercent + r.CritRate + r.CritDamage >= 5, new RuneSet[] { RuneSet.Fatal, RuneSet.Blade }), s => s.Health / 300 + s.Attack / 20 + s.Speed + s.CritRate * 3 + s.CritDamage * 2, s => s.Contains(RuneSet.Fatal) && s.Contains(RuneSet.Blade));/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("lushen1: " + best); best.Lock(); best = MakeBuild(lushen2, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed + r.AttackPercent + r.CritRate + r.CritDamage >= 5, new RuneSet[] { RuneSet.Fatal, RuneSet.Blade }), s => s.Health / 300 + s.Attack / 20 + s.Speed + s.CritRate * 3 + s.CritDamage * 2, s => s.Contains(RuneSet.Fatal) && s.Contains(RuneSet.Blade));/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("lushen2: " + best); best.Lock(); best = MakeBuild(xing, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed + r.AttackPercent + r.CritRate + r.CritDamage + r.HealthPercent >= 10, new RuneSet[] { RuneSet.Energy}), s => s.Health / 100 + s.Attack / 8 + s.Speed + s.CritRate * 4 + s.CritDamage * 3 + s.Defense / 10, s => !s.Contains(RuneSet.Null));/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/**/ Console.WriteLine("xing: " + best); best.Lock(); best = MakeBuild(darion, MakeSets(data.Runes, Attr.Null, Attr.Null, Attr.Null, r => r.Speed / 2 + r.DefensePercent + r.AttackPercent + r.HealthFlat + r.HealthPercent * 2 >= 10, new RuneSet[] { RuneSet.Energy }), s => s.Health / 200 + s.Attack / 40 + s.Speed / 2 + s.Defense / 30, s => true, s => s.Health >= 15000);/**/ Console.WriteLine("darion: " + best); /* best = MakeBuild(darion, MakeSets(data.Runes, r => r.AttackPercent + r.DefensePercent + r.HealthPercent >= 18, r => r.AttackPercent + r.DefensePercent + r.HealthPercent + r.HealthFlat >= 12), s => s.Health / 200 + s.Attack / 50 + s.Speed + s.Defense / 25, s => !s.Contains(RuneSet.Null));/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/** Console.WriteLine("darion: " + best); best.Lock(); */ /* best = MakeBuild(gina, MakeSets(data.Runes, r => r.MainType != Attr.CritRate && r.MainType != Attr.CritDamage && r.MainType != Attr.Resistance && (r.Speed + r.HealthPercent > 0), r => r.Accuracy + r.Speed + r.HealthPercent + r.HealthFlat >= 10), s => s.Health / 200 + s.Accuracy + s.Speed / 2 + s.Defense / 30, s => !s.Contains(RuneSet.Null));/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/** Console.WriteLine("gina: " + best); best.Lock(); */ /* best = MakeBuild(mav, MakeSets(data.Runes, r => true, r => true), s => s.Health, s => !s.Contains(RuneSet.Null), null);/*, s => s.Accuracy >= 50 && s.Health >= 15000 && s.Speed > 130);/ Console.WriteLine("mav: " + best); best.Lock(); */ Console.ReadKey(); }
/// <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()); } } }
// NYI rune comparison public EquipCompare CompareTo(Rune rhs) { if (Set != rhs.Set) return EquipCompare.Unknown; if (HealthPercent < rhs.HealthPercent) return EquipCompare.Worse; if (AttackPercent < rhs.AttackPercent) return EquipCompare.Worse; if (DefensePercent < rhs.DefensePercent) return EquipCompare.Worse; if (Speed < rhs.Speed) return EquipCompare.Worse; if (CritRate < rhs.CritRate) return EquipCompare.Worse; if (CritDamage < rhs.CritDamage) return EquipCompare.Worse; if (Accuracy < rhs.Accuracy) return EquipCompare.Worse; if (Resistance < rhs.Resistance) return EquipCompare.Worse; return EquipCompare.Better; }
// Put the rune on the build public void AddRune(Rune rune) { // don't bother if not a rune if (rune == null) return; if (runes[rune.Slot - 1] == null) runeCount++; runes[rune.Slot - 1] = rune;//new Rune(rune); if (runeCount % 2 == 0) CheckSets(); }