private static BodyPartGroup BuildTree(List <BodyPartGroupDef> defs) { // Create our root node, holds no data. var root = new BodyPartGroup(null, null); foreach (var child in BuildTreeHelper(root, defs)) { root.AddChild(child); } return(root); }
private static IEnumerable <BodyPartGroup> BuildTreeHelper(BodyPartGroup curParent, IEnumerable <BodyPartGroupDef> defs) { // We are given a parent, and a list of defs, and we aim to return a list of // `BodyPartGroupDef`s in order of their `listOrder` which all are <= to their parent // in vanilla, I claim that we can observe that 'associated' BodyPartGroupDefs are // given similar `listOrder` values. For example. Upper Head > Ears > Teeth > Eyes // and, more notably, all associated records fall in the range // [parentListOrder, parentListOrder - 9). We use this to group records by their // associated defs if (defs.EnumerableNullOrEmpty()) { yield break; } // Find the current largest def that we have in our current list, according // to the `listOrder` var curHead = defs.MaxBy(def => def.listOrder); while (curHead != null) { // We now have a potential parent, we will now check to see if it // has any children, remembering that children of this def have a // list order x in the range [x, x - 9) var group = new BodyPartGroup(curParent, curHead); var children = GatherChildren(group, defs .Where(def => def.listOrder < curHead.listOrder && def.listOrder >= curHead.listOrder - 9) .ToList()); foreach (var child in children) { group.AddChild(child); } // return this current sub-tree yield return(group); // when defs aren't associated, there is simply another def with an arbitrary but // lower value than that of the def we just returned. var options = defs.Where(d => d.listOrder <= group.def.listOrder - 10); if (options.EnumerableNullOrEmpty()) { yield break; } curHead = options.MaxBy(def => def.listOrder); } }