public static int[][] GetPowerSet(int n) { //There is no reason to generate a new version of a power set everytime we need one //They're just a description of the laws of the universe if (PowerSets.ContainsKey(n)) { return(PowerSets[n]); } else { return(PowerSets[n] = EnumeratePowerSet(n)); } }
public List <PowerEntry>?Parse() { Regex r; Regex rs; Match m; Match ms; string cnt; int i; var p = new RawPowerData { Valid = false }; var powerSlots = new List <RawEnhData>(); var e = new RawEnhData(); var listPowers = new List <PowerEntry>(); try { cnt = File.ReadAllText(BuildString); } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace); return(null); } cnt = Regex.Replace(cnt, @"[\r\n]", "\r\n"); // Line conversion to PC/Win format (just in case) cnt = Regex.Replace(cnt, @"\<br \/\>", string.Empty); // For good ol' Mids 1.962 support cnt = Regex.Replace(cnt, @"\ \;", " "); // Nbsp html entities to spaces cnt = Regex.Replace(cnt, @" {2,}", "\t"); // Note: [JS] Use of \s here break newlines // Compact a little those modern builds cnt = Regex.Replace(cnt, @"\t{2,}", "\t"); cnt = Regex.Replace(cnt, @"(\r\n){2,}", "\r\n"); // Alignment, builder software and version // Note: old Pine Hero Designer is listed as 'Hero Hero Designer' // Extended: Rogue/Vigilante will be added in a later release. r = new Regex(@"(Hero|Villain|Rogue|Vigilante) Plan by ([a-zA-Z\:\'\s]+) ([0-9\.]+)"); m = r.Match(cnt); if (!m.Success) { _ = MessageBox.Show( "This build cannot be recovered because it doesn't contain a valid plain text part.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } CharacterInfo.Alignment = m.Groups[1].Value; BuilderApp.Software = m.Groups[2].Value; BuilderApp.Version = m.Groups[3].Value; // Character name, level, origin and archetype r = new Regex(@"([^\r\n\t]+)\: Level ([0-9]{1,2}) ([a-zA-Z]+) ([a-zA-Z ]+)"); m = r.Match(cnt); if (!m.Success) { // Name is empty rs = new Regex(@"Level ([0-9]{1,2}) ([a-zA-Z]+) ([a-zA-Z ]+)"); ms = rs.Match(cnt); CharacterInfo.Name = string.Empty; CharacterInfo.Level = Convert.ToInt32(ms.Groups[1].Value, null); CharacterInfo.Origin = ms.Groups[2].Value; CharacterInfo.Archetype = ms.Groups[3].Value; } else { CharacterInfo.Name = m.Groups[1].Value; CharacterInfo.Level = Convert.ToInt32(m.Groups[2].Value, null); CharacterInfo.Origin = m.Groups[3].Value; CharacterInfo.Archetype = m.Groups[4].Value; } SetCharacterInfo(); // Main powersets r = new Regex(@"(Primary|Secondary) Power Set\: ([^\r\n\t]+)"); m = r.Match(cnt); while (m.Success) { PowerSets.Add(m.Groups[2].Value); m = m.NextMatch(); } // Pools and Ancillary/Epic powersets r = new Regex(@"(Power|Ancillary) Pool\: ([^\r\n\t]+)"); m = r.Match(cnt); while (m.Success) { if (m.Groups[2].Value != "Fitness") { PowerSets.Add(m.Groups[2].Value); } m = m.NextMatch(); } // Powers string PSlotsStr; string[] PSlots; string[] s; string? sContentEnh; r = new Regex(@"Level ([0-9]{1,2})\:\t([^\t]+)\t([^\r\n\t]+)"); m = r.Match(cnt); while (m.Success) { p = new RawPowerData(); e = new RawEnhData(); p.Slots = new List <RawEnhData>(); p.DisplayName = m.Groups[2].Value.Trim(); p.Level = Convert.ToInt32(m.Groups[1].Value, null); p.pData = DatabaseAPI.GetPowerByDisplayName(p.DisplayName, DatabaseAPI.GetArchetypeByName(CharacterInfo.Archetype).Idx); p.Powerset = p.pData != null?DatabaseAPI.GetPowersetByIndex(p.pData.PowerSetIndex) : null; p.Valid = CheckValid(p.pData); PSlotsStr = m.Groups.Count > 3 ? m.Groups[3].Value.Trim() : string.Empty; if (!string.IsNullOrEmpty(PSlotsStr)) { // Extract enhancement name and slot level ('A' for power inherent slot) // Handle special enhancements with parenthesis like ExpRnf-+Res(Pets)(50) PSlotsStr = Regex.Replace(PSlotsStr, @"\(([^A0-9]+)\)", "[$1]"); PSlots = Regex.Split(PSlotsStr, @",\s"); for (i = 0; i < PSlots.Length; i++) { s = Regex.Split(PSlots[i], @"/[\(\)]"); s = Array.FindAll(s, e => !string.IsNullOrWhiteSpace(e)); sContentEnh = s[0] == "Empty" ? null : ShortNamesConversion(s[0]); // Enhancement name (Enhancement.ShortName) try { e.InternalName = s[0]; e.Level = s[1] == "A" ? 0 : Convert.ToInt32(s[1], null); // Slot level ("A" is the auto-granted one) e.Boosters = 0; // Not handled e.HasCatalyst = false; e.eData = DatabaseAPI.GetEnhancementByUIDName(e.InternalName); p.Slots.Add(e); } catch (FormatException) // if (isNaN(s[1] { e.InternalName = "Empty"; e.Level = 0; e.Boosters = 0; e.HasCatalyst = false; e.eData = -1; p.Slots.Add(e); } } } if (p.Valid) { if (CheckValid(p.Powerset)) { PowerSets.Add(p.Powerset.FullName); } AddPowerToBuildSheet(p, ref listPowers); } } return(listPowers); }
public List <PowerEntry>?Parse() { Regex r; Match m; Regex r1; Regex r2; Regex r3; Match m1; Match m2; Match m3; string rawPowerset; var p = new RawPowerData { Valid = false }; var powerSlots = new List <RawEnhData>(); RawEnhData e; var listPowers = new List <PowerEntry>(); string[] powerIDChunks; r1 = new Regex(@"^Level ([0-9]+)\: (.+)$"); // Picked power r2 = new Regex(@"^[\t\s]*EMPTY$"); // Empty enhancement slot r3 = new Regex(@"^[\t\s]*([0-9a-zA-Z\+\:\-_]+) \(([0-9]+)(\+([1-5]))?\)$"); // Filled enhancement slot var line = -1; string lineText; using var streamReader = new StreamReader(BuildString); while ((lineText = streamReader.ReadLine()) != null) { line++; if (line == 0) { // Name, Level, Origin, ClassID r = new Regex(@"^([^\:]+)\: Level ([0-9]+) ([a-zA-Z]+) ([a-zA-Z_]+)$"); m = r.Match(lineText); if (!m.Success) { MessageBox.Show("This build cannot be imported because it doesn't match the expected format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } CharacterInfo.Name = m.Groups[1].Value; CharacterInfo.Archetype = m.Groups[4].Value.Replace("Class_", string.Empty); CharacterInfo.Origin = m.Groups[3].Value; CharacterInfo.Level = Convert.ToInt32(m.Groups[2].Value, null); SetCharacterInfo(); } else if (line < HeaderSize) { continue; } m1 = r1.Match(lineText); m2 = r2.Match(lineText); m3 = r3.Match(lineText); if (m1.Success) { if (p.Valid) { AddPowerToBuildSheet(p, ref listPowers); } powerIDChunks = m1.Groups[2].Value.Split(' '); rawPowerset = (powerIDChunks[0] + "." + powerIDChunks[1]).Trim(); p.FullName = m1.Groups[2].Value.Replace(" ", "."); p.Powerset = DatabaseAPI.GetPowersetByName(rawPowerset); p.pData = DatabaseAPI.GetPowerByFullName(p.FullName); if (p.pData == null) { p.FullName = FixKheldPowerNames(p.FullName); powerIDChunks = p.FullName.Split('.'); rawPowerset = (powerIDChunks[0] + "." + powerIDChunks[1]).Trim(); p.Powerset = DatabaseAPI.GetPowersetByName(rawPowerset); p.pData = DatabaseAPI.GetPowerByFullName(p.FullName); } p.Valid = CheckValid(p.pData); p.Level = Convert.ToInt32(m1.Groups[1].Value, null); p.Slots = new List <RawEnhData>(); if (CheckValid(p.Powerset)) { PowerSets.Add(p.Powerset.FullName); } } else if (m2.Success) { // Empty slot e = new RawEnhData { InternalName = "Empty", Level = 0, Boosters = 0, HasCatalyst = false, eData = -1 }; p.Slots.Add(e); } else if (m3.Success) { // Enhancement: internal name, level, (dummy), boosters e = new RawEnhData(); e.InternalName = DatabaseAPI.GetEnhancementBaseUIDName(m3.Groups[1].Value); e.Level = Convert.ToInt32(m3.Groups[2].Value, null); e.Boosters = (m3.Groups.Count > 3) & !string.IsNullOrWhiteSpace(m3.Groups[4].Value) ? Convert.ToInt32(m3.Groups[4].Value, null) : 0; e.HasCatalyst = DatabaseAPI.EnhHasCatalyst(m3.Groups[1].Value); e.eData = DatabaseAPI.GetEnhancementByUIDName(e.InternalName); p.Slots.Add(e); } } streamReader.Close(); if (p.Valid) { AddPowerToBuildSheet(p, ref listPowers); } return(listPowers); }