public static bool VehicleMaterialOnCopyBuildGizmo(Vector2 topLeft, float maxWidth, BuildableDef ___entDef, ref GizmoResult __result, Command __instance) { if (___entDef is VehicleBuildDef def) { __result = RenderHelper.GizmoOnGUIWithMaterial(__instance, new Rect(topLeft.x, topLeft.y, __instance.GetWidth(maxWidth), 75f), def); if (def.MadeFromStuff) { Designator_Dropdown.DrawExtraOptionsIcon(topLeft, __instance.GetWidth(maxWidth)); } return(false); } return(true); }
// Architect Menu: public static void ArchitectMenu_ChangeLocation(string newDefName, bool loadingOnStartup = false) { // Utils.Warn(Utils.DBF.Settings, "SettingsChanged()"); DesignationCategoryDef prevDesignationCatDef; if (loadingOnStartup) { prevDesignationCatDef = DefDatabase <DesignationCategoryDef> .GetNamed(architectMenuDefaultDesigCatDef); } else { prevDesignationCatDef = DefDatabase <DesignationCategoryDef> .GetNamed(architectMenuDesigCatDef, false); } // If switching to default, put default into def database. if (newDefName == architectMenuDefaultDesigCatDef) { ArchitectMenu_Show(); } // Compatibility Logic: // If certain mods are loaded and all storage units are to go in one menu, // maybe we want to remove the other menu? Or maybe we want to use that // one by default: // For Deep Storage, if the player also has Quantum Storage, use their menu insead: if (architectMenuMoveALLStorageItems && !architectMenuAlwaysShowCategory && newDefName == architectMenuDefaultDesigCatDef && ModLister.GetActiveModWithIdentifier("Cheetah.QuantumStorageRedux") != null) { newDefName = "QSRStorage"; } DesignationCategoryDef newDesignationCatDef = DefDatabase <DesignationCategoryDef> .GetNamed(newDefName); if (newDesignationCatDef == null) { Log.Warning("LWM.DeepStorage: Failed to find menu category " + newDefName + " - reverting to default"); newDefName = architectMenuDefaultDesigCatDef; ArchitectMenu_Show(); newDesignationCatDef = DefDatabase <DesignationCategoryDef> .GetNamed(newDefName); } // Architect Menu: Specify all your buildings/etc: // var allMyBuildings=DefDatabase<ThingDef>.AllDefsListForReading.FindAll(x=>x.HasComp(etc))); List <ThingDef> itemsToMove = LoadedDeepStorageUnits.ToList(); // We can move ALL the storage buildings! If the player wants. I do. List <DesignationCategoryDef> desigsToNotMove = new List <DesignationCategoryDef>(); List <DesignationCategoryDef> desigsToOnlyCopy = new List <DesignationCategoryDef>(); if (architectMenuMoveALLStorageItems) { // Log.Error("Trying to mvoe everythign:"); // Don't move hoppers, etc: desigsToNotMove.Add(DefDatabase <DesignationCategoryDef> .GetNamed("Production")); // Don't move Replimat either: // (hoppers, etc.) // Note that it's possible the ReplimatFeedTank should be copied to Storage, // but I think it's okay to leave it in Replimat. DesignationCategoryDef tmp = DefDatabase <DesignationCategoryDef> .GetNamed("Replimat_Replimat", false); if (tmp != null) { desigsToNotMove.Add(tmp); } // TODO: get these categories in a more flexible way! // ProjectRimFactory has several subclasses of Building_Storage that are in the Industrial category. // Several users of PRF have gotten confused when they couldn't find the storage things. DesignationCategoryDef industrialCategory = DefDatabase <DesignationCategoryDef> .GetNamed("Industrial", false); // So we COULD remove those storage buildings from our list too: // if (industrialCategory!=null) desigsToNotMove.Add(industrialCategory); // But, let's just copy them: if (industrialCategory != null) { desigsToOnlyCopy.Add(industrialCategory); } // Bonus PRF: DocWorld changes the designation from Industrial to DZ_Industrial. // Get them both: industrialCategory = DefDatabase <DesignationCategoryDef> .GetNamed("DZ_Industrial", false); if (industrialCategory != null) { desigsToOnlyCopy.Add(industrialCategory); } // Interesting detail: apparently it IS possible to have thingDefs with null thingClass... weird. itemsToMove = DefDatabase <ThingDef> .AllDefsListForReading .FindAll(x => ((x?.thingClass != null) && (x.thingClass == typeof(Building_Storage) || x.thingClass.IsSubclassOf(typeof(Building_Storage))) && x.designationCategory != null && !desigsToNotMove.Contains(x.designationCategory) //&& !toCopy.Contains(x.designationCategory) )); /*if (ModLister.GetActiveModWithIdentifier("spdskatr.projectrimfactory")!=null) { * if (industrialCategory==null) { * Log.Warning("LWM.DeepStorage: menu compatibility with Project RimFactory failed: could not find Industrial cat"); * } else { * * } * }*/ // testing: // itemsToMove.AddRange(DefDatabase<ThingDef>.AllDefsListForReading.FindAll(x=>x.defName.Contains("MURWallLight"))); } Utils.Mess(Utils.DBF.Settings, "Moving these units to 'Storage' menu: " + string.Join(", ", itemsToMove)); // get access to a DesignationCategoryDef's resolvedDesignators: var _resolvedDesignatorsField = typeof(DesignationCategoryDef) .GetField("resolvedDesignators", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); foreach (var d in itemsToMove) { if (d.designationCategory == null) { continue; // very very possible } // Log.Error("Moving item "+d.defName+" (category: "+(d.designationCategory!=null?d.designationCategory.ToString():"NONE")); List <Designator> resolvedDesignators = (List <Designator>)_resolvedDesignatorsField.GetValue(d.designationCategory); if (d.designatorDropdown == null) { // Log.Message("No dropdown"); // easy case: // Old menu location: if (!desigsToOnlyCopy.Contains(d.designationCategory)) { // Log.Message(" Removed this many entries in "+d.designationCategory+": "+ resolvedDesignators.RemoveAll(x => ((x is Designator_Build) && ((Designator_Build)x).PlacingDef == d)); } // ); // Now do new: resolvedDesignators = (List <Designator>)_resolvedDesignatorsField.GetValue(newDesignationCatDef); // To make sure there are no duplicates: resolvedDesignators.RemoveAll(x => ((x is Designator_Build) && ((Designator_Build)x).PlacingDef == d)); resolvedDesignators.Add(new Designator_Build(d)); } else { // Log.Warning("LWM.DeepStorage: ThingDef "+d.defName+" has a dropdown Designator."); // Hard case: Designator_Dropdowns! Designator_Dropdown dd = (Designator_Dropdown)resolvedDesignators.Find(x => (x is Designator_Dropdown) && ((Designator_Dropdown)x).Elements .Find(y => (y is Designator_Build) && ((Designator_Build)y).PlacingDef == d) != null); if (dd != null) { // Log.Message("Found dropdown designator for "+d.defName); if (!desigsToOnlyCopy.Contains(d.designationCategory)) { resolvedDesignators.Remove(dd); } // Switch to new category: resolvedDesignators = (List <Designator>)_resolvedDesignatorsField.GetValue(newDesignationCatDef); if (!resolvedDesignators.Contains(dd)) { // Log.Message(" Adding to new category "+newDesignationCatDef); resolvedDesignators.Add(dd); } // } else { //debug // Log.Message(" ThingDef "+d.defName+" has designator_dropdown "+d.designatorDropdown.defName+ // ", but cannot find it in "+d.designationCategory+" - this is okay if something else added it."); } } d.designationCategory = newDesignationCatDef; } // Flush designation category defs:.....dammit // foreach (var x in DefDatabase<DesignationCategoryDef>.AllDefs) { // x.ResolveReferences(); // } // prevDesignationCatDef?.ResolveReferences(); // newDesignationCatDef.ResolveReferences(); //ArchitectMenu_ClearCache(); // we do this later one way or another // To remove the mod's DesignationCategoryDef from Architect menu: // remove it from RimWorld.MainTabWindow_Architect's desPanelsCached. // To do that, we remove it from the DefDatabase and then rebuild the cache. // Removing only the desPanelsCached entry does work: the entry is // recreated when a new game is started. So if the options are changed // and then a new game started...the change gets lost. // So we have to update the DefsDatabase. // This is potentially difficult: the .index can get changed, and that // can cause problems. But nothing seems to use the .index for any // DesignationCategoryDef except for the menu, so manually adjusting // the DefsDatabase is safe enough: if (!architectMenuAlwaysShowCategory && newDefName != architectMenuDefaultDesigCatDef) { ArchitectMenu_Hide(); // ArchitectMenu_ClearCache(); //hide flushes cache // if (tmp.AllResolvedDesignators.Count <= tmp.specialDesignatorClasses.Count) // isCategoryEmpty=false; /* * // Log.Message("Removing old menu!"); * // DefDatabase<DesignationCategoryDef>.Remove(tmp); * if (!tmp.AllResolvedDesignators.NullOrEmpty()) { * foreach (var d in tmp.AllResolvedDesignators) { * if (!tmp.specialDesignatorClasses.Contains(d)) { * isCategoryEmpty=false; * break; * } * } * } */ // if (isCategoryEmpty) } else { // Simply flush cache: ArchitectMenu_ClearCache(); } // Note that this is not perfect: if the default menu was already open, it will still be open (and // empty) when the settings windows are closed. Whatever. // Oh, and actually change the setting that's stored: architectMenuDesigCatDef = newDefName; // Finally, if Extended Storage(!) is loaded, and we took all their // storage items, remove their menu as well: DesignationCategoryDef tmpD; if (ModLister.HasActiveModWithName("Extended Storage") && ((tmpD = DefDatabase <DesignationCategoryDef> .GetNamed("FurnitureStorage", false)) != null) && !architectMenuAlwaysShowCategory && architectMenuDesigCatDef != "FurnitureStorage") { // DefDatabase<DesignationCategoryDef>.Remove(tmpD); typeof(DefDatabase <>).MakeGenericType(new Type[] { typeof(DesignationCategoryDef) }) .GetMethod("Remove", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) .Invoke(null, new object [] { tmpD }); } /* List<ArchitectCategoryTab> archMenu=(List<ArchitectCategoryTab>)Harmony.AccessTools * .Field(typeof(RimWorld.MainTabWindow_Architect), "desPanelsCached") * .GetValue((MainTabWindow_Architect)MainButtonDefOf.Architect.TabWindow); * archMenu.RemoveAll(t=>t.def.defName==architectMenuDefaultDesigCatDef); * * archMenu.Add(new ArchitectCategoryTab(newDesignationCatDef)); * archMenu.Sort((a,b)=>a.def.order.CompareTo(b.def.order)); * archMenu.SortBy(a=>a.def.order, b=>b.def.order); // May need (type of var a)=>... * */ /* Harmony.AccessTools.Method(typeof(RimWorld.MainTabWindow_Architect), "CacheDesPanels") * .Invoke(((MainTabWindow_Architect)MainButtonDefOf.Architect.TabWindow), null);*/ /* * * if (architectMenuDesignationCatDefDefName=="LWM_DS_Storage") { // default * if (DefDatabase<DesignationCategoryDef>.GetNamedSilentFail("LWM_DS_Storage") == null) { * Utils.Mess(Utils.DBF.Settings,"Adding 'Storage' to the architect menu."); * DefDatabase<DesignationCategoryDef>.Add(architectLWM_DS_Storage_DesignationCatDef); * } else { * Utils.Mess(Utils.DBF.Settings, "No need to add 'Storage' to the architect menu."); * } * architectCurrentDesignationCatDef=architectLWM_DS_Storage_DesignationCatDef; * } else { * // remove our "Storage" from the architect menu: * Utils.Mess(Utils.DBF.Settings,"Removing 'Storage' from the architect menu."); * DefDatabase<DesignationCategoryDef>.AllDefsListForReading.Remove(architectLWM_DS_Storage_DesignationCatDef); * if (DefDatabase<DesignationCategoryDef>.GetNamedSilentFail("LWM_DS_Storage") != null) { * Log.Error("Failed to remove LWM_DS_Storage :("+DefDatabase<DesignationCategoryDef>.GetNamedSilentFail("LWM_DS_Storage")); * } * * architectCurrentDesignationCatDef=DefDatabase<DesignationCategoryDef>.GetNamed(architectMenuDesignationCatDefDefName); * } * prevDesignationCatDef?.ResolveReferences(); * architectCurrentDesignationCatDef.ResolveReferences(); * * Harmony.AccessTools.Method(typeof(RimWorld.MainTabWindow_Architect), "CacheDesPanels") * .Invoke((), null); */ Utils.Warn(Utils.DBF.Settings, "Settings changed architect menu"); }
//public void Add(Designator des) public static void Postfix(Designator_Dropdown __instance, List <Designator> ___elements) { __instance.order = ___elements.Sum(d => d.order) / ___elements.Count(); }
public static void Postfix(Designator_Dropdown __instance) { __instance.order = 20f; }