diff --git a/Assemblies/0Harmony.dll b/Assemblies/0Harmony.dll index f6120e2..a95b6df 100644 Binary files a/Assemblies/0Harmony.dll and b/Assemblies/0Harmony.dll differ diff --git a/Assemblies/ExtendedStorage.dll b/Assemblies/ExtendedStorage.dll index 5ad6bfb..8e87bac 100644 Binary files a/Assemblies/ExtendedStorage.dll and b/Assemblies/ExtendedStorage.dll differ diff --git a/Assemblies/_harmonycheck.dll b/Assemblies/_harmonycheck.dll new file mode 100644 index 0000000..916bd98 Binary files /dev/null and b/Assemblies/_harmonycheck.dll differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b1b23..5ef12dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,19 @@ -# Version 2.5(???) +# Version 3.0.1 + + +## Bugfixes +- Changes to storage priority correctly trigger hauling jobs to & from Extended Storage buildings +- Correctly update total item count label when partial stack is used from output slot. +- Move single non-max stacks from input cell to output. +- Fix error for reinstalled non empty Extended Storage buildings. +- Disallowing & reallowing a stored item while paused will no longer eject the stored item from storage after unpause. + +## New features +- Skip now officially supports storing stone chunks +- (Debug) options in God mode (Allow switching displayed filter between User & Storage settings. User settings are default, storage settings are what is actually currently stored in the building). +- Upgrade Harmony to 1.0.9.1 + +# Version 3.0 _Upgrading to this version in an existing savegame is fully supported._ diff --git a/Defs/ThingDefs/Storage/Storage_Skip.xml b/Defs/ThingDefs/Storage/Storage_Skip.xml index 34b7b38..3d2afe7 100644 --- a/Defs/ThingDefs/Storage/Storage_Skip.xml +++ b/Defs/ThingDefs/Storage/Storage_Skip.xml @@ -39,6 +39,7 @@
  • ResourcesRaw
  • +
  • StoneChunks
  • diff --git a/Source/ExtendedStorage/Building_ExtendedStorage.cs b/Source/ExtendedStorage/Building_ExtendedStorage.cs index f7867ef..fe3b640 100644 --- a/Source/ExtendedStorage/Building_ExtendedStorage.cs +++ b/Source/ExtendedStorage/Building_ExtendedStorage.cs @@ -10,15 +10,19 @@ namespace ExtendedStorage { - public class Building_ExtendedStorage : Building_Storage + public interface IUserSettingsOwner : IStoreSettingsParent { + void Notify_UserSettingsChanged(); + } + + + public class Building_ExtendedStorage : Building_Storage, IUserSettingsOwner { #region fields internal Graphic _gfxStoredThing; private string _label; private ThingDef _storedThingDef; - internal Thing _suppressedDrawCandidate; private Func> Building_GetGizmos; private IntVec3 inputSlot; @@ -27,23 +31,18 @@ public class Building_ExtendedStorage : Building_Storage private Action queuedTickAction; internal string label; - public StorageSettings userSettings; - - internal static Action SetSettingsChanged; + public UserSettings userSettings; #endregion - static Building_ExtendedStorage() - { - SetSettingsChanged = Access.GetFieldSetter("settingsChangedCallback"); - } - #region Properties public bool AtCapacity => StoredThingTotal >= ApparentMaxStorage; - public int ApparentMaxStorage => (int) (StoredThingDef?.stackLimit*this.GetStatValue(DefReferences.Stat_ES_StorageFactor) ?? Int32.MaxValue); + public int ApparentMaxStorage => StoredThingDef == null + ? Int32.MaxValue + : (int) (StoredThingDef.stackLimit*this.GetStatValue(DefReferences.Stat_ES_StorageFactor)); public IntVec3 OutputSlot => outputSlot; @@ -85,7 +84,6 @@ public IEnumerable StoredThings public override string LabelNoCount => label; - #endregion #region Base overrides @@ -107,38 +105,27 @@ public override void DrawGUIOverlay() GenMapUI.DrawThingLabel(StoredThings.First(), _label, labelColor); } + public override void Draw() + { + base.Draw(); + if (true == StoredThingDef?.IsApparel) + return; + + _gfxStoredThing?.DrawFromDef( + Gen.TrueCenter(OutputSlot, Rot4.North, IntVec2.One, Altitudes.AltitudeFor(AltitudeLayer.Item)), + Rot4.North, + StoredThingDef); + } + public override void ExposeData() { base.ExposeData(); Scribe_Defs.Look(ref _storedThingDef, "storedThingDef"); - Scribe_Deep.Look(ref userSettings, "userSettings"); + Scribe_Deep.Look(ref userSettings, "userSettings", this); if (Scribe.mode != LoadSaveMode.Saving || this.label != null) { Scribe_Values.Look(ref label, "label", def.label, false); } - - // we need to re-apply our callback on the userSettings after load. - // in addition, we need some migration code for handling mid-save upgrades. - // todo: the migration part of this can be removed on the A17 update. - if (Scribe.mode == LoadSaveMode.PostLoadInit) - { - // migration - if (userSettings == null) - { - // create 'user' storage settings - userSettings = new StorageSettings(this); - - // copy over previous filter/priority - userSettings.filter.CopyAllowancesFrom(settings.filter); - userSettings.Priority = settings.Priority; - - // apply currently stored logic - Notify_StoredThingDefChanged(); - } - - // re-apply callback - SetSettingsChanged(userSettings.filter, Notify_UserSettingsChanged); - } } public override IEnumerable GetGizmos() @@ -204,14 +191,11 @@ public override void PostMake() base.PostMake(); // create 'user' storage settings - userSettings = new StorageSettings(this); + userSettings = new UserSettings(this); // copy over default filter/priority if (def.building.defaultStorageSettings != null) userSettings.CopyFrom(def.building.defaultStorageSettings); - - // change callback to point to our custom logic - SetSettingsChanged(userSettings.filter, Notify_UserSettingsChanged); } @@ -269,6 +253,8 @@ public override void Tick() base.Tick(); if (this.IsHashIntervalTick(10)) { + TryGrabOutputItem(); + queuedTickAction?.Invoke(); queuedTickAction = null; @@ -278,12 +264,22 @@ public override void Tick() } } + private void TryGrabOutputItem() + { + if (StoredThingDef == null) + { + StoredThingDef = Find.VisibleMap.thingGrid.ThingsAt(outputSlot).Where(userSettings.AllowedToAccept).FirstOrDefault()?.def; + InvalidateThingSection(_storedThingDef); + } + } + #endregion #region Notification handlers public void Notify_UserSettingsChanged() { + // the vanilla StorageSettings.TryNotifyChanged will alert the SlotGroupManager that // storage settings have changed. We don't need this behaviour for user settings, as these // don't directly influence the slotgroup, and any changes we make are propagated to the @@ -303,7 +299,24 @@ public void Notify_UserSettingsChanged() else { TryUnstackStoredItems(); + var storedDef = StoredThingDef; StoredThingDef = null; + InvalidateThingSection(storedDef); + } + } + + /// + /// Checks if the storedDef has a mapMesh painting - if so, invalidate the apppropriate SectionLayer (needed for + /// chunks to appear immediately while game is paused & exclusion by filter) + /// + private void InvalidateThingSection(ThingDef storedDef) + { + switch (storedDef?.drawerType) + { + case DrawerType.MapMeshOnly: + case DrawerType.MapMeshAndRealTime: + Map?.mapDrawer.SectionAt(OutputSlot).RegenerateLayers(MapMeshFlag.Things); + break; } } @@ -460,6 +473,7 @@ private IEnumerable SplurgeThings(IEnumerable things, IntVec3 cent private void TryMoveItem() { Thing input = StoredThingAtInput; + if (input == null) return; @@ -500,9 +514,9 @@ internal void TrySplurgeStoredItems() SplurgeThings(storedThings, outputSlot, true); SoundDef.Named("DropPodOpen").PlayOneShot(new TargetInfo(outputSlot, Map, false)); + StoredThingDef = null; } - /// /// we can't really dump items immediately - otherwise typical use scenarios like "clear all, reselect X" would dump items immediately /// @@ -519,12 +533,13 @@ private void TryUnstackStoredItems() if (validThings.Length != 0) SoundDef.Named("DropPodOpen").PlayOneShot(new TargetInfo(outputSlot, Map, false)); }; + } /// /// Update necessary data for label & icon overrides /// - private void UpdateCachedAttributes() + public void UpdateCachedAttributes() { if (StoredThingDef != null) { @@ -561,19 +576,16 @@ private void UpdateCachedAttributes() _gfxStoredThing = (StoredThingDef.graphic as Graphic_StackCount) ?.SubGraphicForStackCount(Math.Min(total, StoredThingDef.stackLimit), StoredThingDef) ?? StoredThingDef.graphic; - _suppressedDrawCandidate = items[0]; } else { _gfxStoredThing = null; - _suppressedDrawCandidate = null; } } else { _label = null; _gfxStoredThing = null; - _suppressedDrawCandidate = null; } } } diff --git a/Source/ExtendedStorage/ExtendedStorage.csproj b/Source/ExtendedStorage/ExtendedStorage.csproj index a4eb700..a8b9771 100644 --- a/Source/ExtendedStorage/ExtendedStorage.csproj +++ b/Source/ExtendedStorage/ExtendedStorage.csproj @@ -71,14 +71,18 @@ True LanguageKeys.Generated.tt - + + + + - + - + - + + diff --git a/Source/ExtendedStorage/ExtendedStorage.csproj.DotSettings b/Source/ExtendedStorage/ExtendedStorage.csproj.DotSettings index 9032b44..a885cd9 100644 --- a/Source/ExtendedStorage/ExtendedStorage.csproj.DotSettings +++ b/Source/ExtendedStorage/ExtendedStorage.csproj.DotSettings @@ -1,4 +1,5 @@  True True + True True \ No newline at end of file diff --git a/Source/ExtendedStorage/Patches/CompressibilityDeciderUtility_IsSaveCompressible.cs b/Source/ExtendedStorage/Patches/CompressibilityDeciderUtility_IsSaveCompressible.cs new file mode 100644 index 0000000..fbb6734 --- /dev/null +++ b/Source/ExtendedStorage/Patches/CompressibilityDeciderUtility_IsSaveCompressible.cs @@ -0,0 +1,16 @@ +using System.Reflection; +using Harmony; +using RimWorld; +using Verse; + +namespace ExtendedStorage { + + [HarmonyPatch(typeof(CompressibilityDeciderUtility), nameof(CompressibilityDeciderUtility.IsSaveCompressible))] + class CompressibilityDeciderUtility_IsSaveCompressible { + + public static void Postfix(ref bool __result, Thing t) + { + __result = __result && !(t.GetSlotGroup()?.parent is Building_ExtendedStorage); + } + } +} diff --git a/Source/ExtendedStorage/Patches/ITab_Storage_FillTab.cs b/Source/ExtendedStorage/Patches/ITab_Storage_FillTab.cs index 5649341..7af4b9d 100644 --- a/Source/ExtendedStorage/Patches/ITab_Storage_FillTab.cs +++ b/Source/ExtendedStorage/Patches/ITab_Storage_FillTab.cs @@ -1,8 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using Harmony; using RimWorld; +using UnityEngine; +using Verse; namespace ExtendedStorage { @@ -11,6 +15,8 @@ public class ITab_Storage_FillTab { private static readonly PropertyInfo piSelStoreSettingsParent; + public static bool showStoreSettings = false; + static ITab_Storage_FillTab() { // accessor for private field @@ -41,7 +47,7 @@ public static StorageSettings GetSettings(RimWorld.ITab_Storage tab, out IStoreS { ITab_Storage extended = tab as ITab_Storage; - if (extended == null) + if (extended == null || (DebugSettings.godMode && showStoreSettings)) { parent = GetSelStoreSettingsParent(tab); return parent.GetStoreSettings(); @@ -52,6 +58,26 @@ public static StorageSettings GetSettings(RimWorld.ITab_Storage tab, out IStoreS return building?.userSettings; } + /// + /// Add debug dropdown to toggle displayed settings to tab. Only visible in GodMode. + /// + public static void Postfix(RimWorld.ITab_Storage __instance) { + if (!DebugSettings.godMode || !(__instance is ITab_Storage)) + return; + + Rect rect = new Rect(160f+10f+5f, 10f, 100f, 29f); + + Text.Font = GameFont.Tiny; + if (Widgets.ButtonText(rect, $"[Debug] {(showStoreSettings ? "Store" : "User")}", true, false, true)) { + List list = new List + { + new FloatMenuOption("User", () => { showStoreSettings = false; }), + new FloatMenuOption("Store", () => { showStoreSettings = true; }) + }; + Find.WindowStack.Add(new FloatMenu(list)); + } + } + /// /// Changes the IL code so the patched method beginning is functionally changed from diff --git a/Source/ExtendedStorage/Patches/StorageSettings.cs b/Source/ExtendedStorage/Patches/StorageSettings.cs new file mode 100644 index 0000000..8ed512b --- /dev/null +++ b/Source/ExtendedStorage/Patches/StorageSettings.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using Harmony; +using RimWorld; +using Verse; + +namespace ExtendedStorage { + [HarmonyPatch(typeof(StorageSettings), methodTryNotifyChanged)] + class StorageSettings_TryNotifyChanged + { + + public const string methodTryNotifyChanged = "TryNotifyChanged"; + + public static bool Prefix(StorageSettings __instance) + { + var us = __instance as UserSettings; + + if (us != null) { + us.NotifyOwnerSettingsChanged(); + return false; + } + return true; + } + } + + + [HarmonyPatch(typeof(StorageSettings), "set_" + nameof(StorageSettings.Priority))] + class StorageSettings_set_Priority + { + public static void Postfix(StorageSettings __instance) { + (__instance as UserSettings)?.NotifyOwnerSettingsChanged(); + } + } +} diff --git a/Source/ExtendedStorage/Patches/Thing_DrawAt.cs b/Source/ExtendedStorage/Patches/Thing_DrawAt.cs deleted file mode 100644 index 780153f..0000000 --- a/Source/ExtendedStorage/Patches/Thing_DrawAt.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Harmony; -using UnityEngine; -using Verse; - -namespace ExtendedStorage -{ - [HarmonyPatch(typeof(Thing), nameof(Thing.DrawAt))] - internal class Thing_DrawAt - { - public static bool Prefix(Thing __instance, Vector3 drawLoc, bool flip) - { - Graphic g; - if (StorageUtility.HasSupressedOrSubstituedGraphics(__instance, out g)) - { - // substitute draws for stored things - g?.DrawWorker( - drawLoc, - flip ? __instance.Rotation.Opposite : __instance.Rotation, - __instance.def, - __instance); - return false; - } - - return true; - } - } -} \ No newline at end of file diff --git a/Source/ExtendedStorage/Patches/Thing_SplitOff.cs b/Source/ExtendedStorage/Patches/Thing_SplitOff.cs new file mode 100644 index 0000000..aec9a88 --- /dev/null +++ b/Source/ExtendedStorage/Patches/Thing_SplitOff.cs @@ -0,0 +1,13 @@ +using Harmony; +using Verse; + +namespace ExtendedStorage { + [HarmonyPatch(typeof(Thing), nameof(Thing.SplitOff))] + class Thing_SplitOff { + + public static void Postfix(Thing __instance) + { + StorageUtility.GetStoringBuilding(__instance)?.UpdateCachedAttributes(); + } + } +} diff --git a/Source/ExtendedStorage/Patches/FloatMenuMakerMap_AddHumanlikeOrders.cs b/Source/ExtendedStorage/Patches/[GUI]/FloatMenuMakerMap_AddHumanlikeOrders.cs similarity index 100% rename from Source/ExtendedStorage/Patches/FloatMenuMakerMap_AddHumanlikeOrders.cs rename to Source/ExtendedStorage/Patches/[GUI]/FloatMenuMakerMap_AddHumanlikeOrders.cs diff --git a/Source/ExtendedStorage/Patches/[GUI]/Thing_DrawAt.cs b/Source/ExtendedStorage/Patches/[GUI]/Thing_DrawAt.cs new file mode 100644 index 0000000..2d6b0fd --- /dev/null +++ b/Source/ExtendedStorage/Patches/[GUI]/Thing_DrawAt.cs @@ -0,0 +1,25 @@ +using System.Diagnostics.Eventing.Reader; +using Harmony; +using UnityEngine; +using Verse; + +namespace ExtendedStorage +{ + [HarmonyPatch(typeof(Thing), nameof(Thing.DrawAt))] + internal class Thing_DrawAt + { + public static bool Prefix(Thing __instance, Vector3 drawLoc, bool flip) + { + return __instance.def.IsApparel || + StorageUtility.GetStoringBuilding(__instance) == null; + } + } + + [HarmonyPatch(typeof(Thing), nameof(Thing.Print))] + internal class Thing_Print { + public static bool Prefix(Thing __instance) { + // no apparel check for now - print & section layers not used for those + return StorageUtility.GetStoringBuilding(__instance) == null; + } + } +} \ No newline at end of file diff --git a/Source/ExtendedStorage/Patches/Thing_DrawGUIOverlay.cs b/Source/ExtendedStorage/Patches/[GUI]/Thing_DrawGUIOverlay.cs similarity index 100% rename from Source/ExtendedStorage/Patches/Thing_DrawGUIOverlay.cs rename to Source/ExtendedStorage/Patches/[GUI]/Thing_DrawGUIOverlay.cs diff --git a/Source/ExtendedStorage/Properties/AssemblyInfo.cs b/Source/ExtendedStorage/Properties/AssemblyInfo.cs index 8f50d25..ec499a5 100644 --- a/Source/ExtendedStorage/Properties/AssemblyInfo.cs +++ b/Source/ExtendedStorage/Properties/AssemblyInfo.cs @@ -11,5 +11,5 @@ [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("a8e081b6-8768-4fe9-817f-f0ee42cf13ef")] -[assembly: AssemblyVersion("0.6.0.0")] -[assembly: AssemblyFileVersion("0.6.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] \ No newline at end of file diff --git a/Source/ExtendedStorage/UserSettings.cs b/Source/ExtendedStorage/UserSettings.cs new file mode 100644 index 0000000..b5c1f93 --- /dev/null +++ b/Source/ExtendedStorage/UserSettings.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using RimWorld; +using Verse; + +namespace ExtendedStorage { + public class UserSettings : StorageSettings { + private IUserSettingsOwner _owner; + + public UserSettings(IUserSettingsOwner owner) : base(owner) + { + _owner = owner; + } + + + public void NotifyOwnerSettingsChanged() + { + _owner.Notify_UserSettingsChanged(); + } + + } +} diff --git a/Source/ExtendedStorage/Utility/StorageUtility.cs b/Source/ExtendedStorage/Utility/StorageUtility.cs index a5d96b6..6fd2b99 100644 --- a/Source/ExtendedStorage/Utility/StorageUtility.cs +++ b/Source/ExtendedStorage/Utility/StorageUtility.cs @@ -1,36 +1,25 @@ using System; using System.Collections.Generic; +using RimWorld; using Verse; namespace ExtendedStorage { internal static class StorageUtility { - public static bool HasSupressedOrSubstituedGraphics(Thing t, out Graphic gfx) - { - Building_ExtendedStorage b = GetStoringBuilding(t); - if ((b != null) && !t.def.IsApparel) - { - gfx = t == b._suppressedDrawCandidate - ? b._gfxStoredThing - : null; - return true; - } - gfx = null; - return false; - } - /// /// Checks if a is currently held as one of the on an /// 's - /// . /// /// to check public static Building_ExtendedStorage GetStoringBuilding(Thing t) { - Building_ExtendedStorage b = t.Map?.thingGrid.ThingAt(t.Position); + // HACK: GetSlotGroup is weird (ish) + var b = t is Building_ExtendedStorage + ? null + : t.GetSlotGroup()?.parent as Building_ExtendedStorage; - return (b?.OutputSlot == t.Position) && (b.StoredThingDef == t.def) + return b?.StoredThingDef == t.def ? b : null; }