Decompiled source of MarsarahTweaks v1.7.3

MarsarahTweaks.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using MarsarahTweaks.Managers;
using MarsarahTweaks.Patches.Balance;
using MarsarahTweaks.Patches.Features;
using MarsarahTweaks.Patches.Grind;
using MarsarahTweaks.Patches.QOL;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MarsarahTweaks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MarsarahTweaks")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("831fc141-e3fa-4e67-9d2f-5e56cf6f3935")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MarsarahTweaks
{
	[BepInPlugin("Marsarah.MarsarahTweaks", "MarsarahTweaks", "1.7.3")]
	public class MarsarahTweaks : BaseUnityPlugin
	{
		internal const string ModName = "MarsarahTweaks";

		internal const string ModVersion = "1.7.3";

		internal const string Author = "Marsarah";

		public const string ModGUID = "Marsarah.MarsarahTweaks";

		private readonly Harmony harmony = new Harmony("Marsarah.MarsarahTweaks");

		private void Awake()
		{
			LogManager.SetGlobalLogLevel(LogManager.LogLevel.Warning);
			ConfigManager.Init(((BaseUnityPlugin)this).Config);
			harmony.PatchAll();
		}

		private void Start()
		{
			CompatibilityManager.Initialize();
			CompatibilityManager.UpdateIncompatibilities();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}
	}
}
namespace MarsarahTweaks.Patches
{
	public static class GlobalKeyChecker
	{
		[HarmonyPatch(typeof(ZoneSystem), "Update")]
		private class BossStatusUpdate_Patch
		{
			private static void Postfix(ZoneSystem __instance)
			{
				UpdateDefeatedStates(__instance);
				EikthyrDefeated = CheckGlobalKey("defeated_eikthyr");
				ElderDefeated = CheckGlobalKey("defeated_gdking");
				BonemassDefeated = CheckGlobalKey("defeated_bonemass");
				ModerDefeated = CheckGlobalKey("defeated_dragon");
				YagluthDefeated = CheckGlobalKey("defeated_goblinking");
				QueenDefeated = CheckGlobalKey("defeated_queen");
				FaderDefeated = CheckGlobalKey("defeated_fader");
				BrennaDefeated = CheckGlobalKey("hildir1");
				GeirrhafaDefeated = CheckGlobalKey("hildir2");
				ThungrNZilDefeated = CheckGlobalKey("hildir3");
			}
		}

		private static readonly LogManager log = new LogManager("Global Key Checker", LogManager.LogLevel.Warning);

		public static bool EikthyrDefeated = false;

		public static bool ElderDefeated = false;

		public static bool BonemassDefeated = false;

		public static bool ModerDefeated = false;

		public static bool YagluthDefeated = false;

		public static bool QueenDefeated = false;

		public static bool FaderDefeated = false;

		public static bool BrennaDefeated = false;

		public static bool GeirrhafaDefeated = false;

		public static bool ThungrNZilDefeated = false;

		private static string lastGlobalKeysSnapshot = null;

		private static readonly Dictionary<string, bool> globalKeyStates = new Dictionary<string, bool>
		{
			{ "defeated_eikthyr", false },
			{ "defeated_gdking", false },
			{ "defeated_bonemass", false },
			{ "defeated_dragon", false },
			{ "defeated_goblinking", false },
			{ "defeated_queen", false },
			{ "defeated_fader", false },
			{ "hildir1", false },
			{ "hildir2", false },
			{ "hildir3", false }
		};

		private static readonly Dictionary<string, string> bossToGlobalKey = new Dictionary<string, string>
		{
			{ "Eikthyr", "defeated_eikthyr" },
			{ "The Elder", "defeated_gdking" },
			{ "Bonemass", "defeated_bonemass" },
			{ "Moder", "defeated_dragon" },
			{ "Yagluth", "defeated_goblinking" },
			{ "The Queen", "defeated_queen" },
			{ "Fader", "defeated_fader" },
			{ "Brenna", "hildir1" },
			{ "Geirrhafa", "hildir2" },
			{ "ThungrNZil", "hildir3" }
		};

		private static void UpdateDefeatedStates(ZoneSystem zoneSystem)
		{
			List<string> globalKeys = zoneSystem.GetGlobalKeys();
			string text = string.Join(", ", globalKeys.OrderBy((string key) => key));
			bool flag = text != lastGlobalKeysSnapshot;
			if (flag)
			{
				log.Info($"=== Global Keys ({globalKeys.Count}) ===");
				log.Info((globalKeys.Count > 0) ? text : "(none)");
			}
			foreach (string item in globalKeyStates.Keys.ToList())
			{
				bool flag2 = globalKeys.Contains(item);
				if (globalKeyStates[item] != flag2)
				{
					log.Info($"Key state changed: {item} | {globalKeyStates[item]} -> {flag2}");
					globalKeyStates[item] = flag2;
				}
			}
			if (!flag)
			{
				return;
			}
			log.Info("=== Expected Key States ===");
			foreach (KeyValuePair<string, bool> globalKeyState in globalKeyStates)
			{
				log.Info($"{globalKeyState.Key}: {globalKeyState.Value}");
			}
			log.Info("=== End Global Keys ===");
			lastGlobalKeysSnapshot = text;
		}

		private static bool CheckGlobalKey(string globalKey)
		{
			return globalKeyStates.ContainsKey(globalKey) && globalKeyStates[globalKey];
		}

		public static bool IsBossDefeated(string boss)
		{
			if (bossToGlobalKey.TryGetValue(boss, out var value))
			{
				return CheckGlobalKey(value);
			}
			log.Warn("IsBossDefeated called with unknown boss: " + boss);
			return false;
		}
	}
}
namespace MarsarahTweaks.Patches.Grind
{
	internal class BuildPieceChanges
	{
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private class BuildPiecesModifications_Patch
		{
			private static void Postfix(ref ZNetScene __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && (ConfigManager.BuildPieceAmountsEnabled.Value || ConfigManager.BuildPieceMaterialsEnabled.Value))
				{
					UpdateBuildPieces(__instance, amountsWasChanged: false, materialsWasChanged: false);
				}
			}
		}

		private static readonly LogManager log = new LogManager("Build Piece Changes", LogManager.LogLevel.Warning);

		private static readonly Dictionary<string, Dictionary<string, (string originalResItem, string newResItem, int amount)>> defaultBuildPieceRequirements = new Dictionary<string, Dictionary<string, (string, string, int)>>();

		private static Dictionary<string, Dictionary<string, int>> newPieceAmounts = new Dictionary<string, Dictionary<string, int>>
		{
			{
				"$piece_rock_01",
				new Dictionary<string, int> { { "Stone", 8 } }
			},
			{
				"$piece_rock_02",
				new Dictionary<string, int> { { "Stone", 5 } }
			},
			{
				"$piece_woodfencegate",
				new Dictionary<string, int> { { "Wood", 2 } }
			},
			{
				"$piece_stonefence",
				new Dictionary<string, int> { { "Stone", 3 } }
			},
			{
				"$piece_preptable",
				new Dictionary<string, int>
				{
					{ "FineWood", 10 },
					{ "LeatherScraps", 10 }
				}
			},
			{
				"$piece_cookingstation_iron",
				new Dictionary<string, int>
				{
					{ "Iron", 2 },
					{ "Chain", 2 }
				}
			},
			{
				"$piece_itemstand",
				new Dictionary<string, int> { { "FineWood", 2 } }
			},
			{
				"$piece_blastfurnace",
				new Dictionary<string, int> { { "Iron", 5 } }
			},
			{
				"$piece_oven",
				new Dictionary<string, int> { { "Iron", 5 } }
			},
			{
				"$piece_forge_ext3",
				new Dictionary<string, int> { { "Wood", 15 } }
			},
			{
				"$piece_forge_ext4",
				new Dictionary<string, int> { { "Iron", 7 } }
			},
			{
				"$piece_forge_ext5",
				new Dictionary<string, int> { { "FineWood", 10 } }
			},
			{
				"$piece_forge_ext6",
				new Dictionary<string, int> { { "Iron", 5 } }
			},
			{
				"$piece_woodwindowshutter",
				new Dictionary<string, int> { { "Wood", 2 } }
			},
			{
				"$piece_darkwoodgate",
				new Dictionary<string, int> { { "Iron", 3 } }
			},
			{
				"$piece_irongate",
				new Dictionary<string, int> { { "Iron", 3 } }
			},
			{
				"$piece_chest",
				new Dictionary<string, int> { { "Iron", 1 } }
			},
			{
				"$piece_chestprivate",
				new Dictionary<string, int> { { "Iron", 4 } }
			},
			{
				"$piece_chestblackmetal",
				new Dictionary<string, int> { { "BlackMetal", 4 } }
			},
			{
				"$piece_brazierceiling01",
				new Dictionary<string, int> { { "Bronze", 3 } }
			},
			{
				"$piece_sconce",
				new Dictionary<string, int> { { "Copper", 1 } }
			},
			{
				"$piece_groundtorchwood",
				new Dictionary<string, int> { { "Wood", 1 } }
			},
			{
				"$piece_groundtorch",
				new Dictionary<string, int> { { "Iron", 1 } }
			},
			{
				"$piece_groundtorchgreen",
				new Dictionary<string, int> { { "Iron", 1 } }
			},
			{
				"$piece_groundtorchblue",
				new Dictionary<string, int> { { "Iron", 1 } }
			},
			{
				"$piece_portal",
				new Dictionary<string, int> { { "FineWood", 10 } }
			},
			{
				"$piece_portal_stone",
				new Dictionary<string, int> { { "Grausten", 10 } }
			},
			{
				"$piece_rug_lox",
				new Dictionary<string, int> { { "LoxPelt", 3 } }
			},
			{
				"$piece_rug_wolf",
				new Dictionary<string, int> { { "WolfPelt", 3 } }
			},
			{
				"$piece_rug_deer",
				new Dictionary<string, int> { { "DeerHide", 3 } }
			},
			{
				"$piece_banner01",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner02",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner03",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner04",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner05",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner06",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner07",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner08",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner09",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner10",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner11",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner12",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner13",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_banner14",
				new Dictionary<string, int> { { "LeatherScraps", 5 } }
			},
			{
				"$piece_fermenter",
				new Dictionary<string, int> { { "FineWood", 15 } }
			},
			{
				"$piece_bathtub",
				new Dictionary<string, int> { { "Iron", 5 } }
			},
			{
				"$piece_crystalwall1x1",
				new Dictionary<string, int> { { "Crystal", 1 } }
			},
			{
				"$piece_incinerator",
				new Dictionary<string, int> { { "Iron", 5 } }
			},
			{
				"$piece_stonewall1x1",
				new Dictionary<string, int> { { "Stone", 2 } }
			},
			{
				"$piece_stonewall2x1",
				new Dictionary<string, int> { { "Stone", 3 } }
			},
			{
				"$piece_stonepillar",
				new Dictionary<string, int> { { "Stone", 3 } }
			},
			{
				"$piece_stonearch",
				new Dictionary<string, int> { { "Stone", 3 } }
			},
			{
				"$piece_stonefloor2x2",
				new Dictionary<string, int> { { "Stone", 4 } }
			},
			{
				"$piece_stonestair",
				new Dictionary<string, int> { { "Stone", 3 } }
			},
			{
				"$piece_darkwoodraven",
				new Dictionary<string, int> { { "FineWood", 6 } }
			},
			{
				"$piece_darkwoodwolf",
				new Dictionary<string, int> { { "FineWood", 6 } }
			},
			{
				"$piece_blackmarble_throne",
				new Dictionary<string, int> { { "Copper", 4 } }
			},
			{
				"$piece_blackmarble2x1x1",
				new Dictionary<string, int> { { "BlackMarble", 3 } }
			},
			{
				"$piece_blackmarble_stair",
				new Dictionary<string, int> { { "BlackMarble", 3 } }
			},
			{
				"$piece_blackmarble_base1",
				new Dictionary<string, int> { { "BlackMarble", 4 } }
			},
			{
				"$piece_blackmarble_basecorner",
				new Dictionary<string, int> { { "BlackMarble", 5 } }
			},
			{
				"$piece_blackmarble_out1",
				new Dictionary<string, int> { { "BlackMarble", 4 } }
			},
			{
				"$piece_blackmarble_outcorner",
				new Dictionary<string, int> { { "BlackMarble", 5 } }
			},
			{
				"$piece_blackmarble_arch",
				new Dictionary<string, int> { { "BlackMarble", 4 } }
			},
			{
				"$piece_dvergr_stake_wall",
				new Dictionary<string, int>
				{
					{ "YggdrasilWood", 4 },
					{ "Iron", 2 }
				}
			},
			{
				"$piece_sharpstakes",
				new Dictionary<string, int>
				{
					{ "Wood", 4 },
					{ "RoundLog", 2 }
				}
			},
			{
				"$piece_dvergr_sharpstakes",
				new Dictionary<string, int>
				{
					{ "YggdrasilWood", 4 },
					{ "Iron", 1 }
				}
			},
			{
				"$piece_trap",
				new Dictionary<string, int>
				{
					{ "BlackMetal", 3 },
					{ "BronzeNails", 5 }
				}
			},
			{
				"$piece_turret",
				new Dictionary<string, int>
				{
					{ "BlackMetal", 7 },
					{ "YggdrasilWood", 7 },
					{ "MechanicalSpring", 2 }
				}
			},
			{
				"$piece_eitrrefinery",
				new Dictionary<string, int> { { "BlackMarble", 10 } }
			},
			{
				"$piece_blackforge_ext2",
				new Dictionary<string, int> { { "Copper", 5 } }
			},
			{
				"$piece_sapcollector",
				new Dictionary<string, int>
				{
					{ "YggdrasilWood", 5 },
					{ "BlackMetal", 3 }
				}
			},
			{
				"$piece_magetable",
				new Dictionary<string, int>
				{
					{ "YggdrasilWood", 10 },
					{ "BlackMetal", 5 }
				}
			},
			{
				"$piece_magetable_ext",
				new Dictionary<string, int>
				{
					{ "BlackMarble", 5 },
					{ "Eitr", 5 }
				}
			},
			{
				"$piece_magetable_ext2",
				new Dictionary<string, int>
				{
					{ "BlackMarble", 5 },
					{ "Eitr", 5 }
				}
			},
			{
				"$piece_magetable_ext3",
				new Dictionary<string, int> { { "Eitr", 5 } }
			},
			{
				"$piece_hexagonalgate",
				new Dictionary<string, int> { { "Copper", 4 } }
			},
			{
				"$piece_dvergr_spiralstair",
				new Dictionary<string, int>
				{
					{ "YggdrasilWood", 3 },
					{ "Copper", 1 }
				}
			},
			{
				"$piece_dvergr_spiralstair_right",
				new Dictionary<string, int>
				{
					{ "YggdrasilWood", 3 },
					{ "Copper", 1 }
				}
			},
			{
				"$piece_blackmarble_bench",
				new Dictionary<string, int>
				{
					{ "BlackMarble", 5 },
					{ "Copper", 2 }
				}
			},
			{
				"$piece_table_round",
				new Dictionary<string, int> { { "IronNails", 10 } }
			},
			{
				"$piece_blackmarble_table",
				new Dictionary<string, int>
				{
					{ "BlackMarble", 5 },
					{ "Copper", 2 }
				}
			},
			{
				"$piece_brazierfloor01",
				new Dictionary<string, int> { { "Bronze", 3 } }
			},
			{
				"$piece_brazierfloor02",
				new Dictionary<string, int>
				{
					{ "Bronze", 3 },
					{ "GreydwarfEye", 2 }
				}
			},
			{
				"$piece_jute_carpet",
				new Dictionary<string, int> { { "JuteRed", 3 } }
			},
			{
				"$piece_juteblue_carpet",
				new Dictionary<string, int> { { "JuteBlue", 3 } }
			},
			{
				"$piece_rug_hare",
				new Dictionary<string, int> { { "ScaleHide", 2 } }
			},
			{
				"$piece_dvergr_lantern",
				new Dictionary<string, int> { { "Copper", 1 } }
			},
			{
				"$piece_dvergr_lantern_pole",
				new Dictionary<string, int> { { "Copper", 2 } }
			},
			{
				"$piece_clothdoor",
				new Dictionary<string, int> { { "JuteRed", 3 } }
			},
			{
				"$piece_hanging_cloth_blue1",
				new Dictionary<string, int> { { "JuteBlue", 3 } }
			},
			{
				"$piece_hanging_cloth_blue2",
				new Dictionary<string, int> { { "JuteBlue", 3 } }
			},
			{
				"$piece_ashwood_archedwall",
				new Dictionary<string, int> { { "Blackwood", 1 } }
			},
			{
				"$piece_ashwood_floor_deco",
				new Dictionary<string, int> { { "Blackwood", 2 } }
			},
			{
				"$piece_ashwoodstair",
				new Dictionary<string, int> { { "Blackwood", 1 } }
			},
			{
				"$piece_ashwood_decowall",
				new Dictionary<string, int> { { "Blackwood", 2 } }
			},
			{
				"$piece_ashwood_decowall_divider",
				new Dictionary<string, int> { { "Blackwood", 1 } }
			},
			{
				"$piece_ashwood_decowall_tree",
				new Dictionary<string, int> { { "Blackwood", 1 } }
			},
			{
				"$piece_grausten_stoneladder",
				new Dictionary<string, int> { { "Grausten", 3 } }
			},
			{
				"$piece_grausten_stair",
				new Dictionary<string, int> { { "Grausten", 3 } }
			},
			{
				"$piece_grausten_floor1x1",
				new Dictionary<string, int> { { "Grausten", 1 } }
			},
			{
				"$piece_grausten_pillarmedium",
				new Dictionary<string, int> { { "Grausten", 2 } }
			},
			{
				"$piece_grausten_pillartapered",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_grausten_pillartaperedinverted",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_grausten_beammedium",
				new Dictionary<string, int> { { "Grausten", 2 } }
			},
			{
				"$piece_grausten_wall1x2",
				new Dictionary<string, int> { { "Grausten", 2 } }
			},
			{
				"$piece_grausten_wall2x2",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_grausten_wall4x2",
				new Dictionary<string, int> { { "Grausten", 8 } }
			},
			{
				"$piece_grausten_window4x2",
				new Dictionary<string, int> { { "Grausten", 8 } }
			},
			{
				"$piece_grausten_roof45_corner",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_grausten_roof45_corner2",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_grausten_roof45_archcorner",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_grausten_roof45_archcorner2",
				new Dictionary<string, int> { { "Grausten", 4 } }
			},
			{
				"$piece_flametalgate",
				new Dictionary<string, int> { { "FlametalNew", 8 } }
			},
			{
				"$piece_rug_asksvin",
				new Dictionary<string, int> { { "AskHide", 3 } }
			}
		};

		private static Dictionary<string, Dictionary<string, string>> newPieceMaterials = new Dictionary<string, Dictionary<string, string>>
		{
			{
				"$piece_workbench_ext4",
				new Dictionary<string, string> { { "Obsidian", "Coal" } }
			},
			{
				"$piece_darkwoodgate",
				new Dictionary<string, string> { { "Iron", "BlackMetal" } }
			},
			{
				"$piece_bathtub",
				new Dictionary<string, string> { { "Iron", "BlackMetal" } }
			}
		};

		public static void UpdateBuildPieces(ZNetScene znScene, bool amountsWasChanged, bool materialsWasChanged)
		{
			foreach (GameObject prefab in znScene.m_prefabs)
			{
				Piece component = prefab.GetComponent<Piece>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Requirement[] resources = component.m_resources;
				string name = component.m_name;
				bool flag = ConfigManager.BuildPieceAmountsEnabled.Value && newPieceAmounts.ContainsKey(name);
				bool flag2 = ConfigManager.BuildPieceMaterialsEnabled.Value && newPieceMaterials.ContainsKey(name);
				Requirement[] array = resources;
				foreach (Requirement val in array)
				{
					if (flag && newPieceAmounts[name].TryGetValue(((Object)val.m_resItem).name, out var value))
					{
						CreateBackup(name, val, null);
						log.Info($"(Piece Amounts) Applying amounts for Piece {name} - Resource {((Object)val.m_resItem).name}: {val.m_amount} -> {value}");
						ApplyChanges(val, (newResItem: null, amount: value));
					}
					if (flag2 && newPieceMaterials[name].TryGetValue(((Object)val.m_resItem).name, out var value2))
					{
						CreateBackup(name, val, value2);
						log.Info("(Piece Materials) Applying material for Piece " + name + " - Resource " + ((Object)val.m_resItem).name + " -> " + value2);
						ApplyChanges(val, (newResItem: value2, amount: null), modifyResItem: true);
					}
					if (!ConfigManager.BuildPieceAmountsEnabled.Value && newPieceAmounts.ContainsKey(name) && amountsWasChanged)
					{
						log.Info($"(Gear Amounts) Was changed: {amountsWasChanged}");
						if (RestoreBackup(name, val, restoreMaterials: false) && (!flag2 || !newPieceMaterials[name].ContainsKey(((Object)val.m_resItem).name)))
						{
							log.Info("(Piece Amounts) Removing backup for: " + name + " - " + ((Object)val.m_resItem).name);
							defaultBuildPieceRequirements[name].Remove(((Object)val.m_resItem).name);
						}
					}
					if (!(!ConfigManager.BuildPieceMaterialsEnabled.Value && newPieceMaterials.ContainsKey(name) && materialsWasChanged))
					{
						continue;
					}
					log.Info($"(Gear Materials) Was changed: {materialsWasChanged}");
					if (!RestoreBackup(name, val, restoreMaterials: true))
					{
						continue;
					}
					if (flag && newPieceAmounts[name].ContainsKey(((Object)val.m_resItem).name))
					{
						if (newPieceAmounts[name].TryGetValue(((Object)val.m_resItem).name, out var value3))
						{
							log.Info("(Piece Materials - Amounts) Re-applying changes for: " + name + " - " + ((Object)val.m_resItem).name);
							ApplyChanges(val, (newResItem: null, amount: value3));
						}
					}
					else if (!flag || !newPieceAmounts[name].ContainsKey(((Object)val.m_resItem).name))
					{
						log.Info("(Piece Materials) Removing backup for: " + name + " - " + ((Object)val.m_resItem).name);
						defaultBuildPieceRequirements[name].Remove(((Object)val.m_resItem).name);
					}
				}
				if (defaultBuildPieceRequirements.ContainsKey(name) && defaultBuildPieceRequirements[name].Count == 0)
				{
					log.Info("(Cleanup) Removing backup for: " + name);
					defaultBuildPieceRequirements.Remove(name);
				}
			}
		}

		private static void ApplyChanges(Requirement req, (string newResItem, int? amount) values, bool modifyResItem = false)
		{
			if (values.amount.HasValue && req.m_amount != values.amount.Value)
			{
				log.Info($"Applying amounts for Resource {((Object)req.m_resItem).name}: {req.m_amount} -> {values.amount.Value}");
				req.m_amount = values.amount.Value;
			}
			if (modifyResItem && !string.IsNullOrEmpty(values.newResItem) && ((Object)req.m_resItem).name != values.newResItem)
			{
				log.Info("Applying material for Resource " + ((Object)req.m_resItem).name + " -> " + values.newResItem);
				req.m_resItem = ZNetScene.instance.GetPrefab(values.newResItem).GetComponent<ItemDrop>();
			}
		}

		private static void CreateBackup(string pieceName, Requirement req, string newResItem)
		{
			if (!defaultBuildPieceRequirements.TryGetValue(pieceName, out Dictionary<string, (string, string, int)> value))
			{
				value = new Dictionary<string, (string, string, int)>();
				defaultBuildPieceRequirements[pieceName] = value;
			}
			string name = ((Object)req.m_resItem).name;
			if (value.TryGetValue(name, out var value2))
			{
				if (newResItem != null && value2.Item2 == null)
				{
					log.Info("Updating backup for " + pieceName + " - oldResItem: " + name + " with newResItem: " + newResItem);
					value[name] = (value2.Item1, newResItem, value2.Item3);
				}
			}
			else
			{
				log.Info("Creating new backup for " + pieceName + " - " + name);
				value[name] = (name, newResItem, req.m_amount);
			}
		}

		private static bool RestoreBackup(string pieceName, Requirement req, bool restoreMaterials)
		{
			if (!defaultBuildPieceRequirements.TryGetValue(pieceName, out Dictionary<string, (string, string, int)> value))
			{
				log.Info("Restore backup first check.");
				return false;
			}
			log.Info("Restore backup - Recipe name: " + pieceName + ", Given requirement: " + ((Object)req.m_resItem).name);
			foreach (KeyValuePair<string, (string, string, int)> item in value)
			{
				var (text, text2, num) = item.Value;
				log.Info($"Restore backup - values: {text}, {text2}, {restoreMaterials}");
				if (((Object)req.m_resItem).name == text2 && restoreMaterials)
				{
					log.Info("Restoring original material for " + pieceName + " from " + ((Object)req.m_resItem).name + " to " + text);
					req.m_resItem = ZNetScene.instance.GetPrefab(text).GetComponent<ItemDrop>();
					break;
				}
			}
			if (value.TryGetValue(((Object)req.m_resItem).name, out var value2))
			{
				log.Info("Restoring backup for: " + pieceName + " - " + ((Object)req.m_resItem).name);
				req.m_amount = value2.Item3;
				return true;
			}
			log.Info("Restore backup - we got to the end.");
			return false;
		}

		public static void LogBuildPieces(ZNetScene znScene)
		{
			if ((Object)(object)znScene == (Object)null)
			{
				log.Warn("ZNetScene is null. Cannot log build pieces.");
				return;
			}
			log.Info("=== Logging All Build Pieces ===");
			foreach (GameObject prefab in znScene.m_prefabs)
			{
				Piece component = prefab.GetComponent<Piece>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				log.Info("[Piece] Name: " + component.m_name + ", Prefab: " + ((Object)prefab).name);
				if (component.m_resources != null && component.m_resources.Length != 0)
				{
					Requirement[] resources = component.m_resources;
					foreach (Requirement val in resources)
					{
						if (!((Object)(object)val?.m_resItem == (Object)null))
						{
							log.Info($"   - Resource: {((Object)val.m_resItem).name}, Amount: {val.m_amount}");
						}
					}
				}
				else
				{
					log.Info("   (No build requirements)");
				}
			}
			log.Info("=== Finished Logging Build Pieces ===");
		}

		public static void LogBuildPiecesExtra(ZNetScene znScene)
		{
			if ((Object)(object)znScene == (Object)null)
			{
				log.Warn("ZNetScene is null. Cannot log build pieces.");
				return;
			}
			log.Info("=== Build Piece Costs ===");
			foreach (GameObject prefab in znScene.m_prefabs)
			{
				Piece component = prefab.GetComponent<Piece>();
				if ((Object)(object)component == (Object)null || component.m_resources == null || component.m_resources.Length == 0)
				{
					continue;
				}
				Dictionary<string, int> value;
				bool flag = newPieceAmounts.TryGetValue(component.m_name, out value);
				log.Info("[Piece] " + component.m_name + " | Prefab: " + ((Object)prefab).name);
				Requirement[] resources = component.m_resources;
				foreach (Requirement val in resources)
				{
					if (!((Object)(object)val?.m_resItem == (Object)null))
					{
						int amount = val.m_amount;
						if (flag && value.TryGetValue(((Object)val.m_resItem).name, out var value2) && value2 != amount)
						{
							log.Info($"   - {((Object)val.m_resItem).name}: Vanilla {amount} -> Modified {value2}");
						}
						else
						{
							log.Info($"   - {((Object)val.m_resItem).name}: Vanilla {amount}");
						}
					}
				}
			}
			log.Info("=== End Build Piece Costs ===");
		}

		private static void LogPrefabs(ZNetScene znScene)
		{
			if ((Object)(object)znScene == (Object)null)
			{
				log.Warn("ZNetScene is null, cannot log prefabs.");
				return;
			}
			log.Info("=== Listing all Prefabs in ZNetScene ===");
			foreach (GameObject prefab in znScene.m_prefabs)
			{
				if (!((Object)(object)prefab == (Object)null))
				{
					string name = ((Object)prefab).name;
					Piece component = prefab.GetComponent<Piece>();
					ItemDrop component2 = prefab.GetComponent<ItemDrop>();
					Character component3 = prefab.GetComponent<Character>();
					string text = "Generic GameObject";
					if ((Object)(object)component != (Object)null)
					{
						text = "Build Piece";
					}
					else if ((Object)(object)component2 != (Object)null)
					{
						text = "Item";
					}
					else if ((Object)(object)component3 != (Object)null)
					{
						text = "Character";
					}
					log.Info("Prefab: " + name + " (" + text + ")");
				}
			}
			log.Info("=== End of Prefabs List ===");
		}
	}
	internal class DoubleBronzeCrafting
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private class OthersSection_Patch
		{
			private static void Postfix(ref ObjectDB __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()))
				{
					UpdateDoubleBronzeCrafting(__instance, wasChanged: false);
				}
			}
		}

		private static readonly LogManager log = new LogManager("Double Bronze", LogManager.LogLevel.Warning);

		private static readonly Dictionary<string, int> doubleBronzeOriginals = new Dictionary<string, int>();

		private static readonly Dictionary<string, int> doubleBronzeChanges = new Dictionary<string, int>
		{
			{ "Recipe_Bronze", 2 },
			{ "Recipe_Bronze5", 10 }
		};

		public static void UpdateDoubleBronzeCrafting(ObjectDB objDB, bool wasChanged)
		{
			if (ConfigManager.DoubleBronzeEnabled.Value)
			{
				foreach (string recipeName in doubleBronzeChanges.Keys)
				{
					Recipe val = objDB.m_recipes.Find((Recipe r) => ((Object)r).name == recipeName);
					if (!((Object)(object)val == (Object)null))
					{
						if (!doubleBronzeOriginals.ContainsKey(((Object)val).name))
						{
							doubleBronzeOriginals[((Object)val).name] = val.m_amount;
							log.Info("Backed up " + ((Object)val).name);
						}
						val.m_amount = doubleBronzeChanges[((Object)val).name];
						log.Info("Applied new values for " + ((Object)val).name);
					}
				}
				return;
			}
			if (!wasChanged)
			{
				return;
			}
			foreach (string recipeName2 in doubleBronzeOriginals.Keys)
			{
				Recipe val2 = objDB.m_recipes.Find((Recipe r) => ((Object)r).name == recipeName2);
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.m_amount = doubleBronzeOriginals[((Object)val2).name];
					log.Info("Restored " + ((Object)val2).name);
				}
			}
			doubleBronzeOriginals.Clear();
		}
	}
	internal class FoodAndMeadChanges
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private class FoodAndMeadChanges_Patch
		{
			private static void Postfix(ref ObjectDB __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()))
				{
					UpdateFoodAndMead(__instance, wasModified: false);
				}
			}
		}

		private class RecipeModification
		{
			public Dictionary<string, int> ResourceChanges { get; set; } = new Dictionary<string, int>();

			public Dictionary<string, string> ResourceReplacements { get; set; } = new Dictionary<string, string>();

			public Dictionary<string, (string originalResItem, string newResItem)> OriginalResourceReplacements { get; set; } = new Dictionary<string, (string, string)>();

			public int? RecipeAmount { get; set; }
		}

		private static readonly LogManager log = new LogManager("Food And Mead", LogManager.LogLevel.Warning);

		private static Dictionary<string, RecipeModification> foodRecipeModifications = new Dictionary<string, RecipeModification>
		{
			{
				"Recipe_QueensJam",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Raspberry", 5 },
						{ "Blueberries", 5 }
					}
				}
			},
			{
				"Recipe_TurnipStew",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_Blacksoup",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Bloodbag", 2 },
						{ "Honey", 2 },
						{ "Turnip", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_CarrotSoup",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_DeerStew",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "CookedDeerMeat", 2 },
						{ "Blueberries", 2 },
						{ "Carrot", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_ShocklateSmoothie",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MinceMeatSauce",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "RawMeat", 2 },
						{ "NeckTail", 2 },
						{ "Carrot", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_Eyescream",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_PulledBear",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "CookedBjornMeat", 2 },
						{ "Blueberries", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_Onionsoup",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_WolfSkewer",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "WolfMeat", 2 },
						{ "Onion", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_SerpentStew",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Mushroom", 2 },
						{ "SerpentMeatCooked", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_BloodPudding",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_FishWraps",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_FishAndBread",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_LoxPie",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			},
			{
				"Recipe_Bread",
				new RecipeModification
				{
					ResourceChanges = { { "BarleyFlour", 6 } }
				}
			},
			{
				"Recipe_HoneyGlazedChicken",
				new RecipeModification
				{
					ResourceChanges = { { "ChickenMeat", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MagicallyStuffedShroom",
				new RecipeModification
				{
					ResourceChanges = { { "GiantBloodSack", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MeatPlatter",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "BugMeat", 2 },
						{ "LoxMeat", 2 },
						{ "HareMeat", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MisthareSupreme",
				new RecipeModification
				{
					ResourceChanges = { { "HareMeat", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MushroomOmelette",
				new RecipeModification
				{
					ResourceChanges = { { "ChickenEgg", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_Salad",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "MushroomJotunPuffs", 4 },
						{ "Onion", 4 },
						{ "Cloudberry", 4 }
					},
					RecipeAmount = 4
				}
			},
			{
				"Recipe_YggdrasilPorridge",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Sap", 2 },
						{ "Barley", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_FierySvinstew",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "AsksvinMeat", 2 },
						{ "MushroomSmokePuff", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MarinatedGreens",
				new RecipeModification
				{
					ResourceChanges = { { "Sap", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_SizzlingBerryBroth",
				new RecipeModification
				{
					ResourceChanges = { { "Sap", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_SparklingShroomshake",
				new RecipeModification
				{
					ResourceChanges = { { "Sap", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_MashedMeat",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "AsksvinMeat", 2 },
						{ "VoltureMeat", 2 },
						{ "Fiddleheadfern", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_ScorchingMedley",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "MushroomJotunPuffs", 4 },
						{ "Onion", 4 },
						{ "Fiddleheadfern", 4 }
					},
					RecipeAmount = 4
				}
			},
			{
				"Recipe_SpiceInducedMarmalade",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Vineberry", 2 },
						{ "Honey", 2 },
						{ "Fiddleheadfern", 2 }
					},
					RecipeAmount = 2
				}
			},
			{
				"Recipe_RoastedCrustPie",
				new RecipeModification
				{
					ResourceChanges = { { "VoltureEgg", 2 } },
					RecipeAmount = 2
				}
			},
			{
				"Recipe_PiquantPie",
				new RecipeModification
				{
					RecipeAmount = 2
				}
			}
		};

		private static Dictionary<string, RecipeModification> meadAndWineModifications = new Dictionary<string, RecipeModification>
		{
			{
				"Recipe_MeadBaseEitrLingering",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Sap", 5 },
						{ "Vineberry", 5 },
						{ "MushroomMagecap", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseHealthLingering",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Sap", 5 },
						{ "Vineberry", 5 },
						{ "MushroomSmokePuff", 5 }
					}
				}
			},
			{
				"Recipe_BarleyWineBase",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Barley", 5 },
						{ "Cloudberry", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseEitrMinor",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Sap", 3 },
						{ "MushroomMagecap", 3 }
					}
				}
			},
			{
				"Recipe_MeadBaseFrostResist",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Thistle", 3 }
					}
				}
			},
			{
				"Recipe_MeadBaseHealthMajor",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "GiantBloodSack", 2 },
						{ "RoyalJelly", 3 }
					},
					ResourceReplacements = { { "RoyalJelly", "MushroomJotunPuffs" } }
				}
			},
			{
				"Recipe_MeadBaseHealthMedium",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Bloodbag", 3 },
						{ "Raspberry", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseHealthMinor",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Raspberry", 5 }
					}
				}
			},
			{
				"Recipe_MeadBasePoisonResist",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Thistle", 3 },
						{ "Coal", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseStaminaLingering",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Sap", 5 },
						{ "Cloudberry", 5 },
						{ "MushroomJotunPuffs", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseStaminaMedium",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Cloudberry", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseStaminaMinor",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Raspberry", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseTasty",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Raspberry", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseHasty",
				new RecipeModification
				{
					ResourceChanges = 
					{
						{ "Honey", 5 },
						{ "Blueberries", 5 }
					}
				}
			},
			{
				"Recipe_MeadBaseStrength",
				new RecipeModification
				{
					ResourceChanges = { { "Honey", 5 } }
				}
			},
			{
				"Recipe_MeadBaseSwimmer",
				new RecipeModification
				{
					ResourceChanges = { { "Dandelion", 7 } }
				}
			},
			{
				"Recipe_MeadBaseTamer",
				new RecipeModification
				{
					ResourceChanges = { { "Carrot", 5 } }
				}
			}
		};

		private static Dictionary<string, int> foodStacksModifications = new Dictionary<string, int>
		{
			{ "QueensJam", 20 },
			{ "CarrotSoup", 20 },
			{ "DeerStew", 20 },
			{ "TurnipStew", 20 },
			{ "PulledBear", 20 },
			{ "BlackSoup", 20 },
			{ "Eyescream", 20 },
			{ "ShocklateSmoothie", 20 },
			{ "MinceMeatSauce", 20 },
			{ "OnionSoup", 20 },
			{ "SerpentStew", 20 },
			{ "BloodPudding", 20 },
			{ "FishWraps", 20 },
			{ "FishAndBread", 20 },
			{ "LoxPie", 20 },
			{ "MushroomOmelette", 20 },
			{ "YggdrasilPorridge", 20 },
			{ "CookedEgg", 20 },
			{ "Salad", 20 },
			{ "SeekerAspic", 20 },
			{ "HoneyGlazedChicken", 20 },
			{ "MagicallyStuffedShroom", 20 },
			{ "MeatPlatter", 20 },
			{ "MisthareSupreme", 20 },
			{ "FierySvinstew", 20 },
			{ "MarinatedGreens", 20 },
			{ "MashedMeat", 20 },
			{ "ScorchingMedley", 20 },
			{ "SizzlingBerryBroth", 20 },
			{ "SpicyMarmalade", 20 },
			{ "SparklingShroomshake", 20 },
			{ "RoastedCrustPie", 20 },
			{ "PiquantPie", 20 },
			{ "FishAndBreadUncooked", 20 },
			{ "LoxPieUncooked", 20 },
			{ "HoneyGlazedChickenUncooked", 20 },
			{ "MagicallyStuffedShroomUncooked", 20 },
			{ "MeatPlatterUncooked", 20 },
			{ "MisthareSupremeUncooked", 20 },
			{ "RoastedCrustPieUncooked", 20 },
			{ "PiquantPieUncooked", 20 }
		};

		private static Dictionary<string, RecipeModification> recipeModifications;

		private static Dictionary<string, RecipeModification> originalRecipeValues = new Dictionary<string, RecipeModification>();

		private static Dictionary<string, int> originalFoodStacks = new Dictionary<string, int>();

		private static Dictionary<string, RecipeModification> GetRecipeModifications()
		{
			if (recipeModifications == null)
			{
				recipeModifications = foodRecipeModifications;
				foreach (KeyValuePair<string, RecipeModification> meadAndWineModification in meadAndWineModifications)
				{
					recipeModifications[meadAndWineModification.Key] = meadAndWineModification.Value;
				}
			}
			return recipeModifications;
		}

		public static void UpdateFoodAndMead(ObjectDB objDB, bool wasModified)
		{
			Dictionary<string, RecipeModification> dictionary = GetRecipeModifications();
			if (ConfigManager.FoodAndMeadModificationsEnabled.Value)
			{
				foreach (KeyValuePair<string, RecipeModification> item in dictionary)
				{
					string recipeName = item.Key;
					RecipeModification value = item.Value;
					Recipe val = ((IEnumerable<Recipe>)objDB.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => ((Object)r).name == recipeName));
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					if (!originalRecipeValues.ContainsKey(recipeName))
					{
						log.Info("Initial backup entry for " + recipeName);
						originalRecipeValues[recipeName] = new RecipeModification
						{
							ResourceChanges = new Dictionary<string, int>(),
							ResourceReplacements = new Dictionary<string, string>(),
							RecipeAmount = val.m_amount
						};
					}
					if (value.RecipeAmount.HasValue)
					{
						log.Info("Apply recipe amount for " + recipeName);
						val.m_amount = value.RecipeAmount.Value;
					}
					Requirement[] resources = val.m_resources;
					foreach (Requirement val2 in resources)
					{
						if (value.ResourceChanges.TryGetValue(((Object)val2.m_resItem).name, out var value2))
						{
							if (!originalRecipeValues[recipeName].ResourceChanges.ContainsKey(((Object)val2.m_resItem).name))
							{
								log.Info("Backup resource amount for " + recipeName + " - " + ((Object)val2.m_resItem).name);
								originalRecipeValues[recipeName].ResourceChanges[((Object)val2.m_resItem).name] = val2.m_amount;
							}
							log.Info($"Apply new resource amount for {recipeName} - {((Object)val2.m_resItem).name} to: {value2}");
							val2.m_amount = value2;
						}
						if (value.ResourceReplacements.TryGetValue(((Object)val2.m_resItem).name, out var value3))
						{
							if (!originalRecipeValues[recipeName].ResourceReplacements.ContainsKey(((Object)val2.m_resItem).name))
							{
								log.Info("Backup resource material for " + recipeName + " - " + ((Object)val2.m_resItem).name);
								originalRecipeValues[recipeName].OriginalResourceReplacements[((Object)val2.m_resItem).name] = (((Object)val2.m_resItem).name, value3);
							}
							log.Info("Apply resource material for " + recipeName + " - " + ((Object)val2.m_resItem).name + " to: " + value3);
							val2.m_resItem = objDB.GetItemPrefab(value3).GetComponent<ItemDrop>();
						}
					}
				}
				{
					foreach (KeyValuePair<string, int> foodStacksModification in foodStacksModifications)
					{
						string itemName = foodStacksModification.Key;
						int value4 = foodStacksModification.Value;
						GameObject val3 = ((IEnumerable<GameObject>)objDB.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject r) => ((Object)r).name == itemName));
						if ((Object)(object)val3 == (Object)null)
						{
							continue;
						}
						ItemDrop component = val3.GetComponent<ItemDrop>();
						if ((Object)(object)component != (Object)null)
						{
							if (!originalFoodStacks.ContainsKey(itemName))
							{
								log.Info("Backup stack for " + itemName);
								originalFoodStacks[itemName] = component.m_itemData.m_shared.m_maxStackSize;
							}
							log.Info($"Apply new stack for {itemName} to: {value4}");
							component.m_itemData.m_shared.m_maxStackSize = value4;
						}
					}
					return;
				}
			}
			if (!wasModified)
			{
				return;
			}
			foreach (KeyValuePair<string, RecipeModification> originalRecipeValue in originalRecipeValues)
			{
				string recipeName2 = originalRecipeValue.Key;
				RecipeModification value5 = originalRecipeValue.Value;
				Recipe val4 = ((IEnumerable<Recipe>)objDB.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => ((Object)r).name == recipeName2));
				if ((Object)(object)val4 == (Object)null)
				{
					continue;
				}
				if (value5.RecipeAmount.HasValue)
				{
					log.Info("Restoring backup: amount for " + recipeName2);
					val4.m_amount = value5.RecipeAmount.Value;
				}
				Requirement[] resources2 = val4.m_resources;
				foreach (Requirement val5 in resources2)
				{
					foreach (KeyValuePair<string, (string, string)> originalResourceReplacement in value5.OriginalResourceReplacements)
					{
						var (text, text2) = originalResourceReplacement.Value;
						if (((Object)val5.m_resItem).name == text2)
						{
							log.Info("Restoring backup: requirement material for " + recipeName2 + " - " + text2 + " back to: " + text);
							val5.m_resItem = objDB.GetItemPrefab(text).GetComponent<ItemDrop>();
							break;
						}
					}
					if (value5.ResourceChanges.TryGetValue(((Object)val5.m_resItem).name, out var value6))
					{
						log.Info("Restoring backup: requirement amount for " + recipeName2 + " - " + ((Object)val5.m_resItem).name);
						val5.m_amount = value6;
					}
				}
			}
			foreach (KeyValuePair<string, int> originalFoodStack in originalFoodStacks)
			{
				string itemName2 = originalFoodStack.Key;
				int value7 = originalFoodStack.Value;
				GameObject val6 = ((IEnumerable<GameObject>)objDB.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject r) => ((Object)r).name == itemName2));
				if (!((Object)(object)val6 == (Object)null))
				{
					ItemDrop component2 = val6.GetComponent<ItemDrop>();
					if ((Object)(object)component2 != (Object)null)
					{
						log.Info("Restoring backup: stacks for " + itemName2);
						component2.m_itemData.m_shared.m_maxStackSize = value7;
					}
				}
			}
			log.Info("(Cleanup) Removing backups");
			originalRecipeValues.Clear();
			originalFoodStacks.Clear();
		}

		private static void LogFoodAndMead(ObjectDB objDB)
		{
			if ((Object)(object)objDB == (Object)null)
			{
				log.Warn("ObjectDB is null. Cannot log food and mead.");
				return;
			}
			Dictionary<string, RecipeModification> dictionary = GetRecipeModifications();
			HashSet<string> hashSet = new HashSet<string>();
			log.Info("=== Food And Mead Recipes ===");
			foreach (Recipe recipe in objDB.m_recipes)
			{
				if (!IsFoodOrMeadRecipe(recipe, dictionary))
				{
					continue;
				}
				ItemDrop item = recipe.m_item;
				string name = ((Object)item).name;
				string name2 = item.m_itemData.m_shared.m_name;
				string text = (((Object)(object)recipe.m_craftingStation != (Object)null) ? ((Object)recipe.m_craftingStation).name : "None");
				hashSet.Add(name);
				dictionary.TryGetValue(((Object)recipe).name, out var value);
				log.Info("[Recipe] " + ((Object)recipe).name + " | Output: " + name + " | Name: " + name2 + " | Station: " + text);
				int amount = recipe.m_amount;
				if (value != null && value.RecipeAmount.HasValue && value.RecipeAmount.Value != amount)
				{
					log.Info($"   Crafted Amount: Vanilla {amount} -> Modified {value.RecipeAmount.Value}");
				}
				else
				{
					log.Info($"   Crafted Amount: Vanilla {amount}");
				}
				int maxStackSize = item.m_itemData.m_shared.m_maxStackSize;
				if (foodStacksModifications.TryGetValue(name, out var value2) && value2 != maxStackSize)
				{
					log.Info($"   Stack: Vanilla {maxStackSize} -> Modified {value2}");
				}
				else
				{
					log.Info($"   Stack: Vanilla {maxStackSize}");
				}
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					if (!((Object)(object)val?.m_resItem == (Object)null))
					{
						string name3 = ((Object)val.m_resItem).name;
						int amount2 = val.m_amount;
						int num = amount2;
						string text2 = name3;
						int value3 = amount2;
						bool flag = value != null && value.ResourceChanges.TryGetValue(name3, out value3) && value3 != amount2;
						if (flag)
						{
							num = value3;
						}
						string value4 = name3;
						bool flag2 = value != null && value.ResourceReplacements.TryGetValue(name3, out value4) && value4 != name3;
						if (flag2)
						{
							text2 = value4;
						}
						if (flag && flag2)
						{
							log.Info($"   - Resource: {name3} | Vanilla Amount: {amount2} | Modified Resource: {text2} | Modified Amount: {num}");
						}
						else if (flag)
						{
							log.Info($"   - Resource: {name3} | Vanilla Amount: {amount2} | Modified Amount: {num}");
						}
						else if (flag2)
						{
							log.Info($"   - Resource: {name3} | Vanilla Amount: {amount2} | Modified Resource: {text2}");
						}
						else
						{
							log.Info($"   - Resource: {name3} | Vanilla Amount: {amount2}");
						}
					}
				}
			}
			log.Info("=== Additional Food Item Stacks ===");
			foreach (GameObject item2 in objDB.m_items)
			{
				if ((Object)(object)item2 == (Object)null || hashSet.Contains(((Object)item2).name))
				{
					continue;
				}
				ItemDrop component = item2.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				SharedData shared = component.m_itemData.m_shared;
				bool flag3 = shared.m_food > 0f;
				int value5;
				bool flag4 = foodStacksModifications.TryGetValue(((Object)item2).name, out value5);
				if (flag3 || flag4)
				{
					int maxStackSize2 = shared.m_maxStackSize;
					if (flag4 && value5 != maxStackSize2)
					{
						log.Info($"[Item] {((Object)item2).name} | Name: {shared.m_name} | Stack: Vanilla {maxStackSize2} -> Modified {value5}");
					}
					else
					{
						log.Info($"[Item] {((Object)item2).name} | Name: {shared.m_name} | Stack: Vanilla {maxStackSize2}");
					}
				}
			}
			log.Info("=== End Food And Mead Audit ===");
		}

		private static bool IsFoodOrMeadRecipe(Recipe recipe, Dictionary<string, RecipeModification> modifications)
		{
			if ((Object)(object)recipe?.m_item == (Object)null)
			{
				return false;
			}
			if (modifications.ContainsKey(((Object)recipe).name))
			{
				return true;
			}
			if (recipe.m_item.m_itemData.m_shared.m_food > 0f)
			{
				return true;
			}
			if ((Object)(object)recipe.m_craftingStation != (Object)null)
			{
				string text = ((Object)recipe.m_craftingStation).name.ToLowerInvariant();
				if (text.Contains("cauldron") || text.Contains("preptable"))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal class GearRecipeChanges
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private class GearRecipeModifications_Patch
		{
			private static void Postfix(ref ObjectDB __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()))
				{
					if (ConfigManager.GearRecipeAmountsEnabled.Value || ConfigManager.GearRecipeMaterialsEnabled.Value)
					{
						UpdateGearRecipes(__instance, amountsWasChanged: false, materialsWasChanged: false);
					}
					UpdateLinenCapeRecipe(__instance, wasChanged: false);
				}
			}
		}

		private static readonly LogManager log = new LogManager("Gear Recipe Changes", LogManager.LogLevel.Warning);

		private static readonly Dictionary<string, Dictionary<string, (string originalResItem, string newResItem, int amount, int amountPerLevel)>> defaultGearRecipeValues = new Dictionary<string, Dictionary<string, (string, string, int, int)>>();

		private static readonly Dictionary<string, Dictionary<string, (int? amount, int? amountPerLevel)>> newGearRecipesAmounts = new Dictionary<string, Dictionary<string, (int?, int?)>>
		{
			{
				"Recipe_Club",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 2)
					},
					{
						"BoneFragments",
						(null, 2)
					}
				}
			},
			{
				"Recipe_SledgeStagbreaker",
				new Dictionary<string, (int?, int?)> { 
				{
					"BoneFragments",
					(2, 8)
				} }
			},
			{
				"Recipe_Bow",
				new Dictionary<string, (int?, int?)> { 
				{
					"LeatherScraps",
					(null, 3)
				} }
			},
			{
				"Recipe_ShieldWood",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(8, null)
					},
					{
						"Resin",
						(0, 0)
					}
				}
			},
			{
				"Recipe_ArrowWood",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_ArrowFire",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(5, null)
					},
					{
						"Resin",
						(5, null)
					}
				}
			},
			{
				"Recipe_AxeStone",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(null, 1)
				} }
			},
			{
				"Recipe_KnifeFlint",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(null, 1)
				} }
			},
			{
				"Recipe_SpearFlint",
				new Dictionary<string, (int?, int?)> { 
				{
					"Flint",
					(8, null)
				} }
			},
			{
				"Recipe_AxeFlint",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 1)
					},
					{
						"LeatherScraps",
						(1, 1)
					}
				}
			},
			{
				"Recipe_ArrowFlint",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_FistBjornClaw",
				new Dictionary<string, (int?, int?)> { 
				{
					"LeatherScraps",
					(2, null)
				} }
			},
			{
				"Recipe_KnifeCopper",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 1)
					},
					{
						"Copper",
						(null, 3)
					},
					{
						"GreydwarfEye",
						(null, 6)
					}
				}
			},
			{
				"Recipe_MaceBronze",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 1)
					},
					{
						"LeatherScraps",
						(null, 1)
					},
					{
						"Bronze",
						(null, 3)
					}
				}
			},
			{
				"Recipe_SwordBronze",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Bronze",
						(null, 3)
					},
					{
						"LeatherScraps",
						(4, null)
					}
				}
			},
			{
				"Recipe_AxeBronze",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 1)
					},
					{
						"Bronze",
						(null, 3)
					}
				}
			},
			{
				"Recipe_AtgeirBronze",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(8, 2)
					},
					{
						"LeatherScraps",
						(null, 1)
					}
				}
			},
			{
				"Recipe_ShieldBronzeBuckler",
				new Dictionary<string, (int?, int?)> { 
				{
					"Bronze",
					(null, 4)
				} }
			},
			{
				"Recipe_PickaxeBronze",
				new Dictionary<string, (int?, int?)> { 
				{
					"Bronze",
					(7, 4)
				} }
			},
			{
				"Recipe_ArrowBronze",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_ShieldRoots",
				new Dictionary<string, (int?, int?)> { 
				{
					"FineWood",
					(null, 4)
				} }
			},
			{
				"Recipe_MaceIron",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 2)
					},
					{
						"Iron",
						(10, 5)
					},
					{
						"LeatherScraps",
						(null, 1)
					}
				}
			},
			{
				"Recipe_SledgeIron",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Iron",
						(15, 7)
					},
					{
						"YmirRemains",
						(6, 0)
					}
				}
			},
			{
				"Recipe_Battleaxe",
				new Dictionary<string, (int?, int?)>
				{
					{
						"ElderBark",
						(20, null)
					},
					{
						"Iron",
						(18, 7)
					},
					{
						"LeatherScraps",
						(null, 1)
					}
				}
			},
			{
				"Recipe_SwordIron",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 2)
					},
					{
						"Iron",
						(10, 5)
					}
				}
			},
			{
				"Recipe_AxeIron",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 2)
					},
					{
						"Iron",
						(10, 5)
					},
					{
						"LeatherScraps",
						(null, 2)
					}
				}
			},
			{
				"Recipe_AtgeirIron",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(null, 3)
					},
					{
						"Iron",
						(15, 7)
					}
				}
			},
			{
				"Recipe_BowHuntsman",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(10, 5)
				} }
			},
			{
				"Recipe_ShieldIronBuckler",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(6, 3)
				} }
			},
			{
				"Recipe_PickaxeIron",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(10, 5)
				} }
			},
			{
				"Recipe_ArrowIron",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_KnifeSilver",
				new Dictionary<string, (int?, int?)> { 
				{
					"Silver",
					(7, 4)
				} }
			},
			{
				"Recipe_MaceSilver",
				new Dictionary<string, (int?, int?)>
				{
					{
						"ElderBark",
						(15, 3)
					},
					{
						"Silver",
						(20, 7)
					}
				}
			},
			{
				"Recipe_SwordSilver",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(15, 3)
					},
					{
						"Silver",
						(20, 7)
					},
					{
						"LeatherScraps",
						(5, null)
					},
					{
						"Iron",
						(3, 1)
					}
				}
			},
			{
				"Recipe_BowDraugrFang",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Silver",
						(10, 5)
					},
					{
						"Guck",
						(7, null)
					}
				}
			},
			{
				"Recipe_Battleaxe_Crystal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Silver",
						(15, 7)
					},
					{
						"Crystal",
						(3, 1)
					}
				}
			},
			{
				"Recipe_FistFenrirClaw",
				new Dictionary<string, (int?, int?)> { 
				{
					"Silver",
					(5, null)
				} }
			},
			{
				"Recipe_ArrowObsidian",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(5, null)
					},
					{
						"Obsidian",
						(3, null)
					}
				}
			},
			{
				"Recipe_ArrowFrost",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(5, null)
					},
					{
						"Obsidian",
						(3, null)
					}
				}
			},
			{
				"Recipe_ArrowPoison",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Wood",
						(5, null)
					},
					{
						"Obsidian",
						(3, null)
					}
				}
			},
			{
				"Recipe_ArrowSilver",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_KnifeChitin",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(null, 2)
					},
					{
						"Chitin",
						(10, 5)
					},
					{
						"LeatherScraps",
						(null, 1)
					}
				}
			},
			{
				"Recipe_SpearChitin",
				new Dictionary<string, (int?, int?)> { 
				{
					"Chitin",
					(15, null)
				} }
			},
			{
				"Recipe_ShieldSerpentscale",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(20, null)
					},
					{
						"Iron",
						(3, 1)
					}
				}
			},
			{
				"Recipe_MaceNeedle",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(4, 2)
					},
					{
						"Iron",
						(10, null)
					},
					{
						"LinenThread",
						(5, 5)
					}
				}
			},
			{
				"Recipe_KnifeBlackmetal",
				new Dictionary<string, (int?, int?)> { 
				{
					"FineWood",
					(null, 1)
				} }
			},
			{
				"Recipe_SwordBlackmetal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(3, 2)
					},
					{
						"BlackMetal",
						(10, 5)
					}
				}
			},
			{
				"Recipe_AtgeirBlackmetal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(null, 3)
					},
					{
						"BlackMetal",
						(15, 7)
					}
				}
			},
			{
				"Recipe_AxeBlackMetal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(null, 2)
					},
					{
						"BlackMetal",
						(10, 5)
					}
				}
			},
			{
				"Recipe_PickaxeBlackMetal",
				new Dictionary<string, (int?, int?)> { 
				{
					"BlackMetal",
					(10, 5)
				} }
			},
			{
				"Recipe_Battleaxe_Blackmetal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(null, 2)
					},
					{
						"BlackMetal",
						(15, 7)
					}
				}
			},
			{
				"Recipe_ShieldBlackmetal",
				new Dictionary<string, (int?, int?)> { 
				{
					"Chain",
					(null, 0)
				} }
			},
			{
				"Recipe_ShieldBlackmetalTower",
				new Dictionary<string, (int?, int?)> { 
				{
					"Chain",
					(6, 0)
				} }
			},
			{
				"Recipe_ArrowNeedle",
				new Dictionary<string, (int?, int?)> { 
				{
					"Needle",
					(3, null)
				} }
			},
			{
				"Recipe_AxeJotunBane",
				new Dictionary<string, (int?, int?)>
				{
					{
						"YggdrasilWood",
						(null, 1)
					},
					{
						"Iron",
						(10, 5)
					},
					{
						"Eitr",
						(null, 2)
					}
				}
			},
			{
				"Recipe_SpearCarapace",
				new Dictionary<string, (int?, int?)> { 
				{
					"YggdrasilWood",
					(null, 2)
				} }
			},
			{
				"Recipe_SwordMistwalker",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FineWood",
						(5, 1)
					},
					{
						"Iron",
						(10, 5)
					},
					{
						"Eitr",
						(null, 2)
					}
				}
			},
			{
				"Recipe_AtgeirHimminAfl",
				new Dictionary<string, (int?, int?)>
				{
					{
						"YggdrasilWood",
						(null, 2)
					},
					{
						"Eitr",
						(10, 5)
					}
				}
			},
			{
				"Recipe_KnifeSkollAndHati",
				new Dictionary<string, (int?, int?)> { 
				{
					"FineWood",
					(5, 1)
				} }
			},
			{
				"Recipe_SledgeDemolisher",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(10, 5)
				} }
			},
			{
				"Recipe_SwordKrom",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Iron",
						(15, 5)
					},
					{
						"Bronze",
						(10, 5)
					}
				}
			},
			{
				"Recipe_Battleaxe_SkullSplittur",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Iron",
						(15, 5)
					},
					{
						"YggdrasilWood",
						(10, 2)
					},
					{
						"Eitr",
						(null, 2)
					}
				}
			},
			{
				"Recipe_ShieldCarapace",
				new Dictionary<string, (int?, int?)> { 
				{
					"Eitr",
					(null, 2)
				} }
			},
			{
				"Recipe_ShieldCarapaceBuckler",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Carapace",
						(15, 7)
					},
					{
						"Eitr",
						(null, 2)
					}
				}
			},
			{
				"Recipe_BowSpineSnap",
				new Dictionary<string, (int?, int?)>
				{
					{
						"BoneFragments",
						(30, 15)
					},
					{
						"Eitr",
						(null, 2)
					}
				}
			},
			{
				"Recipe_ArrowCarapace",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Carapace",
						(2, null)
					},
					{
						"Wood",
						(5, null)
					}
				}
			},
			{
				"Recipe_BoltBlackmetal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"BlackMetal",
						(1, null)
					},
					{
						"Wood",
						(5, null)
					}
				}
			},
			{
				"Recipe_BoltBone",
				new Dictionary<string, (int?, int?)> { 
				{
					"BoneFragments",
					(5, null)
				} }
			},
			{
				"Recipe_BoltCarapace",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_BoltIron",
				new Dictionary<string, (int?, int?)> { 
				{
					"Wood",
					(5, null)
				} }
			},
			{
				"Recipe_StaffSkeleton",
				new Dictionary<string, (int?, int?)> { 
				{
					"Eitr",
					(15, 5)
				} }
			},
			{
				"Recipe_StaffFireball",
				new Dictionary<string, (int?, int?)>
				{
					{
						"YggdrasilWood",
						(15, null)
					},
					{
						"Eitr",
						(15, 5)
					}
				}
			},
			{
				"Recipe_StaffIceShards",
				new Dictionary<string, (int?, int?)>
				{
					{
						"YggdrasilWood",
						(15, null)
					},
					{
						"Eitr",
						(15, 5)
					}
				}
			},
			{
				"Recipe_StaffShield",
				new Dictionary<string, (int?, int?)>
				{
					{
						"YggdrasilWood",
						(15, null)
					},
					{
						"Eitr",
						(15, 5)
					}
				}
			},
			{
				"Recipe_MaceEldner",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(10, 5)
				} }
			},
			{
				"Recipe_MaceEldner_Blood",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_MaceEldner_Lightning",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_MaceEldner_Nature",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SpearSplitner",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(10, 5)
					},
					{
						"BonemawSerpentTooth",
						(null, 2)
					}
				}
			},
			{
				"Recipe_SpearSplitner_Blood",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SpearSplitner_Lightning",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SpearSplitner_Nature",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SwordNiedhogg",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(10, 5)
					},
					{
						"CharredBone",
						(null, 1)
					}
				}
			},
			{
				"Recipe_SwordNiedhogg_Blood",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SwordNiedhogg_Lightning",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SwordNiedhogg_Nature",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_SwordSlayer",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(15, 7)
					},
					{
						"AskHide",
						(null, 4)
					}
				}
			},
			{
				"Recipe_SwordSlayer_Blood",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 7)
				} }
			},
			{
				"Recipe_SwordSlayer_Lightning",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 7)
				} }
			},
			{
				"Recipe_SwordSlayer_Nature",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 7)
				} }
			},
			{
				"Recipe_AxeBerzerkr",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(15, 7)
					},
					{
						"CharredBone",
						(null, 2)
					}
				}
			},
			{
				"Recipe_BowAshlands",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(8, 4)
					},
					{
						"CharredBone",
						(15, null)
					},
					{
						"BonemawSerpentTooth",
						(4, 4)
					}
				}
			},
			{
				"Recipe_CrossbowRipper_Blood",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_CrossbowRipper_Lightning",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_CrossbowRipper_Nature",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 5)
				} }
			},
			{
				"Recipe_ArrowCharred",
				new Dictionary<string, (int?, int?)> { 
				{
					"Blackwood",
					(5, null)
				} }
			},
			{
				"Recipe_BoltCharred",
				new Dictionary<string, (int?, int?)> { 
				{
					"Blackwood",
					(5, null)
				} }
			},
			{
				"Recipe_StaffGreenRoots",
				new Dictionary<string, (int?, int?)> { 
				{
					"CelestialFeather",
					(null, 2)
				} }
			},
			{
				"Recipe_StaffLightning",
				new Dictionary<string, (int?, int?)> { 
				{
					"CelestialFeather",
					(null, 2)
				} }
			},
			{
				"Recipe_StaffRedTroll",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(null, 2)
				} }
			},
			{
				"Recipe_ArmorRagsChest",
				new Dictionary<string, (int?, int?)> { 
				{
					"LeatherScraps",
					(6, 4)
				} }
			},
			{
				"Recipe_ArmorRagsLegs",
				new Dictionary<string, (int?, int?)> { 
				{
					"LeatherScraps",
					(6, 4)
				} }
			},
			{
				"Recipe_HelmetLeather",
				new Dictionary<string, (int?, int?)>
				{
					{
						"DeerHide",
						(7, 5)
					},
					{
						"BoneFragments",
						(0, 1)
					}
				}
			},
			{
				"Recipe_ArmorLeatherChest",
				new Dictionary<string, (int?, int?)>
				{
					{
						"DeerHide",
						(7, 5)
					},
					{
						"BoneFragments",
						(0, 1)
					}
				}
			},
			{
				"Recipe_ArmorLeatherLegs",
				new Dictionary<string, (int?, int?)>
				{
					{
						"DeerHide",
						(7, 5)
					},
					{
						"BoneFragments",
						(0, 1)
					}
				}
			},
			{
				"Recipe_CapeDeerHide",
				new Dictionary<string, (int?, int?)>
				{
					{
						"DeerHide",
						(5, 3)
					},
					{
						"BoneFragments",
						(0, 1)
					}
				}
			},
			{
				"Recipe_HelmetTrollLeather",
				new Dictionary<string, (int?, int?)> { 
				{
					"BoneFragments",
					(0, 0)
				} }
			},
			{
				"Recipe_ArmorTrollLeatherChest",
				new Dictionary<string, (int?, int?)> { 
				{
					"TrollHide",
					(6, null)
				} }
			},
			{
				"Recipe_ArmorTrollLeatherLegs",
				new Dictionary<string, (int?, int?)> { 
				{
					"TrollHide",
					(6, null)
				} }
			},
			{
				"Recipe_CapeTrollHide",
				new Dictionary<string, (int?, int?)>
				{
					{
						"TrollHide",
						(4, 3)
					},
					{
						"BoneFragments",
						(5, 3)
					}
				}
			},
			{
				"Recipe_HelmetRoot",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Root",
						(5, null)
					},
					{
						"ElderBark",
						(null, 4)
					}
				}
			},
			{
				"Recipe_ArmorRootChest",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Root",
						(5, null)
					},
					{
						"ElderBark",
						(null, 4)
					}
				}
			},
			{
				"Recipe_ArmorRootLegs",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Root",
						(5, null)
					},
					{
						"ElderBark",
						(null, 4)
					}
				}
			},
			{
				"Recipe_HelmetIron",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(10, 4)
				} }
			},
			{
				"Recipe_ArmorIronChest",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(10, 4)
				} }
			},
			{
				"Recipe_ArmorIronLegs",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(10, 4)
				} }
			},
			{
				"Recipe_HelmetFenrir",
				new Dictionary<string, (int?, int?)>
				{
					{
						"WolfHairBundle",
						(10, 4)
					},
					{
						"WolfPelt",
						(3, 1)
					}
				}
			},
			{
				"Recipe_ArmorFenrirChest",
				new Dictionary<string, (int?, int?)>
				{
					{
						"WolfHairBundle",
						(10, 4)
					},
					{
						"WolfPelt",
						(4, 2)
					},
					{
						"LeatherScraps",
						(7, 3)
					}
				}
			},
			{
				"Recipe_ArmorFenrirLegs",
				new Dictionary<string, (int?, int?)>
				{
					{
						"WolfHairBundle",
						(10, 4)
					},
					{
						"WolfPelt",
						(4, 2)
					},
					{
						"LeatherScraps",
						(7, 3)
					}
				}
			},
			{
				"Recipe_HelmetDrake",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Silver",
						(10, 4)
					},
					{
						"WolfPelt",
						(null, 1)
					},
					{
						"TrophyHatchling",
						(1, null)
					}
				}
			},
			{
				"Recipe_ArmorWolfChest",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Silver",
						(10, 4)
					},
					{
						"WolfPelt",
						(null, 1)
					}
				}
			},
			{
				"Recipe_ArmorWolfLegs",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Silver",
						(10, 4)
					},
					{
						"WolfPelt",
						(null, 1)
					},
					{
						"WolfFang",
						(null, 0)
					}
				}
			},
			{
				"Recipe_CapeWolf",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Silver",
						(2, 1)
					},
					{
						"WolfPelt",
						(5, 1)
					}
				}
			},
			{
				"Recipe_ArmorBerserkerUndeadChest",
				new Dictionary<string, (int?, int?)> { 
				{
					"BjornHide",
					(5, null)
				} }
			},
			{
				"Recipe_ArmorBerserkerUndeadLegs",
				new Dictionary<string, (int?, int?)> { 
				{
					"BjornHide",
					(null, 2)
				} }
			},
			{
				"Recipe_ArmorLoxChest",
				new Dictionary<string, (int?, int?)> { 
				{
					"LoxPelt",
					(null, 4)
				} }
			},
			{
				"Recipe_HelmetPadded",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(5, 3)
				} }
			},
			{
				"Recipe_ArmorPaddedCuirass",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(5, null)
				} }
			},
			{
				"Recipe_ArmorPaddedGreaves",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(5, null)
				} }
			},
			{
				"Recipe_CapeLinen",
				new Dictionary<string, (int?, int?)> { 
				{
					"LinenThread",
					(10, 2)
				} }
			},
			{
				"Recipe_CapeLox",
				new Dictionary<string, (int?, int?)> { 
				{
					"LoxPelt",
					(5, null)
				} }
			},
			{
				"Recipe_HelmetMage",
				new Dictionary<string, (int?, int?)>
				{
					{
						"LinenThread",
						(15, 5)
					},
					{
						"Iron",
						(0, null)
					}
				}
			},
			{
				"Recipe_ArmorMageChest",
				new Dictionary<string, (int?, int?)> { 
				{
					"Eitr",
					(15, null)
				} }
			},
			{
				"Recipe_ArmorMageLegs",
				new Dictionary<string, (int?, int?)> { 
				{
					"Eitr",
					(15, null)
				} }
			},
			{
				"Recipe_HelmetCarapace",
				new Dictionary<string, (int?, int?)> { 
				{
					"Carapace",
					(15, 5)
				} }
			},
			{
				"Recipe_CapeFeather",
				new Dictionary<string, (int?, int?)>
				{
					{
						"ScaleHide",
						(7, 3)
					},
					{
						"Eitr",
						(10, null)
					}
				}
			},
			{
				"Recipe_Lantern",
				new Dictionary<string, (int?, int?)> { 
				{
					"Bronze",
					(1, null)
				} }
			},
			{
				"Recipe_MechanicalSpring",
				new Dictionary<string, (int?, int?)> { 
				{
					"Iron",
					(1, null)
				} }
			},
			{
				"Recipe_HelmetMage_Ashlands",
				new Dictionary<string, (int?, int?)> { 
				{
					"LinenThread",
					(15, 5)
				} }
			},
			{
				"Recipe_ArmorMageChest_Ashlands",
				new Dictionary<string, (int?, int?)>
				{
					{
						"Eitr",
						(15, null)
					},
					{
						"FlametalNew",
						(0, 0)
					}
				}
			},
			{
				"Recipe_ArmorMageLegs_Ashlands",
				new Dictionary<string, (int?, int?)> { 
				{
					"Eitr",
					(15, null)
				} }
			},
			{
				"Recipe_HelmetMedium_Ashlands",
				new Dictionary<string, (int?, int?)> { 
				{
					"AskHide",
					(null, 4)
				} }
			},
			{
				"Recipe_ArmorMediumChest_Ashlands",
				new Dictionary<string, (int?, int?)> { 
				{
					"AskHide",
					(null, 4)
				} }
			},
			{
				"Recipe_ArmorMediumLegs_Ashlands",
				new Dictionary<string, (int?, int?)> { 
				{
					"AskHide",
					(null, 4)
				} }
			},
			{
				"Recipe_HelmetFlametal",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(10, 5)
					},
					{
						"CharredBone",
						(3, 1)
					},
					{
						"Eitr",
						(null, 0)
					}
				}
			},
			{
				"Recipe_ArmorFlametalChest",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(10, 5)
					},
					{
						"CharredBone",
						(null, 1)
					}
				}
			},
			{
				"Recipe_ArmorFlametalLegs",
				new Dictionary<string, (int?, int?)>
				{
					{
						"FlametalNew",
						(10, 5)
					},
					{
						"CharredBone",
						(null, 1)
					}
				}
			},
			{
				"Recipe_CapeAsh",
				new Dictionary<string, (int?, int?)> { 
				{
					"FlametalNew",
					(0, null)
				} }
			}
		};

		private static readonly Dictionary<string, Dictionary<string, (string newResItem, int? amount, int? amountPerLevel)>> newGearRecipesMaterials = new Dictionary<string, Dictionary<string, (string, int?, int?)>>
		{
			{
				"Recipe_Club",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"BoneFragments",
					("LeatherScraps", null, null)
				} }
			},
			{
				"Recipe_KnifeCopper",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"GreydwarfEye",
					("LeatherScraps", null, 2)
				} }
			},
			{
				"Recipe_KnifeSilver",
				new Dictionary<string, (string, int?, int?)>
				{
					{
						"Wood",
						("FineWood", null, null)
					},
					{
						"Iron",
						("Obsidian", null, null)
					}
				}
			},
			{
				"Recipe_SwordSilver",
				new Dictionary<string, (string, int?, int?)>
				{
					{
						"Wood",
						("FineWood", 10, 2)
					},
					{
						"Iron",
						("Obsidian", 4, 2)
					}
				}
			},
			{
				"Recipe_ShieldSerpentscale",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Iron",
					("Chitin", 4, 2)
				} }
			},
			{
				"Recipe_MaceNeedle",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Iron",
					("BlackMetal", null, null)
				} }
			},
			{
				"Recipe_ArmorWolfChest",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Chain",
					("WolfFang", 3, null)
				} }
			},
			{
				"Recipe_HelmetPadded",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Iron",
					("BlackMetal", 5, 3)
				} }
			},
			{
				"Recipe_ArmorPaddedCuirass",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Iron",
					("BlackMetal", 5, null)
				} }
			},
			{
				"Recipe_ArmorPaddedGreaves",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Iron",
					("BlackMetal", 5, null)
				} }
			},
			{
				"Recipe_CapeLox",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Silver",
					("BlackMetal", null, null)
				} }
			},
			{
				"Recipe_CrossbowArbalest",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Wood",
					("FineWood", null, null)
				} }
			},
			{
				"Recipe_HelmetMage",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"Iron",
					("ScaleHide", 3, null)
				} }
			},
			{
				"Recipe_ArmorMageChest_Ashlands",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"FlametalNew",
					("SulfurStone", 5, 2)
				} }
			},
			{
				"Recipe_CapeAsh",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"FlametalNew",
					("SulfurStone", 5, null)
				} }
			},
			{
				"Recipe_StaffLightning",
				new Dictionary<string, (string, int?, int?)> { 
				{
					"GemstoneRed",
					("GemstoneBlue", 1, 1)
				} }
			}
		};

		public static void UpdateGearRecipes(ObjectDB objDB, bool amountsWasChanged, bool materialsWasChanged)
		{
			foreach (Recipe recipe in objDB.m_recipes)
			{
				bool flag = ConfigManager.GearRecipeAmountsEnabled.Value && newGearRecipesAmounts.ContainsKey(((Object)recipe).name);
				bool flag2 = ConfigManager.GearRecipeMaterialsEnabled.Value && newGearRecipesMaterials.ContainsKey(((Object)recipe).name);
				bool flag3 = ConfigManager.EarlyLinenCapeEnabled.Value && ((Object)recipe).name == "Recipe_CapeLinen";
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					if (flag && newGearRecipesAmounts[((Object)recipe).name].TryGetValue(((Object)val.m_resItem).name, out (int?, int?) value))
					{
						CreateBackup(((Object)recipe).name, val, null);
						log.Info("(Amounts) Applying changes for: " + ((Object)recipe).name + " - " + ((Object)val.m_resItem).name);
						ApplyChanges(val, (newResItem: null, amount: value.Item1, amountPerLevel: value.Item2), objDB);
					}
					if (flag2 && newGearRecipesMaterials[((Object)recipe).name].TryGetValue(((Object)val.m_resItem).name, out (string, int?, int?) value2))
					{
						CreateBackup(((Object)recipe).name, val, value2.Item1);
						log.Info("(Materials) Applying changes for: " + ((Object)recipe).name + " - " + ((Object)val.m_resItem).name);
						ApplyChanges(val, value2, objDB, modifyResItem: true);
					}
					if (!ConfigManager.GearRecipeAmountsEnabled.Value && newGearRecipesAmounts.ContainsKey(((Object)recipe).name) && amountsWasChanged)
					{
						log.Info($"(Amounts) Was changed: {amountsWasChanged}");
						if (RestoreBackup(((Object)recipe).name, val, objDB, restoreMaterials: false) && (!flag2 || !newGearRecipesMaterials[((Object)recipe).name].ContainsKey(((Object)val.m_resItem).name)) && (!flag3 || !ConfigManager.EarlyLinenCapeEnabled.Value))
						{
							log.Info("(Amounts) Removing backup for: " + ((Object)recipe).name + " - " + ((Object)val.m_resItem).name);
							defaultGearRecipeValues[((Object)recipe).name].Remove(((Object)val.m_resItem).name);
						}
					}
					if (!(!ConfigManager.GearRecipeMaterialsEnabled.Value && newGearRecipesMaterials.ContainsKey(((Object)recipe).name) && materialsWasChanged))
					{
						continue;
					}
					log.Info($"(Materials) Was changed: {materialsWasChanged}");
					if (!RestoreBackup(((Object)recipe).name, val, objDB, restoreMaterials: true))
					{
						continue;
					}
					if (flag && newGearRecipesAmounts[((Object)recipe).name].ContainsKey(((Object)val.m_resItem).name))
					{
						if (newGearRecipesAmounts[((Object)recipe).name].TryGetValue(((Object)val.m_resItem).name, out (int?, int?) value3))
						{
							log.Info("(Materials - Amounts) Re-applying changes for: " + ((Object)recipe).name + " - " + ((Object)val.m_resItem).name);
							ApplyChanges(val, (newResItem: null, amount: value3.Item1, amountPerLevel: value3.Item2), objDB);
						}
					}
					else if (!flag || !newGearRecipesAmounts[((Object)recipe).name].ContainsKey(((Object)val.m_resItem).name))
					{
						log.Info("(Materials) Removing backup for: " + ((Object)recipe).name + " - " + ((Object)val.m_resItem).name);
						defaultGearRecipeValues[((Object)recipe).name].Remove(((Object)val.m_resItem).name);
					}
				}
				if (defaultGearRecipeValues.ContainsKey(((Object)recipe).name) && defaultGearRecipeValues[((Object)recipe).name].Count == 0)
				{
					log.Info("(Cleanup) Removing backup for: " + ((Object)recipe).name);
					defaultGearRecipeValues.Remove(((Object)recipe).name);
				}
			}
		}

		public static void UpdateLinenCapeRecipe(ObjectDB objDB, bool wasChanged)
		{
			Recipe val = objDB.m_recipes.Find((Recipe r) => ((Object)r).name == "Recipe_CapeLinen");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (ConfigManager.EarlyLinenCapeEnabled.Value)
			{
				Requirement[] resources = val.m_resources;
				foreach (Requirement val2 in resources)
				{
					string name = ((Object)val2.m_resItem).name;
					string text = name;
					if (!(text == "LinenThread"))
					{
						if (text == "Silver")
						{
							CreateBackup(((Object)val).name, val2, "Iron");
							ApplyChanges(val2, (newResItem: "Iron", amount: 1, amountPerLevel: 0), objDB, modifyResItem: true);
						}
					}
					else
					{
						CreateBackup(((Object)val).name, val2, "DeerHide");
						ApplyChanges(val2, (newResItem: "DeerHide", amount: 5, amountPerLevel: 2), objDB, modifyResItem: true);
					}
				}
				val.m_minStationLevel = 1;
			}
			else
			{
				if (!wasChanged)
				{
					return;
				}
				log.Info("Early Linen Cape: Backup beginning");
				bool flag = ConfigManager.GearRecipeAmountsEnabled.Value && newGearRecipesAmounts.ContainsKey(((Object)val).name);
				Requirement[] resources2 = val.m_resources;
				foreach (Requirement val3 in resources2)
				{
					if (!RestoreBackup(((Object)val).name, val3, objDB, restoreMaterials: true))
					{
						continue;
					}
					log.Info("Early Linen Cape: Backup restored for " + ((Object)val3.m_resItem).name);
					if (flag && newGearRecipesAmounts[((Object)val).name].ContainsKey(((Object)val3.m_resItem).name))
					{
						if (newGearRecipesAmounts[((Object)val).name].TryGetValue(((Object)val3.m_resItem).name, out (int?, int?) value))
						{
							log.Info("Early Linen Cape: Re-applying changes for: " + ((Object)val).name + " - " + ((Object)val3.m_resItem).name);
							ApplyChanges(val3, (newResItem: null, amount: value.Item1, amountPerLevel: value.Item2), objDB);
						}
					}
					else if (!flag || !newGearRecipesAmounts[((Object)val).name].ContainsKey(((Object)val3.m_resItem).name))
					{
						log.Info("Early Linen Cape: Removing backup for: " + ((Object)val).name + " - " + ((Object)val3.m_resItem).name);
						defaultGearRecipeValues[((Object)val).name].Remove(((Object)val3.m_resItem).name);
					}
				}
				if (!flag)
				{
					log.Info("Early Linen Cape: Removing backup for " + ((Object)val).name);
					if (defaultGearRecipeValues.ContainsKey(((Object)val).name) && defaultGearRecipeValues[((Object)val).name].Count == 0)
					{
						defaultGearRecipeValues.Remove(((Object)val).name);
					}
				}
				val.m_minStationLevel = 2;
			}
		}

		private static void ApplyChanges(Requirement req, (string newResItem, int? amount, int? amountPerLevel) values, ObjectDB objDB, bool modifyResItem = false)
		{
			if (values.amount.HasValue)
			{
				req.m_amount = values.amount.Value;
			}
			if (values.amountPerLevel.HasValue)
			{
				req.m_amountPerLevel = values.amountPerLevel.Value;
			}
			if (modifyResItem && !string.IsNullOrEmpty(values.newResItem))
			{
				req.m_resItem = objDB.GetItemPrefab(values.newResItem).GetComponent<ItemDrop>();
			}
		}

		private static void CreateBackup(string recipeName, Requirement req, string newResItem)
		{
			if (!defaultGearRecipeValues.TryGetValue(recipeName, out Dictionary<string, (string, string, int, int)> value))
			{
				value = new Dictionary<string, (string, string, int, int)>();
				defaultGearRecipeValues[recipeName] = value;
			}
			string name = ((Object)req.m_resItem).name;
			if (value.TryGetValue(name, out var value2))
			{
				if (newResItem != null && value2.Item2 == null)
				{
					log.Info("Updating backup for " + recipeName + " - " + name + " with newResItem: " + newResItem);
					value[name] = (value2.Item1, newResItem, value2.Item3, value2.Item4);
				}
			}
			else
			{
				log.Info("Creating new backup for " + recipeName + " - " + name);
				value[name] = (name, newResItem, req.m_amount, req.m_amountPerLevel);
			}
		}

		private static bool RestoreBackup(string recipeName, Requirement req, ObjectDB objDB, bool restoreMaterials)
		{
			if (!defaultGearRecipeValues.TryGetValue(recipeName, out Dictionary<string, (string, string, int, int)> value))
			{
				return false;
			}
			log.Info("Restore backup - Recipe name: " + recipeName + ", Given requirement: " + ((Object)req.m_resItem).name);
			foreach (KeyValuePair<string, (string, string, int, int)> item in value)
			{
				var (text, text2, num, num2) = item.Value;
				log.Info($"Restore backup - values: {text}, {text2}, {restoreMaterials}");
				if (((Object)req.m_resItem).name == text2 && restoreMaterials)
				{
					log.Info("Restoring original material for " + recipeName + " from " + ((Object)req.m_resItem).name + " to " + text);
					req.m_resItem = objDB.GetItemPrefab(text).GetComponent<ItemDrop>();
					break;
				}
			}
			if (value.TryGetValue(((Object)req.m_resItem).name, out var value2))
			{
				log.Info("Restoring backup for: " + recipeName + " - " + ((Object)req.m_resItem).name);
				req.m_amount = value2.Item3;
				req.m_amountPerLevel = value2.Item4;
				return true;
			}
			return false;
		}

		private static void LogRecipes(ObjectDB objDb)
		{
			if ((Object)(object)objDb == (Object)null)
			{
				log.Warn("ObjectDB is null, cannot log recipes.");
				return;
			}
			log.Info("=== Listing all Recipes in ObjectDB ===");
			foreach (Recipe recipe in objDb.m_recipes)
			{
				if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || recipe.m_item.m_itemData == null)
				{
					continue;
				}
				string name = ((Object)recipe).name;
				string name2 = recipe.m_item.m_itemData.m_shared.m_name;
				int minStationLevel = recipe.m_minStationLevel;
				string arg = (((Object)(object)recipe.m_craftingStation != (Object)null) ? recipe.m_craftingStation.m_name : "None");
				log.Info("Recipe: " + name);
				log.Info("   Produces: " + name2);
				log.Info($"   Station: {arg} (min level {minStationLevel})");
				if (recipe.m_resources != null && recipe.m_resources.Length != 0)
				{
					log.Info("   Requirements:");
					Requirement[] resources = recipe.m_resources;
					foreach (Requirement val in resources)
					{
						if ((Object)(object)val?.m_resItem != (Object)null)
						{
							string name3 = ((Object)val.m_resItem).name;
							log.Info($"      - {name3} x{val.m_amount} (upgrade: {val.m_amountPerLevel})");
						}
					}
				}
				else
				{
					log.Info("   Requirements: None");
				}
			}
			log.Info("=== End of Recipes List ===");
		}
	}
}
namespace MarsarahTweaks.Patches.QOL
{
	internal static class MoreUsableFuel
	{
		[HarmonyPatch(typeof(Smelter), "Awake")]
		public static class AddAncientBarkToKiln_Patch
		{
			private static void Postfix(Smelter __instance)
			{
				UpdateKiln(__instance);
			}
		}

		[HarmonyPatch(typeof(ShieldGenerator), "Start")]
		public static class AddWitheredBonesToShieldGenerator_Patch
		{
			private static void Postfix(ShieldGenerator __instance)
			{
				UpdateShieldGenerator(__instance);
			}
		}

		private static readonly LogManager log = new LogManager("More Usable Fuel", LogManager.LogLevel.Warning);

		public static void UpdateMoreUsableFuel()
		{
			UpdateAllKilns();
			UpdateAllShieldGenerators();
		}

		private static void UpdateAllKilns()
		{
			Smelter[] array = Object.FindObjectsByType<Smelter>((FindObjectsSortMode)0);
			foreach (Smelter kiln in array)
			{
				UpdateKiln(kiln);
			}
		}

		private static void UpdateKiln(Smelter kiln)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			if (!kiln.m_conversion.Exists((ItemConversion conv) => (Object)(object)conv.m_to != (Object)null && ((Object)conv.m_to).name == "Coal"))
			{
				return;
			}
			ObjectDB instance = ObjectDB.instance;
			GameObject val = ((instance != null) ? instance.GetItemPrefab("ElderBark") : null);
			ObjectDB instance2 = ObjectDB.instance;
			GameObject val2 = ((instance2 != null) ? instance2.GetItemPrefab("Coal") : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				log.Warn("Missing prefab: AncientBark or Coal.");
				return;
			}
			ItemDrop barkDrop = val.GetComponent<ItemDrop>();
			ItemDrop coalDrop = val2.GetComponent<ItemDrop>();
			ItemConversion val3 = ((IEnumerable<ItemConversion>)kiln.m_conversion).FirstOrDefault((Func<ItemConversion, bool>)((ItemConversion conv) => (Object)(object)conv.m_from == (Object)(object)barkDrop && (Object)(object)conv.m_to == (Object)(object)coalDrop));
			if (ConfigManager.MoreUsableFuelEnabled.Value)
			{
				if (val3 == null)
				{
					ItemConversion item = new ItemConversion
					{
						m_from = barkDrop,
						m_to = coalDrop
					};
					kiln.m_conversion.Add(item);
					log.Info("Added Ancient Bark as fuel for Kiln.");
				}
			}
			else if (val3 != null)
			{
				kiln.m_conversion.Remove(val3);
				log.Info("Removed Ancient Bark as fuel from Kiln.");
			}
		}

		private static void UpdateAllShieldGenerators()
		{
			ShieldGenerator[] array = Object.FindObjectsByType<ShieldGenerator>((FindObjectsSortMode)0);
			foreach (ShieldGenerator sg in array)
			{
				UpdateShieldGenerator(sg);
			}
		}

		private static void UpdateShieldGenerator(ShieldGenerator sg)
		{
			ObjectDB instance = ObjectDB.instance;
			GameObject val = ((instance != null) ? instance.GetItemPrefab("WitheredBone") : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				log.Warn("WitheredBone prefab not found.");
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				log.Warn("WitheredBone does not have ItemDrop component.");
			}
			else if (ConfigManager.MoreUsableFuelEnabled.Value)
			{
				if (!sg.m_fuelItems.Contains(component))
				{
					sg.m_fuelItems.Add(component);
					log.Info("Added WitheredBone as fuel for Shield Generator.");
				}
			}
			else if (sg.m_fuelItems.Contains(component))
			{
				sg.m_fuelItems.Remove(component);
				log.Info("Removed WitheredBone as fuel from Shield Generator.");
			}
		}
	}
	internal class BoatRadiusChanges
	{
		[HarmonyPatch(typeof(Minimap), "UpdateExplore")]
		private class LargerBoatExploreRadius_Patch
		{
			private static float originalExploreRadius = -1f;

			private static void Prefix(ref float ___m_exploreRadius)
			{
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated())
				{
					return;
				}
				if (ConfigManager.LargerBoatExploreRadiusEnabled.Value)
				{
					if (Object.op_Implicit((Object)(object)Ship.GetLocalShip()) && Ship.GetLocalShip().HasPlayerOnboard())
					{
						if (originalExploreRadius == -1f)
						{
							log.Info($"Backing up explore radius: {___m_exploreRadius}");
							originalExploreRadius = ___m_exploreRadius;
						}
						if (___m_exploreRadius != 100f)
						{
							log.Info("Applying new explore radius: 100");
							___m_exploreRadius = 100f;
						}
					}
					else if (originalExploreRadius != -1f && ___m_exploreRadius != originalExploreRadius)
					{
						log.Info($"Restoring original explore radius: {originalExploreRadius}");
						___m_exploreRadius = originalExploreRadius;
					}
				}
				else if (originalExploreRadius != -1f && ___m_exploreRadius != originalExploreRadius)
				{
					log.Info($"Restoring original explore radius: {originalExploreRadius} due to config OFF");
					___m_exploreRadius = originalExploreRadius;
				}
			}
		}

		private static readonly LogManager log = new LogManager("Boat Radius", LogManager.LogLevel.Warning);
	}
	internal class FasterEquipChanges
	{
		[HarmonyPatch(typeof(Player), "QueueEquipAction")]
		private static class EquipActionSpeed_Patch
		{
			private static void Prefix(ItemData item)
			{
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				if (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) || !ConfigManager.FasterEquipEnabled.Value)
				{
					return;
				}
				if (item.IsWeapon())
				{
					if (item.m_shared.m_equipDuration > 0f)
					{
						item.m_shared.m_equipDuration = 0f;
					}
					log.Info($"Weapon {item.m_shared.m_name} - anim state: {item.m_shared.m_animationState}");
				}
				if (item.IsEquipable() && !item.IsWeapon() && item.m_shared.m_equipDuration > 1f)
				{
					item.m_shared.m_equipDuration = 1f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "QueueUnequipAction")]
		private static class UnequipActionSpeed_Patch
		{
			private static void Prefix(ItemData item)
			{
				if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && ConfigManager.FasterEquipEnabled.Value)
				{
					if (item.IsWeapon() && item.m_shared.m_equipDuration > 0f)
					{
						item.m_shared.m_equipDuration = 0f;
					}
					if (item.IsEquipable() && !item.IsWeapon() && item.m_shared.m_equipDuration > 1f)
					{
						item.m_shared.m_equipDuration = 1f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZSyncAnimation), "SetTrigger")]
		private class RemoveEquipAndEatAnimation
		{
			private static bool Prefix(ZSyncAnimation __instance, string name)
			{
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated())
				{
					return true;
				}
				if (ConfigManager.FasterEquipEnabled.Value && name == "equip_hip")
				{
					return false;
				}
				return true;
			}
		}

		private static readonly LogManager log = new LogManager("Faster Equip", LogManager.LogLevel.Warning);
	}
	internal class FasterResourceDrops
	{
		[HarmonyPatch(typeof(Ragdoll), "Awake")]
		private class FasterResourceDrops_Patch
		{
			public static void Prefix(Ragdoll __instance, ref float ___m_ttl)
			{
				if (!((Object)(object)__instance == (Object)null) && ConfigManager.FasterResourceDropsEnabled.Value)
				{
					if (___m_ttl > 5f)
					{
						___m_ttl = 5f;
						log.Info("Large monster ttl set to 5s");
					}
					else if (___m_ttl > 0.5f)
					{
						___m_ttl = 0.5f;
						log.Info("Small monster ttl set to 0.5s");
					}
				}
			}
		}

		private static readonly LogManager log = new LogManager("Faster Resource Drops", LogManager.LogLevel.Warning);
	}
	internal class FriendlyBallistas
	{
		[HarmonyPatch(typeof(Turret), "UpdateTarget")]
		private class FriendlyBallistas_Patch
		{
			private static bool originalTargetsFriendly = true;

			private static readonly bool newTargetsFriendly = false;

			private static void Postfix([NotNull] ref bool ___m_targetPlayers, [NotNull] ref bool ___m_targetTamed)
			{
				if (ConfigManager.FriendlyBallistasEnabled.Value)
				{
					if (___m_targetPlayers != newTargetsFriendly)
					{
						log.Info($"Applying new player targeting: {newTargetsFriendly}");
						___m_targetPlayers = newTargetsFriendly;
					}
					if (___m_targetTamed != newTargetsFriendly)
					{
						log.Info($"Applying new tamed targeting: {newTargetsFriendly}");
						___m_targetTamed = newTargetsFriendly;
					}
				}
				else
				{
					if (___m_targetPlayers != originalTargetsFriendly)
					{
						log.Info($"Restoring player targeting: {originalTargetsFriendly}");
						___m_targetPlayers = originalTargetsFriendly;
					}
					if (___m_targetTamed != originalTargetsFriendly)
					{
						log.Info($"Restoring tamed targeting: {originalTargetsFriendly}");
						___m_targetTamed = originalTargetsFriendly;
					}
				}
			}
		}

		private static readonly LogManager log = new LogManager("Friendly Ballistas", LogManager.LogLevel.Warning);
	}
	internal class LargerPickupAreaChanges
	{
		[HarmonyPatch(typeof(Player), "Awake")]
		private class LargerPickupArea_Patch
		{
			private static void Prefix(Player __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()))
				{
					UpdatePickupArea(__instance, wasChanged: false);
				}
			}
		}

		private static readonly LogManager log = new LogManager("Larger Pickup Area", LogManager.LogLevel.Warning);

		private static float originalPickupArea = -1f;

		public static void UpdatePickupArea(Player player, bool wasChanged)
		{
			if (ConfigManager.LargerPickupAreaEnabled.Value)
			{
				if (originalPickupArea == -1f)
				{
					log.Info($"Backing up pickup area ({player.m_autoPickupRange})");
					originalPickupArea = player.m_autoPickupRange;
				}
				log.Info($"Assigning new pickup area (3) - from {player.m_autoPickupRange}");
				player.m_autoPickupRange = 3f;
			}
			else if (wasChanged && originalPickupArea != -1f)
			{
				log.Info($"Restoring pickup area: {originalPickupArea} - from {player.m_autoPickupRange}");
				player.m_autoPickupRange = originalPickupArea;
			}
		}
	}
	internal class LessFallDamage
	{
		[HarmonyPatch(typeof(SEMan), "ModifyFallDamage")]
		private class FallDamage_Patch
		{
			private static void Prefix(ref float damage)
			{
				if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && ConfigManager.LessFallDamageEnabled.Value)
				{
					log.Info("Reducing fall damage by 40%");
					damage *= 0.6f;
				}
			}
		}

		private static readonly LogManager log = new LogManager("Less Fall Damage", LogManager.LogLevel.Warning);
	}
	internal class LighterMetalWeight
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private class OthersSection_Patch
		{
			private static void Postfix(ref ObjectDB __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()))
				{
					UpdateLighterMetalWeight(__instance, wasChanged: false);
				}
			}
		}

		private static readonly LogManager log = new LogManager("Lighter Metal Weight", LogManager.LogLevel.Warning);

		private static readonly Dictionary<string, float> metalWeightOriginals = new Dictionary<string, float>();

		private static readonly Dictionary<string, float> metalWeightChanges = new Dictionary<string, float>
		{
			{ "TinOre", 8f },
			{ "Tin", 8f },
			{ "CopperOre", 8f },
			{ "Copper", 8f },
			{ "Bronze", 8f },
			{ "IronOre", 8f },
			{ "IronScrap", 8f },
			{ "Iron", 8f },
			{ "SilverOre", 8f },
			{ "Silver", 8f },
			{ "BlackMetalScrap", 8f },
			{ "BlackMetal", 8f },
			{ "CopperScrap", 8f },
			{ "BronzeScrap", 8f },
			{ "Flametal", 8f },
			{ "FlametalNew", 8f },
			{ "FlametalOre", 8f },
			{ "FlametalOreNew", 8f }
		};

		public static void UpdateLighterMetalWeight(ObjectDB objDB, bool wasChanged)
		{
			if (ConfigManager.LighterMetalWeightEnabled.Value)
			{
				foreach (string itemName in metalWeightChanges.Keys)
				{
					GameObject val = objDB.m_items.Find((GameObject i) => ((Object)i).name == itemName);
					if (!((Object)(object)val == (Object)null))
					{
						ItemDrop component = val.GetComponent<ItemDrop>();
						if (!((Object)(object)component == (Object)null))
						{
							if (!metalWeightOriginals.ContainsKey(((Object)val).name))
							{
								metalWeightOriginals[((Object)val).name] = component.m_itemData.m_shared.m_weight;
							}
							if (metalWeightChanges.TryGetValue(((Obj