static MonstrousThingDefGenerator() { IEnumerable <ThingDef> enumerable = MonstrousThingDefGenerator.ImpliedMonstrousDefs(); foreach (ThingDef current in enumerable) { current.PostLoad(); DefDatabase <ThingDef> .Add(current); } CrossRefLoader.ResolveAllWantedCrossReferences(FailMode.Silent); }
public override void PostLoad() { var mod = ( from m in LoadedModManager.RunningMods where m.Name == requiredMod select m ).FirstOrDefault(); if (mod == null) { #if DEBUG Log.Message("Miniaturisation :: Skipping " + requiredMod); #endif return; } Log.Message("Miniaturisation :: Found " + requiredMod + " (" + targetsDefNames.Count + ")"); var things = ( from m in LoadedModManager.RunningMods from def in m.AllDefs where targetsDefNames.Contains(def.defName) && def.GetType() == typeof(ThingDef) select def ); foreach (Def thing in things) { #if DEBUG Log.Message("> " + thing.defName); #endif CrossRefLoader.RegisterObjectWantsCrossRef(thing, thingDef_minifiedDef, "MinifiedFurniture"); } // don't waste hashes //base.PostLoad (); }
public static ThingDef GenerateMonstrousDef(ThingDef oldDef) { ThingDef newDef = new ThingDef(); try { #region baseproperties //Copy every base thing //newDef.Verbs = oldDef.Verbs; //Pawn_MeleeVerbs tempVerbs = oldDef.Verbs; newDef.tradeTags = new List <string>(); //Cthulhu.Utility.DebugReport("trade tags"); newDef.altitudeLayer = oldDef.altitudeLayer; newDef.category = oldDef.category; newDef.thingClass = oldDef.thingClass; newDef.selectable = oldDef.selectable; newDef.tickerType = TickerType.Normal; newDef.useHitPoints = oldDef.useHitPoints; newDef.hasTooltip = oldDef.hasTooltip; newDef.alwaysHaulable = oldDef.alwaysHaulable; newDef.socialPropernessMatters = oldDef.socialPropernessMatters; newDef.pathCost = oldDef.pathCost; newDef.tradeability = oldDef.tradeability; newDef.soundImpactDefault = oldDef.soundImpactDefault; newDef.inspectorTabs = new List <Type>(); foreach (Type tab in oldDef.inspectorTabs) { newDef.inspectorTabs.Add(tab); //Cthulhu.Utility.DebugReport("Added " + tab.ToString()); } newDef.inspectorTabsResolved = new List <InspectTabBase>(); foreach (InspectTabBase tab in oldDef.inspectorTabsResolved) { newDef.inspectorTabsResolved.Add(tab); } newDef.comps = new List <CompProperties>(); foreach (CompProperties comp in oldDef.comps) { newDef.comps.Add(comp); } newDef.drawGUIOverlay = oldDef.drawGUIOverlay; #endregion baseproperties //Copy every animal base thing newDef.statBases = new List <StatModifier>(); foreach (StatModifier mod in oldDef.statBases) { newDef.statBases.Add(mod); } newDef.race = oldDef.race; newDef.recipes = new List <RecipeDef>(); foreach (RecipeDef recipe in oldDef.recipes) { newDef.recipes.Add(recipe); } foreach (string s in oldDef.tradeTags) { newDef.tradeTags.Add(s); } if (newDef.thingCategories == null) { newDef.thingCategories = new List <ThingCategoryDef>(); } string oldName = oldDef.defName; string newName = Regex.Replace(oldName, "[0-9]", ""); if (!newName.Contains("Monstrous")) { newName = newName + "_Monstrous"; } Cthulhu.Utility.DebugReport(oldName); Cthulhu.Utility.DebugReport(newName); newDef.defName = oldDef.defName + "_Monstrous"; newDef.label = "Monstrous " + oldDef.label; newDef.description = oldDef.description; CrossRefLoader.RegisterListWantsCrossRef <ThingCategoryDef>(newDef.thingCategories, "Animal"); } catch (Exception e) { Log.Error(e.ToString()); } return(newDef); }
internal static void LoadAllPlayData(bool recovering = false) { if (PlayDataLoader.Loaded) { Log.Error("Loading play data when already loaded. Call ClearAllPlayData first."); } else { queueRecovering = false; queueLoadAllPlayData = false; DeepProfiler.Start("LoadAllPlayData"); try { DoPlayLoad(); } catch (Exception ex) { if (!Prefs.ResetModsConfigOnCrash) { throw; } else if (recovering) { Log.Warning("Could not recover from errors loading play data. Giving up."); throw; } else { IEnumerable <ModMetaData> activeMods = ModsConfig.ActiveModsInLoadOrder; if (Enumerable.Count <ModMetaData>(activeMods) == 1 && Enumerable.First <ModMetaData>(activeMods).IsCoreMod) { throw; } else { Log.Warning("Caught exception while loading play data but there are active mods other than Core. Resetting mods config and trying again.\nThe exception was: " + (object)ex); try { PlayDataLoader.ClearAllPlayData(); } catch { Log.Warning("Caught exception while recovering from errors and trying to clear all play data. Ignoring it.\nThe exception was: " + (object)ex); } ModsConfig.Reset(); CrossRefLoader.Clear(); PostLoadInitter.Clear(); PlayDataLoader.LoadAllPlayData(true); return; } } } finally { DeepProfiler.End(); } // A14 - PlayDataLoader.loaded is now private, Loaded property is getter only PlayDataLoader_loaded.SetValue(null, false); if (!recovering) { return; } Log.Message("Successfully recovered from errors and loaded play data."); DelayedErrorWindowRequest.Add(Translator.Translate("RecoveredFromErrorsText"), Translator.Translate("RecoveredFromErrorsDialogTitle")); } }
private void OverrideDataFromXml(XmlNode xmlRoot, Verse.Def destinationDef, bool debug) { Type destinationType = destinationDef.GetType(); string prefix = "Override :: " + destinationDef + " :: "; foreach (XmlNode node in xmlRoot.ChildNodes) { // field we are about to change string name = node.Name; if (name == null // may cause save issues if these change || name == "shortHash" || name == "index" || name == "debugRandomId") { continue; } string text = node.InnerText; Mode mode = getMode(node); if (string.IsNullOrEmpty(text) && mode != Mode.Clear) { // removal must be explicit replace or it's ignored continue; } if (name == "defName") { // not allowed to change target defName // we use it for tracking if (debug) { Log.Message(prefix + text); } prefix = "Override :: " + text + " :: "; continue; } FieldInfo destinationField = destinationType.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (destinationField == null) { Log.Warning(prefix + "\"" + name + "\" not found in target"); continue; } Type destinationFieldType = destinationField.FieldType; object destinationValue; if (mode == Mode.Clear && !destinationFieldType.IsPrimitive) { // we are clearing // primitives can't be null, set to 0 ? destinationValue = null; destinationField.SetValue(destinationDef, destinationValue); if (debug) { Log.Message(prefix + "\"" + name + "\" has been set to null"); } } else { destinationValue = destinationField.GetValue(destinationDef); } if (destinationFieldType.HasGenericDefinition(typeof(List <>))) { // its a list, search the source and queue or insert Type[] genericArguments = destinationFieldType.GetGenericArguments(); // Is it a def or derivate? Type targetDefType = null; foreach (Type t in genericArguments) { if (typeof(Verse.Def).IsAssignableFrom(t)) { targetDefType = t; break; } } // sometimes, they don't exist. Don't worry, no one will interfere. if (destinationValue == null) { destinationValue = Activator.CreateInstance(destinationFieldType); destinationField.SetValue(destinationDef, destinationValue); if (debug) { Log.Message(prefix + "\"" + name + "\" has been set to \"" + destinationValue + "\""); } } FieldParser parserFactory = getParserFactory(node); Func <XmlNode, object> parser = parserFactory.makeParser(genericArguments); // compares destination and result. Only available for Replace mode FieldComparer comparer = mode == Mode.Replace ? getComparer(node, genericArguments) : null; if (targetDefType != null) { // Crossreferencing a List needs the generic method MethodInfo crossRefLoader_RegisterListWantsCrossRef_generic = crossRefLoader_RegisterListWantsCrossRef.MakeGenericMethod(targetDefType); foreach (XmlNode child in node.ChildNodes) { object[] parameters = new object[] { destinationValue, child.InnerText }; crossRefLoader_RegisterListWantsCrossRef_generic.Invoke(null, parameters); if (debug) { Log.Message(prefix + "Registered into \"" + name + "\" the value \"" + child.InnerText + "\" of type \"" + targetDefType + "\""); } } } else { if (parser == null) { Log.Warning(prefix + "Parser is null"); continue; } IList destinationList = (IList)destinationValue; foreach (XmlNode child in node.ChildNodes) { object result = parser(child); if (result == null) { // no nulls allowed, they are troublemakers Log.Warning(prefix + "Can't Add null into \"" + name + "\""); continue; } if (mode == Mode.Replace) { if (comparer == null) { Log.Warning(prefix + "No known comparer for \"" + name + "\""); break; } Action findAndReplace = delegate { bool found = false; int index; for (index = 0; index < destinationList.Count; index++) { if (comparer.Compare(result, destinationList [index])) { destinationList [index] = result; found = true; break; } } if (found) { if (debug) { Log.Message(prefix + "Replaced into postion " + index + " at \"" + name + "\" the value \"" + result + "\""); } } else { destinationList.Add(result); if (debug) { Log.Message(prefix + "Added into \"" + name + "\" the value \"" + result + "\""); } } }; if (comparer.delay) { resolveReferencesActionQueue.Enqueue(findAndReplace); if (debug) { Log.Message(prefix + "Delaying Replace of element in \"" + name + "\" list"); } } else { findAndReplace(); } } else if (mode == Mode.Append) { destinationList.Add(result); if (debug) { Log.Message(prefix + "Added into \"" + name + "\" the value \"" + result + "\""); } } else { int index = mode == Mode.Insert ? getIndex(child, destinationList) : 0; destinationList.Insert(index, result); if (debug) { Log.Message(prefix + "Inserted into position " + index + " at \"" + destinationField.Name + "\" the value \"" + result + "\""); } } } } } else if (destinationFieldType.HasGenericDefinition(typeof(Dictionary <, >))) { // its a dict, what do we do? Log.Warning(prefix + "We don't know how to override Dictionary yet..."); } else if (typeof(Verse.Def).IsAssignableFrom(destinationFieldType)) { // its a Def, queue CrossRefLoader.RegisterObjectWantsCrossRef(destinationDef, destinationField, text); if (debug) { Log.Message(prefix + "Registered \"" + name + "\" with value \"" + destinationValue + "\" of type \"" + destinationFieldType.Name + "\" into \"" + text + "\""); } } else if (ParseHelper.HandlesType(destinationFieldType)) { // it can be handled by ParserHelper object result = ParseHelper.FromString(text, destinationFieldType); destinationField.SetValue(destinationDef, result); if (debug) { Log.Message(prefix + "Set \"" + name + "\" with value \"" + destinationValue + "\" of type \"" + destinationFieldType.Name + "\" into \"" + text + "\""); } } else { // it's most likely an object, try XmlToObject. FieldParser parserFactory = getParserFactory(node); Func <XmlNode, object> parser = parserFactory.makeParser(destinationFieldType); object result = null; if (parser != null) { result = parser(node); } if (result != null) { // this may fail, try catch? destinationField.SetValue(destinationDef, result); if (debug) { Log.Message(prefix + "Set \"" + name + "\" with value \"" + destinationValue + "\" of type \"" + destinationFieldType.Name + "\" into \"" + result + "\""); } } else { // user entered null Log.Warning(prefix + "Can't Set \"" + name + "\""); } } } }