diff --git a/Defs/ThingDefs_Buildings/Buildings_Storage.xml b/Defs/ThingDefs_Buildings/Buildings_Storage.xml index 8a862eaf..4784c78b 100644 --- a/Defs/ThingDefs_Buildings/Buildings_Storage.xml +++ b/Defs/ThingDefs_Buildings/Buildings_Storage.xml @@ -361,6 +361,113 @@ + + + + ProjectRimFactory.Storage.Building_ColdStoragePowered + PRF_ColdStorageUnit_I + + A matter-energy conversion based storage unit which can hold up to 10k stacks, consuming 10 W of power per stack of items. In the event of a power outage, items already inside will be safe, but the DSU will not be able to store more. Don't break it. + PRF_IoGroup + 0.9 + +
  • Furniture
  • +
    + Building + Impassable + true + 1.0 + true + false + false + true + MinifiedThing + Heavy + 0.5 + Item + +
  • ITab_Storage
  • +
  • ProjectRimFactory.Storage.UI.ITab_Items
  • +
    + + Graphic_Single + Storage/CargoPlatform + (3,3) + + Damage/Corner + Damage/Corner + + + + 50 + 450 + 5000 + 10880 + 0.05 + 0.5 + + + true + true + + Normal + + +
  • Manufactured
  • +
  • ResourcesRaw
  • +
  • Items
  • +
  • BuildingsArt
  • +
  • Weapons
  • +
  • Apparel
  • +
  • BodyParts
  • +
    + +
  • AllowRotten
  • +
    +
    +
    +
    + (3,3) + 150 + + 300 + 50 + 20 + 100 + 100 + 15 + 1 + 1 + + Normal + +
  • PRF_StorageIO
  • +
    + +
  • + 6 + (115,198,206,0) +
  • +
  • + CompPowerTrader + true + 0 +
  • +
  • +
  • + + 10 + +
  • +
  • + 10000 + true + true + false + true +
  • + +
    diff --git a/Source/ProjectRimFactory/AutoMachineTool/Building_BeltConveyor.cs b/Source/ProjectRimFactory/AutoMachineTool/Building_BeltConveyor.cs index 82f8f9f8..8b5f0ab5 100644 --- a/Source/ProjectRimFactory/AutoMachineTool/Building_BeltConveyor.cs +++ b/Source/ProjectRimFactory/AutoMachineTool/Building_BeltConveyor.cs @@ -262,13 +262,11 @@ public override void SpawnSetup(Map map, bool respawningAfterLoad) { } // already set, but just in case: this.products = thingOwnerInt.InnerListForReading; - map.GetComponent().RegisterIHideItemPos(this.Position, this); } public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) { var targets = AllNearbyLinkables().ToList(); - this.Map.GetComponent().DeRegisterIHideItemPos(this.Position,this); base.DeSpawn(mode); targets.ForEach(x => x.Unlink(this)); diff --git a/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs b/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs index f588eb87..2cdd61a4 100644 --- a/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs +++ b/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs @@ -6,35 +6,130 @@ using Verse; using HarmonyLib; using Verse.AI; +using ProjectRimFactory.Storage; +using System.Reflection; namespace ProjectRimFactory.Common { public static class ConditionalPatchHelper { + public class TogglePatch + { + private bool Patched = false; + + private readonly MethodInfo base_m; + private readonly HarmonyMethod trans_hm = null; + private readonly HarmonyMethod pre_hm = null; + private readonly HarmonyMethod post_hm = null; + private readonly MethodInfo trans_m = null; + private readonly MethodInfo pre_m = null; + private readonly MethodInfo post_m = null; + + public TogglePatch(MethodInfo base_method, MethodInfo prefix = null, MethodInfo postfix = null, MethodInfo Transpiler = null) + { + base_m = base_method; + if (Transpiler != null) trans_hm = new HarmonyMethod(Transpiler); + if (prefix != null) pre_hm = new HarmonyMethod(prefix); + if (postfix != null) post_hm = new HarmonyMethod(postfix); + trans_m = Transpiler; + pre_m = prefix; + post_m = postfix; + } + + public void PatchHandler(bool patch) + { + if (patch && !Patched) + { + harmony_instance.Patch(base_m,pre_hm,post_hm,trans_hm); + Patched = true; + } + else if (Patched && !patch) + { + if (trans_m != null) harmony_instance.Unpatch(base_m, trans_m); + if (pre_m != null) harmony_instance.Unpatch(base_m, pre_m); + if (post_m != null) harmony_instance.Unpatch(base_m, post_m); + Patched = false; + } + } + + } + //conditional private static Harmony harmony_instance = null; - private static bool Patch_Reachability_CanReach = false; + public static TogglePatch Patch_Reachability_CanReach = new TogglePatch( + AccessTools.Method(typeof(Verse.Reachability), "CanReach", new Type[] { typeof(IntVec3), typeof(LocalTargetInfo), typeof(PathEndMode), typeof(TraverseParms) }), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Reachability_CanReach), "Prefix") + ); + + //Storage Patches + public static TogglePatch Patch_MinifiedThing_Print = new TogglePatch( + AccessTools.Method(typeof(RimWorld.MinifiedThing), "Print", new Type[] { typeof(SectionLayer)}), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_MinifiedThing_Print), "Prefix") + ); + public static TogglePatch Patch_Thing_Print = new TogglePatch( + AccessTools.Method(typeof(Verse.Thing), "Print", new Type[] { typeof(SectionLayer) }), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Thing_Print), "Prefix") + ); + public static TogglePatch Patch_ThingWithComps_Draw = new TogglePatch( + AccessTools.Method(typeof(Verse.ThingWithComps), "Print", new Type[] { typeof(SectionLayer) }), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_ThingWithComps_Draw), "Prefix") + ); + public static TogglePatch Patch_ThingWithComps_DrawGUIOverlay = new TogglePatch( + AccessTools.Method(typeof(Verse.ThingWithComps), "DrawGUIOverlay"), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_ThingWithComps_DrawGUIOverlay), "Prefix") + ); + public static TogglePatch Patch_Thing_DrawGUIOverlay = new TogglePatch( + AccessTools.Method(typeof(Verse.ThingWithComps), "DrawGUIOverlay"), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Thing_DrawGUIOverlay), "Prefix") + ); + public static TogglePatch Patch_FloatMenuMakerMap_ChoicesAtFor = new TogglePatch( + AccessTools.Method(typeof(RimWorld.FloatMenuMakerMap), "ChoicesAtFor", new Type[] { typeof(UnityEngine.Vector3), typeof(Pawn), typeof(bool) }), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_FloatMenuMakerMap_ChoicesAtFor), "Prefix") + ); + public static TogglePatch Patch_Building_Storage_Accepts = new TogglePatch( + AccessTools.Method(typeof(RimWorld.Building_Storage), "Accepts", new Type[] { typeof(Verse.Thing)}), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Building_Storage_Accepts), "Prefix") + ); + public static TogglePatch Patch_ForbidUtility_IsForbidden = new TogglePatch( + AccessTools.Method(typeof(RimWorld.ForbidUtility), "IsForbidden", new Type[] { typeof(Thing), typeof(Pawn) }), + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_ForbidUtility_IsForbidden), "Prefix") + ); + + + + public static void InitHarmony(Harmony harmony) { harmony_instance = harmony; } - public static void Update_Patch_Reachability_CanReach() + static List building_MassStorages = new List(); + + private static void updatePatchStorage() { - var patch = AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Reachability_CanReach), "Prefix"); - var base_m = AccessTools.Method(typeof(Verse.Reachability), "CanReach", new Type[] { typeof(IntVec3), typeof(LocalTargetInfo), typeof(PathEndMode), typeof(TraverseParms) }); - if (ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach) - { - harmony_instance.Patch(base_m, new HarmonyMethod(patch) ); - Patch_Reachability_CanReach = true; - } - else if(Patch_Reachability_CanReach) - { - harmony_instance.Unpatch(base_m, patch); - Patch_Reachability_CanReach = false; - } + bool state = building_MassStorages.Count > 0; + + Patch_MinifiedThing_Print.PatchHandler(state); + Patch_Thing_Print.PatchHandler(state); + Patch_ThingWithComps_Draw.PatchHandler(state); + Patch_ThingWithComps_DrawGUIOverlay.PatchHandler(state); + Patch_Thing_DrawGUIOverlay.PatchHandler(state); + Patch_FloatMenuMakerMap_ChoicesAtFor.PatchHandler(state); + Patch_Building_Storage_Accepts.PatchHandler(state); + Patch_ForbidUtility_IsForbidden.PatchHandler(state); + } + + public static void Register(Building_MassStorageUnit building) + { + building_MassStorages.Add(building); + updatePatchStorage(); + } + public static void Deregister(Building_MassStorageUnit building) + { + building_MassStorages.Remove(building); + updatePatchStorage(); } } diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/AdvancedIO_PatchHelper.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/AdvancedIO_PatchHelper.cs index 193fb7e4..e1667fde 100644 --- a/Source/ProjectRimFactory/Common/HarmonyPatches/AdvancedIO_PatchHelper.cs +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/AdvancedIO_PatchHelper.cs @@ -112,7 +112,7 @@ public static bool CanMoveItem(Building_AdvancedStorageUnitIOPort port, Thing th /// public static bool CanMoveItem(Building_AdvancedStorageUnitIOPort port, IntVec3 thingPos) { - return port.boundStorageUnit?.AllSlotCells()?.Contains(thingPos) ?? false; + return port.boundStorageUnit?.HoldsPos(thingPos) ?? false; } diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs index 83a37da8..cb4d7071 100644 --- a/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs @@ -12,7 +12,6 @@ namespace ProjectRimFactory.Common.HarmonyPatches { - [HarmonyPatch(typeof(ForbidUtility), "IsForbidden", new Type[] { typeof(Thing), typeof(Pawn) })] class Patch_ForbidUtility_IsForbidden { static bool Prefix(Thing t, Pawn pawn, out bool __result) @@ -33,7 +32,6 @@ static bool Prefix(Thing t, Pawn pawn, out bool __result) } } - [HarmonyPatch(typeof(Building_Storage), "Accepts")] class Patch_Building_Storage_Accepts { static bool Prefix(Building_Storage __instance, Thing t, out bool __result) @@ -50,7 +48,6 @@ static bool Prefix(Building_Storage __instance, Thing t, out bool __result) } } - [HarmonyPatch(typeof(FloatMenuMakerMap), "ChoicesAtFor")] class Patch_FloatMenuMakerMap_ChoicesAtFor { static bool Prefix(Vector3 clickPos, Pawn pawn, out List __result) @@ -65,7 +62,6 @@ static bool Prefix(Vector3 clickPos, Pawn pawn, out List __resu } } - [HarmonyPatch(typeof(Thing), "DrawGUIOverlay")] class Patch_Thing_DrawGUIOverlay { static bool Prefix(Thing __instance) @@ -81,7 +77,6 @@ static bool Prefix(Thing __instance) } } - [HarmonyPatch(typeof(ThingWithComps), "DrawGUIOverlay")] class Patch_ThingWithComps_DrawGUIOverlay { static bool Prefix(Thing __instance) @@ -97,7 +92,6 @@ static bool Prefix(Thing __instance) } } - [HarmonyPatch(typeof(ThingWithComps), "Draw")] class Patch_ThingWithComps_Draw { static bool Prefix(Thing __instance) @@ -113,7 +107,6 @@ static bool Prefix(Thing __instance) } } - [HarmonyPatch(typeof(Thing), "Print")] class Patch_Thing_Print { static bool Prefix(Thing __instance, SectionLayer layer) @@ -129,7 +122,6 @@ static bool Prefix(Thing __instance, SectionLayer layer) } } - [HarmonyPatch(typeof(MinifiedThing), "Print")] class Patch_MinifiedThing_Print { static bool Prefix(Thing __instance, SectionLayer layer) diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Reachability_CanReach.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Reachability_CanReach.cs index daa6c8df..06cb9563 100644 --- a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Reachability_CanReach.cs +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Reachability_CanReach.cs @@ -23,7 +23,7 @@ public static bool Prefix(IntVec3 start, LocalTargetInfo dest, PathEndMode peMod if (mapcomp.ShouldHideItemsAtPos(ThingPos)) { //Is in a DSU - var pathToIO = mapcomp.GetadvancedIOLocations.Where(p => p.Value.boundStorageUnit?.Position == ThingPos && __instance.CanReach(start, p.Key, PathEndMode.Touch, traverseParams)).Any(); + var pathToIO = mapcomp.GetadvancedIOLocations.Where(p => p.Value.boundStorageUnit?.GetPosition == ThingPos && __instance.CanReach(start, p.Key, PathEndMode.Touch, traverseParams)).Any(); if (pathToIO) { __result = true; diff --git a/Source/ProjectRimFactory/Common/PRFGameComponent.cs b/Source/ProjectRimFactory/Common/PRFGameComponent.cs index 155b9568..495d8b7b 100644 --- a/Source/ProjectRimFactory/Common/PRFGameComponent.cs +++ b/Source/ProjectRimFactory/Common/PRFGameComponent.cs @@ -15,6 +15,8 @@ public class PRFGameComponent : GameComponent { public static Pawn PRF_StaticPawn = null; public static Job PRF_StaticJob = null; + + public static void GenStaticPawn() { PRF_StaticPawn = PawnGenerator.GeneratePawn(PRFDefOf.PRFSlavePawn, Faction.OfPlayer); diff --git a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs index 90273863..cb298220 100644 --- a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs +++ b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs @@ -26,7 +26,7 @@ public ProjectRimFactory_ModComponent(ModContentPack content) : base(content) availableSpecialSculptures = SpecialSculpture.LoadAvailableSpecialSculptures(content); LoadModSupport(); ConditionalPatchHelper.InitHarmony(this.HarmonyInstance); - ConditionalPatchHelper.Update_Patch_Reachability_CanReach(); + ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach); } catch (Exception ex) diff --git a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs index ac30a40c..64952477 100644 --- a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs +++ b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs @@ -76,7 +76,7 @@ private static void CSharpSettings(Listing_Standard list) { list.Gap(); if (PRF_Patch_Reachability_CanReach != PRF_Patch_Reachability_CanReach_last) { - ConditionalPatchHelper.Update_Patch_Reachability_CanReach(); + ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach); } PRF_Patch_Reachability_CanReach_last = PRF_Patch_Reachability_CanReach; diff --git a/Source/ProjectRimFactory/Storage/Building_AdvancedStorageUnitIOPort.cs b/Source/ProjectRimFactory/Storage/Building_AdvancedStorageUnitIOPort.cs index 75a26162..18598872 100644 --- a/Source/ProjectRimFactory/Storage/Building_AdvancedStorageUnitIOPort.cs +++ b/Source/ProjectRimFactory/Storage/Building_AdvancedStorageUnitIOPort.cs @@ -64,6 +64,8 @@ private Thing GetstoredItem() public bool CanGetNewItem => GetstoredItem() == null && (powerComp?.PowerOn ?? false); + public override bool IsAdvancedPort => true; + private void updateQueue() { if (CanGetNewItem && placementQueue.Count > 0) diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs new file mode 100644 index 00000000..8e286352 --- /dev/null +++ b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs @@ -0,0 +1,371 @@ +using System.Collections.Generic; +using System.Text; +using System.Linq; +using ProjectRimFactory.Common; +using ProjectRimFactory.Common.HarmonyPatches; +using ProjectRimFactory.Storage.Editables; +using ProjectRimFactory.Storage.UI; +using RimWorld; +using UnityEngine; +using Verse; + +namespace ProjectRimFactory.Storage +{ + public interface ILinkableStorageParent + { + public List StoredItems { get; } + + public bool AdvancedIOAllowed { get; } + + public void HandleNewItem(Thing item); + + public void HandleMoveItem(Thing item); + + public bool CanReciveThing(Thing item); + + public bool HoldsPos(IntVec3 pos); + + //What is that even for ?? + public void DeregisterPort(Building_StorageUnitIOBase port); + public void RegisterPort(Building_StorageUnitIOBase port); + + public StorageSettings GetSettings { get; } + + public IntVec3 GetPosition { get; } + + public string LabelCap { get; } + public bool CanReceiveIO { get; } + public Map Map { get; } + + public int StoredItemsCount { get; } + + public string GetITabString(int itemsSelected); + + public LocalTargetInfo GetTargetInfo { get; } + + public bool OutputItem(Thing item); + + public bool Powered { get; } + + public bool CanUseIOPort { get; } + + } + + + [StaticConstructorOnStartup] + public abstract class Building_ColdStorage : Building, IRenameBuilding, IHaulDestination, IStoreSettingsParent, ILinkableStorageParent, IThingHolder + { + private static readonly Texture2D RenameTex = ContentFinder.Get("UI/Buttons/Rename"); + + private ThingOwner thingOwner = new ThingOwner(); + + private List items => thingOwner.InnerListForReading; + + private List ports = new List(); + + public string UniqueName { get => uniqueName; set => uniqueName = value; } + private string uniqueName; + public Building Building => this; + + public StorageSettings settings; + + //Initialized at spawn + public DefModExtension_Crate ModExtension_Crate = null; + + public abstract bool CanStoreMoreItems { get; } + // The maximum number of item stacks at this.Position: + // One item on each cell and the rest multi-stacked on Position? + public int MaxNumberItemsInternal => (ModExtension_Crate?.limit ?? int.MaxValue) + - def.Size.Area + 1; + public List StoredItems => items; + public int StoredItemsCount => items.Count; + public override string LabelNoCount => uniqueName ?? base.LabelNoCount; + public override string LabelCap => uniqueName ?? base.LabelCap; + public virtual bool CanReceiveIO => true; + public virtual bool Powered => true; + + public bool ForbidPawnAccess => ModExtension_Crate?.forbidPawnAccess ?? false; + + public virtual bool ForbidPawnInput => ForbidPawnAccess; + + public virtual bool ForbidPawnOutput => ForbidPawnAccess; + + public virtual bool HideItems => ModExtension_Crate?.hideItems ?? false; + + public virtual bool HideRightClickMenus => + ModExtension_Crate?.hideRightClickMenus ?? false; + + IntVec3 IHaulDestination.Position => this.Position; + + Map IHaulDestination.Map => this.Map; + + bool IStoreSettingsParent.StorageTabVisible => true; + + public bool AdvancedIOAllowed => false; + + public IntVec3 GetPosition => this.Position; + + public StorageSettings GetSettings => settings; + + public LocalTargetInfo GetTargetInfo => this; + + public bool CanUseIOPort => true; + + public void DeregisterPort(Building_StorageUnitIOBase port) + { + ports.Remove(port); + } + + public void RegisterPort(Building_StorageUnitIOBase port) + { + ports.Add(port); + } + + public override IEnumerable GetGizmos() + { + foreach (var g in base.GetGizmos()) + yield return g; + yield return new Command_Action + { + icon = RenameTex, + action = () => Find.WindowStack.Add(new Dialog_RenameMassStorageUnit(this)), + hotKey = KeyBindingDefOf.Misc1, + defaultLabel = "PRFRenameMassStorageUnitLabel".Translate(), + defaultDesc = "PRFRenameMassStorageUnitDesc".Translate() + }; + } + + public virtual string GetUIThingLabel() + { + return "PRFMassStorageUIThingLabel".Translate(StoredItemsCount); + } + + public virtual string GetITabString(int itemsSelected) + { + return "PRFItemsTabLabel".Translate(StoredItemsCount, itemsSelected); + } + + public virtual void RegisterNewItem(Thing newItem) + { + + Log.Message($"RegisterNewItem: {newItem}"); + if (items.Contains(newItem)) + { + Log.Message($"dup: {newItem}"); + return; + } + for (var i = 0; i < items.Count; i++) + { + var item = items[i]; + if (item.def.category == ThingCategory.Item && item.CanStackWith(newItem)) + item.TryAbsorbStack(newItem, true); + if (newItem.Destroyed) break; + } + + //Add a new stack of a thing + if (!newItem.Destroyed) + { + items.Add(newItem); + + //What appens if its full? + if (CanStoreMoreItems) + { + newItem.Position = Position; + } + if (newItem.Spawned) newItem.DeSpawn(); + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Collections.Look(ref ports, "ports", LookMode.Reference); + Scribe_Deep.Look(ref this.thingOwner, "thingowner"); + Scribe_Values.Look(ref uniqueName, "uniqueName"); + Scribe_Deep.Look(ref settings, "settings", this); + ModExtension_Crate ??= def.GetModExtension(); + } + + public override string GetInspectString() + { + var original = base.GetInspectString(); + var stringBuilder = new StringBuilder(); + if (!string.IsNullOrEmpty(original)) stringBuilder.AppendLine(original); + stringBuilder.Append("PRF_TotalStacksNum".Translate(items.Count)); + return stringBuilder.ToString(); + } + + public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) + { + var thingsToSplurge = new List(Position.GetThingList(Map)); + for (var i = 0; i < thingsToSplurge.Count; i++) + if (thingsToSplurge[i].def.category == ThingCategory.Item) + { + thingsToSplurge[i].DeSpawn(); + GenPlace.TryPlaceThing(thingsToSplurge[i], Position, Map, ThingPlaceMode.Near); + } + base.DeSpawn(mode); + } + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + ModExtension_Crate ??= def.GetModExtension(); + /*Log.Message("----------------"); + foreach (var item in this.StoredItems) + { + Log.Message(item.ToString()); + }*/ + foreach (var port in ports) + { + if (port?.Spawned ?? false) + { + if (port.Map != map) + { + port.BoundStorageUnit = null; + } + } + } + + } + + public override void DrawGUIOverlay() + { + base.DrawGUIOverlay(); + if (Current.CameraDriver.CurrentZoom <= CameraZoomRange.Close) + GenMapUI.DrawThingLabel(this, LabelCap + "\n\r" + GetUIThingLabel()); + } + + public bool OutputItem(Thing item) + { + var outputCell = GetComp()?.CurrentCell ?? Position + new IntVec3(0, 0, -2); + return GenPlace.TryPlaceThing(item.SplitOff(item.stackCount), outputCell, Map, ThingPlaceMode.Near); + } + + //----------- For compatibility with Pick Up And Haul: ----------- + // (not used internally in any way) + // true if can store, capacity is how many can store (more than one stack possible) + public bool CapacityAt(Thing thing, IntVec3 cell, Map map, out int capacity) + { + //Some Sanity Checks + capacity = 0; + if (thing == null || map == null || map != this.Map || cell == null || !this.Spawned) + { + Log.Error("PRF DSU CapacityAt Sanity Check Error"); + return false; + } + thing = thing.GetInnerIfMinified(); + + //Check if thing can be stored based upon the storgae settings + if (!this.Accepts(thing)) + { + return false; + } + + //TODO Check if we want to forbid access if power is off + //if (!GetComp().PowerOn) return false; + + //Get List of items stored in the DSU + var storedItems = Position.GetThingList(Map).Where(t => t.def.category == ThingCategory.Item); + + //Find the Stack size for the thing + int maxstacksize = thing.def.stackLimit; + //Get capacity of partial Stacks + // So 45 Steel and 75 Steel and 11 Steel give 30+64 more capacity for steel + foreach (Thing partialStack in storedItems.Where(t => t.def == thing.def && t.stackCount < maxstacksize)) + { + capacity += maxstacksize - partialStack.stackCount; + } + + //capacity of empy slots + capacity += (MaxNumberItemsInternal - storedItems.Count()) * maxstacksize; + + //Access point: + if (cell != Position) + { + var maybeThing = Map.thingGrid.ThingAt(cell, ThingCategory.Item); + if (maybeThing != null) + { + if (maybeThing.def == thing.def) capacity += (thing.def.stackLimit - maybeThing.stackCount); + } + else + { + capacity += thing.def.stackLimit; + } + } + return capacity > 0; + } + + // ...The above? I think? But without needing to know how many + public bool StackableAt(Thing thing, IntVec3 cell, Map map) + { + return CapacityAt(thing, cell, map, out _); + } + + public bool Accepts(Thing t) + { + return settings.AllowedToAccept(t); + } + + StorageSettings IStoreSettingsParent.GetStoreSettings() + { + return settings; + } + + StorageSettings IStoreSettingsParent.GetParentStoreSettings() + { + StorageSettings fixedStorageSettings = def.building.fixedStorageSettings; + if (fixedStorageSettings != null) + { + return fixedStorageSettings; + } + return StorageSettings.EverStorableFixedSettings(); + } + + public override void PostMake() + { + base.PostMake(); + settings = new StorageSettings(this); + if (def.building.defaultStorageSettings != null) + { + settings.CopyFrom(def.building.defaultStorageSettings); + } + } + + public void HandleNewItem(Thing item) + { + RegisterNewItem(item); + } + + public void HandleMoveItem(Thing item) + { + //With the use of thingOwner this check might be redundent + if (items.Contains(item)) + { + items.Remove(item); + } + } + + public bool CanReciveThing(Thing item) + { + return settings.AllowedToAccept(item) && CanReceiveIO && CanStoreMoreItems; + } + + public void GetChildHolders(List outChildren) + { + + } + + public ThingOwner GetDirectlyHeldThings() + { + return thingOwner; + } + + + //Only used for Advanced IO + public bool HoldsPos(IntVec3 pos) + { + return false; + } + } +} \ No newline at end of file diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs b/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs new file mode 100644 index 00000000..814476b5 --- /dev/null +++ b/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs @@ -0,0 +1,155 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Verse; +using ProjectRimFactory.Storage.Editables; +using UnityEngine; + +namespace ProjectRimFactory.Storage +{ + [StaticConstructorOnStartup] + public class Building_ColdStoragePowered : Building_ColdStorage + { + private static Texture2D StoragePawnAccessSwitchIcon = ContentFinder.Get("PRFUi/dsu", true); + + //Initialized on spawn + private CompPowerTrader compPowerTrader = null; + + public override bool Powered => compPowerTrader?.PowerOn ?? false; + + public override bool CanStoreMoreItems => (Powered) && this.Spawned && + (ModExtension_Crate == null || StoredItemsCount < MaxNumberItemsInternal); + public override bool CanReceiveIO => base.CanReceiveIO && compPowerTrader.PowerOn && this.Spawned; + + public override bool ForbidPawnInput => this.ForbidPawnAccess || !this.pawnAccess || !this.CanStoreMoreItems; + + public override bool ForbidPawnOutput => this.ForbidPawnAccess || !this.pawnAccess; + + private bool pawnAccess = true; + + public void UpdatePowerConsumption() + { + compPowerTrader ??= GetComp(); + compPowerTrader.PowerOutput = -10 * StoredItemsCount; + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref pawnAccess, "pawnAccess", true); + compPowerTrader ??= GetComp(); + } + + protected override void ReceiveCompSignal(string signal) + { + base.ReceiveCompSignal(signal); + } + + public override void Tick() + { + base.Tick(); + if (this.IsHashIntervalTick(60)) + { + UpdatePowerConsumption(); + } + } + + public override void PostMapInit() + { + base.PostMapInit(); + compPowerTrader ??= GetComp(); + } + + public override IEnumerable GetGizmos() + { + foreach (Gizmo g in base.GetGizmos()) yield return g; + if (Prefs.DevMode) + { + yield return new Command_Action() + { + defaultLabel = "DEBUG: Debug actions", + action = () => + { + Find.WindowStack.Add(new FloatMenu(new List(DebugActions()))); + } + }; + } + + if (!this.ForbidPawnAccess) + { + yield return new Command_Toggle() + { + defaultLabel = "PRFPawnAccessLabel".Translate(), + isActive = () => this.pawnAccess, + toggleAction = () => this.pawnAccess = !this.pawnAccess, + defaultDesc = "PRFPawnAccessDesc".Translate(), + icon = StoragePawnAccessSwitchIcon + }; + } + } + + public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) + { + if (mode == DestroyMode.Deconstruct) + { + if (def.GetModExtension()?.destroyContainsItems ?? false) + { + this.StoredItems.Where(t => !t.Destroyed).ToList().ForEach(x => x.Destroy()); + } + } + base.DeSpawn(mode); + } + + protected virtual IEnumerable DebugActions() + { + yield return new FloatMenuOption("Update power consumption", UpdatePowerConsumption); + yield return new FloatMenuOption("Log item count", () => Log.Message(StoredItemsCount.ToString())); + } + + public override string GetUIThingLabel() + { + if ((def.GetModExtension()?.limit).HasValue) + { + return "PRFCrateUIThingLabel".Translate(StoredItemsCount, def.GetModExtension().limit); + } + else + { + return base.GetUIThingLabel(); + } + } + + public override string GetITabString(int itemsSelected) + { + if ((def.GetModExtension()?.limit).HasValue) + { + return "PRFItemsTabLabel_Crate".Translate(StoredItemsCount, def.GetModExtension().limit, itemsSelected); + } + else + { + return base.GetITabString(itemsSelected); + } + } + + //This Exists as I don't know how to call .Any() with CodeInstruction + //Can be removed if the Transpiler is Updated to inclued that + public static bool AnyPowerd(Map map) + { + return AllPowered(map).Any(); + } + + public static IEnumerable AllPowered(Map map) + { + foreach (Building_MassStorageUnitPowered item in map.listerBuildings.AllBuildingsColonistOfClass()) + { + CompPowerTrader comp = item.GetComp(); + if (comp == null || comp.PowerOn) + { + yield return item; + } + } + } + + } +} diff --git a/Source/ProjectRimFactory/Storage/Building_IOPusher.cs b/Source/ProjectRimFactory/Storage/Building_IOPusher.cs index 71c5c833..ed8b94ed 100644 --- a/Source/ProjectRimFactory/Storage/Building_IOPusher.cs +++ b/Source/ProjectRimFactory/Storage/Building_IOPusher.cs @@ -25,6 +25,8 @@ public override IntVec3 WorkPosition { public override StorageIOMode IOMode { get => StorageIOMode.Output; set => _ = value; } + public override bool IsAdvancedPort => false; + public override void SpawnSetup(Map map, bool respawningAfterLoad) { base.SpawnSetup(map, respawningAfterLoad); diff --git a/Source/ProjectRimFactory/Storage/Building_MassStorageUnit.cs b/Source/ProjectRimFactory/Storage/Building_MassStorageUnit.cs index 5250dfb4..3fef565c 100644 --- a/Source/ProjectRimFactory/Storage/Building_MassStorageUnit.cs +++ b/Source/ProjectRimFactory/Storage/Building_MassStorageUnit.cs @@ -13,7 +13,7 @@ namespace ProjectRimFactory.Storage { [StaticConstructorOnStartup] public abstract class Building_MassStorageUnit : Building_Storage, IHideItem, IHideRightClickMenu, - IForbidPawnOutputItem, IForbidPawnInputItem ,IRenameBuilding + IForbidPawnOutputItem, IForbidPawnInputItem ,IRenameBuilding, ILinkableStorageParent { private static readonly Texture2D RenameTex = ContentFinder.Get("UI/Buttons/Rename"); @@ -23,6 +23,12 @@ public abstract class Building_MassStorageUnit : Building_Storage, IHideItem, IH public string UniqueName { get => uniqueName; set => uniqueName = value; } private string uniqueName; public Building Building => this; + public IntVec3 GetPosition => this.Position; + public StorageSettings GetSettings => settings; + + public bool CanUseIOPort => def.GetModExtension() != null; + + public LocalTargetInfo GetTargetInfo => this; //Initialized at spawn public DefModExtension_Crate ModExtension_Crate = null; @@ -64,6 +70,8 @@ public override void Notify_LostThing(Thing newItem) public virtual bool HideRightClickMenus => ModExtension_Crate?.hideRightClickMenus ?? false; + public bool AdvancedIOAllowed => true; + public void DeregisterPort(Building_StorageUnitIOBase port) { ports.Remove(port); @@ -166,10 +174,12 @@ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) Map.GetComponent().DeRegisterIForbidPawnOutputItem(cell, this); } base.DeSpawn(mode); + ConditionalPatchHelper.Deregister(this); } public override void SpawnSetup(Map map, bool respawningAfterLoad) { + ConditionalPatchHelper.Register(this); base.SpawnSetup(map, respawningAfterLoad); Map.GetComponent().AddIHideRightClickMenu(this); foreach (var cell in this.OccupiedRect().Cells) @@ -179,6 +189,16 @@ public override void SpawnSetup(Map map, bool respawningAfterLoad) } ModExtension_Crate ??= def.GetModExtension(); RefreshStorage(); + foreach(var port in ports) + { + if (port?.Spawned ?? false) + { + if (port.Map != map) + { + port.BoundStorageUnit = null; + } + } + } } @@ -286,7 +306,24 @@ public bool StackableAt(Thing thing, IntVec3 cell, Map map) return CapacityAt(thing, cell, map, out _); } + public void HandleNewItem(Thing item) + { + //throw new System.NotImplementedException(); + } + public void HandleMoveItem(Thing item) + { + //throw new System.NotImplementedException(); + } + public bool CanReciveThing(Thing item) + { + return settings.AllowedToAccept(item) && CanReceiveIO && CanStoreMoreItems; + } + + public bool HoldsPos(IntVec3 pos) + { + return AllSlotCells()?.Contains(pos) ?? false; + } } } \ No newline at end of file diff --git a/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs b/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs index 6d0ffe04..f9a23cd0 100644 --- a/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs +++ b/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs @@ -28,7 +28,8 @@ public abstract class Building_StorageUnitIOBase : Building_Storage, IForbidPawn public static readonly Texture2D IOModeTex = ContentFinder.Get("PRFUi/IoIcon"); public StorageIOMode mode; - public Building_MassStorageUnit boundStorageUnit; + private Building linkedStorageParentBuilding; + public ILinkableStorageParent boundStorageUnit => linkedStorageParentBuilding as ILinkableStorageParent; protected StorageSettings outputStoreSettings; private OutputSettings outputSettings; @@ -36,6 +37,8 @@ public abstract class Building_StorageUnitIOBase : Building_Storage, IForbidPawn protected CompPowerTrader powerComp; + public abstract bool IsAdvancedPort { get; } + public virtual bool ShowLimitGizmo => true; @@ -68,7 +71,7 @@ public virtual StorageIOMode IOMode } } - public Building_MassStorageUnit BoundStorageUnit + public ILinkableStorageParent BoundStorageUnit { get { @@ -77,7 +80,7 @@ public Building_MassStorageUnit BoundStorageUnit set { boundStorageUnit?.DeregisterPort(this); - boundStorageUnit = value; + linkedStorageParentBuilding = (Building)value; value?.RegisterPort(this); Notify_NeedRefresh(); } @@ -123,7 +126,7 @@ public override void ExposeData() { base.ExposeData(); Scribe_Values.Look(ref mode, "mode"); - Scribe_References.Look(ref boundStorageUnit, "boundStorageUnit"); + Scribe_References.Look(ref linkedStorageParentBuilding, "boundStorageUnit"); Scribe_Deep.Look(ref outputStoreSettings, "outputStoreSettings", this); Scribe_Deep.Look(ref outputSettings, "outputSettings", "IOPort_Minimum_UseTooltip", "IOPort_Maximum_UseTooltip"); Scribe_Values.Look(ref uniqueName, "uniqueName"); @@ -150,7 +153,11 @@ public override void SpawnSetup(Map map, bool respawningAfterLoad) base.SpawnSetup(map, respawningAfterLoad); powerComp = GetComp(); - if (boundStorageUnit?.Map != map) BoundStorageUnit = null; + //Issues occurs if the boundStorageUnit spawns after this... Needs a check form the other way + if (boundStorageUnit?.Map != map && (linkedStorageParentBuilding?.Spawned ?? false)) + { + BoundStorageUnit = null; + } } protected override void ReceiveCompSignal(string signal) @@ -215,15 +222,15 @@ public void RefreshStoreSettings() if (mode == StorageIOMode.Output) { settings = outputStoreSettings; - if (boundStorageUnit != null && settings.Priority != boundStorageUnit.settings.Priority) + if (boundStorageUnit != null && settings.Priority != boundStorageUnit.GetSettings.Priority) { //the setter of settings.Priority is expensive - settings.Priority = boundStorageUnit.settings.Priority; + settings.Priority = boundStorageUnit.GetSettings.Priority; } } else if (boundStorageUnit != null) { - settings = boundStorageUnit.settings; + settings = boundStorageUnit.GetSettings; } else { @@ -236,16 +243,9 @@ public virtual void RefreshInput() if (powerComp.PowerOn) { Thing item = WorkPosition.GetFirstItem(Map); - if (mode == StorageIOMode.Input && item != null && boundStorageUnit != null && boundStorageUnit.settings.AllowedToAccept(item) && boundStorageUnit.CanReceiveIO && boundStorageUnit.CanStoreMoreItems) + if (mode == StorageIOMode.Input && item != null && (boundStorageUnit?.CanReciveThing(item) ?? false)) { - foreach (IntVec3 cell in boundStorageUnit.AllSlotCells()) - { - if (cell.GetFirstItem(Map) == null) - { - boundStorageUnit.RegisterNewItem(item); - break; - } - } + boundStorageUnit.HandleNewItem(item); } } } @@ -294,7 +294,9 @@ protected virtual void RefreshOutput() // int count = Math.Min(item.stackCount, OutputSettings.CountNeededToReachMax(currentItem.stackCount, currentItem.def.stackLimit)); if (count > 0) { - currentItem.TryAbsorbStack(item.SplitOff(count), true); + var ThingToRemove = item.SplitOff(count); + if (item.stackCount <= 0) boundStorageUnit.HandleMoveItem(item); + currentItem.TryAbsorbStack(ThingToRemove, true); } } } @@ -303,7 +305,9 @@ protected virtual void RefreshOutput() // int count = OutputSettings.CountNeededToReachMax(0, item.stackCount); if (count > 0) { - currentItem = GenSpawn.Spawn(item.SplitOff(count), WorkPosition, Map); + var ThingToRemove = item.SplitOff(count); + if (item.stackCount <= 0) boundStorageUnit.HandleMoveItem(item); + currentItem = GenSpawn.Spawn(ThingToRemove, WorkPosition, Map); } } if (currentItem != null && !OutputSettings.SatisfiesMax(currentItem.stackCount, currentItem.def.stackLimit)) @@ -314,20 +318,20 @@ protected virtual void RefreshOutput() // } } //Transfre a item back if it is either too few or disallowed - if (currentItem != null && (!settings.AllowedToAccept(currentItem) || !OutputSettings.SatisfiesMin(currentItem.stackCount)) && boundStorageUnit.settings.AllowedToAccept(currentItem)) + if (currentItem != null && (!settings.AllowedToAccept(currentItem) || !OutputSettings.SatisfiesMin(currentItem.stackCount)) && boundStorageUnit.GetSettings.AllowedToAccept(currentItem)) { currentItem.SetForbidden(false, false); - boundStorageUnit.RegisterNewItem(currentItem); + boundStorageUnit.HandleNewItem(currentItem); } //Transfer the diffrence back if it is too much - if (currentItem != null && (!OutputSettings.SatisfiesMax(currentItem.stackCount, currentItem.def.stackLimit) && boundStorageUnit.settings.AllowedToAccept(currentItem))) + if (currentItem != null && (!OutputSettings.SatisfiesMax(currentItem.stackCount, currentItem.def.stackLimit) && boundStorageUnit.GetSettings.AllowedToAccept(currentItem))) { int splitCount = -OutputSettings.CountNeededToReachMax(currentItem.stackCount, currentItem.def.stackLimit); if (splitCount > 0) { Thing returnThing = currentItem.SplitOff(splitCount); returnThing.SetForbidden(false, false); - boundStorageUnit.RegisterNewItem(returnThing); + boundStorageUnit.HandleNewItem(returnThing); } } if (currentItem != null) @@ -345,11 +349,12 @@ public override IEnumerable GetGizmos() defaultLabel = "PRFBoundStorageBuilding".Translate() + ": " + (boundStorageUnit?.LabelCap ?? "NoneBrackets".Translate()), action = () => { + //ILinkableStorageParent + List mylist = Map.listerBuildings.allBuildingsColonist.Where(b => (b as ILinkableStorageParent) != null && (b as ILinkableStorageParent).CanUseIOPort).ToList(); + if (IsAdvancedPort) mylist.RemoveAll(b => !(b as ILinkableStorageParent).AdvancedIOAllowed); List list = new List( - from Building_MassStorageUnit b in Find.CurrentMap.listerBuildings.AllBuildingsColonistOfClass() - where b.def.GetModExtension() != null - select new FloatMenuOption(b.LabelCap, () => SelectedPorts().ToList().ForEach(p => p.BoundStorageUnit = b)) - ); + mylist.Select(b => new FloatMenuOption(b.LabelCap, () => SelectedPorts().ToList().ForEach(p => p.BoundStorageUnit = (b as ILinkableStorageParent)))) + ) ; if (list.Count == 0) { list.Add(new FloatMenuOption("NoneBrackets".Translate(), null)); @@ -450,6 +455,8 @@ public override StorageIOMode IOMode } } + public override bool IsAdvancedPort => false; + public override void Notify_ReceivedThing(Thing newItem) { base.Notify_ReceivedThing(newItem); @@ -473,16 +480,9 @@ public override void RefreshInput() if (powerComp.PowerOn) { Thing item = Position.GetFirstItem(Map); - if (mode == StorageIOMode.Input && item != null && boundStorageUnit != null && boundStorageUnit.settings.AllowedToAccept(item) && boundStorageUnit.CanReceiveIO && boundStorageUnit.CanStoreMoreItems) + if (mode == StorageIOMode.Input && item != null && (boundStorageUnit?.CanReciveThing(item) ?? false)) { - foreach (IntVec3 cell in boundStorageUnit.AllSlotCells()) - { - if (cell.GetFirstItem(Map) == null) - { - boundStorageUnit.RegisterNewItem(item); - break; - } - } + boundStorageUnit.HandleNewItem(item); } } } @@ -563,6 +563,7 @@ protected override void RefreshOutput() //For SplitOff "MakeThing" is expensive //For TryAbsorbStack "Destroy" is expensive AbsorbAmmount(ref currentItem, ref Mything, count); + if (Mything.stackCount <= 0) boundStorageUnit.HandleMoveItem(Mything); } } } @@ -573,7 +574,9 @@ protected override void RefreshOutput() { //Nothing on the IO Port - grab thing from storage and place it on the port //For SplitOff "MakeThing" is expensive - currentItem = GenSpawn.Spawn(item.SplitOff(count), Position, Map); + var ThingToRemove = item.SplitOff(count); + if (item.stackCount <= 0 || ThingToRemove == item) boundStorageUnit.HandleMoveItem(item); + currentItem = GenSpawn.Spawn(ThingToRemove, Position, Map); } } if (currentItem != null && !OutputSettings.SatisfiesMax(currentItem.stackCount, currentItem.def.stackLimit)) @@ -584,20 +587,20 @@ protected override void RefreshOutput() } } //Transfre a item back if it is either too few or disallowed - if (currentItem != null && (!settings.AllowedToAccept(currentItem) || !OutputSettings.SatisfiesMin(currentItem.stackCount)) && boundStorageUnit.settings.AllowedToAccept(currentItem)) + if (currentItem != null && (!settings.AllowedToAccept(currentItem) || !OutputSettings.SatisfiesMin(currentItem.stackCount)) && boundStorageUnit.GetSettings.AllowedToAccept(currentItem)) { currentItem.SetForbidden(false, false); - boundStorageUnit.RegisterNewItem(currentItem); + boundStorageUnit.HandleNewItem(currentItem); } //Transfer the diffrence back if it is too much - if (currentItem != null && (!OutputSettings.SatisfiesMax(currentItem.stackCount, currentItem.def.stackLimit) && boundStorageUnit.settings.AllowedToAccept(currentItem))) + if (currentItem != null && (!OutputSettings.SatisfiesMax(currentItem.stackCount, currentItem.def.stackLimit) && boundStorageUnit.GetSettings.AllowedToAccept(currentItem))) { int splitCount = -OutputSettings.CountNeededToReachMax(currentItem.stackCount, currentItem.def.stackLimit); if (splitCount > 0) { Thing returnThing = currentItem.SplitOff(splitCount); returnThing.SetForbidden(false, false); - boundStorageUnit.RegisterNewItem(returnThing); + boundStorageUnit.HandleNewItem(returnThing); } } if (currentItem != null) diff --git a/Source/ProjectRimFactory/Storage/UI/ITab_Items.cs b/Source/ProjectRimFactory/Storage/UI/ITab_Items.cs index 5b7711a9..e747c3a3 100644 --- a/Source/ProjectRimFactory/Storage/UI/ITab_Items.cs +++ b/Source/ProjectRimFactory/Storage/UI/ITab_Items.cs @@ -40,10 +40,10 @@ public ITab_Items() labelKey = "PRFItemsTab"; } - private static Building_MassStorageUnit oldSelectedMassStorageUnit = null; + private static ILinkableStorageParent oldSelectedMassStorageUnit = null; - public Building_MassStorageUnit SelectedMassStorageUnit => - IOPortSelected ? SelectedIOPort.BoundStorageUnit : (Building_MassStorageUnit) SelThing; + public ILinkableStorageParent SelectedMassStorageUnit => + IOPortSelected ? SelectedIOPort.BoundStorageUnit : (ILinkableStorageParent) SelThing; public override bool IsVisible => IOPortSelected ? SelectedIOPort.BoundStorageUnit?.CanReceiveIO ?? false : true; @@ -144,8 +144,8 @@ orderby t.Label descending //Do it once as they are all on the same spot in the DSU //Even if is where to have multible sport's that way should work I think - pawnCanReach_Touch_Deadly = pawns.Where(p => p.CanReach(SelectedMassStorageUnit, PathEndMode.ClosestTouch, Danger.Deadly)).ToList(); - pawnCanReach_Oncell_Deadly = pawns.Where(p => p.CanReach(SelectedMassStorageUnit, PathEndMode.OnCell, Danger.Deadly)).ToList(); + pawnCanReach_Touch_Deadly = pawns.Where(p => p.CanReach(SelectedMassStorageUnit.GetTargetInfo, PathEndMode.ClosestTouch, Danger.Deadly)).ToList(); + pawnCanReach_Oncell_Deadly = pawns.Where(p => p.CanReach(SelectedMassStorageUnit.GetTargetInfo, PathEndMode.OnCell, Danger.Deadly)).ToList(); @@ -191,7 +191,7 @@ orderby t.Label descending // Credits to LWM Deep Storage :) private void DrawThingRow(ref float y, float width, Thing thing, List colonists) { - if (thing == null || !thing.Spawned) return; // not here, whatever happened... + //if (thing == null || !thing.Spawned) return; // not here, whatever happened... //each call to LabelCap also accesses MaxHitPoints therefor it is read here slightly diffrently; @@ -307,9 +307,13 @@ private void dropThing(Thing thing) var item = SelectedMassStorageUnit .StoredItems.Where(i => i == thing).ToList(); if (IOPortSelected && SelectedIOPort.OutputItem(item[0])) + { itemsToShow.Remove(thing); + } else if (SelectedMassStorageUnit.OutputItem(item[0])) + { itemsToShow.Remove(thing); + } }