Beispiel #1
0
        public void Save()
        {
            string saveDirectory = SaveUtils.GetCurrentSaveDataDir();

            DeathRun.saveData.countSave.AboutToSaveGame();
            DeathRun.saveData.playerSave.AboutToSaveGame();

            try
            {
                var settings = new JsonSerializerSettings
                {
                    NullValueHandling     = NullValueHandling.Ignore,
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore, // Keeps our Vector3's etc from generating infinite references
                    //PreserveReferencesHandling = PreserveReferencesHandling.Objects
                };

                var saveDataJson = JsonConvert.SerializeObject(this, Formatting.Indented, settings);

                if (!Directory.Exists(saveDirectory))
                {
                    Directory.CreateDirectory(saveDirectory);
                }

                File.WriteAllText(Path.Combine(saveDirectory, DeathRun.SaveFile), saveDataJson);
            }
            catch (Exception e)
            {
                CattleLogger.GenericError(e);
                CattleLogger.Message("Failed");
            }
        }
Beispiel #2
0
        /**
         * This deserializes a byte stream we've retrieved from other sources (used on the main menu)
         */
        public static bool LoadFromBytes(byte[] bytes, out DeathRunSaveData target)
        {
            try
            {
                string @jsonData = Encoding.UTF8.GetString(bytes);

                var jsonSerializerSettings = new JsonSerializerSettings
                {
                    MissingMemberHandling = MissingMemberHandling.Ignore,
                    NullValueHandling     = NullValueHandling.Ignore,
                };


                // This deserializes the whole saveData object all at once.
                target = JsonConvert.DeserializeObject <DeathRunSaveData>(jsonData, jsonSerializerSettings);
            }
            catch (Exception e)
            {
                CattleLogger.GenericError(e);
                CattleLogger.Message("Death Run thumbnail data not found - using defaults");
                CattleLogger.Message(e.StackTrace);

                target = null;
                return(false);
            }

            return(true);
        }
Beispiel #3
0
        public static void Prefix(uGUI_HardcoreGameOver __instance)
        {
            DeathRun.setCause("Victory");
            DeathRun.saveData.runData.updateVitals(true);
            DeathRun.statsData.SaveStats();

            TimeSpan timeSpan = TimeSpan.FromSeconds((double)DeathRun.saveData.playerSave.allLives);
            string   text     = "Victory! In " + DeathRunUtils.sayTime(timeSpan) + " (" + (DeathRun.saveData.playerSave.numDeaths + 1) + " ";

            if (DeathRun.saveData.playerSave.numDeaths == 0)
            {
                text += "life";
            }
            else
            {
                text += "lives";
            }

            text += ")";

            DeathRunUtils.CenterMessage(text, 10);
            CattleLogger.Message(text);

            string text2 = "Score: " + DeathRun.saveData.runData.Score;

            DeathRunUtils.CenterMessage(text, 10, 1);
            CattleLogger.Message(text);

            //ErrorMessage.AddMessage(text);
        }
Beispiel #4
0
 private void Awake()
 {
     cachedOxygenManager = Player.main.oxygenMgr;
     cachedDayNight      = DayNightCycle.main;
     cachedTemp          = WaterTemperatureSimulation.main;
     CattleLogger.Message("SpecialtyTanks is Awake() and running!");
 }
Beispiel #5
0
        public void SaveStats()
        {
            if (DeathRun.patchFailed)
            {
                return;
            }

            Version = DeathRunUtils.VERSION;

            try
            {
                var settings = new JsonSerializerSettings
                {
                    NullValueHandling     = NullValueHandling.Ignore,
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore, // Keeps our Vector3's etc from generating infinite references
                    //PreserveReferencesHandling = PreserveReferencesHandling.Objects
                };

                var statsDataJson = JsonConvert.SerializeObject(this, Formatting.Indented, settings);

                File.WriteAllText(Path.Combine(DeathRun.modFolder, DeathRun.StatsFile), statsDataJson);
            }
            catch (Exception e)
            {
                CattleLogger.GenericError(e);
                CattleLogger.Message("Failed");
            }
        }
Beispiel #6
0
        public void startNewRun()
        {
            ID      = DeathRun.statsData.getNewRunID();
            Start   = DeathRun.saveData.startSave.message;
            Version = DeathRunUtils.VERSION;

            CattleLogger.Message("Starting new run - " + ID + " " + Start);

            countSettings();
        }
Beispiel #7
0
        public static bool Prefix(EscapePod __instance, ref Vector3 __result)
        {
            DeathRun.playerIsDead = false;

            if (Config.BASIC_GAME.Equals(DeathRun.config.startLocation))
            {
                DeathRun.saveData.podSave.podGravity  = false;
                DeathRun.saveData.podSave.podSinking  = false;
                DeathRun.saveData.podSave.podAnchored = false;
                DeathRun.saveData.podSave.spotPicked  = true;
                DeathRun.saveData.startSave           = new StartSpot(0, 0, "Safe Shallows");

                DeathRunUtils.CenterMessage("DEATH RUN", 10, 2);
                DeathRunUtils.CenterMessage("Start: \"" + DeathRun.saveData.startSave.message + "\"", 10, 3);

                CattleLogger.Message("Start: " + DeathRun.saveData.startSave.message);

                return(true);
            }

            int       picker = UnityEngine.Random.Range(0, spots.Count);
            StartSpot spot   = spots[picker];

            // If a specific spot was specified in the config, use that instead.
            foreach (StartSpot s in spots)
            {
                if (s.message.Equals(DeathRun.config.startLocation))
                {
                    spot = s;
                    break;
                }
            }

            DeathRun.saveData.podSave.podGravity  = true;  // Pod should sink
            DeathRun.saveData.podSave.podSinking  = false; // ... but isn't sinking yet
            DeathRun.saveData.podSave.podAnchored = false; // ... and hasn't come to rest on the bottom
            DeathRun.saveData.podSave.spotPicked  = true;  // But we have picked the spot for it
            DeathRun.saveData.startSave           = spot;  // Here's where we started

            //ErrorMessage.AddMessage("\"" + spot.message + "\"");
            DeathRunUtils.CenterMessage("DEATH RUN", 10, 2);
            DeathRunUtils.CenterMessage("Start: \"" + spot.message + "\"", 10, 3);

            CattleLogger.Message("Start: " + spot.message);

            __result.x = spot.x;
            __result.y = spot.y;
            __result.z = spot.z;
            return(false);
        }
Beispiel #8
0
        public void Load()
        {
            var path = Path.Combine(SaveUtils.GetCurrentSaveDataDir(), DeathRun.SaveFile);

            if (!File.Exists(path))
            {
                CattleLogger.Message("Death Run data not found - using defaults");
                setDefaults();
                return;
            }

            try
            {
                var save = File.ReadAllText(path);

                var jsonSerializerSettings = new JsonSerializerSettings
                {
                    MissingMemberHandling = MissingMemberHandling.Ignore,
                    NullValueHandling     = NullValueHandling.Ignore,
                    //PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                };

                //var json = JsonConvert.DeserializeObject<DeathRunSaveData>(save, jsonSerializerSettings);
                //this.exampleString = json.exampleString;
                //this.exampleData = json.exampleData;

                // This deserializes the whole saveData object all at once.
                DeathRun.saveData = JsonConvert.DeserializeObject <DeathRunSaveData>(save, jsonSerializerSettings);

                DeathRun.saveData.countSave.JustLoadedGame();
                DeathRun.saveData.playerSave.JustLoadedGame();

                // Special escape-pod re-adjustments
                EscapePod_FixedUpdate_Patch.JustLoadedGame();

                DeathRunUtils.JustLoadedGame();
            }
            catch (Exception e)
            {
                CattleLogger.GenericError(e);
                CattleLogger.Message("Death Run data not found - using defaults");
                CattleLogger.Message(e.StackTrace);
                setDefaults();
            }
        }
Beispiel #9
0
        public static bool Prefix(DamageType damageType)
        {
            try
            {
                setCauseOfDeath(damageType);

                DeathRun.saveData.playerSave.numDeaths++;

                DeathRun.saveData.playerSave.timeOfDeath = DayNightCycle.main.timePassedAsFloat;
                DeathRun.saveData.playerSave.spanAtDeath = DeathRun.saveData.playerSave.allLives;

                TimeSpan timeSpan = TimeSpan.FromSeconds((double)DeathRun.saveData.playerSave.currentLife);

                string text = "Time of Death";
                if (DeathRun.saveData.playerSave.numDeaths > 1)
                {
                    text += " #" + DeathRun.saveData.playerSave.numDeaths;
                }
                text += ": ";

                text += DeathRunUtils.sayTime(timeSpan);

                DeathRunUtils.CenterMessage(text, 10);
                CattleLogger.Message(text);

                text = "Cause of Death: " + DeathRun.cause;
                DeathRunUtils.CenterMessage(text, 10, 1);

                //ErrorMessage.AddMessage(text);

                DeathRun.saveData.playerSave.killOpening = true;
                DeathRun.saveData.runData.updateVitals(false);

                DeathRun.saveData.nitroSave.setDefaults(); // Reset all nitrogen state

                DeathRun.playerIsDead = true;
            }
            catch (Exception ex)
            {
                CattleLogger.GenericError("During Player.OnKill - ", ex);
            }

            return(true);
        }
Beispiel #10
0
        internal static void PatchTanks()
        {
            var tabIcon = ImageUtils.LoadSpriteFromFile(@"./Qmods/" + Assets + @"/TankTabIcon.png");

            CraftTreeHandler.AddTabNode(CraftTree.Type.Workbench, craftTab, "Specialty O2 Tanks", tabIcon);
            CattleLogger.Message("Creating new O2 tank crafting tab");

            var smallPhotoTank = new PhotosynthesisSmallTank();
            var photoTank      = new PhotosynthesisTank();
            var chemoTank      = new ChemosynthesisTank();

            smallPhotoTank.Patch();
            photoTank.Patch();
            chemoTank.Patch();

            CraftDataHandler.SetItemSize(PhotosynthesisSmallID, new Vector2int(2, 3));
            CraftDataHandler.SetItemSize(PhotosynthesisTankID, new Vector2int(2, 3));
            CraftDataHandler.SetItemSize(ChemosynthesisTankID, new Vector2int(2, 3));
        }
Beispiel #11
0
        public static void RegisterSave(string slotName, DeathRunSaveData saveData)
        {
            DeathRunSaveData already = new DeathRunSaveData();

            if (saveList.TryGetValue(slotName, out already))
            {
                saveList.Remove(slotName);
            }

            try
            {
                saveList.Add(slotName, saveData);
            }
            catch (Exception ex)
            {
                CattleLogger.Message("Failed to add to dictionary");
                CattleLogger.GenericError(ex);
            }
        }
        internal static void PatchSuits()
        {
            var tabIcon = ImageUtils.LoadSpriteFromFile(@"./Qmods/" + Assets + @"/SuitTabIcon.png");

            CraftTreeHandler.AddTabNode(CraftTree.Type.Workbench, craftTab, "Dive Suit Upgrades", tabIcon);
            CattleLogger.Message("Creating new dive suit crafting tab");

            var DiveSuitMk2  = new ReinforcedSuitMark2();
            var DiveSuitMk3  = new ReinforcedSuitMark3();
            var StillSuitMk2 = new ReinforcedStillSuit();

            DiveSuitMk2.Patch();
            DiveSuitMk3.Patch();
            StillSuitMk2.Patch();

            CraftDataHandler.SetItemSize(ReinforcedSuit2ID, new Vector2int(2, 2));
            CraftDataHandler.SetItemSize(ReinforcedSuit3ID, new Vector2int(2, 2));
            CraftDataHandler.SetItemSize(ReinforcedStillSuit, new Vector2int(2, 2));
        }
Beispiel #13
0
        public void LoadStats()
        {
            var path = Path.Combine(DeathRun.modFolder, DeathRun.StatsFile);

            if (!File.Exists(path))
            {
                CattleLogger.Message("Death Run `Stats` data not found - starting new Stats");
                setDefaults();
                SaveStats();
                return;
            }

            try
            {
                var save = File.ReadAllText(path);

                var jsonSerializerSettings = new JsonSerializerSettings
                {
                    MissingMemberHandling = MissingMemberHandling.Ignore,
                    NullValueHandling     = NullValueHandling.Ignore,
                    //PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                };

                // This deserializes the whole statsData object all at once.
                DeathRun.statsData = JsonConvert.DeserializeObject <DeathRunStats>(save, jsonSerializerSettings);

                DeathRun.statsData.JustLoadedStats();
            }
            catch (Exception e)
            {
                CattleLogger.GenericError(e);
                CattleLogger.Message("Death Run Stats not found - starting new Stats");
                CattleLogger.Message(e.StackTrace);
                setDefaults();
                SaveStats();
            }
        }
Beispiel #14
0
        public static void Postfix()
        {
            CattleLogger.Message("Item descriptions");

            // First aid kit -- Nitrogen effects
            string original = Language.main.Get("Tooltip_FirstAidKit");
            string add      = " Also cleans nitrogen from the bloodstream to prevent 'The Bends'.";
            string updated;

            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.FirstAidKit, updated);
            }

            // Pipe!
            original = Language.main.Get("Tooltip_Pipe");
            add      = " Supplies 'trimix' or 'nitrox' as appropriate to help clean nitrogen from the bloodstream. Thus, 'Safe Depth' will decrease more quickly when breathing at a pipe.";
            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.Pipe, updated);
            }

            // Floating Air Pump
            original = Language.main.Get("Tooltip_PipeSurfaceFloater");
            add      = " Renders surface air BREATHABLE. Supplies 'trimix' or 'nitrox' as appropriate to help clean nitrogen from the bloodstream. ";
            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.PipeSurfaceFloater, updated);
            }

            // Base Air Pump
            original = Language.main.Get("Tooltip_PipeSurfaceFloater");
            add      = " Supplies 'trimix' or 'nitrox' as appropriate to help clean nitrogen from the bloodstream. ";
            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.BasePipeConnector, updated);
            }

            // Boomerang
            original = Language.main.Get("Tooltip_Boomerang");
            add      = " Seems to have unusual nitrogen-filtering blood chemistry.";
            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.Boomerang, updated);
            }

            // Lava Boomerang
            original = Language.main.Get("Tooltip_LavaBoomerang");
            add      = " Seems to have unusual nitrogen-filtering blood chemistry.";
            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.LavaBoomerang, updated);
            }

            // Reinforced Dive Suit - personal depth limit
            original = Language.main.Get("Tooltip_ReinforcedDiveSuit");
            if (!original.Contains("Personal diving"))
            {
                if (Config.DEATHRUN.Equals(DeathRun.config.personalCrushDepth))
                {
                    updated = original + " Personal diving depth limit 800m.";
                }
                else if (Config.HARD.Equals(DeathRun.config.personalCrushDepth))
                {
                    updated = original + " Personal diving depth unlimited.";
                }
                else
                {
                    updated = original;
                }
                LanguageHandler.Main.SetTechTypeTooltip(TechType.ReinforcedDiveSuit, updated);
            }

            // Radiation Suit - personal depth limit
            original = Language.main.Get("Tooltip_RadiationSuit");
            add      = " Personal depth limit 500m.";
            if (!original.Contains(add))
            {
                if (!Config.NORMAL.Equals(DeathRun.config.personalCrushDepth))
                {
                    updated = original + add;
                    LanguageHandler.Main.SetTechTypeTooltip(TechType.RadiationSuit, updated);
                }
            }

            // StillSuit - personal depth limit
            original = Language.main.Get("Tooltip_Stillsuit");
            if (!original.Contains("Personal depth"))
            {
                if (Config.DEATHRUN.Equals(DeathRun.config.personalCrushDepth))
                {
                    updated = original + " Personal depth limit 800m.";
                }
                else if (Config.HARD.Equals(DeathRun.config.personalCrushDepth))
                {
                    updated = original + " Personal depth limit 1300m.";
                }
                else
                {
                    updated = original;
                }
                LanguageHandler.Main.SetTechTypeTooltip(TechType.Stillsuit, updated);
            }

            // Habitat Builder if we're doing underwater explosions
            if (!Config.NORMAL.Equals(DeathRun.config.explodeDepth) || !Config.NORMAL.Equals(DeathRun.config.radiationDepth))
            {
                original = Language.main.Get("Tooltip_Builder");
                add      = " Build DEEP if you're expecting any big explosions or radiation!";
                if (!original.Contains(add))
                {
                    updated = original + add;
                    LanguageHandler.Main.SetTechTypeTooltip(TechType.Builder, updated);
                }
            }

            if (!Config.NORMAL.Equals(DeathRun.config.batteryCosts))
            {
                LanguageHandler.Main.SetLanguageLine("Battery", "Lithium Battery");
                LanguageHandler.Main.SetLanguageLine("PowerCell", "Lithium Cell");

                LanguageHandler.Main.SetTechTypeTooltip(TechType.Battery, "Advanced Rechargeable Mobile Power Source");
                LanguageHandler.Main.SetTechTypeTooltip(TechType.PowerCell, "High Capacity Mobile Power Source");
            }

            // Update Escape pod "status screen text" for new situation
            // ... post-secondary-system fix
            LanguageHandler.SetLanguageLine("IntroEscapePod4Header", "CONDITION YELLOW");

            original = Language.main.Get("Tooltip_VehicleArmorPlating");
            add      = " REDUCES 'EXTRA' DEATH RUN DAMAGE FROM CREATURES.";
            if (!original.Contains(add))
            {
                updated = original + add;
                LanguageHandler.Main.SetTechTypeTooltip(TechType.VehicleArmorPlating, updated);
            }

            // Forces the language handler to restart with our updates
            Language.main.SetCurrentLanguage(Language.main.GetCurrentLanguage());

            DeathRun.encyclopediaAdded = false; // Have not yet added the DeathRun encyclopedia entries
        }
Beispiel #15
0
        public int calcScore()
        {
            CattleLogger.Message("=== CALCULATING SCORE ===");

            float timeVal  = 0;
            float timeLeft = RunTime;

            while (timeLeft > 0)
            {
                if (timeLeft <= 3600)
                {
                    timeVal += timeLeft;
                    break;
                }
                else
                {
                    timeVal += 3600;
                    timeLeft = (timeLeft - 3600) / 2;
                }
            }
            ;

            CattleLogger.Message("Survival Points: " + timeVal);

            float vehicleVal = 0;

            if ((VehicleFlags & FLAG_SEAGLIDE) != 0)
            {
                vehicleVal += 1000;
            }
            if ((VehicleFlags & FLAG_SEAMOTH) != 0)
            {
                vehicleVal += 5000;
            }
            if ((VehicleFlags & FLAG_EXOSUIT) != 0)
            {
                vehicleVal += 7500;
            }
            if ((VehicleFlags & FLAG_CYCLOPS) != 0)
            {
                vehicleVal += 15000;
            }
            if ((VehicleFlags & FLAG_HABITAT) != 0)
            {
                vehicleVal += 4000;
            }
            if ((VehicleFlags & FLAG_CURE) != 0)
            {
                vehicleVal += 25000;
            }

            if ((VehicleFlags & FLAG_BEACON) != 0)
            {
                vehicleVal += 200;
            }

            if ((VehicleFlags & FLAG_DIVEREEL) != 0)
            {
                vehicleVal += 400;
            }

            if ((VehicleFlags & FLAG_REINFORCED) != 0)
            {
                vehicleVal += 1500;
            }

            if ((VehicleFlags & FLAG_RADIATION) != 0)
            {
                vehicleVal += 300;
            }

            if ((VehicleFlags & FLAG_ULTRAGLIDE) != 0)
            {
                vehicleVal += 500;
            }

            if ((VehicleFlags & FLAG_DOUBLETANK) != 0)
            {
                vehicleVal += 250;
            }

            if ((VehicleFlags & FLAG_PLASTEEL_TANK) != 0)
            {
                vehicleVal += 1000;
            }

            CattleLogger.Message("Vehicle/Tool Points: " + vehicleVal);


            float victoryVal = 0;

            if (Victory)
            {
                victoryVal = 35000 - timeVal * 3 / 2; // SHORTER victory runs are better

                timeVal = 0;
                if (victoryVal < 20000)
                {
                    victoryVal = 20000;
                }

                if ((VehicleFlags & (FLAG_SEAMOTH + FLAG_EXOSUIT + FLAG_CYCLOPS)) == 0)
                {
                    victoryVal += 30000;
                }
            }

            CattleLogger.Message("Victory Points: " + victoryVal);

            float totalVal = timeVal + vehicleVal + victoryVal;

            CattleLogger.Message("SUBTOTAL: " + totalVal);

            if ((Deaths > 1) || ((Deaths > 0) && Victory))
            {
                totalVal = totalVal / (Deaths + (Victory ? 1 : 0));
                CattleLogger.Message("ADJUSTED FOR " + Deaths + " DEATHS: " + totalVal);
            }

            if (DeathRunSettingCount >= 0)
            {
                Score = (int)(totalVal * (DeathRunSettingCount + DeathRunSettingBonus / 2) / MAX_DEATHRUN_SETTING_COUNT);
                CattleLogger.Message("ADJUSTED FOR DEATHRUN SETTINGS: " + Score);
            }
            else
            {
                Score = (int)totalVal;
            }

            if (Score > 99999)
            {
                Score = 99999;
            }

            CattleLogger.Message("FINAL SCORE: " + Score);

            return(Score);
        }
Beispiel #16
0
        static void setCauseOfDeath(DamageType damageType)
        {
            try
            {
                switch (damageType)
                {
                case DamageType.Acid:
                    DeathRun.setCause("Acid");
                    break;

                case DamageType.Collide:
                    DeathRun.setCause("Collision");
                    break;

                case DamageType.Electrical:
                    DeathRun.setCause("Electrocution");
                    break;

                case DamageType.Explosive:
                    DeathRun.setCause("Explosion");
                    break;

                case DamageType.Fire:
                    DeathRun.setCause("Burned to Death");
                    break;

                case DamageType.Heat:
                    DeathRun.setCause("Extreme Heat");
                    break;

                case DamageType.Poison:
                    DeathRun.setCause("Poison");
                    break;

                case DamageType.Pressure:
                    DeathRun.setCause("Pressure");
                    break;

                case DamageType.Puncture:
                    DeathRun.setCause("Puncture Wounds");
                    break;

                case DamageType.Radiation:
                    DeathRun.setCause("Radiation");
                    break;

                case DamageType.Smoke:
                    DeathRun.setCause("Smoke Asphyxiation");
                    break;

                //case DamageType.Starve:
                //case DamageType.Normal:
                default:
                    if (DeathRun.CAUSE_UNKNOWN_CREATURE.Equals(DeathRun.cause))
                    {
                        if (DeathRun.causeObject != null)
                        {
                            GameObject go;
                            TechType   t = CraftData.GetTechType(DeathRun.causeObject, out go);

                            if (t != TechType.None)
                            {
                                DeathRun.setCause(Language.main.Get(t.AsString(false)));

                                CattleLogger.Message("Cause of Death: " + DeathRun.cause);
                            }
                            else
                            {
                                CattleLogger.Message("(Couldn't find creature that caused player death) - ");
                            }
                        }
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
                CattleLogger.GenericError("Getting cause of death", ex);
            }
        }
        internal static void PatchAll()
        {
            if (Config.NORMAL.Equals(DeathRun.config.batteryCosts))
            {
                // If we're leaving normal batteries alone, don't patch in our alternates.
                return;
            }

            string mainDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            // Create a new crafting tree tab for batteries and power cells
            string assetsFolder = Path.Combine(mainDirectory, "Assets");
            string pathToIcon   = Path.Combine(assetsFolder, @"CraftingTabIcon.png");

            Atlas.Sprite tabIcon = ImageUtils.LoadSpriteFromFile(pathToIcon);
            CraftTreeHandler.AddTabNode(CraftTree.Type.Fabricator, BatteryPowerCraftingTab, "Batteries and Power Cells", tabIcon, ResourcesCraftingTab, ElectronicsCraftingTab);

            // Remove the original batteries from the Electronics tab
            CraftTreeHandler.RemoveNode(CraftTree.Type.Fabricator, ResourcesCraftingTab, ElectronicsCraftingTab, TechType.Battery.ToString());
            CraftTreeHandler.RemoveNode(CraftTree.Type.Fabricator, ResourcesCraftingTab, ElectronicsCraftingTab, TechType.PowerCell.ToString());
            CraftTreeHandler.RemoveNode(CraftTree.Type.Fabricator, ResourcesCraftingTab, ElectronicsCraftingTab, TechType.PrecursorIonBattery.ToString());
            CraftTreeHandler.RemoveNode(CraftTree.Type.Fabricator, ResourcesCraftingTab, ElectronicsCraftingTab, TechType.PrecursorIonPowerCell.ToString());

            //var config = new DeepConfig();
            //config.ReadConfigFile(mainDirectory);
            //QuickLogger.Info($"Selected PowerStyle in config: {config.SelectedPowerStyle} - (Battery Capacity:{Mathf.RoundToInt(config.BatteryCapacity)})");

            CattleLogger.Message("Patching AcidBattery");

            int battSize;
            int powerSize;

            if (Config.EXORBITANT.Equals(DeathRun.config.batteryCosts))
            {
                battSize  = 25;
                powerSize = 75;
            }
            else if (Config.DEATHRUN.Equals(DeathRun.config.batteryCosts))
            {
                battSize  = 50;
                powerSize = 125;
            }
            else if (Config.HARD.Equals(DeathRun.config.batteryCosts))
            {
                battSize  = 75;
                powerSize = 150;
            }
            else
            {
                battSize  = 100;
                powerSize = 200;
            }

            var acidBattery = new AcidBattery(battSize);

            acidBattery.Patch();

            CattleLogger.Message("Patching AcidPowerCell");
            var lithiumPowerCell = new AcidPowerCell(acidBattery, powerSize);

            lithiumPowerCell.Patch();

            // And "regular" batteries (now Lithium) back in on the new Batteries and PowerCells tab
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, TechType.Battery, PathToNewTab);
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, TechType.PowerCell, PathToNewTab);

            // Add the Ion Batteries after the Lithium Batteries
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, TechType.PrecursorIonBattery, PathToNewTab);
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, TechType.PrecursorIonPowerCell, PathToNewTab);

            CattleLogger.Message("Patching Copper Recycling");
            // Add recycling of batteries for copper
            CraftTreeHandler.AddCraftingNode(CraftTree.Type.Fabricator, TechType.Copper, PathToBasicTab);
            CattleLogger.Message("Patching Copper Recycling Done");
        }