Decompiled source of SeaAnimals v0.3.8

SeaAnimals/SeaAnimals.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CreatureManager;
using HarmonyLib;
using ItemManager;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: AssemblyFileVersion("0.3.8")]
[assembly: Guid("E74EB49A-461D-48EA-85BC-F462D60C98C4")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyProduct("SeaAnimals")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("SeaAnimals")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Marlthon")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.8.0")]
[module: <0934178a-1a6d-4aff-ba91-82e3e5b1f41d>RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<946165a7-17e5-4981-9d6c-1230914ad734>Embedded]
	internal sealed class <946165a7-17e5-4981-9d6c-1230914ad734>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[<946165a7-17e5-4981-9d6c-1230914ad734>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <2dc67916-7bee-45d9-affd-2c5a7b8c583c>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <2dc67916-7bee-45d9-affd-2c5a7b8c583c>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <2dc67916-7bee-45d9-affd-2c5a7b8c583c>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<946165a7-17e5-4981-9d6c-1230914ad734>Embedded]
	[CompilerGenerated]
	internal sealed class <5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[<946165a7-17e5-4981-9d6c-1230914ad734>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class <0934178a-1a6d-4aff-ba91-82e3e5b1f41d>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <0934178a-1a6d-4aff-ba91-82e3e5b1f41d>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SeaAnimals
{
	[HarmonyPatch]
	public static class MarineLifeMountControl
	{
		public static float currentTurnInput;
	}
	[HarmonyPatch(typeof(Player), "StartDoodadControl")]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	public static class Player_StartDoodadControl_MarineLife
	{
		public static Humanoid RidingHumanoid;

		private static bool Prefix(Player __instance, IDoodadController shipControl)
		{
			if (shipControl == null)
			{
				return true;
			}
			Component controlledComponent = shipControl.GetControlledComponent();
			object obj;
			if (controlledComponent == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = controlledComponent.transform;
				obj = ((transform != null) ? ((Component)transform).GetComponentInParent<Humanoid>() : null);
			}
			Humanoid val = (Humanoid)obj;
			if ((Object)(object)val == (Object)null || !Utils.GetPrefabName(((Object)((Component)val).gameObject).name).StartsWith("SA_"))
			{
				return true;
			}
			RidingHumanoid = val;
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "StopDoodadControl")]
	public static class Player_StopDoodadControl_MarineLife
	{
		private static void Postfix()
		{
			Player_StartDoodadControl_MarineLife.RidingHumanoid = null;
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	public static class Player_Update_Input_MarineLife
	{
		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
		private static void Prefix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).IsRiding() || (Object)(object)Player_StartDoodadControl_MarineLife.RidingHumanoid == (Object)null)
			{
				return;
			}
			Humanoid ridingHumanoid = Player_StartDoodadControl_MarineLife.RidingHumanoid;
			string prefabName = Utils.GetPrefabName(((Object)((Component)ridingHumanoid).gameObject).name);
			if (!prefabName.Contains("Crocodile") && ((Character)ridingHumanoid).IsOnGround() && !((Character)ridingHumanoid).IsSwimming())
			{
				__instance.StopDoodadControl();
				return;
			}
			float num = 0f;
			if (ZInput.GetButton("Left"))
			{
				num -= 1f;
			}
			if (ZInput.GetButton("Right"))
			{
				num += 1f;
			}
			MarineLifeMountControl.currentTurnInput = num;
		}
	}
	[HarmonyPatch(typeof(Sadle), "ApplyControlls")]
	public static class Sadle_ApplyControlls_Movement_Patch
	{
		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
		private static bool Prefix(Sadle __instance, Vector3 moveDir, Vector3 lookDir, bool run)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Expected I4, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			Humanoid ridingHumanoid = Player_StartDoodadControl_MarineLife.RidingHumanoid;
			if ((Object)(object)ridingHumanoid == (Object)null || (Object)(object)__instance.m_character != (Object)(object)ridingHumanoid)
			{
				return true;
			}
			if ((Object)(object)__instance.m_monsterAI != (Object)null)
			{
				((MonoBehaviour)__instance.m_monsterAI).StopAllCoroutines();
			}
			float currentTurnInput = MarineLifeMountControl.currentTurnInput;
			bool flag = Mathf.Abs(moveDir.z) > 0.1f;
			Vector3 val = ((Component)ridingHumanoid).transform.forward;
			if (Mathf.Abs(currentTurnInput) > 0.01f)
			{
				Vector3 val2 = ((Component)ridingHumanoid).transform.forward + ((Component)ridingHumanoid).transform.right * currentTurnInput * 0.5f;
				val = ((Vector3)(ref val2)).normalized;
			}
			((Character)ridingHumanoid).SetLookDir(val, 0f);
			Vector3 val3 = Vector3.zero;
			Speed val4 = (Speed)0;
			if (flag)
			{
				((Component)ridingHumanoid).transform.Rotate(0f, currentTurnInput * 2f, 0f);
				val3 = ((Component)ridingHumanoid).transform.forward * Mathf.Sign(moveDir.z);
				val4 = (Speed)((!run) ? 1 : 2);
			}
			else if (Mathf.Abs(currentTurnInput) > 0.01f)
			{
				((Component)ridingHumanoid).transform.Rotate(0f, currentTurnInput * 1.5f, 0f);
				val3 = ((Component)ridingHumanoid).transform.right * currentTurnInput * 0.01f;
				val4 = (Speed)1;
			}
			float skillFactor = ((Character)Player.m_localPlayer).GetSkills().GetSkillFactor((SkillType)110);
			__instance.m_nview.InvokeRPC("Controls", new object[3]
			{
				val3,
				(int)val4,
				skillFactor
			});
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "SetControls")]
	public static class Player_SetControls_ActionRedirect_Patch
	{
		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
		private static void Prefix(Player __instance, ref bool jump, ref bool attack, ref bool secondaryAttack)
		{
			Humanoid ridingHumanoid = Player_StartDoodadControl_MarineLife.RidingHumanoid;
			if (!((Character)__instance).IsRiding() || !((Object)(object)ridingHumanoid != (Object)null))
			{
				return;
			}
			attack = false;
			secondaryAttack = false;
			if (jump && !Utils.GetPrefabName(((Object)((Component)ridingHumanoid).gameObject).name).Contains("Crocodile"))
			{
				((Character)ridingHumanoid).Jump(false);
				if ((Object)(object)((Character)ridingHumanoid).m_animator != (Object)null)
				{
					((Character)ridingHumanoid).m_animator.SetTrigger("jump");
				}
			}
			jump = false;
		}
	}
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[HarmonyPatch(typeof(Player), "Update")]
	public static class Player_Update_MountAttack_MarineLife
	{
		private static void Postfix(Player __instance)
		{
			Humanoid ridingHumanoid = Player_StartDoodadControl_MarineLife.RidingHumanoid;
			if (!((Object)(object)ridingHumanoid == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ((Character)__instance).TakeInput() && !((Character)ridingHumanoid).InAttack())
			{
				if (ZInput.GetButtonDown("Attack"))
				{
					ProcessAttack(ridingHumanoid, 0);
				}
				if (ZInput.GetButtonDown("SecondaryAttack"))
				{
					ProcessAttack(ridingHumanoid, 1);
				}
			}
		}

		private static void ProcessAttack(Humanoid mount, int index)
		{
			if (mount.m_defaultItems != null && mount.m_defaultItems.Length > index)
			{
				mount.m_rightItem = mount.m_defaultItems[index].GetComponent<ItemDrop>().m_itemData;
				((Character)mount).StartAttack((Character)null, false);
			}
		}
	}
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	public class CreatureJump : MonoBehaviour
	{
		private Animator animator;

		private Character character;

		private readonly List<string> allowedCreatures = new List<string> { "SA_Orca", "SA_Dolphin" };

		private bool isAllowed = false;

		private void Start()
		{
			character = ((Component)this).GetComponent<Character>();
			string prefabName = Utils.GetPrefabName(((Object)((Component)this).gameObject).name);
			if (allowedCreatures.Contains(prefabName))
			{
				isAllowed = true;
			}
			Transform val = ((Component)this).transform.Find("Visual");
			if ((Object)(object)val != (Object)null)
			{
				animator = ((Component)val).GetComponent<Animator>();
			}
			if (isAllowed)
			{
				((MonoBehaviour)this).StartCoroutine(JumpRoutine());
			}
		}

		private IEnumerator JumpRoutine()
		{
			while (true)
			{
				float waitTime = Random.Range(30f, 60f);
				yield return (object)new WaitForSeconds(waitTime);
				if ((Object)(object)animator != (Object)null && (Object)(object)character != (Object)null)
				{
					bool isTamed = character.IsTamed();
					bool isBeingRidden = character.IsAttached();
					bool isOwner = (Object)(object)character.m_nview != (Object)null && character.m_nview.IsOwner();
					if (!isTamed && !isBeingRidden && isOwner)
					{
						Debug.Log((object)("[SeaAnimals] Pulando (Selvagem): " + ((Object)((Component)this).gameObject).name + "."));
						animator.SetTrigger("jump");
					}
				}
			}
		}
	}
	[BepInPlugin("marlthon.SeaAnimals", "SeaAnimals", "0.3.8")]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	public class SeaAnimalsPlugin : BaseUnityPlugin
	{
		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)]
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class SeaAnimalsZNetScene_AwakePost_Patch
		{
			[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
			private static void Postfix(ZNetScene __instance)
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Expected O, but got Unknown
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Expected O, but got Unknown
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				List<GameObject> prefabs = __instance.m_prefabs;
				if (prefabs == null || prefabs.Count <= 0)
				{
					return;
				}
				CookingStation component = __instance.GetPrefab("piece_cookingstation").GetComponent<CookingStation>();
				CookingStation component2 = __instance.GetPrefab("piece_cookingstation_iron").GetComponent<CookingStation>();
				foreach (KeyValuePair<GameObject, GameObject> seaanimalscarne in seaanimalscarnes)
				{
					component.m_conversion.Add(new ItemConversion
					{
						m_cookTime = 25f,
						m_from = __instance.GetPrefab(((Object)seaanimalscarne.Key).name).GetComponent<ItemDrop>(),
						m_to = __instance.GetPrefab(((Object)seaanimalscarne.Value).name).GetComponent<ItemDrop>()
					});
					component2.m_conversion.Add(new ItemConversion
					{
						m_cookTime = 25f,
						m_from = __instance.GetPrefab(((Object)seaanimalscarne.Key).name).GetComponent<ItemDrop>(),
						m_to = __instance.GetPrefab(((Object)seaanimalscarne.Value).name).GetComponent<ItemDrop>()
					});
				}
			}
		}

		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			public bool? Browsable = false;
		}

		internal const string ModName = "SeaAnimals";

		internal const string ModVersion = "0.3.8";

		internal const string Author = "marlthon";

		private const string ModGUID = "marlthon.SeaAnimals";

		private static string ConfigFileName = "marlthon.SeaAnimals.cfg";

		private static string ConfigFileFullPath;

		private readonly Harmony _harmony = new Harmony("marlthon.SeaAnimals");

		private static Dictionary<GameObject, GameObject> seaanimalscarnes;

		public static readonly ManualLogSource SeaAnimals;

		private static readonly ConfigSync ConfigSync;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private static ConfigEntry<bool> _serverConfigLocked;

		public void Awake()
		{
			_serverConfigLocked = config("General", "Force Server Config", value: true, "Force Server Config");
			ConfigSync.AddLockingConfigEntry<bool>(_serverConfigLocked);
			Creature creature = new Creature("mar_seaanimals", "SA_Orca").ConfigureBiome((Biome)320).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureFoodItems("SA_BlueSharkMeat, SA_CrocoMeat, SA_HumboldMeat, SA_WhaleMeat, SA_SeaTurtleMeat, SA_SharkMeat, SA_TurtleMeat, SerpentMeat")
				.ConfigureForestSpawn(Forest.No)
				.ConfigureRequiredGlobalKey(GlobalKey.KilledEikthyr)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 2f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming()
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(500f)
				.ConfigureRegenAllHpTime(3600f);
			creature.Localize().Portuguese_Brazilian("Orca").English("Orca");
			creature.ConfigureDrops();
			creature.Drops["SA_WhaleMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature.Drops["SA_WhaleMeat"].DropChance = 100f;
			GameObject val = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Orca_Attack_Bite1_marinelife");
			GameObject val2 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Orca_Attack_Jump_marinelife");
			GameObject val3 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_alert_orca_marinelife");
			GameObject val4 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_death_orca_marinelife");
			GameObject val5 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_idle_orca_marinelife");
			GameObject val6 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_littleorca_marinelife");
			GameObject val7 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_pet_orca_marinelife");
			GameObject val8 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_tamed_orca_marinelife");
			GameObject val9 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_orcasoundhit_marinelife");
			Creature creature2 = new Creature("mar_seaanimals", "SA_Dolphin").ConfigureBiome((Biome)320).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureFoodItems("SA_BlueSharkMeat, SA_CrocoMeat, SA_HumboldMeat, SA_WhaleMeat, SA_SeaTurtleMeat, SA_SharkMeat, SA_TurtleMeat, SerpentMeat")
				.ConfigureForestSpawn(Forest.No)
				.ConfigureRequiredGlobalKey(GlobalKey.KilledEikthyr)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming()
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(400f)
				.ConfigureRegenAllHpTime(3600f);
			creature2.Localize().Portuguese_Brazilian("Golfinho").English("Dolphin");
			creature2.ConfigureDrops();
			creature2.Drops["SA_WhaleMeat"].Amount = new CreatureManager.Range(1f, 2f);
			creature2.Drops["SA_WhaleMeat"].DropChance = 100f;
			GameObject val10 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_01_dolphin_marinelife");
			GameObject val11 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_birth_dolphin_marinelife");
			GameObject val12 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_death_dolphin_marinelife");
			GameObject val13 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_idle_dolphin_marinelife");
			GameObject val14 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_love_dolphin_marinelife");
			GameObject val15 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_pet_dolphin_marinelife");
			GameObject val16 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_tamed_dolphin_marinelife");
			Creature creature3 = new Creature("mar_seaanimals", "SA_Crocodile").ConfigureBiome((Biome)10).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1f, 2f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureFoodItems("SA_BlueSharkMeat, SA_CrocoMeat, SA_HumboldMeat, SA_WhaleMeat, SA_SeaTurtleMeat, SA_SharkMeat, SA_TurtleMeat, SerpentMeat")
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.KilledEikthyr)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming()
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(200f)
				.ConfigureRegenAllHpTime(3600f);
			creature3.Localize().Portuguese_Brazilian("Crocodilo").English("Crocodile");
			creature3.ConfigureDrops();
			creature3.Drops["SA_CrocoMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature3.Drops["SA_CrocoMeat"].DropChance = 100f;
			GameObject val17 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_Crocodile01_marinelife");
			GameObject val18 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_Crocodile02_marinelife");
			GameObject val19 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_Crocodile03_marinelife");
			GameObject val20 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_Crocodile04_marinelife");
			GameObject val21 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_alert_Crocodile_marinelife");
			GameObject val22 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_attack_crocodile_marinelife");
			GameObject val23 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_death_crocodile_marinelife");
			GameObject val24 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_Idle_Crocodile_marinelife");
			Creature creature4 = new Creature("mar_seaanimals", "SA_WhiteShark").ConfigureBiome((Biome)320).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureFoodItems("SA_BlueSharkMeat, SA_CrocoMeat, SA_HumboldMeat, SA_WhaleMeat, SA_SeaTurtleMeat, SA_SharkMeat, SA_TurtleMeat, SerpentMeat")
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.KilledBonemass)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(400f)
				.ConfigureRegenAllHpTime(3600f);
			creature4.Localize().Portuguese_Brazilian("Tubarão Branco").English("White Shark");
			creature4.ConfigureDrops();
			creature4.Drops["SA_SharkMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature4.Drops["SA_SharkMeat"].DropChance = 100f;
			GameObject val25 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "WhiteShark_Attack_Bite1_marinelife");
			GameObject val26 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "WhiteShark_Attack_Jump_marinelife");
			GameObject val27 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_attack_whiteshark_marinelife");
			GameObject val28 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_pet_whiteshark_marinelife");
			GameObject val29 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_tamed_whiteshark_marinelife");
			Creature creature5 = new Creature("mar_seaanimals", "SA_HumboldtSquid").ConfigureBiome((Biome)256).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(250f)
				.ConfigureRegenAllHpTime(3600f);
			creature5.Localize().Portuguese_Brazilian("Luladrão").English("Humboldt Squid");
			creature5.ConfigureDrops();
			creature5.Drops["SA_HumboldMeat"].Amount = new CreatureManager.Range(1f, 2f);
			creature5.Drops["SA_HumboldMeat"].DropChance = 100f;
			GameObject val30 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_HumboldtSquid");
			GameObject val31 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "HumboldtSquid_Aoe");
			GameObject val32 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_humboldtsquid_attack");
			GameObject val33 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_humboldtsquid_attack_hit");
			GameObject val34 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_humboldtsquid_pray");
			Creature creature6 = new Creature("mar_seaanimals", "SA_LeatherbackSeaTurtle").ConfigureBiome((Biome)256).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(350f)
				.ConfigureRegenAllHpTime(3600f);
			creature6.Localize().Portuguese_Brazilian("Tartaruga de Couro").English("Leatherback SeaTurtle");
			creature6.ConfigureDrops();
			creature6.Drops["SA_SeaTurtleMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature6.Drops["SA_SeaTurtleMeat"].DropChance = 100f;
			Creature creature7 = new Creature("mar_seaanimals", "SA_RightWhale").ConfigureBiome((Biome)320).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(500f)
				.ConfigureRegenAllHpTime(3600f);
			creature7.Localize().Portuguese_Brazilian("Baleia Franca").English("Right Whale");
			creature7.ConfigureDrops();
			creature7.Drops["SA_WhaleMeat"].Amount = new CreatureManager.Range(2f, 4f);
			creature7.Drops["SA_WhaleMeat"].DropChance = 100f;
			Creature creature8 = new Creature("mar_seaanimals", "SA_WhaleShark").ConfigureBiome((Biome)256).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-1000f, 0f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(400f)
				.ConfigureRegenAllHpTime(3600f);
			creature8.Localize().Portuguese_Brazilian("Tubarão Baleia").English("Whale Shark");
			creature8.ConfigureDrops();
			creature8.Drops["SA_WhaleMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature8.Drops["SA_WhaleMeat"].DropChance = 100f;
			Creature creature9 = new Creature("mar_seaanimals", "SA_BlueShark").ConfigureBiome((Biome)1).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-4f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(30f)
				.ConfigureRegenAllHpTime(3600f);
			creature9.Localize().Portuguese_Brazilian("Tubarão Azul").English("Blue Shark");
			creature9.ConfigureDrops();
			creature9.Drops["SA_BlueSharkMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature9.Drops["SA_BlueSharkMeat"].DropChance = 100f;
			GameObject val35 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_BlueShark01_marinelife");
			Creature creature10 = new Creature("mar_seaanimals", "SA_HammerHeadShark").ConfigureBiome((Biome)16).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-5f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.KilledBonemass)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(300f)
				.ConfigureRegenAllHpTime(3600f);
			creature10.Localize().Portuguese_Brazilian("Tubarão Martelo").English("HammerHead Shark");
			creature10.ConfigureDrops();
			creature10.Drops["SA_SharkMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature10.Drops["SA_SharkMeat"].DropChance = 100f;
			GameObject val36 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_HammerHeadShark01_marinelife");
			GameObject val37 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_HammerHeadShark02_marinelife");
			GameObject val38 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_HammerHeadShark03_marinelife");
			Creature creature11 = new Creature("mar_seaanimals", "SA_TigerShark").ConfigureBiome((Biome)512).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-10f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.KilledBonemass)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 1f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Day)
				.ConfigureMaximum(2)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableStars()
				.EnableSpawning()
				.ConfigureHealth(350f)
				.ConfigureRegenAllHpTime(3600f);
			creature11.Localize().Portuguese_Brazilian("Tubarão Tigre").English("Tiger Shark");
			creature11.ConfigureDrops();
			creature11.Drops["SA_SharkMeat"].Amount = new CreatureManager.Range(1f, 3f);
			creature11.Drops["SA_SharkMeat"].DropChance = 100f;
			GameObject val39 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_TigerShark01_marinelife");
			GameObject val40 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_TigerShark02_marinelife");
			GameObject val41 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "Attack_TigerShark03_marinelife");
			Creature creature12 = new Creature("mar_seaanimals", "SA_BlueTurtle").ConfigureBiome((Biome)8).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-5f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.ClearSkies | Weather.LightRain | Weather.ClearThunderStorm | Weather.BlackForestFog)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Always)
				.ConfigureMaximum(3)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableSpawning()
				.ConfigureHealth(80f)
				.ConfigureRegenAllHpTime(3600f);
			creature12.Localize().Portuguese_Brazilian("Tartaruga Azul").English("Blue Turtle");
			creature12.ConfigureDrops();
			creature12.Drops["SA_TurtleMeat"].Amount = new CreatureManager.Range(1f, 1f);
			creature12.Drops["SA_TurtleMeat"].DropChance = 100f;
			Creature creature13 = new Creature("mar_seaanimals", "SA_GreenTurtle").ConfigureBiome((Biome)1).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-5f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.ClearSkies | Weather.MeadowsClearSkies | Weather.LightRain | Weather.ClearThunderStorm)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Always)
				.ConfigureMaximum(3)
				.EnableSpawning()
				.ConfigureHealth(40f)
				.ConfigureRegenAllHpTime(3600f);
			creature13.Localize().Portuguese_Brazilian("Tartaruga Verde").English("Green Turtle");
			creature13.ConfigureDrops();
			creature13.Drops["SA_TurtleMeat"].Amount = new CreatureManager.Range(1f, 1f);
			creature13.Drops["SA_TurtleMeat"].DropChance = 100f;
			Creature creature14 = new Creature("mar_seaanimals", "SA_RedTurtle").ConfigureBiome((Biome)16).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-5f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Always)
				.ConfigureMaximum(3)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableSpawning()
				.ConfigureHealth(160f)
				.ConfigureRegenAllHpTime(3600f);
			creature14.Localize().Portuguese_Brazilian("Tartaruga Vermelha").English("Red Turtle");
			creature14.ConfigureDrops();
			creature14.Drops["SA_TurtleMeat"].Amount = new CreatureManager.Range(1f, 2f);
			creature14.Drops["SA_TurtleMeat"].DropChance = 100f;
			Creature creature15 = new Creature("mar_seaanimals", "SA_YellowTurtle").ConfigureBiome((Biome)512).ConfigureSpawnArea(SpawnArea.Everywhere).ConfigureRequiredAltitude(new CreatureManager.Range(-5f, -1f))
				.ConfigureRequiredOceanDepth(new CreatureManager.Range(0f, 0f))
				.ConfigureRequiredWeather(Weather.None)
				.ConfigureForestSpawn(Forest.Both)
				.ConfigureRequiredGlobalKey(GlobalKey.None)
				.ConfigureSpawnChance(10f)
				.ConfigureGroupSize(new CreatureManager.Range(1f, 3f))
				.ConfigureSpawnInterval(1000)
				.ConfigureSpawnTime(SpawnTime.Always)
				.ConfigureMaximum(3)
				.EnableTaming(enabled: false, isConfigurable: false)
				.EnableSpawning()
				.ConfigureHealth(250f)
				.ConfigureRegenAllHpTime(3600f);
			creature15.Localize().Portuguese_Brazilian("Tartaruga Amarela").English("Yellow Turtle");
			creature15.ConfigureDrops();
			creature15.Drops["SA_TurtleMeat"].Amount = new CreatureManager.Range(1f, 2f);
			creature15.Drops["SA_TurtleMeat"].DropChance = 100f;
			GameObject val42 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "SA_blue_atk");
			GameObject val43 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "SA_green_atk");
			GameObject val44 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "SA_red_atk");
			GameObject val45 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "SA_yellow_atk");
			Item item = new Item("mar_seaanimals", "SA_BlueSharkMeat");
			item.Name.Portuguese_Brazilian("Carne de Tubarão Azul");
			item.Name.English("Blue Shark Meat");
			item.Description.Portuguese_Brazilian("Carne crua de Tubarão Azul.");
			item.Description.English("Raw Blue Shark meat.");
			item.Configurable = Configurability.Disabled;
			Item item2 = new Item("mar_seaanimals", "SA_RoastBlueSharkMeat");
			item2.Name.Portuguese_Brazilian("Carne de Tubarão Azul Assada");
			item2.Name.English("Roasted Blue Shark Meat");
			item2.Description.Portuguese_Brazilian("Carne de Tubarão Azul assada.");
			item2.Description.English("Roasted Blue Shark meat.");
			item2.Configurable = Configurability.Stats;
			Item item3 = new Item("mar_seaanimals", "SA_CrocoMeat");
			item3.Name.Portuguese_Brazilian("Carne de Crocodilo");
			item3.Name.English("Crocodile Meat");
			item3.Description.Portuguese_Brazilian("Carne crua de Crocodilo.");
			item3.Description.English("Raw Crocodile meat.");
			item3.Configurable = Configurability.Disabled;
			Item item4 = new Item("mar_seaanimals", "SA_CrocoMeatCook");
			item4.Name.Portuguese_Brazilian("Carne de Crocodilo Assada");
			item4.Name.English("Roasted Crocodile Meat");
			item4.Description.Portuguese_Brazilian("Carne de Crocodilo assada.");
			item4.Description.English("Roasted Crocodile meat.");
			item4.Configurable = Configurability.Stats;
			Item item5 = new Item("mar_seaanimals", "SA_HumboldMeat");
			item5.Name.Portuguese_Brazilian("Carne de Luladrão");
			item5.Name.English("Humboldt Squid Meat");
			item5.Description.Portuguese_Brazilian("Carne de Luladrão");
			item5.Description.English("Raw Humboldt Squid meat.");
			item5.Configurable = Configurability.Disabled;
			Item item6 = new Item("mar_seaanimals", "SA_HumboldMeatCooked");
			item6.Name.Portuguese_Brazilian("Carne de Luladrão Assada");
			item6.Name.English("Roasted Humboldt Squid Meat");
			item6.Description.Portuguese_Brazilian("Carne de Luladrão assada.");
			item6.Description.English("Roasted Humboldt Squid meat.");
			item6.Configurable = Configurability.Stats;
			Item item7 = new Item("mar_seaanimals", "SA_WhaleMeat");
			item7.Name.Portuguese_Brazilian("Carne de Baleia");
			item7.Name.English("Whale Meat");
			item7.Description.Portuguese_Brazilian("Carne crua de Baleia.");
			item7.Description.English("Raw Whale meat.");
			item7.Configurable = Configurability.Disabled;
			Item item8 = new Item("mar_seaanimals", "SA_RoastWhaleMeat");
			item8.Name.Portuguese_Brazilian("Carne de Baleia Assada");
			item8.Name.English("Roasted Whale Meat");
			item8.Description.Portuguese_Brazilian("Carne de Baleia assada.");
			item8.Description.English("Roasted Whale meat.");
			item8.Configurable = Configurability.Stats;
			Item item9 = new Item("mar_seaanimals", "SA_SeaTurtleMeat");
			item9.Name.Portuguese_Brazilian("Carne de Tartaruga Marinha");
			item9.Name.English("Sea Turtle Meat");
			item9.Description.Portuguese_Brazilian("Carne crua de Tartaruga Marinha.");
			item9.Description.English("Raw Sea Turtle meat.");
			item9.Configurable = Configurability.Disabled;
			Item item10 = new Item("mar_seaanimals", "SA_SeaTurtleMeatCooked");
			item10.Name.Portuguese_Brazilian("Carne de Tartaruga Marinha Assada");
			item10.Name.English("Roasted Sea Turtle Meat");
			item10.Description.Portuguese_Brazilian("Carne de Tartaruga Marinha assada.");
			item10.Description.English("Roasted Sea Turtle meat.");
			item10.Configurable = Configurability.Stats;
			Item item11 = new Item("mar_seaanimals", "SA_SharkMeat");
			item11.Name.Portuguese_Brazilian("Carne de Tubarão");
			item11.Name.English("Shark Meat");
			item11.Description.Portuguese_Brazilian("Carne crua de Tubarão.");
			item11.Description.English("Raw Shark meat.");
			item11.Configurable = Configurability.Disabled;
			Item item12 = new Item("mar_seaanimals", "SA_RoastSharkMeat");
			item12.Name.Portuguese_Brazilian("Carne de Tubarão Assada");
			item12.Name.English("Roasted Shark Meat");
			item12.Description.Portuguese_Brazilian("Carne de Tubarão assada.");
			item12.Description.English("Roasted Shark meat.");
			item12.Configurable = Configurability.Stats;
			Item item13 = new Item("mar_seaanimals", "SA_TurtleMeat");
			item13.Name.Portuguese_Brazilian("Carne de Tartaruga");
			item13.Name.English("Turtle Meat");
			item13.Description.Portuguese_Brazilian("Carne crua de Tartaruga.");
			item13.Description.English("Raw Turtle meat.");
			item13.Configurable = Configurability.Disabled;
			Item item14 = new Item("mar_seaanimals", "SA_TurtleMeatCook");
			item14.Name.Portuguese_Brazilian("Carne de Tartaruga Assada");
			item14.Name.English("Roasted Turtle Meat");
			item14.Description.Portuguese_Brazilian("Carne de Tartaruga assada.");
			item14.Description.English("Roasted Turtle meat.");
			item14.Configurable = Configurability.Stats;
			seaanimalscarnes.Add(item.Prefab, item2.Prefab);
			seaanimalscarnes.Add(item3.Prefab, item4.Prefab);
			seaanimalscarnes.Add(item5.Prefab, item6.Prefab);
			seaanimalscarnes.Add(item7.Prefab, item8.Prefab);
			seaanimalscarnes.Add(item9.Prefab, item10.Prefab);
			seaanimalscarnes.Add(item11.Prefab, item12.Prefab);
			seaanimalscarnes.Add(item13.Prefab, item14.Prefab);
			Item item15 = new Item("mar_seaanimals", "SA_Sadle");
			item15.Name.Portuguese_Brazilian("Sela Marítima");
			item15.Name.English("Maritime Saddle");
			item15.Description.Portuguese_Brazilian("Sela Marítima usada para montaria em Orcas, Golfinhos, Crocodilo e Tubarão Branco.");
			item15.Description.English("Maritime Saddle used for riding in Orca, Dolphin, Crocodile and White Shark.");
			item15.Crafting.Add(CraftingTable.Workbench, 1);
			item15.RequiredItems.Add("Wood", 2);
			item15.RequiredItems.Add("DeerHide", 5);
			item15.RequiredItems.Add("LeatherScraps", 5);
			GameObject val46 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_build_hammer_wood_marinelife");
			GameObject val47 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_wood_destroyed_marinelife");
			GameObject val48 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_seaturtle_attack_hit");
			GameObject val49 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "fx_backstab_marinelife");
			GameObject val50 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "fx_crit_marinelife");
			GameObject val51 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "fx_pet_marinelife");
			GameObject val52 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "fx_tamed_marinelife");
			GameObject val53 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_birth_marinelife");
			GameObject val54 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_corpse_medium_marinelife");
			GameObject val55 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_corpse_mini_marinelife");
			GameObject val56 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_corpse_small_marinelife");
			GameObject val57 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_death_marinelife");
			GameObject val58 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_hit_marinelife");
			GameObject val59 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_HitSparks_marinelife");
			GameObject val60 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_love_marinelife");
			GameObject val61 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_Place_wood_pole_marinelife");
			GameObject val62 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_SawDust_marinelife");
			GameObject val63 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_soothed_marinelife");
			GameObject val64 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_wsurface_medium_marinelife");
			GameObject val65 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_wsurface_small_marinelife");
			GameObject val66 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_hurt_marinelife");
			GameObject val67 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_death_seaanimals");
			GameObject val68 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_death_seaanimals_big");
			GameObject val69 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "vfx_death_seaanimals_medium");
			GameObject val70 = ItemManager.PrefabManager.RegisterPrefab("mar_seaanimals", "sfx_hit_seamar");
			SetupWatcher();
			_harmony.PatchAll();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				SeaAnimals.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				SeaAnimals.LogError((object)("There was an issue loading your " + ConfigFileName));
				SeaAnimals.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private ConfigEntry<T> config<[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		private ConfigEntry<T> config<[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		private static int GetZDO(int prefabHash)
		{
			int num = 0;
			List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector;
			foreach (List<ZDO> list in objectsBySector)
			{
				if (list == null)
				{
					continue;
				}
				for (int j = 0; j < list.Count; j++)
				{
					ZDO val = list[j];
					if (val.GetPrefab() == prefabHash)
					{
						num++;
					}
				}
			}
			return num;
		}

		private static int GetPrefabCount(int prefabHash)
		{
			int num = 0;
			List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector;
			foreach (List<ZDO> list in objectsBySector)
			{
				if (list == null)
				{
					continue;
				}
				for (int j = 0; j < list.Count; j++)
				{
					ZDO val = list[j];
					if (val.GetPrefab() == prefabHash)
					{
						num++;
					}
				}
			}
			return num;
		}

		static SeaAnimalsPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			seaanimalscarnes = new Dictionary<GameObject, GameObject>();
			SeaAnimals = Logger.CreateLogSource("SeaAnimals");
			ConfigSync = new ConfigSync("marlthon.SeaAnimals")
			{
				DisplayName = "SeaAnimals",
				CurrentVersion = "0.3.8",
				MinimumRequiredVersion = "0.3.8"
			};
		}
	}
}
namespace PieceManager
{
	[PublicAPI]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	public static class MaterialReplacer
	{
		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)]
		public enum ShaderType
		{
			PieceShader,
			VegetationShader,
			RockShader,
			RugShader,
			GrassShader,
			CustomCreature,
			UseUnityShader
		}

		private static readonly Dictionary<GameObject, bool> ObjectToSwap;

		private static readonly Dictionary<string, Material> OriginalMaterials;

		private static readonly Dictionary<GameObject, ShaderType> ObjectsForShaderReplace;

		private static readonly HashSet<Shader> CachedShaders;

		private static bool hasRun;

		static MaterialReplacer()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			CachedShaders = new HashSet<Shader>();
			hasRun = false;
			OriginalMaterials = new Dictionary<string, Material>();
			ObjectToSwap = new Dictionary<GameObject, bool>();
			ObjectsForShaderReplace = new Dictionary<GameObject, ShaderType>();
			Harmony val = new Harmony("org.bepinex.helpers.PieceManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaterialReplacer), "ReplaceAllMaterialsWithOriginal", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void RegisterGameObjectForShaderSwap(GameObject go, ShaderType type)
		{
			if (!ObjectsForShaderReplace.ContainsKey(go))
			{
				ObjectsForShaderReplace.Add(go, type);
			}
		}

		public static void RegisterGameObjectForMatSwap(GameObject go, bool isJotunnMock = false)
		{
			if (!ObjectToSwap.ContainsKey(go))
			{
				ObjectToSwap.Add(go, isJotunnMock);
			}
		}

		private static void GetAllMaterials()
		{
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			foreach (Material val in array)
			{
				OriginalMaterials[((Object)val).name] = val;
			}
		}

		[HarmonyPriority(700)]
		private static void ReplaceAllMaterialsWithOriginal()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType == 4 || hasRun)
			{
				return;
			}
			if (OriginalMaterials.Count == 0)
			{
				GetAllMaterials();
			}
			foreach (KeyValuePair<GameObject, bool> item in ObjectToSwap)
			{
				GameObject key = item.Key;
				bool value = item.Value;
				ProcessGameObjectMaterials(key, value);
			}
			AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>();
			AssetBundle[] array2 = array;
			foreach (AssetBundle val in array2)
			{
				IEnumerable<Shader> enumerable3;
				try
				{
					IEnumerable<Shader> enumerable2;
					if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val))
					{
						IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>();
						enumerable2 = enumerable;
					}
					else
					{
						enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>)
							where (Object)(object)shader != (Object)null
							select shader;
					}
					enumerable3 = enumerable2;
				}
				catch (Exception)
				{
					continue;
				}
				if (enumerable3 == null)
				{
					continue;
				}
				foreach (Shader item2 in enumerable3)
				{
					CachedShaders.Add(item2);
				}
			}
			foreach (KeyValuePair<GameObject, ShaderType> item3 in ObjectsForShaderReplace)
			{
				GameObject key2 = item3.Key;
				ShaderType value2 = item3.Value;
				ProcessGameObjectShaders(key2, value2);
			}
			hasRun = true;
		}

		private static void ProcessGameObjectMaterials(GameObject go, bool isJotunnMock)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Material[] sharedMaterials = val.sharedMaterials.Select([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Material material) => ReplaceMaterial(material, isJotunnMock)).ToArray();
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static Material ReplaceMaterial(Material originalMaterial, bool isJotunnMock)
		{
			string text = (isJotunnMock ? "JVLmock_" : "_REPLACE_");
			if (!((Object)originalMaterial).name.StartsWith(text, StringComparison.Ordinal))
			{
				return originalMaterial;
			}
			string text2 = ((Object)originalMaterial).name.Replace(" (Instance)", "").Replace(text, "");
			if (OriginalMaterials.TryGetValue(text2, out var value))
			{
				return value;
			}
			Debug.LogWarning((object)("No suitable material found to replace: " + text2));
			return originalMaterial;
		}

		private static void ProcessGameObjectShaders(GameObject go, ShaderType shaderType)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						val2.shader = GetShaderForType(val2.shader, shaderType, ((Object)val2.shader).name);
					}
				}
			}
		}

		private static Shader GetShaderForType(Shader orig, ShaderType shaderType, string originalShaderName)
		{
			return (Shader)(shaderType switch
			{
				ShaderType.PieceShader => FindShaderWithName(orig, "Custom/Piece"), 
				ShaderType.VegetationShader => FindShaderWithName(orig, "Custom/Vegetation"), 
				ShaderType.RockShader => FindShaderWithName(orig, "Custom/StaticRock"), 
				ShaderType.RugShader => FindShaderWithName(orig, "Custom/Rug"), 
				ShaderType.GrassShader => FindShaderWithName(orig, "Custom/Grass"), 
				ShaderType.CustomCreature => FindShaderWithName(orig, "Custom/Creature"), 
				ShaderType.UseUnityShader => FindShaderWithName(orig, ((Object)(object)FindShaderWithName(orig, originalShaderName) != (Object)null) ? originalShaderName : "ToonDeferredShading2017"), 
				_ => FindShaderWithName(orig, "Standard"), 
			});
		}

		public static Shader FindShaderWithName(Shader origShader, string name)
		{
			foreach (Shader cachedShader in CachedShaders)
			{
				if (((Object)cachedShader).name == name)
				{
					return cachedShader;
				}
			}
			return origShader;
		}
	}
	[PublicAPI]
	public enum CraftingTable
	{
		None,
		[InternalName("piece_workbench")]
		Workbench,
		[InternalName("piece_cauldron")]
		Cauldron,
		[InternalName("forge")]
		Forge,
		[InternalName("piece_artisanstation")]
		ArtisanTable,
		[InternalName("piece_stonecutter")]
		StoneCutter,
		[InternalName("piece_magetable")]
		MageTable,
		[InternalName("blackforge")]
		BlackForge,
		[InternalName("piece_preptable")]
		FoodPreparationTable,
		[InternalName("piece_MeadCauldron")]
		MeadKetill,
		Custom
	}
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[PublicAPI]
	public class ExtensionList
	{
		public readonly List<ExtensionConfig> ExtensionStations = new List<ExtensionConfig>();

		public void Set(CraftingTable table, int maxStationDistance = 5)
		{
			ExtensionStations.Add(new ExtensionConfig
			{
				Table = table,
				maxStationDistance = maxStationDistance
			});
		}

		public void Set(string customTable, int maxStationDistance = 5)
		{
			ExtensionStations.Add(new ExtensionConfig
			{
				Table = CraftingTable.Custom,
				custom = customTable,
				maxStationDistance = maxStationDistance
			});
		}
	}
	public struct ExtensionConfig
	{
		public CraftingTable Table;

		public float maxStationDistance;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		public string custom;
	}
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[PublicAPI]
	public class CraftingStationList
	{
		public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>();

		public void Set(CraftingTable table)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = table
			});
		}

		public void Set(string customTable)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = CraftingTable.Custom,
				custom = customTable
			});
		}
	}
	public struct CraftingStationConfig
	{
		public CraftingTable Table;

		public int level;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		public string custom;
	}
	[PublicAPI]
	public enum BuildPieceCategory
	{
		Misc = 0,
		Crafting = 1,
		BuildingWorkbench = 2,
		BuildingStonecutter = 3,
		Furniture = 4,
		DeepNorth = 5,
		Feasts = 6,
		Food = 7,
		Meads = 8,
		All = 100,
		Custom = 99
	}
	[PublicAPI]
	public class PieceUsage
	{
		public UsageTagFlags Tags;

		public void Add(UsageTagFlags tag)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Tags |= tag;
		}

		public void Set(UsageTagFlags tags)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Tags = tags;
		}
	}
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[PublicAPI]
	public class RequiredResourcesList
	{
		public readonly List<Requirement> Requirements = new List<Requirement>();

		public void Add(string item, int amount, bool recover)
		{
			Requirements.Add(new Requirement
			{
				itemName = item,
				amount = amount,
				recover = recover
			});
		}
	}
	public struct Requirement
	{
		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(1)]
		public string itemName;

		public int amount;

		public bool recover;
	}
	public struct SpecialProperties
	{
		[Description("Admins should be the only ones that can build this piece.")]
		public bool AdminOnly;

		[Description("Turns off generating a config for this build piece.")]
		public bool NoConfig;
	}
	[PublicAPI]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	public class BuildingPieceCategory
	{
		public BuildPieceCategory Category;

		public string custom = "";

		public void Set(BuildPieceCategory category)
		{
			Category = category;
		}

		public void Set(string customCategory)
		{
			Category = BuildPieceCategory.Custom;
			custom = customCategory;
		}
	}
	[PublicAPI]
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	public class PieceTool
	{
		public readonly HashSet<string> Tools = new HashSet<string>();

		public void Add(string tool)
		{
			Tools.Add(tool);
		}
	}
	[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
	[PublicAPI]
	[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(1)]
	public class BuildPiece
	{
		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
		internal class PieceConfig
		{
			public ConfigEntry<string> craft = null;

			public ConfigEntry<BuildPieceCategory> category = null;

			public ConfigEntry<string> customCategory = null;

			public ConfigEntry<UsageTagFlags> usage = null;

			public ConfigEntry<string> tools = null;

			public ConfigEntry<CraftingTable> extensionTable = null;

			public ConfigEntry<string> customExtentionTable = null;

			public ConfigEntry<float> maxStationDistance = null;

			public ConfigEntry<CraftingTable> table = null;

			public ConfigEntry<string> customTable = null;
		}

		[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
			public string Category;

			[UsedImplicitly]
			[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(new byte[] { 2, 1 })]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(0)]
		private class SerializedRequirements
		{
			public readonly List<Requirement> Reqs;

			public SerializedRequirements(List<Requirement> reqs)
			{
				Reqs = reqs;
			}

			public SerializedRequirements(string reqs)
			{
				Reqs = reqs.Split(new char[1] { ',' }).Select([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (string r) =>
				{
					string[] array = r.Split(new char[1] { ':' });
					int result;
					bool result2 = default(bool);
					return new Requirement
					{
						itemName = array[0],
						amount = ((array.Length <= 1 || !int.TryParse(array[1], out result)) ? 1 : result),
						recover = (array.Length <= 2 || !bool.TryParse(array[2], out result2) || result2)
					};
				}).ToList();
			}

			public override string ToString()
			{
				return string.Join(",", Reqs.Select([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Requirement r) => $"{r.itemName}:{r.amount}:{r.recover}"));
			}

			[return: <2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
			public static ItemDrop fetchByName(ObjectDB objectDB, string name)
			{
				GameObject itemPrefab = objectDB.GetItemPrefab(name);
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Debug.LogWarning((object)(((!string.IsNullOrWhiteSpace(((Object)plugin).name)) ? ("[" + ((Object)plugin).name + "]") : "") + " The required item '" + name + "' does not exist."));
				}
				return val;
			}

			public static Requirement[] toPieceReqs(SerializedRequirements craft)
			{
				Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Requirement r) => r.itemName), (Func<Requirement, Requirement>)([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Requirement r) =>
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0025: Unknown result type (might be due to invalid IL or missing references)
					ItemDrop val = ResItem(r);
					return (val == null) ? ((Requirement)null) : new Requirement
					{
						m_amount = r.amount,
						m_resItem = val,
						m_recover = r.recover
					};
				}));
				return dictionary.Values.Where([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Requirement v) => v != null).ToArray();
				[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(2)]
				static ItemDrop ResItem(Requirement r)
				{
					return fetchByName(ObjectDB.instance, r.itemName);
				}
			}
		}

		internal static readonly List<BuildPiece> registeredPieces = new List<BuildPiece>();

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(new byte[] { 1, 0, 1 })]
		private static readonly Queue<(GameObject prefab, float lightIntensity, Quaternion? camRot)> _snapshotQueue = new Queue<(GameObject, float, Quaternion?)>();

		private static readonly Dictionary<Piece, BuildPiece> pieceMap = new Dictionary<Piece, BuildPiece>();

		internal static Dictionary<BuildPiece, PieceConfig> pieceConfigs = new Dictionary<BuildPiece, PieceConfig>();

		internal List<Conversion> Conversions = new List<Conversion>();

		internal List<ItemConversion> conversions = new List<ItemConversion>();

		[Description("Disables generation of the configs for your pieces. This is global, this turns it off for all pieces in your mod.")]
		public static bool ConfigurationEnabled = true;

		public readonly GameObject Prefab;

		[Description("Specifies the resources needed to craft the piece.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the building piece should need.")]
		public readonly RequiredResourcesList RequiredItems = new RequiredResourcesList();

		[Description("Sets the category for the building piece.")]
		public readonly BuildingPieceCategory Category = new BuildingPieceCategory();

		[Description("Sets which tags the piece is listed under in the build menu.\nLeave it empty and one gets picked from the category.")]
		public readonly PieceUsage Usage = new PieceUsage();

		[Description("Specifies the tool needed to build your piece.\nUse .Add to add a tool.")]
		public readonly PieceTool Tool = new PieceTool();

		[Description("Specifies the crafting station needed to build your piece.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.")]
		public CraftingStationList Crafting = new CraftingStationList();

		[Description("Makes this piece a station extension")]
		public ExtensionList Extension = new ExtensionList();

		[Description("Change the extended/special properties of your build piece.")]
		public SpecialProperties SpecialProperties;

		[Description("Specifies a config entry which toggles whether a recipe is active.")]
		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		public ConfigEntryBase RecipeIsActive = null;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private LocalizeKey _name;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private LocalizeKey _description;

		internal string[] activeTools = null;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private static object configManager;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private static Localization _english;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		internal static BaseUnityPlugin _plugin = null;

		private static bool hasConfigSync = true;

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private static object _configSync;

		public LocalizeKey Name
		{
			get
			{
				LocalizeKey name = _name;
				if (name != null)
				{
					return name;
				}
				Piece component = Prefab.GetComponent<Piece>();
				if (component.m_name.StartsWith("$"))
				{
					_name = new LocalizeKey(component.m_name);
				}
				else
				{
					string text = "$piece_" + ((Object)Prefab).name.Replace(" ", "_");
					_name = new LocalizeKey(text).English(component.m_name);
					component.m_name = text;
				}
				return _name;
			}
		}

		public LocalizeKey Description
		{
			get
			{
				LocalizeKey description = _description;
				if (description != null)
				{
					return description;
				}
				Piece component = Prefab.GetComponent<Piece>();
				if (component.m_description.StartsWith("$"))
				{
					_description = new LocalizeKey(component.m_description);
				}
				else
				{
					string text = "$piece_" + ((Object)Prefab).name.Replace(" ", "_") + "_description";
					_description = new LocalizeKey(text).English(component.m_description);
					component.m_description = text;
				}
				return _description;
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		internal static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Expected O, but got Unknown
				if (_plugin != null)
				{
					return _plugin;
				}
				IEnumerable<TypeInfo> source;
				try
				{
					source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
				}
				catch (ReflectionTypeLoadException ex)
				{
					source = from t in ex.Types
						where t != null
						select t.GetTypeInfo();
				}
				_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				return _plugin;
			}
		}

		[<2dc67916-7bee-45d9-affd-2c5a7b8c583c>Nullable(2)]
		private static object configSync
		{
			[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(2)]
			get
			{
				if (_configSync != null || !hasConfigSync)
				{
					return _configSync;
				}
				Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
				if ((object)type != null)
				{
					_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " PieceManager");
					type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
					type.GetProperty("IsLocked").SetValue(_configSync, true);
				}
				else
				{
					hasConfigSync = false;
				}
				return _configSync;
			}
		}

		public BuildPiece(string assetBundleFileName, string prefabName, string folderName = "assets")
			: this(PiecePrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName)
		{
		}

		public BuildPiece(AssetBundle bundle, string prefabName)
		{
			Prefab = PiecePrefabManager.RegisterPrefab(bundle, prefabName);
			registeredPieces.Add(this);
		}

		internal static void Patch_FejdStartup(FejdStartup __instance)
		{
			//IL_00f7: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Invalid comparison between Unknown and I4
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Invalid comparison between Unknown and I4
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Expected O, but got Unknown
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Expected O, but got Unknown
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Expected O, but got Unknown
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Expected O, but got Unknown
			//IL_0788: Unknown result type (might be due to invalid IL or missing references)
			//IL_0792: Expected O, but got Unknown
			//IL_0a6c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a76: Expected O, but got Unknown
			//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0807: Expected O, but got Unknown
			//IL_08a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ad: Expected O, but got Unknown
			//IL_0ae1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aeb: Expected O, but got Unknown
			//IL_0d00: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d0a: Expected O, but got Unknown
			//IL_0d9a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0da4: Expected O, but got Unknown
			Type configManagerType = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager");
			configManager = ((configManagerType == null) ? null : Chainloader.ManagerObject.GetComponent(configManagerType));
			foreach (BuildPiece registeredPiece in registeredPieces)
			{
				registeredPiece.activeTools = registeredPiece.Tool.Tools.DefaultIfEmpty("Hammer").ToArray();
				Piece component = registeredPiece.Prefab.GetComponent<Piece>();
				if (registeredPiece.Category.Category != BuildPieceCategory.Custom)
				{
					component.m_category = (PieceCategory)registeredPiece.Category.Category;
				}
				else
				{
					component.m_category = PiecePrefabManager.GetCategory(registeredPiece.Category.custom);
				}
				if ((int)registeredPiece.Usage.Tags > 0)
				{
					component.m_usage = registeredPiece.Usage.Tags;
				}
				else if ((int)component.m_usage == 0)
				{
					component.m_usage = DefaultUsageFor(component.m_category);
				}
				if (registeredPiece.Category.Category == BuildPieceCategory.Custom)
				{
					component.m_usage |= PiecePrefabManager.GetCustomTag(registeredPiece.Category.custom);
				}
			}
			if (!ConfigurationEnabled)
			{
				return;
			}
			bool saveOnConfigSet = plugin.Config.SaveOnConfigSet;
			plugin.Config.SaveOnConfigSet = false;
			foreach (BuildPiece registeredPiece2 in registeredPieces)
			{
				BuildPiece piece = registeredPiece2;
				if (piece.SpecialProperties.NoConfig)
				{
					continue;
				}
				PieceConfig pieceConfig = (pieceConfigs[piece] = new PieceConfig());
				PieceConfig cfg = pieceConfig;
				Piece piecePrefab = piece.Prefab.GetComponent<Piece>();
				string pieceName = piecePrefab.m_name;
				string englishName = new Regex("[=\\n\\t\\\\\"\\'\\[\\]]*").Replace(english.Localize(pieceName), "").Trim();
				string localizedName = Localization.instance.Localize(pieceName).Trim();
				int order = 0;
				cfg.category = config(englishName, "Build Table Category", piece.Category.Category, new ConfigDescription("Build Category where " + localizedName + " is available.", (AcceptableValueBase)null, new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Order = (order -= 1),
						Category = localizedName
					}
				}));
				ConfigurationManagerAttributes customTableAttributes = new ConfigurationManagerAttributes
				{
					Order = (order -= 1),
					Browsable = (cfg.category.Value == BuildPieceCategory.Custom),
					Category = localizedName
				};
				cfg.customCategory = config(englishName, "Custom Build Category", piece.Category.custom, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes }));
				cfg.category.SettingChanged += BuildTableConfigChanged;
				cfg.customCategory.SettingChanged += BuildTableConfigChanged;
				if (cfg.category.Value == BuildPieceCategory.Custom)
				{
					piecePrefab.m_category = PiecePrefabManager.GetCategory(cfg.customCategory.Value);
				}
				else
				{
					piecePrefab.m_category = (PieceCategory)cfg.category.Value;
				}
				UsageTagFlags customTag = (UsageTagFlags)((cfg.category.Value == BuildPieceCategory.Custom) ? ((int)PiecePrefabManager.GetCustomTag(cfg.customCategory.Value)) : 0);
				cfg.usage = config<UsageTagFlags>(englishName, "Build Menu Tags", (UsageTagFlags)(piecePrefab.m_usage & ~customTag), new ConfigDescription("Tags " + localizedName + " is listed under in the build menu.", (AcceptableValueBase)null, new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Order = (order -= 1),
						Category = localizedName
					}
				}));
				piecePrefab.m_usage = (UsageTagFlags)(cfg.usage.Value | customTag);
				cfg.usage.SettingChanged += [<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (object _, EventArgs _) =>
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					piecePrefab.m_usage = (UsageTagFlags)(cfg.usage.Value | customTag);
					PiecePrefabManager.RefreshBuildMenu();
				};
				cfg.tools = config(englishName, "Tools", string.Join(", ", piece.activeTools), new ConfigDescription("Comma separated list of tools where " + localizedName + " is available.", (AcceptableValueBase)null, new object[1] { customTableAttributes }));
				piece.activeTools = (from s in cfg.tools.Value.Split(new char[1] { ',' })
					select s.Trim()).ToArray();
				cfg.tools.SettingChanged += [<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (object _, EventArgs _) =>
				{
					Inventory[] source = (from c in Player.s_players.Select([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsByType<Container>((FindObjectsSortMode)0)
							select c.GetInventory())
						where c != null
						select c).ToArray();
					Dictionary<string, List<PieceTable>> dictionary = (from kv in (from i in (from p in ObjectDB.instance.m_items
								select p.GetComponent<ItemDrop>() into c
								where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent<ZNetView>())
								select c).Concat(ItemDrop.s_instances)
							select new KeyValuePair<string, ItemData>(Utils.GetPrefabName(((Component)i).gameObject), i.m_itemData)).Concat(from i in source.SelectMany([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (Inventory i) => i.GetAllItems())
							select new KeyValuePair<string, ItemData>(((Object)i.m_dropPrefab).name, i))
						where Object.op_Implicit((Object)(object)kv.Value.m_shared.m_buildPieces)
						group kv by kv.Key).ToDictionary([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (IGrouping<string, KeyValuePair<string, ItemData>> g) => g.Key, [<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (IGrouping<string, KeyValuePair<string, ItemData>> g) => g.Select([<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (KeyValuePair<string, ItemData> kv) => kv.Value.m_shared.m_buildPieces).Distinct().ToList());
					string[] array4 = piece.activeTools;
					foreach (string key in array4)
					{
						if (dictionary.TryGetValue(key, out var value))
						{
							foreach (PieceTable item3 in value)
							{
								item3.m_pieces.Remove(piece.Prefab);
							}
						}
					}
					piece.activeTools = (from s in cfg.tools.Value.Split(new char[1] { ',' })
						select s.Trim()).ToArray();
					if (Object.op_Implicit((Object)(object)ObjectDB.instance))
					{
						string[] array5 = piece.activeTools;
						foreach (string key2 in array5)
						{
							if (dictionary.TryGetValue(key2, out var value2))
							{
								foreach (PieceTable item4 in value2)
								{
									if (!item4.m_pieces.Contains(piece.Prefab))
									{
										item4.m_pieces.Add(piece.Prefab);
									}
								}
							}
						}
						if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)Player.m_localPlayer.m_buildPieces))
						{
							PiecePrefabManager.CategoryRefreshNeeded = true;
							PiecePrefabManager.RefreshBuildMenu();
							((Humanoid)Player.m_localPlayer).SetPlaceMode(Player.m_localPlayer.m_buildPieces);
						}
					}
				};
				StationExtension pieceExtensionComp;
				List<ConfigurationManagerAttributes> hideWhenNoneAttributes;
				if (piece.Extension.ExtensionStations.Count > 0)
				{
					pieceExtensionComp = piece.Prefab.GetOrAddComponent<StationExtension>();
					PieceConfig pieceConfig3 = cfg;
					string text = englishName;
					CraftingTable table = piece.Extension.ExtensionStations.First().Table;
					string text2 = "Crafting station that " + localizedName + " extends.";
					object[] array = new object[1];
					ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes();
					int num = order - 1;
					order = num;
					configurationManagerAttributes.Order = num;
					array[0] = configurationManagerAttributes;
					pieceConfig3.extensionTable = config(text, "Extends Station", table, new ConfigDescription(text2, (AcceptableValueBase)null, array));
					cfg.customExtentionTable = config(englishName, "Custom Extend Station", piece.Extension.ExtensionStations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes }));
					PieceConfig pieceConfig4 = cfg;
					string text3 = englishName;
					float maxStationDistance = piece.Extension.ExtensionStations.First().maxStationDistance;
					string text4 = "Distance from the station that " + localizedName + " can be placed.";
					object[] array2 = new object[1];
					ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes();
					num = order - 1;
					order = num;
					configurationManagerAttributes2.Order = num;
					array2[0] = configurationManagerAttributes2;
					pieceConfig4.maxStationDistance = config(text3, "Max Station Distance", maxStationDistance, new ConfigDescription(text4, (AcceptableValueBase)null, array2));
					hideWhenNoneAttributes = new List<ConfigurationManagerAttributes>();
					cfg.extensionTable.SettingChanged += ExtensionTableConfigChanged;
					cfg.customExtentionTable.SettingChanged += ExtensionTableConfigChanged;
					cfg.maxStationDistance.SettingChanged += ExtensionTableConfigChanged;
					ConfigurationManagerAttributes configurationManagerAttributes3 = new ConfigurationManagerAttributes();
					num = order - 1;
					order = num;
					configurationManagerAttributes3.Order = num;
					configurationManagerAttributes3.Browsable = cfg.extensionTable.Value != CraftingTable.None;
					ConfigurationManagerAttributes item = configurationManagerAttributes3;
					hideWhenNoneAttributes.Add(item);
				}
				List<ConfigurationManagerAttributes> hideWhenNoneAttributes2;
				if (piece.Crafting.Stations.Count > 0)
				{
					hideWhenNoneAttributes2 = new List<ConfigurationManagerAttributes>();
					PieceConfig pieceConfig5 = cfg;
					string text5 = englishName;
					CraftingTable table2 = piece.Crafting.Stations.First().Table;
					string text6 = "Crafting station where " + localizedName + " is available.";
					object[] array3 = new object[1];
					ConfigurationManagerAttributes configurationManagerAttributes4 = new ConfigurationManagerAttributes();
					int num = order - 1;
					order = num;
					configurationManagerAttributes4.Order = num;
					array3[0] = configurationManagerAttributes4;
					pieceConfig5.table = config(text5, "Crafting Station", table2, new ConfigDescription(text6, (AcceptableValueBase)null, array3));
					cfg.customTable = config(englishName, "Custom Crafting Station", piece.Crafting.Stations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes }));
					cfg.table.SettingChanged += TableConfigChanged;
					cfg.customTable.SettingChanged += TableConfigChanged;
					ConfigurationManagerAttributes configurationManagerAttributes5 = new ConfigurationManagerAttributes();
					num = order - 1;
					order = num;
					configurationManagerAttributes5.Order = num;
					configurationManagerAttributes5.Browsable = cfg.table.Value != CraftingTable.None;
					ConfigurationManagerAttributes item2 = configurationManagerAttributes5;
					hideWhenNoneAttributes2.Add(item2);
				}
				cfg.craft = itemConfig("Crafting Costs", new SerializedRequirements(piece.RequiredItems.Requirements).ToString(), "Item costs to craft " + localizedName);
				cfg.craft.SettingChanged += [<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (object _, EventArgs _) =>
				{
					if (Object.op_Implicit((Object)(object)ObjectDB.instance) && (Object)(object)ObjectDB.instance.GetItemPrefab("YmirRemains") != (Object)null)
					{
						Requirement[] resources = SerializedRequirements.toPieceReqs(new SerializedRequirements(cfg.craft.Value));
						piecePrefab.m_resources = resources;
						Piece[] array4 = Object.FindObjectsByType<Piece>((FindObjectsSortMode)0);
						foreach (Piece val in array4)
						{
							if (val.m_name == pieceName)
							{
								val.m_resources = resources;
							}
						}
					}
				};
				for (int num2 = 0; num2 < piece.Conversions.Count; num2++)
				{
					string text7 = ((piece.Conversions.Count > 1) ? $"{num2 + 1}. " : "");
					Conversion conversion = piece.Conversions[num2];
					conversion.config = new Conversion.ConversionConfig();
					int index = num2;
					conversion.config.input = config(englishName, text7 + "Conversion Input Item", conversion.Input, new ConfigDescription("Conversion input item within " + englishName, (AcceptableValueBase)null, new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = localizedName
						}
					}));
					conversion.config.input.SettingChanged += [<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (object _, EventArgs _) =>
					{
						if (index < piece.conversions.Count)
						{
							ObjectDB instance = ObjectDB.instance;
							if (instance != null)
							{
								ItemDrop val = SerializedRequirements.fetchByName(instance, conversion.config.input.Value);
								piece.conversions[index].m_from = val;
							}
						}
					};
					conversion.config.output = config(englishName, text7 + "Conversion Output Item", conversion.Output, new ConfigDescription("Conversion output item within " + englishName, (AcceptableValueBase)null, new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = localizedName
						}
					}));
					conversion.config.output.SettingChanged += [<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(0)] (object _, EventArgs _) =>
					{
						if (index < piece.conversions.Count)
						{
							ObjectDB instance = ObjectDB.instance;
							if (instance != null)
							{
								ItemDrop to = SerializedRequirements.fetchByName(instance, conversion.config.output.Value);
								piece.conversions[index].m_to = to;
							}
						}
					};
				}
				void BuildTableConfigChanged(object o, EventArgs e)
				{
					//IL_0066: Unknown result type (might be due to invalid IL or missing references)
					//IL_0042: Unknown result type (might be due to invalid IL or missing references)
					//IL_0047: Unknown result type (might be due to invalid IL or missing references)
					if (registeredPieces.Count > 0)
					{
						if (cfg.category.Value == BuildPieceCategory.Custom)
						{
							piecePrefab.m_category = PiecePrefabManager.GetCategory(cfg.customCategory.Value);
						}
						else
						{
							piecePrefab.m_category = (PieceCategory)cfg.category.Value;
						}
						if (Object.op_Implicit((Object)(object)Hud.instance))
						{
							PiecePrefabManager.CategoryRefreshNeeded = true;
							PiecePrefabManager.CreateCategoryTabs();
							PiecePrefabManager.RefreshBuildMenu();
						}
					}
					customTableAttributes.Browsable = cfg.category.Value == BuildPieceCategory.Custom;
					ReloadConfigDisplay();
				}
				void ExtensionTableConfigChanged(object o, EventArgs e)
				{
					if (piece.RequiredItems.Requirements.Count > 0)
					{
						CraftingTable value = cfg.extensionTable.Value;
						CraftingTable craftingTable = value;
						if (craftingTable == CraftingTable.Custom)
						{
							StationExtension obj = pieceExtensionComp;
							GameObject prefab = ZNetScene.instance.GetPrefab(cfg.customExtentionTable.Value);
							obj.m_craftingStation = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
						}
						else
						{
							pieceExtensionComp.m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(cfg.extensionTable.Value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent<CraftingStation>();
						}
						pieceExtensionComp.m_maxStationDistance = cfg.maxStationDistance.Value;
					}
					customTableAttributes.Browsable = cfg.extensionTable.Value == CraftingTable.Custom;
					foreach (ConfigurationManagerAttributes item5 in hideWhenNoneAttributes)
					{
						item5.Browsable = cfg.extensionTable.Value != CraftingTable.None;
					}
					ReloadConfigDisplay();
					plugin.Config.Save();
				}
				void TableConfigChanged(object o, EventArgs e)
				{
					if (piece.RequiredItems.Requirements.Count > 0)
					{
						switch (cfg.table.Value)
						{
						case CraftingTable.None:
							piecePrefab.m_craftingStation = null;
							break;
						case CraftingTable.Custom:
						{
							Piece obj = piecePrefab;
							GameObject prefab = ZNetScene.instance.GetPrefab(cfg.customTable.Value);
							obj.m_craftingStation = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
							break;
						}
						default:
							piecePrefab.m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(cfg.table.Value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent<CraftingStation>();
							break;
						}
					}
					customTableAttributes.Browsable = cfg.table.Value == CraftingTable.Custom;
					foreach (ConfigurationManagerAttributes item6 in hideWhenNoneAttributes2)
					{
						item6.Browsable = cfg.table.Value != CraftingTable.None;
					}
					ReloadConfigDisplay();
					plugin.Config.Save();
				}
				ConfigEntry<string> itemConfig(string name, string value, string desc)
				{
					//IL_0066: Unknown result type (might be due to invalid IL or missing references)
					//IL_0070: Expected O, but got Unknown
					ConfigurationManagerAttributes configurationManagerAttributes6 = new ConfigurationManagerAttributes
					{
						CustomDrawer = DrawConfigTable,
						Order = (order -= 1),
						Category = localizedName
					};
					return config(englishName, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes6 }));
				}
			}
			foreach (BuildPiece registeredPiece3 in registeredPieces)
			{
				ConfigEntryBase enabledCfg = registeredPiece3.RecipeIsActive;
				Piece piecePrefab2;
				if (enabledCfg != null)
				{
					piecePrefab2 = registeredPiece3.Prefab.GetComponent<Piece>();
					ConfigChanged(null, null);
					((object)enabledCfg).GetType().GetEvent("SettingChanged").AddEventHandler(enabledCfg, new EventHandler(ConfigChanged));
				}
				registeredPiece3.InitializeNewRegisteredPiece(registeredPiece3);
				[<5ef510cc-27a7-4857-bd6d-7b053ae45128>NullableContext(2)]
				void ConfigChanged(object o, EventArgs e)
				{
					piecePrefab2.m_enabled = (int)enabledCfg.BoxedValue != 0;
				}
			}
			if (saveOnConfigSet)
			{
				plugin.Config.SaveOnConfigSet = true;
				plugin.Config.Save();
			}
			void ReloadConfigDisplay()
			{
				if (configManagerType?.GetProperty("DisplayingWindow").GetValue(configManager) is int num3 && num3 != 0)
				{
					configManagerType.GetMethod("BuildSettingList").Invoke(configManager, Array.Empty<object>());
				}
			}
		}

		private static UsageTagFlags DefaultUsageFor(PieceCategory category)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected I4, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (1 == 0)
			{
			}
			UsageTagFlags result;
			switch (category - 1)
			{
			case 0:
				result = (UsageTagFlags)2;
				break;
			case 1:
			case 2:
				result = (UsageTagFlags)4;
				break;
			case 3:
				result = (UsageTagFlags)128;
				break;
			case 6:
				result = (UsageTagFlags)4096;
				break;
			case 7:
				result = (UsageTagFlags)8192;
				break;
			case 5:
				result = (UsageTagFlags)16384;
				break;
			default:
				result = (UsageTagFlags)1;
				break;
			}
			if (1 == 0)
			{
			}
			return result;
		}

		private void InitializeNewRegisteredPiece(BuildPiece piece)
		{
			ConfigEntryBase recipeIsActive = piece.RecipeIsActive;
			PieceConfig cfg;
			Piece piecePrefab;
			string pieceName;
			if (recipeIsActive != null)
			{
				pieceConfigs.TryGetValue(piece, out cfg);
				piecePrefab = piece.Prefab.GetComponent<Piece>();
				pieceName = piecePrefab.m_name;
				((object)recipeIsActive).GetType().GetEvent("SettingChanged").AddEventHandler(recipeIsActive, new EventHandler(ConfigChanged));
			}
			void ConfigChanged(object o, EventArgs e)
			{
				if (Object.op_Implicit((Object)(object)ObjectDB.instance) && (Object)(object)ObjectDB.instance.GetItemPrefab("YmirRemains") != (Object)null && cfg != null)
				{
					Requirement[] resources = SerializedRequirements.toPieceReqs(new SerializedRequirements(cfg.craft.Value));
					piecePrefab.m_resources = resources;
					Piece[] array = Object.FindObjectsByType<Piece>((FindObjectsSortMode)0);
					foreach (Piece val in array)
					{
						if (val.m_name == pieceName)
						{
							val.m_resources = resources;
						}
					}
				}
			}
		}

		[HarmonyPriority(700)]
		internal static void Patch_ObjectDBInit(ObjectDB __instance)
		{
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Expected O, but got Unknown
			if ((Object)(object)__instance.GetItemPrefab("YmirRemains") == (Object)null)
			{
				return;
			}
			foreach (BuildPiece registeredPiece in registeredPieces)
			{
				pieceConfigs.TryGetValue(registeredPiece, out var value);
				registeredPiece.Prefab.GetComponent<Piece>().m_resources = SerializedRequirements.toPieceReqs((value == null) ? new SerializedRequirements(registeredPiece.RequiredItems.Requirements) : new SerializedRequirements(value.craft.Value));
				foreach (ExtensionConfig extensionStation in registeredPiece.Extension.ExtensionStations)
				{
					switch ((value == null || registeredPiece.Extension.ExtensionStations.Count > 1) ? extensionStation.Table : value.extensionTable.Value)
					{
					case CraftingTable.None:
						registeredPiece.Prefab.GetComponent<StationExtension>().m_craftingStation = null;
						break;
					case CraftingTable.Custom:
					{
						GameObject prefab = ZNetScene.instance.GetPrefab((value == null || registeredPiece.Extension.ExtensionStations.Count > 0) ? extensionStation.custom : value.customExtentionTable.Value);
						if (prefab != null)
						{
							registeredPiece.Prefab.GetComponent<StationExtension>().m_craftingStation = prefab.GetComponent<CraftingStation>();
						}
						else
						{
							Debug.LogWarning((object)("Custom crafting station '" + ((value == null || registeredPiece.Extension.ExtensionStations.Count > 0) ? extensionStation.custom : value.customExtentionTable.Value) + "' does not exist"));
						}
						break;
					}
					default:
						if (value != null && value.table.Value == CraftingTable.None)
						{
							registeredPiece.Prefab.GetComponent<StationExtension>().m_craftingStation = null;
						}
						else
						{
							registeredPiece.Prefab.GetComponent<StationExtension>().m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(((value == null || registeredPiece.Extension.ExtensionStations.Count > 1) ? extensionStation.Table : value.extensionTable.Value).ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent<CraftingStation>();
						}
						break;
					}
				}
				foreach (CraftingStationConfig station in registeredPiece.Crafting.Stations)
				{
					switch ((value == null || registeredPiece.Crafting.Stations.Count > 1) ? station.Table : value.table.Value)
					{
					case CraftingTable.None:
						registeredPiece.Prefab.GetComponent<Piece>().m_craftingStation = null;
						break;
					case CraftingTable.Custom:
					{
						GameObject prefab2 = ZNetScene.instance.GetPrefab((value == null || registeredPiece.Crafting.Stations.Count > 0) ? station.custom : value.customTable.Value);
						if (prefab2 != null)
						{
							registeredPiece.Prefab.GetComponent<Piece>().m_craftingStation = prefab2.GetComponent<CraftingStation>();
						}
						else
						{
							Debug.LogWarning((object)("Custom crafting station '" + ((value == null || registeredPiece.Crafting.Stations.Count > 0) ? station.custom : value.customTable.Value) + "' does not exist"));
						}
						break;
					}
					default:
						if (value != null && value.table.Value == CraftingTable.None)
						{
							registeredPiece.Prefab.GetComponent<Piece>().m_craftingStation = null;
						}
						else
						{
							registeredPiece.Prefab.GetComponent<Piece>().m_craftingStation = ZNetScene.instance.GetPrefab(((InternalName)typeof(CraftingTable).GetMember(((value == null || registeredPiece.Crafting.Stations.Count > 1) ? station.Table : value.table.Value).ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).GetComponent<CraftingStation>();
						}
						break;
					}
				}
				registeredPiece.conversions = new List<ItemConversion>();
				for (int i = 0; i < registeredPiece.Conversions.Count; i++)
				{
					Conversion conversion = registeredPiece.Conversions[i];
					registeredPiece.conversions.Add(new ItemConversion
					{
						m_from = SerializedRequirements.fetchByName(ObjectDB.instance, conversion.config?.input.Value ?? conversion.Input),
						m_to = SerializedRequirements.fetchByName(ObjectDB.instance, conversion.config?.output.Value ?? conversion.Output)
					});
					if (registeredPiece.conversions[i].m_from != null && registeredPiece.conversions[i].m_to != null)
					{
						registeredPiece.Prefab.GetComponent<Smelter>().m_conversion.Add(registeredPiece.conversions[i]);
					}
				}
			}
		}

		public void Snapshot(float lightIntensity = 1.3f, Quaternion? cameraRotation = null)
		{
			QueueSnapshot(Prefab, lightIntensity, cameraRotation);
		}

		internal void QueueSnapshot(GameObject prefab, float lightIntensity, Quaternion? cameraRotation = null)
		{