コード例 #1
0
        private static IEnumerator AddToVehicle(TechType techType, ItemsContainer itemsContainer)
        {
            CoroutineTask <GameObject> coroutineTask = CraftData.GetPrefabForTechTypeAsync(techType, false);

            yield return(coroutineTask);

            GameObject prefab = coroutineTask.GetResult();

            if (prefab is null)
            {
                prefab = Utils.CreateGenericLoot(techType);
            }

            GameObject gameObject = GameObject.Instantiate(prefab, null);
            Pickupable pickupable = gameObject.EnsureComponent <Pickupable>();

#if SUBNAUTICA_EXP
            TaskResult <Pickupable> result1 = new TaskResult <Pickupable>();
            yield return(pickupable.InitializeAsync(result1));

            pickupable = result1.Get();
#else
            pickupable.Initialize();
#endif
            var item = new InventoryItem(pickupable);
            itemsContainer.UnsafeAdd(item);
            string name = Language.main.GetOrFallback(techType.AsString(), techType.AsString());
            ErrorMessage.AddMessage(Language.main.GetFormat("VehicleAddedToStorage", name));
            uGUI_IconNotifier.main.Play(techType, uGUI_IconNotifier.AnimationType.From, null);
            pickupable.PlayPickupSound();

            yield break;
        }
コード例 #2
0
        internal static void AddToCustomGroup(TechGroup group, TechCategory category, TechType techType, TechType after)
        {
            if (!CraftData.groups.TryGetValue(group, out Dictionary <TechCategory, List <TechType> > techGroup))
            {
                // Should never happen, but doesn't hurt to add it.
                Logger.Log("Invalid TechGroup!", LogLevel.Error);
                return;
            }

            if (!techGroup.TryGetValue(category, out List <TechType> techCategory))
            {
                Logger.Log($"{group} does not contain {category} as a registered group. Please ensure to register your TechCategory to the TechGroup using the TechCategoryHandler before using the combination.", LogLevel.Error);
                return;
            }

            if (techCategory.Contains(techType))
            {
                Logger.Log($"\"{techType.AsString():G}\" Already exists at \"{group:G}->{category:G}\", Skipping Duplicate Entry", LogLevel.Debug);
                return;
            }

            int index = techCategory.IndexOf(after);

            if (index == -1) // Not found
            {
                techCategory.Add(techType);
                Logger.Log($"Added \"{techType.AsString():G}\" to groups under \"{group:G}->{category:G}\"", LogLevel.Debug);
            }
            else
            {
                techCategory.Insert(index + 1, techType);

                Logger.Log($"Added \"{techType.AsString():G}\" to groups under \"{group:G}->{category:G}\" after \"{after.AsString():G}\"", LogLevel.Debug);
            }
        }
コード例 #3
0
        internal void RemoveAnalysisTechEntry(TechType targetTechType)
        {
            foreach (KnownTech.AnalysisTech tech in KnownTechPatcher.AnalysisTech.Values)
            {
                if (tech.unlockTechTypes.Contains(targetTechType))
                {
                    Logger.Debug($"Removed {targetTechType.AsString()} from {tech.techType.AsString()} unlocks that was added by another mod!");
                    tech.unlockTechTypes.Remove(targetTechType);
                }
            }

            if (KnownTechPatcher.CompoundTech.TryGetValue(targetTechType, out var types))
            {
                Logger.Debug($"Removed Compound Unlock for {targetTechType.AsString()} that was added by another mod!");
                KnownTechPatcher.CompoundTech.Remove(targetTechType);
            }

            if (KnownTechPatcher.UnlockedAtStart.Contains(targetTechType))
            {
                Logger.Debug($"Removed UnlockedAtStart for {targetTechType.AsString()} that was added by another mod!");
                KnownTechPatcher.UnlockedAtStart.Remove(targetTechType);
            }

            if (!KnownTechPatcher.RemovalTechs.Contains(targetTechType))
            {
                KnownTechPatcher.RemovalTechs.Add(targetTechType);
            }
        }
コード例 #4
0
        internal void AddCompoundUnlock(TechType techType, List <TechType> compoundTechsForUnlock)
        {
            if (techType == TechType.None)
            {
                Logger.Error("Cannot Add Unlock to TechType.None!");
                return;
            }

            if (compoundTechsForUnlock.Contains(techType))
            {
                Logger.Error("Cannot Add Compound Unlock that contains itself!");
                return;
            }


            if (KnownTechPatcher.CompoundTech.TryGetValue(techType, out KnownTech.CompoundTech compoundTech))
            {
                Logger.Debug($"Compound Unlock already found for {techType.AsString()}, Overwriting.");
                compoundTech.dependencies = compoundTechsForUnlock;
            }
            else
            {
                Logger.Debug($"Adding Compound Unlock for {techType.AsString()}");
                KnownTechPatcher.CompoundTech.Add(techType, new KnownTech.CompoundTech()
                {
                    techType = techType, dependencies = compoundTechsForUnlock
                });
            }
        }
コード例 #5
0
        internal static void AddToCustomGroup(TechGroup group, TechCategory category, TechType techType, TechType after)
        {
            Dictionary <TechGroup, Dictionary <TechCategory, List <TechType> > > groups = CraftData.groups;
            Dictionary <TechCategory, List <TechType> > techGroup = groups[group];

            if (techGroup == null)
            {
                // Should never happen, but doesn't hurt to add it.
                Logger.Log("Invalid TechGroup!", LogLevel.Error);
                return;
            }

            List <TechType> techCategory = techGroup[category];

            if (techCategory == null)
            {
                Logger.Log($"Invalid TechCategory Combination! TechCategory: {category} TechGroup: {group}", LogLevel.Error);
                return;
            }

            int index = techCategory.IndexOf(after);

            if (index == -1) // Not found
            {
                techCategory.Add(techType);
                Logger.Log($"Added \"{techType.AsString():G}\" to groups under \"{group:G}->{category:G}\"", LogLevel.Debug);
            }
            else
            {
                techCategory.Insert(index + 1, techType);

                Logger.Log($"Added \"{techType.AsString():G}\" to groups under \"{group:G}->{category:G}\" after \"{after.AsString():G}\"", LogLevel.Debug);
            }
        }
コード例 #6
0
 public TankCraftHelper(TechType baseTank) : base(baseTank.AsString(false) + "RefillHelper", "Refilled " + Language.main.Get(baseTank), "Refilled " + Language.main.Get(baseTank))
 {
     Log.LogDebug($"{baseTank.AsString(false) + "RefillHelper"} constructor initialising; this.TechType == {this.TechType.AsString()}");
     OnFinishedPatching += () =>
     {
         Log.LogDebug($"{this.TechType.AsString(false)} OnFinishedPatching begin");
         RequiredUnlockDict[this.TechType] = baseTank;
         thisBaseTank = baseTank;
         Main.bannedTech.Add(this.TechType);
         Log.LogDebug($"{this.TechType.AsString(false)} adding crafting node");
         CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, this.TechType, new string[] {
             "Personal",
             "TankRefill",
             this.TechType.AsString(false)
         });
         myRecipe = new RecipeData()
         {
             craftAmount = 0,
             Ingredients = new List <Ingredient>()
             {
                 new Ingredient(baseTank, 1)
             }
         };
         myRecipe.LinkedItems.Add(baseTank);
         Log.LogDebug($"{this.TechType.AsString(false)} OnFinishedPatching completed");
     };
 }
コード例 #7
0
        public static void AddModTechType(TechType tech, GameObject prefab = null)
        {
            if (tech == TechType.None)
            {
                Log.LogError("AddModTechType called with TechType None!");
                return;
            }

            Log.LogDebug($"Adding mod TechType {tech.AsString()}");
            string key = tech.AsString(true);

            if (ModTechTypes.ContainsKey(key))
            {
                // Okay, so there's two possibilities here; one, AddModTechType is being called for the same TechType, and only the TechType, multiple times, which is an error.
                // Two, AddModTechType is being called a second time for a TechType to add a prefab. This is not an error.
                if (prefab == null)
                {
                    Log.LogError($"AddModTechType called multiple times for key '{key}'");
                    return;
                }
            }
            else
            {
                ModTechTypes.Add(key, tech);
            }

            if (prefab != null)
            {
                ModPrefabs[key] = prefab;
            }
        }
コード例 #8
0
            private static void LoadRecyclingTooltip(TechType recyclingTech)
            {
                TooltipFactoryWrapper.RegisterTech(recyclingTech);
                var lang = Language.main;

                if (lang == null)
                {
                    return;
                }

                if (IsBlackListed(recyclingTech))
                {
                    var errorText = lang.Get(nonRecyclableTooltipID);
                    LanguageWrapper.SetDefault("Tooltip_" + recyclingTech.AsString(), errorText);
                    return;
                }

                var data = CraftData.Get(recyclingTech);

                if (data == null)
                {
                    return;
                }
                var ings = new Dictionary <TechType, int>();

                for (var i = 0; i < data.linkedItemCount; i++)
                {
                    var item = data.GetLinkedItem(i);
                    ings[item] = ings.ContainsKey(item) ? (ings[item] + 1) : 1;
                }

                var builder = new System.Text.StringBuilder();

                foreach (var ing in ings)
                {
                    builder.Append(lang.Get(ing.Key.AsString()));
                    if (ing.Value > 1)
                    {
                        builder.Append(" (x");
                        builder.Append(ing.Value);
                        builder.Append(')');
                    }
                    builder.Append(", ");
                }
                if (builder.Length >= 2)
                {
                    builder.Length -= 2;
                }
                var ingList = builder.ToString();

                var tooltip  = lang.Get(recycleTooltipID);
                var formated = StringUtil.FormatWithFallback(tooltip, recycleTooltip, ingList);

                LanguageWrapper.SetDefault("Tooltip_" + recyclingTech.AsString(), formated);
            }
コード例 #9
0
        public bool SetCapacityOverride(TechType tank, float capacity, bool bUpdateIfPresent = false, bool bIsDefault = false, bool bIsManualMode = false)
        {
            // if bIsDefault, the value should be added to the defaults list, not the active list.
            if (bIsDefault)
            {
                string tankID = tank.AsString(true);
                if (defaultTankCapacities.ContainsKey(tankID))
                {
                    if (bUpdateIfPresent)
                    {
                        defaultTankCapacities[tankID] = capacity;
                        Save();
                        return(true);
                    }

                    return(false);
                }

                Main.TankTypes.AddTank(tank, capacity, null, bUpdateIfPresent);
                defaultTankCapacities[tank.AsString(true)] = capacity;
                return(false);
            }

            if (bIsManualMode)
            {
                if (manualTypedCapacityOverrides.ContainsKey(tank))
                {
                    if (!bUpdateIfPresent)
                    {
                        return(false);
                    }
                }
                manualTypedCapacityOverrides[tank] = capacity;
            }
            else
            {
                if (typedCapacityOverrides.ContainsKey(tank))
                {
                    if (!bUpdateIfPresent)
                    {
                        return(false);
                    }
                }
                typedCapacityOverrides[tank] = capacity;
            }
            Save();
            return(true);
        }
コード例 #10
0
        internal static void AddChipData(TechType chip, int maxDischargeValue, bool bDestroy)
        {
            Log.LogDebug($"DiverPerimeterDefenceBehaviour.AddChipData: chip = {chip.AsString()}, maxDischargeValue = {maxDischargeValue}, bDestroy = {bDestroy}");

            maxDischarges[chip]         = maxDischargeValue;
            destroyWhenDischarged[chip] = bDestroy;
        }
コード例 #11
0
        internal static (int discharges, bool bDestroy) GetChipData(TechType chip)
        {
            int  discharges;
            bool bDestroy = false;

            (int discharges, bool bDestroy)returnValue = (0, false);

            if (maxDischarges.TryGetValue(chip, out discharges))
            {
                returnValue.discharges = discharges;
            }
            else
            {
                returnValue.discharges = -1;
            }

            if (destroyWhenDischarged.TryGetValue(chip, out bDestroy))
            {
                returnValue.bDestroy = bDestroy;
            }

            Log.LogDebug($"DiverPerimeterDefenceBehaviour.GetChipData({chip.AsString()}): got values of {returnValue.ToString()}");

            return(returnValue);
        }
コード例 #12
0
ファイル: Core.cs プロジェクト: snoopybeegle/Subnautica-Mods
        private static bool Prefix(uGUI_BuilderMenu __instance)
        {
            __instance.iconGrid.Clear();
            __instance.items.Clear();

            List <TechType> techTypesForGroup = __instance.GetTechTypesForGroup(__instance.selected);
            int             num = 0;

            for (int i = 0; i < techTypesForGroup.Count; i++)
            {
                TechType techType = techTypesForGroup[i];
                if (!Core.RecipeBlacklist.Contains(techType.AsString()))
                {
                    TechUnlockState techUnlockState = KnownTech.GetTechUnlockState(techType);
                    if (techUnlockState == TechUnlockState.Available || techUnlockState == TechUnlockState.Locked)
                    {
                        string stringForInt = IntStringCache.GetStringForInt(num);
                        __instance.items.Add(stringForInt, techType);
                        __instance.iconGrid.AddItem(stringForInt, SpriteManager.Get(techType), SpriteManager.GetBackground(techType), techUnlockState == TechUnlockState.Locked, num);
                        __instance.iconGrid.RegisterNotificationTarget(stringForInt, NotificationManager.Group.Builder, techType.EncodeKey());
                        num++;
                    }
                }
            }
            return(false);
        }
コード例 #13
0
        private void AddItemsToTracker(StorageContainer sc, TechType item, int amountToAdd = 1)
        {
            if (IsBeingDeleted == true)
            {
                return;
            }

            if (DONT_TRACK_GAMEOBJECTS.Contains(item.AsString().ToLower()))
            {
                return;
            }

            if (TrackedResources.ContainsKey(item))
            {
                TrackedResources[item].Amount = TrackedResources[item].Amount + amountToAdd;
                TrackedResources[item].Containers.Add(sc);
            }
            else
            {
                TrackedResources.Add(item, new TrackedResource()
                {
                    TechType   = item,
                    Amount     = amountToAdd,
                    Containers = new HashSet <StorageContainer>()
                    {
                        sc
                    }
                });
            }

            rmd?.ItemModified(item, TrackedResources[item].Amount);
        }
コード例 #14
0
        private static string TryGetTechTypeNameFromId(string techType)
        {
            // Check if given string is not empty
            if (string.IsNullOrEmpty(techType))
            {
                return(techType);
            }
            // Check if given string is only composed of digits
            bool isDigits = true;

            for (int i = 0; ((i < techType.Length) && isDigits); i++)
            {
                if (techType[i] < '0' || techType[i] > '9')
                {
                    isDigits = false;
                }
            }
            // Try get TechType by ID
            Array values = Enum.GetValues(typeof(TechType));
            int   length = values.Length;

            for (int i = 0; i < length; i++)
            {
                TechType currentTechType = (TechType)values.GetValue(i);
                if (string.Compare(Convert.ToString((int)currentTechType), techType, false, CultureInfo.InvariantCulture) == 0)
                {
                    return(currentTechType.AsString());
                }
            }
            return(techType);
        }
コード例 #15
0
 public CustomSprite(TechType type, Atlas.Sprite sprite)
 {
     Group    = SpriteManager.Group.None;
     TechType = type;
     Id       = type.AsString();
     Sprite   = sprite;
 }
コード例 #16
0
ファイル: Patch.cs プロジェクト: MrPurple6411/Subnautica-Mods
        public static void Postfix(ref TechType __result)
        {
            if (__result == TechType.None)
            {
                return;
            }

            RecipeData recipeData;
            TechType   techType2;
            bool       eggCheck;

            while (!(eggCheck = TechTypeExtensions.FromString(__result.AsString() + "Egg", out techType2, true)) && (recipeData = CraftDataHandler.GetTechData(__result)) != null && recipeData.ingredientCount > 0)
            {
                try{ __result = recipeData.Ingredients.GetRandom().techType; }
                catch
                {
                    // ignored
                }
            }

            if (eggCheck)
            {
                __result = techType2;
            }
        }
コード例 #17
0
            public bool AddTank(TechType tank, float baseCapacity, Sprite sprite = null, bool bUpdate = false, bool bUnlockAtStart = false)
            {
                if (TankTypes == null)
                {
                    TankTypes = new Dictionary <TechType, TankType>();
                }

                //if (TankTypes[i].tankTechType == tank)
                if (TankTypes.TryGetValue(tank, out TankType tt))
                {
                    if (bUpdate)
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Updating tank type for TechType '{tank.AsString()}' with value {baseCapacity}");
#endif
                        TankTypes[tank].UpdateCapacity(baseCapacity);
                    }
                    return(false);
                }
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Adding Tank '{tank.AsString()}' with capacity of {baseCapacity}");
#endif
                TankTypes[tank] = new TankType(tank, baseCapacity, bUnlockAtStart: bUnlockAtStart);
                return(true);
            }
コード例 #18
0
 /// <summary>
 /// Creates a new ModSprite to be used with a specific group and internal ID.
 /// Created with an Atlas Sprite.
 /// </summary>
 /// <param name="group">The sprite group.</param>
 /// <param name="type">The techtype paired to this sprite.</param>
 /// <param name="sprite">The sprite to be added.</param>
 public ModSprite(SpriteManager.Group group, TechType type, Atlas.Sprite sprite)
 {
     Group    = group;
     Id       = type.AsString();
     Sprite   = sprite;
     TechType = type;
 }
コード例 #19
0
        public static bool PreAllowedToAdd(Equipment __instance, ref bool __result, string slot, Pickupable pickupable, bool verbose)
        {
            //Log.LogDebug($"EquipmentPatches.PreAllowedToAdd(): __result = {__result}, slot = '{slot}'");

            TechType objTechType = pickupable.GetTechType();
            //Log.LogDebug($"EquipmentPatches.PreAllowedToAdd(): objTechType = {objTechType.AsString()}");
            EquipmentType slotType = Equipment.GetSlotType(slot);

            if (slotType == EquipmentType.BatteryCharger && InventoryPatches.IsChip(objTechType))
            {
#if BELOWZERO
                EquipmentType eType = TechData.GetEquipmentType(objTechType);
#else
                EquipmentType eType = CraftData.GetEquipmentType(objTechType);
#endif
                if (eType == EquipmentType.Chip || eType == EquipmentType.BatteryCharger)
                {
#if false
                    Logger.Log("DEBUG: AllowedToAdd battery charger for " + objTechType.AsString(false));
#endif
                    bool result = ((IItemsContainer)__instance).AllowedToAdd(pickupable, verbose);
                    __result = result;
                    return(false);
                }
            }

            return(true);
        }
コード例 #20
0
 /// <summary>
 /// Creates a new ModSprite to be used with a specific TechType.
 /// Created with an Atlas Sprite.
 /// </summary>
 /// <param name="type">The techtype paired to this sprite.</param>
 /// <param name="sprite">The sprite to be added.</param>
 public ModSprite(TechType type, Atlas.Sprite sprite)
 {
     TechType = type;
     Id       = type.AsString();
     Sprite   = sprite;
     Group    = SpriteManager.Group.Item;
 }
コード例 #21
0
        private void UpdateGUIState()
        {
            TechType activeTechType = manager.GetActiveTechType();

            resourceListRoot.SetActive(activeTechType == TechType.None);
            scanningRoot.SetActive(activeTechType > TechType.None);

            if (lastActiveTechType != activeTechType)
            {
                if (activeTechType != TechType.None)
                {
                    Sprite sprite = SpriteManager.Get(activeTechType, null);

                    if (sprite != null)
                    {
                        scanningIcon.sprite  = sprite;
                        scanningIcon.enabled = true;
                    }
                    else
                    {
                        scanningIcon.enabled = false;
                    }

                    activeTechTypeLabel.text = Language.main.Get(activeTechType.AsString(false));

                    Utils.PlayFMODAsset(startScanningSound, transform, 20f);
                }
                else
                {
                    Utils.PlayFMODAsset(cancelScanningSound, transform, 20f);
                }
            }

            lastActiveTechType = activeTechType;
        }
コード例 #22
0
        private static int CompareByName(TechType a, TechType b)
        {
            string strA = Language.main.Get(a.AsString(false));
            string strB = Language.main.Get(b.AsString(false));

            return(string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase));
        }
コード例 #23
0
        public void HandleUpgrades()
        {
            if (!initialized)
            {
                InitializeUpgradeHandlers();
            }

            QuickLogger.Debug($"UpgradeManager clearing cyclops upgrades");

            // Turn off all upgrades and clear all values
            for (int i = 0; i < upgradeHandlers.Length; i++)
            {
                UpgradeHandler upgradeType = upgradeHandlers[i];

                if (upgradeType.HasUpgrade)
                {
                    QuickLogger.Debug($"UpgradeManager clearing {upgradeType.TechType.AsString()}");
                }

                upgradeType.UpgradesCleared(); // UpgradeHandler event
            }

            bool foundUpgrades = false;

            // Go through all slots and check what upgrades are available
            QuickLogger.Debug($"UpgradeManager checking upgrade slots");
            foreach (UpgradeSlot upgradeSlot in this.UpgradeSlots)
            {
                TechType techTypeInSlot = upgradeSlot.GetTechTypeInSlot();

                if (techTypeInSlot == TechType.None)
                {
                    continue;
                }

                foundUpgrades = true;

                if (KnownsUpgradeModules.TryGetValue(techTypeInSlot, out UpgradeHandler handler))
                {
                    QuickLogger.Debug($"UpgradeManager counting cyclops upgrade '{techTypeInSlot.AsString()}'");
                    handler.UpgradeCounted(upgradeSlot); // UpgradeHandler event
                }
                else
                {
                    QuickLogger.Warning($"UpgradeManager encountered unmanaged cyclops upgrade '{techTypeInSlot.AsString()}'");
                }
            }

            for (int i = 0; i < upgradeHandlers.Length; i++)
            {
                upgradeHandlers[i].UpgradesFinished(); // UpgradeHandler event
            }
            // If any upgrades were found, play the sound to alert the player
            if (foundUpgrades)
            {
                Cyclops.slotModSFX?.Play();
                PdaOverlayManager.RemapItems();
            }
        }
コード例 #24
0
                static IEnumerator _dumpPrefab(TechType techType)
                {
                    var task = PrefabUtils.getPrefabAsync(techType);

                    yield return(task);

                    task.GetResult()?.dump(techType.AsString());
                }
コード例 #25
0
        internal static void PostSeaTruckUpgradesModuleChange(ref SeaTruckUpgrades __instance, TechType techType)
        {
            QuickLogger.Debug($"{nameof(PostSeaTruckUpgradesModuleChange)} {techType.AsString()}", true);
            SeaTruckMotor cab = __instance.motor;

            //cab.gameObject.EnsureComponent<VehicleUpgrader>().UpgradeVehicle(techType, ref cab);
            CoroutineHost.StartCoroutine(DeferUpgrade(cab, techType));
        }
コード例 #26
0
 public static void AddSurvivalSuit(TechType suit)
 {
     Log.LogDebug($"AddSurvivalSuit: called with TechType {suit.AsString()}");
     if (!SurvivalSuits.Contains(suit))
     {
         SurvivalSuits.Add(suit);
     }
 }
コード例 #27
0
        } // a bit inefficient but ok

        /// <summary>
        /// [TODO]
        /// </summary>
        /// <param name="baseType"></param>
        /// <param name="type"></param>
        /// <param name="friendlyName"></param>
        /// <param name="description"></param>
        /// <param name="ingredientType"></param>
        public CompressedObject(TechType baseType, CompactType type, string friendlyName, string description, TechType ingredientType = TechType.None) :
            base($"{baseType.AsString()}{type}", friendlyName, description)
        {
            _type     = type;
            _baseType = baseType;

            _ingredientType = ingredientType != TechType.None ? ingredientType : baseType;
        }
コード例 #28
0
 public static void RegisterTech(TechType techType)
 {
     if (techTypeTooltips.ContainsKey(techType))
     {
         Logger.Exception(new ArgumentException($"TooltipFactory already contains TechType '{techType}'."));
     }
     techTypeTooltips[techType] = "Tooltip_" + techType.AsString();
 }
コード例 #29
0
 internal static void ConsumeResourcesPrefix(TechType techType, uGUI_IconNotifier.AnimationDone endFunc = null)
 {
     Log.LogDebug($"InventoryPatches.ConsumeResourcesPrefix: techType = {techType.AsString()}");
     if (Main.compatibleBatteries.Contains(techType))
     {
         Log.LogDebug($"InventoryPatches.ConsumeResourcesPrefix: battery TechType is being consumed, caching TechType");
         cachedBatteryType = techType;
     }
 }
コード例 #30
0
 internal static void PreRemoveItem(ItemsContainer __instance, TechType techType)
 {
     //Log.LogDebug($"InventoryPatches.PreRemoveItem: techType = {techType.AsString()}");
     if (Main.compatibleBatteries.Contains(techType))
     {
         Log.LogDebug($"InventoryPatches.RemoveItemPrefix: battery TechType {techType.AsString()} is being consumed, caching TechType");
         cachedBatteryType = techType;
     }
 }