public static IEnumerable <MorphDef> GetAllMorphsInClass([NotNull] this AnimalClassBase classDef) { if (classDef == null) { throw new ArgumentNullException(nameof(classDef)); } if (_morphsUnderCache.TryGetValue(classDef, out List <MorphDef> morphs)) { return(morphs); } morphs = new List <MorphDef>(); if (classDef is MorphDef morph) { morphs.Add(morph); _morphsUnderCache[classDef] = morphs; return(morphs); } IEnumerable <AnimalClassBase> preorder = TreeUtilities.Preorder(classDef, c => c.Children); foreach (MorphDef morphDef in preorder.OfType <MorphDef>()) { morphs.Add(morphDef); } _morphsUnderCache[classDef] = morphs; return(morphs); }
static AnimalClassUtilities() { foreach (AnimalClassDef animalClassDef in DefDatabase <AnimalClassDef> .AllDefs) { animalClassDef.FindChildren(); //have to do this after all other def's 'ResolveReferences' have been called } foreach (AnimalClassDef animalClassDef in DefDatabase <AnimalClassDef> .AllDefs) { if (animalClassDef.parent != null) { continue; } if (animalClassDef != AnimalClassDefOf.Animal) { Log.Warning($"{animalClassDef.defName} does not have a parent! only {nameof(AnimalClassDefOf.Animal)} should not have a parent!"); } } if (CheckForCycles()) //don't precede if there are any cycles in the tree { throw new InvalidDataException("detected cycles in animal class tree!"); //not sure what we should throw here, but we can't continue with } //cycles in the class tree //save the pre and post order traversal orders for performance reasons PostorderTreeInternal = TreeUtilities.Postorder <AnimalClassBase>(AnimalClassDefOf.Animal, c => c.Children); PreorderTreeInternal = TreeUtilities.Preorder <AnimalClassBase>(AnimalClassDefOf.Animal, c => c.Children).ToList(); string treeStr = TreeUtilities.PrettyPrintTree <AnimalClassBase>(AnimalClassDefOf.Animal, a => a.Children, a => ((Def)a).defName); Log.Message(treeStr); //print a pretty tree c: }