/// <summary> /// Retrieve Trainer Tree /// List of MiniLines Containing Skill and attached Skill count (2 and 3 attachments supported) /// </summary> /// <param name="living"></param> public virtual List <Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > > > GetTrainerTreeDisplay(GameLiving living, Type type) { if (typeof(MiniLineSpecialization).IsAssignableFrom(type)) { var minispecs = SkillBase.GetSpecializationByType(type).OrderBy(e => e.KeyName); List <Tuple <MiniLineSpecialization, List <Skill> > > allLines = new List <Tuple <MiniLineSpecialization, List <Skill> > >(); foreach (var spec in minispecs) { MiniLineSpecialization minispec = (MiniLineSpecialization)spec; minispec.Level = living.GetBaseSpecLevel(minispec.KeyName); allLines.Add(new Tuple <MiniLineSpecialization, List <Skill> >(minispec, minispec.GetMiniLineSkillsForLiving(living, MaxChampionSpecLevel).Select(t => t.Item1).ToList())); } var final = new List <Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > > >(); // Find intersecting Lines for (int i = 0; i < MaxChampionSpecLevel; i++) { var grouped = allLines.Where(l => l.Item2.Count > i).GroupBy(l => new { l.Item2[i].Name, l.Item2[i].ID }).Where(grp => grp.Count() > 1 && grp.Count() < 4).Select(grp => grp.OrderBy(msp => msp.Item1.KeyName)); foreach (var groups in grouped) { // Champion display only handle these tree merge if (groups.Count() == 3) { byte index = 0; foreach (var tsp in groups) { final.Add(new Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > >( tsp.Item1, tsp.Item2.Take(index == 1 ? tsp.Item2.Count : i) .Select(e => new Tuple <Skill, byte>(e, 0)).ToList())); allLines.Remove(tsp); index++; } // Set group int ins = final.Count - 2; var skill = final[ins].Item2[i]; final[ins].Item2[i] = new Tuple <Skill, byte>(skill.Item1, 3); } else if (groups.Count() == 2) { // firsts lines foreach (var tsp in groups) { final.Add(new Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > >( tsp.Item1, tsp.Item2.Take(i) .Select(e => new Tuple <Skill, byte>(e, 0)).ToList())); allLines.Remove(tsp); } // Remaining int ins = final.Count - 1; final.Insert(ins, new Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > >( groups.First().Item1, groups.First().Item2.Skip(i).Select(e => new Tuple <Skill, byte>(e, 0)).ToList())); // Set Group and add "nulls" for (int n = 0; n < i; n++) { final[ins].Item2.Insert(0, new Tuple <Skill, byte>(null, 0)); } var skill = final[ins].Item2[i]; final[ins].Item2[i] = new Tuple <Skill, byte>(skill.Item1, 2); } } } Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > > pivot = final.Count > 0 ? final[0] : null; // Insert not intersecting lines (try keeping order) foreach (var elem in allLines) { var item = new Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > >(elem.Item1, elem.Item2 .Select(e => new Tuple <Skill, byte>(e, 0)) .ToList()); if (pivot != null && elem.Item1.KeyName.CompareTo(pivot.Item1.KeyName) <= 0) { // insert int ins = final.FindIndex(el => el == pivot); if (ins > -1) { final.Insert(ins, item); } else { final.Insert(0, item); } } else { // add final.Add(item); } } return(final); } // default return(new List <Tuple <MiniLineSpecialization, List <Tuple <Skill, byte> > > >()); }
/// <summary> /// Retrieve Trainer Tree /// List of MiniLines Containing Skill and attached Skill count (2 and 3 attachments supported) /// </summary> /// <param name="living"></param> public virtual List<Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>> GetTrainerTreeDisplay(GameLiving living, Type type) { if (typeof(MiniLineSpecialization).IsAssignableFrom(type)) { var minispecs = SkillBase.GetSpecializationByType(type).OrderBy(e => e.KeyName); List<Tuple<MiniLineSpecialization, List<Skill>>> allLines = new List<Tuple<MiniLineSpecialization, List<Skill>>>(); foreach (var spec in minispecs) { MiniLineSpecialization minispec = (MiniLineSpecialization)spec; minispec.Level = living.GetBaseSpecLevel(minispec.KeyName); allLines.Add(new Tuple<MiniLineSpecialization, List<Skill>>(minispec, minispec.GetMiniLineSkillsForLiving(living, MaxChampionSpecLevel).Select(t => t.Item1).ToList())); } var final = new List<Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>>(); // Find intersecting Lines for (int i = 0 ; i < MaxChampionSpecLevel ; i++) { var grouped = allLines.Where(l => l.Item2.Count > i).GroupBy(l => new { l.Item2[i].Name, l.Item2[i].ID }).Where(grp => grp.Count() > 1 && grp.Count() < 4).Select(grp => grp.OrderBy(msp => msp.Item1.KeyName)); foreach (var groups in grouped) { // Champion display only handle these tree merge if (groups.Count() == 3) { byte index = 0; foreach(var tsp in groups) { final.Add(new Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>(tsp.Item1, tsp.Item2.Take(index == 1 ? tsp.Item2.Count : i) .Select(e => new Tuple<Skill, byte>(e, 0)).ToList())); allLines.Remove(tsp); index++; } // Set group int ins = final.Count - 2; var skill = final[ins].Item2[i]; final[ins].Item2[i] = new Tuple<Skill, byte>(skill.Item1, 3); } else if (groups.Count() == 2) { // firsts lines foreach(var tsp in groups) { final.Add(new Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>(tsp.Item1, tsp.Item2.Take(i) .Select(e => new Tuple<Skill, byte>(e, 0)).ToList())); allLines.Remove(tsp); } // Remaining int ins = final.Count - 1; final.Insert(ins, new Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>( groups.First().Item1, groups.First().Item2.Skip(i).Select(e => new Tuple<Skill, byte>(e, 0)).ToList())); // Set Group and add "nulls" for (int n = 0 ; n < i ; n++) final[ins].Item2.Insert(0, new Tuple<Skill, byte>(null, 0)); var skill = final[ins].Item2[i]; final[ins].Item2[i] = new Tuple<Skill, byte>(skill.Item1, 2); } } } Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>> pivot = final.Count > 0 ? final[0] : null; // Insert not intersecting lines (try keeping order) foreach (var elem in allLines) { var item = new Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>(elem.Item1, elem.Item2 .Select(e => new Tuple<Skill, byte>(e, 0)) .ToList()); if (pivot != null && elem.Item1.KeyName.CompareTo(pivot.Item1.KeyName) <= 0) { // insert int ins = final.FindIndex(el => el == pivot); if (ins > -1) { final.Insert(ins, item); } else { final.Insert(0, item); } } else { // add final.Add(item); } } return final; } // default return new List<Tuple<MiniLineSpecialization, List<Tuple<Skill, byte>>>>(); }