From 24b3597d99c983f20a7c39e118acc70d6f7d9a9d Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Thu, 1 Sep 2022 11:19:47 +0200 Subject: [PATCH 01/10] #612 implemented option removed Belts use of patch changed Storage Patches to be conditional added Cold Storage Building --- .../ThingDefs_Buildings/Buildings_Storage.xml | 107 +++++ .../AutoMachineTool/Building_BeltConveyor.cs | 2 - .../Common/ConditionalPatchHelper.cs | 123 +++++- .../HarmonyPatches/AdvancedIO_PatchHelper.cs | 2 +- .../Common/HarmonyPatches/PatchStorage.cs | 8 - .../Patch_Reachability_CanReach.cs | 2 +- .../Common/PRFGameComponent.cs | 2 + .../Common/ProjectRimFactory_ModComponent.cs | 2 +- .../Common/ProjectRimFactory_ModSettings.cs | 2 +- .../Building_AdvancedStorageUnitIOPort.cs | 2 + .../Storage/Building_ColdStorage.cs | 371 ++++++++++++++++++ .../Storage/Building_ColdStoragePowerd.cs | 155 ++++++++ .../Storage/Building_IOPusher.cs | 2 + .../Storage/Building_MassStorageUnit.cs | 39 +- .../Storage/Building_StorageUnitIOPort.cs | 85 ++-- .../Storage/UI/ITab_Items.cs | 16 +- 16 files changed, 844 insertions(+), 76 deletions(-) create mode 100644 Source/ProjectRimFactory/Storage/Building_ColdStorage.cs create mode 100644 Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs 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); + } } From c859320de31a41041e904c14a18ad64a4ec2bff3 Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Thu, 1 Sep 2022 14:48:38 +0200 Subject: [PATCH 02/10] #612 Updated to Tick contents resolved some doulble call issues slightly improved the stacking --- .../Storage/Building_ColdStorage.cs | 14 ++++++++------ .../Storage/Building_ColdStoragePowerd.cs | 1 + .../Storage/Building_StorageUnitIOPort.cs | 8 -------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs index 8e286352..14cd44cf 100644 --- a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs +++ b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs @@ -57,7 +57,7 @@ public abstract class Building_ColdStorage : Building, IRenameBuilding, IHaulDes { private static readonly Texture2D RenameTex = ContentFinder.Get("UI/Buttons/Rename"); - private ThingOwner thingOwner = new ThingOwner(); + protected ThingOwner thingOwner = new ThingOwner(); private List items => thingOwner.InnerListForReading; @@ -147,17 +147,19 @@ public virtual string GetITabString(int 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 items_arr = items.ToArray(); + for (var i = 0; i < items_arr.Length; i++) { - var item = items[i]; - if (item.def.category == ThingCategory.Item && item.CanStackWith(newItem)) + var item = items_arr[i]; + //CanStackWith is already called by TryAbsorbStack... + //Is the Item Check really needed? + if (item.def.category == ThingCategory.Item) item.TryAbsorbStack(newItem, true); if (newItem.Destroyed) break; } diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs b/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs index 814476b5..73478702 100644 --- a/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs +++ b/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs @@ -54,6 +54,7 @@ public override void Tick() { UpdatePowerConsumption(); } + thingOwner.ThingOwnerTick(); } public override void PostMapInit() diff --git a/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs b/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs index f9a23cd0..60126729 100644 --- a/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs +++ b/Source/ProjectRimFactory/Storage/Building_StorageUnitIOPort.cs @@ -460,19 +460,11 @@ public override StorageIOMode IOMode public override void Notify_ReceivedThing(Thing newItem) { base.Notify_ReceivedThing(newItem); - if (mode == StorageIOMode.Input) - { - RefreshInput(); - } } public override void Notify_LostThing(Thing newItem) { base.Notify_LostThing(newItem); - if (mode == StorageIOMode.Output) - { - RefreshOutput(); - } } public override void RefreshInput() From 647622e6187bb082b06b054342a71c1cf8b95f9a Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Sun, 4 Sep 2022 19:48:20 +0200 Subject: [PATCH 03/10] #612 Added WealthWatcher Patch (may be toggeld) Added support for Orbital Trading Fixed issue when creating ThingOwner Fixed Typos in Conditional Patches Fixed Null ref issue for DSU Moved code to better locations --- Languages/English/Keyed/AllKeyed_Settings.xml | 2 + .../Common/ConditionalPatchHelper.cs | 10 ++- .../HarmonyPatches/Patch_DSU_OrbitalTrade.cs | 29 +++++++- .../Patch_TradeDeal_InSellablePosition.cs | 41 ++++++++++++ ...atch_WealthWatcher_CalculateWealthItems.cs | 29 ++++++++ .../Common/PRFMapComponent.cs | 20 ++++++ .../Common/ProjectRimFactory_ModComponent.cs | 1 + .../Common/ProjectRimFactory_ModSettings.cs | 20 ++++-- .../Storage/Building_ColdStorage.cs | 67 +++++-------------- .../Storage/Building_ColdStoragePowerd.cs | 10 +++ .../Building_MassStorageUnitPowered.cs | 22 +----- .../Storage/ILinkableStorageParent.cs | 49 ++++++++++++++ 12 files changed, 219 insertions(+), 81 deletions(-) create mode 100644 Source/ProjectRimFactory/Common/HarmonyPatches/Patch_TradeDeal_InSellablePosition.cs create mode 100644 Source/ProjectRimFactory/Common/HarmonyPatches/Patch_WealthWatcher_CalculateWealthItems.cs create mode 100644 Source/ProjectRimFactory/Storage/ILinkableStorageParent.cs diff --git a/Languages/English/Keyed/AllKeyed_Settings.xml b/Languages/English/Keyed/AllKeyed_Settings.xml index b319444a..948a4794 100644 --- a/Languages/English/Keyed/AllKeyed_Settings.xml +++ b/Languages/English/Keyed/AllKeyed_Settings.xml @@ -7,6 +7,8 @@ Patches Toggels the Advanced IO CanReach Patch\nWhen checked the Patch is active and allowes Pawns to reach DSU contents using Advanced IO Ports even if the Path to the DSU is blocked\nPatch is not active by default as it may cause spikes and is only usefull in some cases.\n(ProjectRimFactory.Common.HarmonyPatches.Patch_Reachability_CanReach:Prefix) Advanced IO CanReach + Toggels the Cold Storage WealthWatcher Patch\nWhen checked the Patch is active and items in Coldstorage contribute to Colony Wealth.\nFor most Players we reccomend this to be on.\nPeformence load on this is ~1ms per 1k Things stored. This runs every 5k Ticks\n(ProjectRimFactory.Common.HarmonyPatches.Patch_WealthWatcher_CalculateWealthItems:Postfix) + Cold Storage WealthWatcher Forbid items on Placment Toggle this to forbid items on placement diff --git a/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs b/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs index 2cdd61a4..715b79f1 100644 --- a/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs +++ b/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs @@ -62,6 +62,12 @@ public void PatchHandler(bool patch) AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Reachability_CanReach), "Prefix") ); + public static TogglePatch Patch_WealthWatcher_CalculateWealthItems = new TogglePatch( + AccessTools.Method(typeof(RimWorld.WealthWatcher), "CalculateWealthItems"), + null, + AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_WealthWatcher_CalculateWealthItems), "Postfix") + ); + //Storage Patches public static TogglePatch Patch_MinifiedThing_Print = new TogglePatch( AccessTools.Method(typeof(RimWorld.MinifiedThing), "Print", new Type[] { typeof(SectionLayer)}), @@ -72,7 +78,7 @@ public void PatchHandler(bool patch) 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(Verse.ThingWithComps), "Draw"), AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_ThingWithComps_Draw), "Prefix") ); public static TogglePatch Patch_ThingWithComps_DrawGUIOverlay = new TogglePatch( @@ -80,7 +86,7 @@ public void PatchHandler(bool patch) 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(Verse.Thing), "DrawGUIOverlay"), AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Thing_DrawGUIOverlay), "Prefix") ); public static TogglePatch Patch_FloatMenuMakerMap_ChoicesAtFor = new TogglePatch( diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_DSU_OrbitalTrade.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_DSU_OrbitalTrade.cs index d12eb071..b92c429f 100644 --- a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_DSU_OrbitalTrade.cs +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_DSU_OrbitalTrade.cs @@ -20,7 +20,7 @@ static void Postfix(Map map, ref IEnumerable __result) { HashSet yieldedThings = new HashSet(); yieldedThings.AddRange(__result); - foreach (Building_MassStorageUnitPowered dsu in Building_MassStorageUnitPowered.AllPowered(map)) + foreach (ILinkableStorageParent dsu in TradePatchHelper.AllPowered(map)) { yieldedThings.AddRange(dsu.StoredItems); } @@ -89,7 +89,7 @@ static IEnumerable Transpiler(IEnumerable inst yield return new CodeInstruction(OpCodes.Call, AccessTools.PropertyGetter(typeof(PassingShip), "Map")); //Call --> Building_MassStorageUnitPowered.AnyPowerd with the above as an argument yield return new CodeInstruction(OpCodes.Call, HarmonyLib.AccessTools - .Method(typeof(Building_MassStorageUnitPowered) ,nameof(Building_MassStorageUnitPowered.AnyPowerd), new[] { typeof(Map)} )); + .Method(typeof(TradePatchHelper) ,nameof(TradePatchHelper.AnyPowerd), new[] { typeof(Map)} )); yield return new CodeInstruction(OpCodes.Brtrue_S, instruction.operand); continue; @@ -103,6 +103,31 @@ static IEnumerable Transpiler(IEnumerable inst } } + public static class TradePatchHelper + { + public static bool AnyPowerd(Map map) + { + return AllPowered(map,true).Any(); + } + + public static IEnumerable AllPowered(Map map, bool any = false) + { + foreach (ILinkableStorageParent item in map.listerBuildings.AllBuildingsColonistOfClass()) + { + if (item.Powered) + { + yield return item; + if (any) break; + } + } + var cs = PatchStorageUtil.GetPRFMapComponent(map).ColdStorageBuildings.Select(b => b as ILinkableStorageParent); + foreach (var item in cs) + { + yield return item; + } + } + } + diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_TradeDeal_InSellablePosition.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_TradeDeal_InSellablePosition.cs new file mode 100644 index 00000000..4647c60e --- /dev/null +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_TradeDeal_InSellablePosition.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using HarmonyLib; +using Verse; +using ProjectRimFactory.Storage; +using System.Reflection.Emit; +using System.Reflection; + +namespace ProjectRimFactory.Common.HarmonyPatches +{ + + [HarmonyPatch(typeof(TradeDeal), "InSellablePosition")] + class Patch_TradeDeal_InSellablePosition + { + public static bool Prefix(Thing t, out string reason, ref bool __result) + { + if (!t.Spawned) + { + var buildings = PatchStorageUtil.GetPRFMapComponent(t.MapHeld).ColdStorageBuildings; + foreach(var building in buildings) + { + if (building.StoredItems.Contains(t)) + { + reason = null; + __result = true; + return false; + } + } + } + + reason = null; + return true; + } + + + } +} diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_WealthWatcher_CalculateWealthItems.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_WealthWatcher_CalculateWealthItems.cs new file mode 100644 index 00000000..f653c70e --- /dev/null +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_WealthWatcher_CalculateWealthItems.cs @@ -0,0 +1,29 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectRimFactory.Common.HarmonyPatches +{ + /// + /// Patch to ensure Items in Cold Storage Contribute to Wealth + /// 1k Items ~ 1ms (every 5k Ticks) + /// + class Patch_WealthWatcher_CalculateWealthItems + { + + public static void Postfix(Verse.Map ___map, ref float __result) + { + var buildings = PatchStorageUtil.GetPRFMapComponent(___map).ColdStorageBuildings; + var cnt = buildings.Count; + for(int i = 0; i < cnt; i++) + { + var building = buildings[i]; + __result += building.GetItemWealth(); + } + + } + } +} diff --git a/Source/ProjectRimFactory/Common/PRFMapComponent.cs b/Source/ProjectRimFactory/Common/PRFMapComponent.cs index 02cbcecc..0e7f33ba 100644 --- a/Source/ProjectRimFactory/Common/PRFMapComponent.cs +++ b/Source/ProjectRimFactory/Common/PRFMapComponent.cs @@ -15,6 +15,8 @@ public class PRFMapComponent : MapComponent // iHideRightMenus: see HarmonyPatches/PatchStorage.cs public HashSet iHideRightMenus = new HashSet(); + public List ColdStorageBuildings = new List(); + private Dictionary> hideItemLocations = new Dictionary>(); private Dictionary> ForbidPawnOutputItemLocations = new Dictionary>(); @@ -23,6 +25,24 @@ public class PRFMapComponent : MapComponent public Dictionary GetadvancedIOLocations => advancedIOLocations; + public void RegisterColdStorageBuilding(ProjectRimFactory.Storage.Building_ColdStorage port) + { + if (!ColdStorageBuildings.Contains(port)) + { + ColdStorageBuildings.Add(port); + } + } + public void DeRegisterColdStorageBuilding(ProjectRimFactory.Storage.Building_ColdStorage port) + { + if (ColdStorageBuildings.Contains(port)) + { + ColdStorageBuildings.Remove(port); + } + + } + + + public void RegisteradvancedIOLocations(IntVec3 pos, ProjectRimFactory.Storage.Building_AdvancedStorageUnitIOPort port) { if (!advancedIOLocations.ContainsKey(pos)) diff --git a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs index cb298220..cdcdc064 100644 --- a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs +++ b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs @@ -27,6 +27,7 @@ public ProjectRimFactory_ModComponent(ModContentPack content) : base(content) LoadModSupport(); ConditionalPatchHelper.InitHarmony(this.HarmonyInstance); ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach); + ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_WealthWatcher_CalculateWealthItems); } catch (Exception ex) diff --git a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs index 64952477..3b5e2458 100644 --- a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs +++ b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs @@ -73,12 +73,18 @@ private static void CSharpSettings(Listing_Standard list) { } TooltipHandler.TipRegion(rect, "PRF_Settings_C_Patches_Reachability_CanReach_ToolTip".Translate()); Widgets.CheckboxLabeled(rect, "PRF_Settings_C_Patches_Reachability_CanReach".Translate(), ref PRF_Patch_Reachability_CanReach); - list.Gap(); - if (PRF_Patch_Reachability_CanReach != PRF_Patch_Reachability_CanReach_last) + list.Gap(); + ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach); + + rect = list.GetRect(20); + if (Mouse.IsOver(rect)) { - ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach); - } - PRF_Patch_Reachability_CanReach_last = PRF_Patch_Reachability_CanReach; + Widgets.DrawHighlight(rect); + } + TooltipHandler.TipRegion(rect, "PRF_Settings_C_Patches_WealthWatcher_CalculateWealthItems_ToolTip".Translate()); + Widgets.CheckboxLabeled(rect, "PRF_Settings_C_Patches_WealthWatcher_CalculateWealthItems".Translate(), ref PRF_Patch_WealthWatcher_CalculateWealthItems); + list.Gap(); + ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_WealthWatcher_CalculateWealthItems); } @@ -104,7 +110,7 @@ private static ContainerRow ParseSettingRows(ModContentPack content) public static bool PRF_LiteMode = false; private static bool PRF_LiteMode_last = false; public static bool PRF_Patch_Reachability_CanReach = false; - private static bool PRF_Patch_Reachability_CanReach_last = false; + public static bool PRF_Patch_WealthWatcher_CalculateWealthItems = true; public override void ExposeData() { @@ -113,8 +119,8 @@ public override void ExposeData() Scribe_Values.Look(ref Debug.activeFlags, "debugFlags", 0); Scribe_Values.Look(ref PRF_LiteMode, "PRF_LiteMode", false); Scribe_Values.Look(ref PRF_Patch_Reachability_CanReach, "PRF_Patch_Reachability_CanReach", false); + Scribe_Values.Look(ref PRF_Patch_WealthWatcher_CalculateWealthItems, "PRF_Patch_WealthWatcher_CalculateWealthItems", true); PRF_LiteMode_last = PRF_LiteMode; - PRF_Patch_Reachability_CanReach_last = PRF_Patch_Reachability_CanReach; } public void DoWindowContents(Rect inRect) diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs index 14cd44cf..ff7d540c 100644 --- a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs +++ b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs @@ -11,53 +11,12 @@ 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"); - protected ThingOwner thingOwner = new ThingOwner(); + protected ThingOwner thingOwner; private List items => thingOwner.InnerListForReading; @@ -199,25 +158,22 @@ public override string GetInspectString() public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) { - var thingsToSplurge = new List(Position.GetThingList(Map)); + var thingsToSplurge = items; for (var i = 0; i < thingsToSplurge.Count; i++) if (thingsToSplurge[i].def.category == ThingCategory.Item) { - thingsToSplurge[i].DeSpawn(); + //thingsToSplurge[i].DeSpawn(); GenPlace.TryPlaceThing(thingsToSplurge[i], Position, Map, ThingPlaceMode.Near); } + PatchStorageUtil.GetPRFMapComponent(Map).DeRegisterColdStorageBuilding(this); base.DeSpawn(mode); } public override void SpawnSetup(Map map, bool respawningAfterLoad) { base.SpawnSetup(map, respawningAfterLoad); + PatchStorageUtil.GetPRFMapComponent(Map).RegisterColdStorageBuilding(this); 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) @@ -231,6 +187,19 @@ public override void SpawnSetup(Map map, bool respawningAfterLoad) } + public float GetItemWealth() + { + float output = 0; + var itemsc = items.Count; + for (int i = 0;i< itemsc; i++) + { + var item = items[i]; + output += item.MarketValue * item.stackCount; + } + + return output; + } + public override void DrawGUIOverlay() { base.DrawGUIOverlay(); diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs b/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs index 73478702..70d0ca81 100644 --- a/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs +++ b/Source/ProjectRimFactory/Storage/Building_ColdStoragePowerd.cs @@ -152,5 +152,15 @@ public static IEnumerable AllPowered(Map map) } } + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + } + + public override void PostMake() + { + base.PostMake(); + thingOwner ??= new ThingOwner(this); + } } } diff --git a/Source/ProjectRimFactory/Storage/Building_MassStorageUnitPowered.cs b/Source/ProjectRimFactory/Storage/Building_MassStorageUnitPowered.cs index aa36b610..29a46753 100644 --- a/Source/ProjectRimFactory/Storage/Building_MassStorageUnitPowered.cs +++ b/Source/ProjectRimFactory/Storage/Building_MassStorageUnitPowered.cs @@ -21,7 +21,7 @@ public class Building_MassStorageUnitPowered : Building_MassStorageUnit 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 CanReceiveIO => base.CanReceiveIO && Powered && this.Spawned; public override bool ForbidPawnInput => this.ForbidPawnAccess || !this.pawnAccess || !this.CanStoreMoreItems; @@ -150,25 +150,5 @@ public override string GetITabString(int itemsSelected) 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/ILinkableStorageParent.cs b/Source/ProjectRimFactory/Storage/ILinkableStorageParent.cs new file mode 100644 index 00000000..2ce05f9c --- /dev/null +++ b/Source/ProjectRimFactory/Storage/ILinkableStorageParent.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ProjectRimFactory.Storage +{ + /// + /// Interface for buildings that can have IO Ports link to them + /// + 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; } + + } +} \ No newline at end of file From 956aba57a27c2d6b354364df5bed8f8a5afbd611 Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Fri, 9 Sep 2022 15:14:41 +0200 Subject: [PATCH 04/10] by Madman666 --- Textures/Storage/ColdStorageUnit.png | Bin 0 -> 45146 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Textures/Storage/ColdStorageUnit.png diff --git a/Textures/Storage/ColdStorageUnit.png b/Textures/Storage/ColdStorageUnit.png new file mode 100644 index 0000000000000000000000000000000000000000..a8c3bfaa3b8e3b0b06fdf439af390945d8337fe3 GIT binary patch literal 45146 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 literal 0 HcmV?d00001 From 3f436e60188eb289cb26c270b8d67dd65efcd130 Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Fri, 9 Sep 2022 15:15:56 +0200 Subject: [PATCH 05/10] Updated to Madman666's Textures Updated Damage overlay config --- Defs/ThingDefs_Buildings/Buildings_Storage.xml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Defs/ThingDefs_Buildings/Buildings_Storage.xml b/Defs/ThingDefs_Buildings/Buildings_Storage.xml index 4784c78b..99b771ed 100644 --- a/Defs/ThingDefs_Buildings/Buildings_Storage.xml +++ b/Defs/ThingDefs_Buildings/Buildings_Storage.xml @@ -366,7 +366,7 @@ 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 @@ -391,12 +391,20 @@ Graphic_Single - Storage/CargoPlatform + Storage/ColdStorageUnit (3,3) + + + + (0.1,0,2.8,2.8) + Damage/Corner - Damage/Corner + Damage/Corner + Damage/Corner + + 50 From e1edd74af95516f417245ff9ebaa82756466780c Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Tue, 13 Sep 2022 07:55:46 +0200 Subject: [PATCH 06/10] #612 Adjusted build cost and research req --- Defs/ThingDefs_Buildings/Buildings_Storage.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Defs/ThingDefs_Buildings/Buildings_Storage.xml b/Defs/ThingDefs_Buildings/Buildings_Storage.xml index 99b771ed..98b40cdd 100644 --- a/Defs/ThingDefs_Buildings/Buildings_Storage.xml +++ b/Defs/ThingDefs_Buildings/Buildings_Storage.xml @@ -442,14 +442,14 @@ 50 20 100 - 100 - 15 + 90 + 20 1 1 Normal -
  • PRF_StorageIO
  • +
  • PRF_StorageIO_II
  • From ec41d7a9160b4e4bd88b4c078857a059120c6cea Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Tue, 13 Sep 2022 08:00:39 +0200 Subject: [PATCH 07/10] reverts acidental edit --- Source/ProjectRimFactory/Common/PRFGameComponent.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/ProjectRimFactory/Common/PRFGameComponent.cs b/Source/ProjectRimFactory/Common/PRFGameComponent.cs index 495d8b7b..155b9568 100644 --- a/Source/ProjectRimFactory/Common/PRFGameComponent.cs +++ b/Source/ProjectRimFactory/Common/PRFGameComponent.cs @@ -15,8 +15,6 @@ 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); From a3c4090e7ce7be6b56d2aaef1ea79a46b4467f02 Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Tue, 13 Sep 2022 08:32:08 +0200 Subject: [PATCH 08/10] #612 fixed copy and paste error --- .../ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs | 2 +- .../ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs index cdcdc064..ff1959da 100644 --- a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs +++ b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModComponent.cs @@ -27,7 +27,7 @@ public ProjectRimFactory_ModComponent(ModContentPack content) : base(content) LoadModSupport(); ConditionalPatchHelper.InitHarmony(this.HarmonyInstance); ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_Reachability_CanReach); - ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_WealthWatcher_CalculateWealthItems); + ConditionalPatchHelper.Patch_WealthWatcher_CalculateWealthItems.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_WealthWatcher_CalculateWealthItems); } catch (Exception ex) diff --git a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs index 3b5e2458..d1f762e9 100644 --- a/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs +++ b/Source/ProjectRimFactory/Common/ProjectRimFactory_ModSettings.cs @@ -84,7 +84,7 @@ private static void CSharpSettings(Listing_Standard list) { TooltipHandler.TipRegion(rect, "PRF_Settings_C_Patches_WealthWatcher_CalculateWealthItems_ToolTip".Translate()); Widgets.CheckboxLabeled(rect, "PRF_Settings_C_Patches_WealthWatcher_CalculateWealthItems".Translate(), ref PRF_Patch_WealthWatcher_CalculateWealthItems); list.Gap(); - ConditionalPatchHelper.Patch_Reachability_CanReach.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_WealthWatcher_CalculateWealthItems); + ConditionalPatchHelper.Patch_WealthWatcher_CalculateWealthItems.PatchHandler(ProjectRimFactory_ModSettings.PRF_Patch_WealthWatcher_CalculateWealthItems); } From 2e0e23033c83a117ab7fa857b38b64fad015f25c Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Tue, 13 Sep 2022 12:32:43 +0200 Subject: [PATCH 09/10] #612 added support for local Trading fixed issue with exposing ThingOwner --- ..._TraderTracker_ColonyThingsWillingToBuy.cs | 35 +++++++++++++++++++ .../Storage/Building_ColdStorage.cs | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Pawn_TraderTracker_ColonyThingsWillingToBuy.cs diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Pawn_TraderTracker_ColonyThingsWillingToBuy.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Pawn_TraderTracker_ColonyThingsWillingToBuy.cs new file mode 100644 index 00000000..77e42d08 --- /dev/null +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_Pawn_TraderTracker_ColonyThingsWillingToBuy.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using ProjectRimFactory.Storage; +using RimWorld; +using Verse; + +namespace ProjectRimFactory.Common.HarmonyPatches +{ + [HarmonyPatch(typeof(Pawn_TraderTracker), "ColonyThingsWillingToBuy")] + class Patch_Pawn_TraderTracker_ColonyThingsWillingToBuy + { + static void Postfix(Pawn playerNegotiator, ref IEnumerable __result) + { + var map = playerNegotiator.Map; + if (map is null) return; + + HashSet yieldedThings = new HashSet(); + yieldedThings.AddRange(__result); + foreach (ILinkableStorageParent dsu in TradePatchHelper.AllPowered(map)) + { + //Only for Cold Storage + if (dsu.AdvancedIOAllowed) continue; + + yieldedThings.AddRange(dsu.StoredItems); + } + __result = yieldedThings; + + } + + } +} diff --git a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs index ff7d540c..94283647 100644 --- a/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs +++ b/Source/ProjectRimFactory/Storage/Building_ColdStorage.cs @@ -141,7 +141,7 @@ public override void ExposeData() { base.ExposeData(); Scribe_Collections.Look(ref ports, "ports", LookMode.Reference); - Scribe_Deep.Look(ref this.thingOwner, "thingowner"); + Scribe_Deep.Look(ref this.thingOwner, "thingowner",this); Scribe_Values.Look(ref uniqueName, "uniqueName"); Scribe_Deep.Look(ref settings, "settings", this); ModExtension_Crate ??= def.GetModExtension(); From 6ef47578cdd2479c57294ce2d6d5d87674885d9c Mon Sep 17 00:00:00 2001 From: Sn1p3rr3c0n Date: Sat, 17 Sep 2022 19:59:50 +0200 Subject: [PATCH 10/10] updated description --- Defs/ThingDefs_Buildings/Buildings_Storage.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Defs/ThingDefs_Buildings/Buildings_Storage.xml b/Defs/ThingDefs_Buildings/Buildings_Storage.xml index 98b40cdd..145f8a34 100644 --- a/Defs/ThingDefs_Buildings/Buildings_Storage.xml +++ b/Defs/ThingDefs_Buildings/Buildings_Storage.xml @@ -367,7 +367,7 @@ 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. + 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 Cold Storage Unit will not be able to store more. Don't break it.\n\nItems stored in this Device are not spawned and therefore won't be automatically accessible by your pawns. Use I/O Ports to interact with it. PRF_IoGroup 0.9