//=====================================================================================================\\ internal void ModifyStackSizes() { List <ModDefinition> mods = this.getSupportedMods(); List <Category> processingOrder = new List <Category>(_PROCESSING_ORDER); // going to break nested loops using -1 as a flag // reverse the order of things so we can go backwards mods.Reverse(); processingOrder.Reverse(); List <string[]> csvData = null; IndividualOverrides overrides = new IndividualOverrides(); bool writeCSV = this.settings.IsDebug; if (writeCSV) { csvData = new List <string[]>(); } ; Dictionary <Category, bool> parsedSettings = _PROCESSING_ORDER .ToDictionary(x => x, y => this.settings.Values[y].ParseBuffer()); foreach (ThingDef thing in DefDatabase <ThingDef> .AllDefs) { if (isStackIncreaseAllowed(thing)) { //string startingLimit = thing.stackLimit.ToString(); string startingLimit = CategorySetting.GetBaseStackLimit(thing).ToString(); // unless altered in a match function // its whatever it started out as string limitAfterMatchProcessed = string.Empty + startingLimit; // category for CSV string category = "Other " + this.settings.Values[Category.Other].ToString(); string support = string.Empty; bool match = false; // check for overrides first int itemOverride = overrides.GetItemLevelOverride(thing.defName); if (itemOverride > 0) { match = true; thing.stackLimit = itemOverride; category = "UserOverride.SetStackLimit(" + thing.defName + ": " + itemOverride + ")"; support = "Overrides.xml"; } // category level local override check if (overrides.IsCategoryBanned(thing.FirstThingCategory.ToString())) { match = true; thing.stackLimit = 1; category = "UserOverride.BanStacking(Category: " + thing.FirstThingCategory.ToString() + ")"; support = "Overrides.xml"; } // cascaded through other mod tweeks // and vanilla rimworld if (!match) { for (int m = mods.Count - 1; m > -1; m--) { if (mods[m].IsNonStackable(thing)) { match = true; category = "StackChangeForbidden"; support = mods[m].GetType().ToString(); break; } for (int c = processingOrder.Count - 1; c > -1; c--) { List <Func <ThingDef, bool> > fns = mods[m].GetCategoryFunctions(processingOrder[c]); if (fns != null) { foreach (Func <ThingDef, bool> fn in fns) { match = fn.Invoke(thing); limitAfterMatchProcessed = thing.stackLimit.ToString(); // for CSV if (match) { if (parsedSettings[processingOrder[c]]) { // successful parse from // the settings menu this.settings.Values[processingOrder[c]].ProcessThing(thing, _activeThings); } category = processingOrder[c].ToString() + " " + this.settings.Values[processingOrder[c]].ToString(); support = mods[m].GetType().ToString(); m = c = -1; // break all loops break; } } } } } } if (!match) { // still stackable, but not specifically // targeted. use the 'other' setting this.settings.Values[Category.Other].ProcessThing(thing, _activeThings); support = "OgreStack.Other"; } if (thing.stackLimit > 1) { thing.drawGUIOverlay = true; if (thing.resourceReadoutPriority == ResourceCountPriority.Uncounted) { // these appear to be all the legs/arms/bionics // in 'uncounted', but they need to be counted in order // for bills to work correctly for the do until 'X' // setting priority to middle is enough to get it flagged // but the Defs in ResourceCounter looks to be populated aready thing.resourceReadoutPriority = ResourceCountPriority.Middle; } } if (writeCSV) { csvData.Add(new string[] { thing.defName, thing.FirstThingCategory.ToString(), startingLimit, limitAfterMatchProcessed, category, thing.stackLimit.ToString(), support }); } } } // this clears the resource counter dictionary // and re adds all the defs that should be countable // some ones that were not countable, are countable now // like stacked bionics RimWorld.ResourceCounter.ResetDefs(); if (writeCSV) { csvData = csvData .OrderBy(x => x[1]) // category .ThenBy(x => x[0]) // defname .ToList <string[]>(); // Make a Header Row csvData.Insert(0, new string[] { "DefName", "RimWorldCategory", "DefaultStackBase", "AlteredBase", "OgreStackCategory(FixedBase)", "FinalStackLimit", "Support" }); try { DataUtil.WriteFisherPriceCSV(csvData, "OgreStack_DefsList.csv"); Verse.Log.Message("[OgreStack]: Write Defs CSV => [" + DataUtil.GenerateFilePath("OgreStack_DefsList.csv").Replace("/", "\\") + "]"); } catch (System.IO.IOException ex) { if (Regex.IsMatch(ex.Message, "sharing violation", RegexOptions.IgnoreCase)) { Verse.Log.Warning("[OgreStack]: Cannot Write 'OgreStack_DefsList.csv'. Make sure you don't have the file open so OgreStack can overwrite it."); Verse.Log.Warning(ex.Message); } } csvData.Clear(); csvData = null; } Verse.Log.Message("[OgreStack]: Modify Stack Sizes Complete"); }
//=====================================================================================================\\ public void ProcessThing(ThingDef def, Dictionary <string, List <Thing> > activeThings) { int baseCount = CategorySetting.GetBaseStackLimit(def); int stackLimit = 1; if (this.Mode == MultiplierMode.Fixed) { stackLimit = Math.Max(1, (int)Math.Floor(this.Value)); } else { int b = Math.Max(1, baseCount); stackLimit = Math.Max(1, (int)Math.Floor(b * this.Value)); } def.stackLimit = stackLimit; if (activeThings != null) { List <Thing> things = null; if (activeThings.TryGetValue(def.defName, out things)) { foreach (Thing t in things) { if (t != null && t.def != null) { if (t.stackCount > stackLimit) { ThingDef stuff = t.Stuff == null ? null : t.Stuff; // if the stack of things is forbidden // make the stacks generated from it // also forbidden bool isForbidden = false; if (t is ThingWithComps) { RimWorld.CompForbiddable comp = (t as ThingWithComps).GetComp <RimWorld.CompForbiddable>(); if (comp != null) { isForbidden = comp.Forbidden; } } for (int over = t.stackCount - stackLimit; over > 0; over = over - stackLimit) { Thing remain = ThingMaker.MakeThing(t.def, stuff); remain.stackCount = Math.Min(over, stackLimit); remain.HitPoints = Math.Min(t.HitPoints, remain.MaxHitPoints); if (isForbidden) { (remain as ThingWithComps).GetComp <RimWorld.CompForbiddable>().Forbidden = true; } Verse.GenPlace.TryPlaceThing(remain, t.Position, t.Map, ThingPlaceMode.Near); } t.stackCount = stackLimit; } } } } } }