Decompiled source of Swimming Ring v1.0.0

BG-SwimmingRing-Joive.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Joive.BurglinGnomes.SwimmingRing.Config;
using Joive.BurglinGnomes.SwimmingRing.Game;
using Joive.BurglinGnomes.SwimmingRing.Gameplay;
using Joive.BurglinGnomes.SwimmingRing.Items;
using Lightbug.CharacterControllerPro.Core;
using Lightbug.CharacterControllerPro.Implementation;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Joive")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Adds a craftable swimming ring equipment item.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e93357b17a5bd3c061e91c11c78c776a117b3496")]
[assembly: AssemblyProduct("BG Swimming Ring")]
[assembly: AssemblyTitle("BG-SwimmingRing-Joive")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Joive.BurglinGnomes.SwimmingRing
{
	[BepInPlugin("joive.bg.swimmingring", "BG Swimming Ring", "1.0.0")]
	public sealed class SwimmingRingPlugin : BaseUnityPlugin
	{
		public const string PluginId = "joive.bg.swimmingring";

		public const string PluginName = "BG Swimming Ring";

		public const string Version = "1.0.0";

		private Harmony harmony;

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			ModLog.Bind(((BaseUnityPlugin)this).Logger);
			SwimmingRingDefinition.Configure(PluginConfig.PlasticCost.Value);
			GameText.RegisterSwimmingRingText();
			if (PluginConfig.DebugLogs.Value)
			{
				ModLog.Info("BG-SwimmingRing-Joive.dll loaded. Version: 1.0.0");
			}
			harmony = new Harmony("joive.bg.swimmingring");
			harmony.PatchAll(typeof(SwimmingRingPlugin).Assembly);
			ModLog.Info("BG Swimming Ring 1.0.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}
namespace Joive.BurglinGnomes.SwimmingRing.Patches
{
	[HarmonyPatch(typeof(EquipmentHandler), "SetWearedEquipment")]
	internal static class EquipmentHandlerSetWearedEquipmentPatch
	{
		private static bool Prefix(string name)
		{
			return !GameApi.IsSwimmingRingName(name);
		}
	}
	[HarmonyPatch(typeof(EquipmentHandler), "SetOtherWearedEquipment")]
	internal static class EquipmentHandlerSetOtherWearedEquipmentPatch
	{
		private static bool Prefix(string name)
		{
			return !GameApi.IsSwimmingRingName(name);
		}
	}
	[HarmonyPatch(typeof(GnomiumDeposit), "OnNetworkSpawn")]
	internal static class GnomiumDepositOnNetworkSpawnPatch
	{
		private static void Postfix(GnomiumDeposit __instance)
		{
			CraftingRegistry.EnsureRegistered(__instance);
		}
	}
	[HarmonyPatch(typeof(InventoryBase), "OnNetworkSpawn")]
	internal static class InventoryOnNetworkSpawnPatch
	{
		private static void Postfix(InventoryBase __instance)
		{
			ItemRegistry.EnsureRegistered(__instance.BoundItems);
		}
	}
	[HarmonyPatch(typeof(ItemInstance), "OnNetworkSpawn")]
	internal static class ItemInstanceOnNetworkSpawnPatch
	{
		private static void Postfix(ItemInstance __instance)
		{
			SwimmingRingVisualApplier.Apply(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemInstance), "OnInstanceDataChange")]
	internal static class ItemInstanceOnInstanceDataChangePatch
	{
		private static void Postfix(ItemInstance __instance)
		{
			SwimmingRingVisualApplier.Apply(__instance);
		}
	}
	[HarmonyPatch(typeof(NormalMovement), "HandleVelocity")]
	internal static class NormalMovementHandleVelocityPatch
	{
		private static void Postfix(NormalMovement __instance, float dt)
		{
			SwimmingRingMovement.Apply(__instance, dt);
		}
	}
	[HarmonyPatch(typeof(Unpinned), "CheckEnterTransition")]
	internal static class UnpinnedCheckEnterTransitionPatch
	{
		private static void Postfix(Unpinned __instance, object fromState, ref bool __result)
		{
			if (__result && fromState is NormalMovement && GameApi.TryGetPlayer((Component)(object)__instance, out var player) && GameApi.CanStandFromWater(player) && GameApi.IsPlayerInWater(__instance))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(Unpinned), "CheckExitTransition")]
	internal static class UnpinnedCheckExitTransitionPatch
	{
		private static void Prefix(Unpinned __instance)
		{
			if (GameApi.TryGetPlayer((Component)(object)__instance, out var player) && GameApi.CanStandFromWater(player) && GameApi.IsPlayerInWater(__instance))
			{
				player.StateController.EnqueueTransition<NormalMovement>();
			}
		}
	}
}
namespace Joive.BurglinGnomes.SwimmingRing.Items
{
	internal static class SwimmingRingDefinition
	{
		internal const string ItemName = "Inflatable Swimming Ring";

		internal const string LegacyItemName = "inflatable_swimming_ring";

		internal const string DisplayName = "Inflatable Swimming Ring";

		internal const string Description = "Keeps you steady in water.";

		internal const float MaxDurability = 100f;

		internal static int PlasticCost { get; private set; } = 4;

		internal static void Configure(int plasticCost)
		{
			PlasticCost = plasticCost;
		}

		internal static LocalizedString NameText()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return new LocalizedString(TableReference.op_Implicit("Items"), TableEntryReference.op_Implicit("Inflatable Swimming Ring"));
		}

		internal static LocalizedString DescriptionText()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return new LocalizedString(TableReference.op_Implicit("Items Descriptions"), TableEntryReference.op_Implicit("Inflatable Swimming Ring"));
		}
	}
}
namespace Joive.BurglinGnomes.SwimmingRing.Game
{
	internal static class CraftingRegistry
	{
		private static bool missingPlasticLogged;

		internal static void EnsureRegistered(GnomiumDeposit deposit)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			if (GameApi.IsEnabled && !((Object)(object)deposit == (Object)null) && !((Object)(object)deposit.Recipes == (Object)null) && !((Object)(object)deposit.ResourceInventory == (Object)null))
			{
				ItemData val = ItemRegistry.EnsureRegistered(deposit.ResourceInventory.BoundItems);
				ItemData val2 = FindPlasticResource(deposit.ResourceInventory.BoundItems);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !HasRecipe(deposit.Recipes, val))
				{
					Recipe val3 = new Recipe();
					val3.craftResultType = (CraftResultType)0;
					val3.cost = (ItemCost[])(object)new ItemCost[1]
					{
						new ItemCost
						{
							item = val2,
							amount = SwimmingRingDefinition.PlasticCost
						}
					};
					Recipe val4 = val3;
					GameApi.SetRecipeItem(val4, val);
					Array.Resize(ref deposit.Recipes.recipes, deposit.Recipes.recipes.Length + 1);
					deposit.Recipes.recipes[deposit.Recipes.recipes.Length - 1] = val4;
					GameApi.Debug("Registered recipe: Inflatable Swimming Ring");
				}
			}
		}

		private static ItemData FindPlasticResource(AllItems allItems)
		{
			string resourceName = ResourceStorage.GetResourceName(3);
			int num = default(int);
			ItemData item = allItems.GetItem(resourceName, ref num);
			if ((Object)(object)item == (Object)null && !missingPlasticLogged)
			{
				missingPlasticLogged = true;
				ModLog.Warning("Plastic resource item was not found.");
			}
			return item;
		}

		private static bool HasRecipe(CraftingRecipes recipes, ItemData result)
		{
			Recipe[] recipes2 = recipes.recipes;
			foreach (Recipe val in recipes2)
			{
				if (val != null && (Object)(object)val.CraftResult == (Object)(object)result)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class GameApi
	{
		private static readonly FieldInfo RecipeItemField = AccessTools.Field(typeof(Recipe), "item");

		private static readonly MethodInfo CheckIsPlayerInWaterMethod = AccessTools.Method(typeof(Unpinned), "CheckIsPlayerInWater", (Type[])null, (Type[])null);

		private static readonly MethodInfo LoadImageMethod = FindLoadImageMethod();

		internal static bool Ready { get; } = Validate();

		internal static bool IsEnabled
		{
			get
			{
				if (PluginConfig.EnableMod != null && PluginConfig.EnableMod.Value)
				{
					return Ready;
				}
				return false;
			}
		}

		internal static void SetRecipeItem(Recipe recipe, ItemData item)
		{
			RecipeItemField.SetValue(recipe, item);
		}

		internal static bool LoadImage(Texture2D texture, byte[] bytes)
		{
			if (LoadImageMethod == null)
			{
				return false;
			}
			object[] parameters = ((LoadImageMethod.GetParameters().Length != 2) ? new object[3] { texture, bytes, false } : new object[2] { texture, bytes });
			return (bool)LoadImageMethod.Invoke(null, parameters);
		}

		internal static bool IsPlayerInWater(Unpinned state)
		{
			return (bool)CheckIsPlayerInWaterMethod.Invoke(state, null);
		}

		internal static bool HasSwimmingRing(PlayerNetworking player)
		{
			return HasSwimmingRing(player, equippedOnly: false);
		}

		internal static bool HasEquippedSwimmingRing(PlayerNetworking player)
		{
			return HasSwimmingRing(player, equippedOnly: true);
		}

		private static bool HasSwimmingRing(PlayerNetworking player, bool equippedOnly)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player.Inventory == (Object)null)
			{
				return false;
			}
			foreach (InventoryItem content in ((InventoryBase)player.Inventory).Contents)
			{
				InventoryItem current = content;
				if (((InventoryItem)(ref current)).IsValidItem && (!equippedOnly || current.slotIndex <= 1))
				{
					ItemData itemData = ((InventoryBase)player.Inventory).GetItemData((int)((InventoryItem)(ref current)).ItemIndex);
					if ((Object)(object)itemData != (Object)null && IsSwimmingRing(itemData))
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static bool IsSwimmingRing(ItemData itemData)
		{
			if ((Object)(object)itemData != (Object)null)
			{
				return IsSwimmingRingName(((CraftableItemBase)itemData).Name);
			}
			return false;
		}

		internal static bool IsSwimmingRingName(string itemName)
		{
			if (!(itemName == "Inflatable Swimming Ring"))
			{
				return itemName == "inflatable_swimming_ring";
			}
			return true;
		}

		internal static bool CanStandFromWater(PlayerNetworking player)
		{
			if (HasEquippedSwimmingRing(player) && !((HealthBase)player.Health).Dead && !player.Tied && player.StatusEffects.StunnedDuration <= 0f)
			{
				return !player.Dismemberment.IsMissingLeg;
			}
			return false;
		}

		internal static bool TryGetPlayer(Component component, out PlayerNetworking player)
		{
			player = component.GetComponentInParent<PlayerNetworking>();
			return (Object)(object)player != (Object)null;
		}

		internal static void Debug(string message)
		{
			if (PluginConfig.DebugLogs != null && PluginConfig.DebugLogs.Value)
			{
				ModLog.Info(message);
			}
		}

		private static bool Validate()
		{
			return (byte)(1u & (Require(RecipeItemField, "CraftingRecipes.Recipe.item") ? 1u : 0u) & (Require(CheckIsPlayerInWaterMethod, "Unpinned.CheckIsPlayerInWater") ? 1u : 0u) & (Require(LoadImageMethod, "UnityEngine.ImageConversion.LoadImage") ? 1u : 0u)) != 0;
		}

		private static MethodInfo FindLoadImageMethod()
		{
			Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule");
			if (type == null)
			{
				return null;
			}
			return type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
			{
				typeof(Texture2D),
				typeof(byte[])
			}, null) ?? type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
			{
				typeof(Texture2D),
				typeof(byte[]),
				typeof(bool)
			}, null);
		}

		private static bool Require(MemberInfo member, string name)
		{
			if (member != null)
			{
				return true;
			}
			ModLog.Warning("Missing game member: " + name);
			return false;
		}
	}
	internal static class GameText
	{
		private readonly struct TextPair
		{
			internal readonly string Name;

			internal readonly string Description;

			internal TextPair(string name, string description)
			{
				Name = name;
				Description = description;
			}
		}

		private static readonly Dictionary<string, TextPair> TextByLanguage = new Dictionary<string, TextPair>
		{
			{
				"en",
				new TextPair("Inflatable Swimming Ring", "Keeps you steady in water.")
			},
			{
				"ru",
				new TextPair("Надувной круг", "Помогает держаться на воде.")
			},
			{
				"uk",
				new TextPair("Надувний круг", "Допомагає триматися на воді.")
			},
			{
				"de",
				new TextPair("Aufblasbarer Schwimmring", "Hilft dir, im Wasser stabil zu bleiben.")
			},
			{
				"fr",
				new TextPair("Bouée gonflable", "Vous aide à rester stable dans l'eau.")
			},
			{
				"es",
				new TextPair("Flotador inflable", "Te ayuda a mantenerte estable en el agua.")
			},
			{
				"pt",
				new TextPair("Boia inflável", "Ajuda você a se manter estável na água.")
			},
			{
				"it",
				new TextPair("Ciambella gonfiabile", "Ti aiuta a restare stabile in acqua.")
			},
			{
				"pl",
				new TextPair("Nadmuchiwane koło", "Pomaga utrzymać się stabilnie w wodzie.")
			},
			{
				"tr",
				new TextPair("Şişme yüzme simidi", "Suda dengede kalmana yardımcı olur.")
			},
			{
				"zh",
				new TextPair("充气游泳圈", "帮助你在水中保持稳定。")
			},
			{
				"ja",
				new TextPair("空気入り浮き輪", "水中で体勢を保ちやすくする。")
			},
			{
				"ko",
				new TextPair("공기 주입식 튜브", "물속에서 안정적으로 움직일 수 있게 해 줍니다.")
			}
		};

		internal static void RegisterSwimmingRingText()
		{
			IReadOnlyList<Locale> locales = LocalizationSettings.AvailableLocales.Locales;
			if (locales == null || locales.Count == 0)
			{
				AddText("Items", "Inflatable Swimming Ring", "Inflatable Swimming Ring");
				AddText("Items Descriptions", "Inflatable Swimming Ring", "Keeps you steady in water.");
				return;
			}
			foreach (Locale item in locales)
			{
				TextPair text = GetText(item);
				AddText("Items", "Inflatable Swimming Ring", text.Name, item);
				AddText("Items Descriptions", "Inflatable Swimming Ring", text.Description, item);
			}
		}

		private static void AddText(string tableName, string key, string value)
		{
			AddText(tableName, key, value, null);
		}

		private static void AddText(string tableName, string key, string value, Locale locale)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			StringTable table = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTable(TableReference.op_Implicit(tableName), (Locale)null);
			if ((Object)(object)locale != (Object)null)
			{
				table = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTable(TableReference.op_Implicit(tableName), locale);
			}
			if (!((Object)(object)table == (Object)null) && ((DetailedLocalizationTable<StringTableEntry>)(object)table).GetEntry(key) == null)
			{
				((DetailedLocalizationTable<StringTableEntry>)(object)table).AddEntry(key, value);
			}
		}

		private static TextPair GetText(Locale locale)
		{
			//IL_0001: 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)
			LocaleIdentifier identifier = locale.Identifier;
			string text = ((LocaleIdentifier)(ref identifier)).Code.ToLowerInvariant();
			if (TextByLanguage.TryGetValue(text, out var value))
			{
				return value;
			}
			int num = text.IndexOf('-');
			string key = ((num >= 0) ? text.Substring(0, num) : text);
			if (TextByLanguage.TryGetValue(key, out var value2))
			{
				return value2;
			}
			return TextByLanguage["en"];
		}
	}
	internal static class ItemRegistry
	{
		private static ItemData swimmingRing;

		private static int swimmingRingIndex = -1;

		internal static bool IsSwimmingRingIndex(byte itemIndex)
		{
			if (swimmingRingIndex >= 0)
			{
				return itemIndex == swimmingRingIndex;
			}
			return false;
		}

		internal static ItemData EnsureRegistered(AllItems allItems)
		{
			if (!GameApi.IsEnabled || (Object)(object)allItems == (Object)null)
			{
				return null;
			}
			GameText.RegisterSwimmingRingText();
			if ((Object)(object)swimmingRing != (Object)null && allItems.IndexOf(swimmingRing) >= 0)
			{
				swimmingRingIndex = allItems.IndexOf(swimmingRing);
				return swimmingRing;
			}
			ItemData val = FindExisting(allItems);
			if ((Object)(object)val != (Object)null)
			{
				NormalizeItem(val);
				swimmingRing = val;
				swimmingRingIndex = allItems.IndexOf(swimmingRing);
				return swimmingRing;
			}
			swimmingRing = CreateItem(allItems);
			Array.Resize(ref allItems.items, allItems.items.Length + 1);
			allItems.items[allItems.items.Length - 1] = swimmingRing;
			swimmingRingIndex = allItems.items.Length - 1;
			GameApi.Debug("Registered item: Inflatable Swimming Ring at index " + swimmingRingIndex + ".");
			return swimmingRing;
		}

		private static ItemData CreateItem(AllItems allItems)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			ItemData obj = ScriptableObject.CreateInstance<ItemData>();
			((Object)obj).name = "Inflatable Swimming Ring";
			((CraftableItemBase)obj).localizedName = SwimmingRingDefinition.NameText();
			((CraftableItemBase)obj).localizedDesc = SwimmingRingDefinition.DescriptionText();
			obj.description = "Keeps you steady in water.";
			((CraftableItemBase)obj).icon = SwimmingRingIcon.GetIcon();
			obj.equipmentType = (EquipmentType)2;
			obj.maxStackSize = 1;
			obj.durabilityLoss = (EquipmentDurabilityLossType)2;
			obj.maxDurability = 100f;
			obj.dontAllowEquipTogetherWith = (ItemData[])(object)new ItemData[0];
			obj.prefab = allItems.defaultPrefab;
			((Object)obj).hideFlags = (HideFlags)32;
			return obj;
		}

		private static ItemData FindExisting(AllItems allItems)
		{
			ItemData[] items = allItems.items;
			foreach (ItemData val in items)
			{
				if ((Object)(object)val != (Object)null && GameApi.IsSwimmingRing(val))
				{
					return val;
				}
			}
			return null;
		}

		private static void NormalizeItem(ItemData item)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			((Object)item).name = "Inflatable Swimming Ring";
			((CraftableItemBase)item).localizedName = SwimmingRingDefinition.NameText();
			((CraftableItemBase)item).localizedDesc = SwimmingRingDefinition.DescriptionText();
			item.description = "Keeps you steady in water.";
			((CraftableItemBase)item).icon = SwimmingRingIcon.GetIcon();
			item.equipmentType = (EquipmentType)2;
			item.dontAllowEquipTogetherWith = (ItemData[])(object)new ItemData[0];
		}
	}
	internal static class ModLog
	{
		private static ManualLogSource logger;

		internal static void Bind(ManualLogSource source)
		{
			logger = source;
		}

		internal static void Info(string message)
		{
			ManualLogSource obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)message);
			}
		}

		internal static void Warning(string message)
		{
			ManualLogSource obj = logger;
			if (obj != null)
			{
				obj.LogWarning((object)message);
			}
		}

		internal static void Error(string message)
		{
			ManualLogSource obj = logger;
			if (obj != null)
			{
				obj.LogError((object)message);
			}
		}
	}
	internal static class SwimmingRingAssets
	{
		private const string BundleFileName = "swimmingring.bundle";

		private const string VisualPrefabPath = "assets/prefabs/swimmingringvisual.prefab";

		private static bool loadAttempted;

		private static AssetBundle bundle;

		private static GameObject visualPrefab;

		internal static GameObject GetVisualPrefab()
		{
			return LoadVisualPrefab();
		}

		private static GameObject LoadVisualPrefab()
		{
			if (loadAttempted)
			{
				return visualPrefab;
			}
			loadAttempted = true;
			try
			{
				byte[] array = ReadBundleBytes();
				GameApi.Debug("Loading embedded AssetBundle bytes: " + array.Length + ".");
				bundle = AssetBundle.LoadFromMemory(array);
				if ((Object)(object)bundle == (Object)null)
				{
					ModLog.Warning("Embedded swimming ring bundle could not be loaded.");
					return null;
				}
				GameApi.Debug("AssetBundle.LoadFromMemory succeeded for swimmingring.bundle.");
				visualPrefab = bundle.LoadAsset<GameObject>("assets/prefabs/swimmingringvisual.prefab");
				if ((Object)(object)visualPrefab == (Object)null)
				{
					ModLog.Warning("Swimming ring visual prefab was not found at assets/prefabs/swimmingringvisual.prefab.");
					return null;
				}
				((Object)visualPrefab).name = "Inflatable Swimming Ring";
				((Object)visualPrefab).hideFlags = (HideFlags)32;
				GameApi.Debug("Loaded prefab SwimmingRingVisual from embedded swimmingring.bundle: " + ((Object)visualPrefab).name + ".");
				return visualPrefab;
			}
			catch (Exception ex)
			{
				ModLog.Warning("Swimming ring bundle failed to load: " + ex.Message);
				return null;
			}
		}

		private static byte[] ReadBundleBytes()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = FindBundleResourceName(executingAssembly);
			if (text == null)
			{
				throw new InvalidOperationException("Missing embedded resource ending with swimmingring.bundle.");
			}
			GameApi.Debug("Using embedded bundle resource: " + text);
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				throw new InvalidOperationException("Could not open embedded resource: " + text);
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static string FindBundleResourceName(Assembly assembly)
		{
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (text.EndsWith("swimmingring.bundle", StringComparison.OrdinalIgnoreCase))
				{
					return text;
				}
			}
			return null;
		}
	}
	internal static class SwimmingRingIcon
	{
		private const string IconResourceFileName = "SwimmingRingIcon.png";

		private const int Size = 128;

		private static Sprite icon;

		internal static Sprite GetIcon()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon != (Object)null)
			{
				return icon;
			}
			icon = LoadEmbeddedIcon();
			if ((Object)(object)icon != (Object)null)
			{
				return icon;
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.08f, 0.34f, 0.95f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.78f, 0.92f, 1f, 1f);
			Color val5 = default(Color);
			((Color)(ref val5))..ctor(0.02f, 0.08f, 0.28f, 1f);
			Vector2 val6 = default(Vector2);
			((Vector2)(ref val6))..ctor(63.5f, 63.5f);
			float num = 53.76f;
			float num2 = 28.16f;
			float num3 = 57.6f;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num4 = Vector2.Distance(new Vector2((float)j, (float)i), val6);
					Color val7 = val2;
					if (num4 <= num3 && num4 >= num2 * 0.92f)
					{
						val7 = val5;
					}
					if (num4 <= num && num4 >= num2)
					{
						val7 = ((Mathf.Sin(Mathf.Atan2((float)i - val6.y, (float)j - val6.x) * 6f) > 0.35f) ? val4 : val3);
					}
					val.SetPixel(j, i, val7);
				}
			}
			val.Apply();
			((Object)val).name = "SwimmingRingIcon";
			((Object)val).hideFlags = (HideFlags)32;
			icon = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 128f);
			((Object)icon).name = "SwimmingRingIcon";
			((Object)icon).hideFlags = (HideFlags)32;
			return icon;
		}

		private static Sprite LoadEmbeddedIcon()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00a9: 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)
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string text = FindIconResourceName(executingAssembly);
				if (text == null)
				{
					ModLog.Warning("Swimming ring icon resource was not found.");
					return null;
				}
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					ModLog.Warning("Swimming ring icon resource could not be opened.");
					return null;
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!GameApi.LoadImage(val, memoryStream.ToArray()))
				{
					ModLog.Warning("Swimming ring icon PNG could not be loaded.");
					return null;
				}
				((Object)val).name = "SwimmingRingIcon";
				((Object)val).hideFlags = (HideFlags)32;
				Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)Mathf.Max(((Texture)val).width, ((Texture)val).height));
				((Object)obj).name = "SwimmingRingIcon";
				((Object)obj).hideFlags = (HideFlags)32;
				return obj;
			}
			catch (Exception ex)
			{
				ModLog.Warning("Swimming ring icon failed to load: " + ex.Message);
				return null;
			}
		}

		private static string FindIconResourceName(Assembly assembly)
		{
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (text.EndsWith("SwimmingRingIcon.png", StringComparison.OrdinalIgnoreCase))
				{
					return text;
				}
			}
			return null;
		}
	}
	internal static class SwimmingRingPlayerVisual
	{
		private const string PlayerVisualRootName = "SwimmingRingPlayerVisual";

		private static readonly Dictionary<int, Transform> playerVisuals = new Dictionary<int, Transform>();

		internal static void Apply(PlayerNetworking player)
		{
			if (!GameApi.IsEnabled || (Object)(object)player == (Object)null)
			{
				return;
			}
			Transform val = GetCachedPlayerVisual(player);
			if (!GameApi.HasEquippedSwimmingRing(player))
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(false);
				}
				return;
			}
			bool flag = (Object)(object)val == (Object)null;
			if (flag)
			{
				GameObject visualPrefab = SwimmingRingAssets.GetVisualPrefab();
				if ((Object)(object)visualPrefab == (Object)null)
				{
					return;
				}
				GameObject obj = Object.Instantiate<GameObject>(visualPrefab, ((Component)player).transform, false);
				((Object)obj).name = "SwimmingRingPlayerVisual";
				val = obj.transform;
				playerVisuals[((Object)player).GetInstanceID()] = val;
				SwimmingRingVisualUtility.StripGameplayComponents(val);
				GameApi.Debug("Instantiated SwimmingRingPlayerVisual for player: " + ((Object)player).name + ".");
			}
			((Component)val).gameObject.SetActive(true);
			ApplyPlayerVisualTransform(val);
			if (flag)
			{
				SwimmingRingVisualUtility.PrepareVisual(val, "SwimmingRingPlayerVisual");
			}
		}

		private static Transform GetCachedPlayerVisual(PlayerNetworking player)
		{
			int instanceID = ((Object)player).GetInstanceID();
			if (!playerVisuals.TryGetValue(instanceID, out var value))
			{
				return null;
			}
			if ((Object)(object)value != (Object)null)
			{
				return value;
			}
			playerVisuals.Remove(instanceID);
			return null;
		}

		private static void ApplyPlayerVisualTransform(Transform visual)
		{
			//IL_001a: 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)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			visual.localPosition = new Vector3(0f, PluginConfig.PlayerVisualHeightOffset.Value, PluginConfig.PlayerVisualForwardOffset.Value);
			visual.localRotation = Quaternion.identity;
			visual.localScale = Vector3.one * PluginConfig.PlayerVisualScale.Value;
		}
	}
	internal static class SwimmingRingVisualApplier
	{
		internal static void Apply(ItemInstance itemInstance)
		{
			SwimmingRingWorldVisual.Apply(itemInstance);
		}

		internal static void ApplyToPlayer(PlayerNetworking player)
		{
			SwimmingRingPlayerVisual.Apply(player);
		}
	}
	internal static class SwimmingRingVisualMaterial
	{
		private const float RuntimeSmoothness = 0.45f;

		private const string RuntimeShaderName = "Standard";

		private static readonly Color FallbackOrange = new Color(1f, 0.58f, 0.22f, 1f);

		private static Material runtimeMaterial;

		private static bool missingShaderLogged;

		internal static Material GetRuntimeMaterial(Material sourceMaterial)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)runtimeMaterial == (Object)null)
			{
				runtimeMaterial = CreateRuntimeMaterial();
				if ((Object)(object)runtimeMaterial == (Object)null)
				{
					return sourceMaterial;
				}
			}
			Texture mainTexture = GetMainTexture(sourceMaterial);
			if ((Object)(object)mainTexture != (Object)null)
			{
				SetMaterialTexture(runtimeMaterial, mainTexture);
				SetMaterialColor(runtimeMaterial, Color.white);
				return runtimeMaterial;
			}
			SetMaterialTexture(runtimeMaterial, null);
			SetMaterialColor(runtimeMaterial, FallbackOrange);
			return runtimeMaterial;
		}

		internal static string GetMaterialName(Renderer renderer)
		{
			Material sharedMaterial = renderer.sharedMaterial;
			if (!((Object)(object)sharedMaterial != (Object)null))
			{
				return "null";
			}
			return ((Object)sharedMaterial).name;
		}

		internal static string GetShaderName(Renderer renderer)
		{
			Material sharedMaterial = renderer.sharedMaterial;
			if (!((Object)(object)sharedMaterial != (Object)null) || !((Object)(object)sharedMaterial.shader != (Object)null))
			{
				return "null";
			}
			return ((Object)sharedMaterial.shader).name;
		}

		internal static string GetTextureName(Renderer renderer)
		{
			Texture mainTexture = GetMainTexture(renderer.sharedMaterial);
			if (!((Object)(object)mainTexture != (Object)null))
			{
				return "null";
			}
			return ((Object)mainTexture).name;
		}

		private static Material CreateRuntimeMaterial()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				if (!missingShaderLogged)
				{
					missingShaderLogged = true;
					ModLog.Warning("Shader not found: Standard.");
				}
				return null;
			}
			Material val2 = new Material(val);
			((Object)val2).name = "SwimmingRingRuntimeOrangeMaterial";
			SetMaterialColor(val2, FallbackOrange);
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0f);
			}
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", 0.45f);
			}
			GameApi.Debug("Created runtime visual material with shader: " + ((Object)val).name + ".");
			return val2;
		}

		private static void SetMaterialColor(Material material, Color color)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", color);
			}
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", color);
			}
		}

		private static void SetMaterialTexture(Material material, Texture texture)
		{
			material.mainTexture = texture;
			if (material.HasProperty("_MainTex"))
			{
				material.SetTexture("_MainTex", texture);
			}
			if (material.HasProperty("_BaseMap"))
			{
				material.SetTexture("_BaseMap", texture);
			}
		}

		private static Texture GetMainTexture(Material material)
		{
			if ((Object)(object)material == (Object)null)
			{
				return null;
			}
			if ((Object)(object)material.mainTexture != (Object)null)
			{
				return material.mainTexture;
			}
			if (material.HasProperty("_BaseMap"))
			{
				return material.GetTexture("_BaseMap");
			}
			if (material.HasProperty("_MainTex"))
			{
				return material.GetTexture("_MainTex");
			}
			return null;
		}
	}
	internal static class SwimmingRingVisualUtility
	{
		internal static void PrepareVisual(Transform visual, string visualName)
		{
			SetActiveRecursive(visual);
			Renderer[] componentsInChildren = ((Component)visual).GetComponentsInChildren<Renderer>(true);
			GameApi.Debug(visualName + " renderer count: " + componentsInChildren.Length + ".");
			if (componentsInChildren.Length == 0)
			{
				ModLog.Warning(visualName + " has no renderers.");
				return;
			}
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.enabled = true;
					if (PluginConfig.ForceRuntimeOrangeMaterial.Value)
					{
						val.sharedMaterial = SwimmingRingVisualMaterial.GetRuntimeMaterial(val.sharedMaterial);
					}
					LogRenderer(val);
				}
			}
		}

		internal static void StripGameplayComponents(Transform visual)
		{
			Collider[] componentsInChildren = ((Component)visual).GetComponentsInChildren<Collider>(true);
			Collider[] array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].enabled = false;
			}
			Rigidbody[] componentsInChildren2 = ((Component)visual).GetComponentsInChildren<Rigidbody>(true);
			Rigidbody[] array2 = componentsInChildren2;
			for (int i = 0; i < array2.Length; i++)
			{
				Object.Destroy((Object)(object)array2[i]);
			}
			Camera[] componentsInChildren3 = ((Component)visual).GetComponentsInChildren<Camera>(true);
			Camera[] array3 = componentsInChildren3;
			for (int i = 0; i < array3.Length; i++)
			{
				((Behaviour)array3[i]).enabled = false;
			}
			Light[] componentsInChildren4 = ((Component)visual).GetComponentsInChildren<Light>(true);
			Light[] array4 = componentsInChildren4;
			for (int i = 0; i < array4.Length; i++)
			{
				((Behaviour)array4[i]).enabled = false;
			}
			GameApi.Debug("Prepared player visual components: disabled colliders=" + componentsInChildren.Length + ", removed rigidbodies=" + componentsInChildren2.Length + ", disabled cameras=" + componentsInChildren3.Length + ", disabled lights=" + componentsInChildren4.Length + ".");
		}

		private static void SetActiveRecursive(Transform root)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			((Component)root).gameObject.SetActive(true);
			foreach (Transform item in root)
			{
				SetActiveRecursive(item);
			}
		}

		private static void LogRenderer(Renderer renderer)
		{
			//IL_0001: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = renderer.bounds;
			GameApi.Debug("Prepared visual renderer: " + ((Object)renderer).name + ", enabled=" + renderer.enabled + ", activeInHierarchy=" + ((Component)renderer).gameObject.activeInHierarchy + ", material=" + SwimmingRingVisualMaterial.GetMaterialName(renderer) + ", shader=" + SwimmingRingVisualMaterial.GetShaderName(renderer) + ", texture=" + SwimmingRingVisualMaterial.GetTextureName(renderer) + ", boundsCenter=" + ((object)((Bounds)(ref bounds)).center/*cast due to .constrained prefix*/).ToString() + ", boundsSize=" + ((object)((Bounds)(ref bounds)).size/*cast due to .constrained prefix*/).ToString() + ".");
		}
	}
	internal static class SwimmingRingWorldVisual
	{
		private const string VisualRootName = "SwimmingRingVisual";

		internal static void Apply(ItemInstance itemInstance)
		{
			if (!GameApi.IsEnabled || (Object)(object)itemInstance == (Object)null || !IsSwimmingRingInstance(itemInstance))
			{
				return;
			}
			GameApi.Debug("Found ItemInstance for Inflatable Swimming Ring: " + ((Object)itemInstance).name + ".");
			Transform transform = ((Component)itemInstance).transform;
			Transform val = FindExistingVisual(transform);
			HideDefaultRenderers(transform, val);
			if ((Object)(object)val != (Object)null)
			{
				ApplyWorldVisualTransform(val);
				SwimmingRingVisualUtility.PrepareVisual(val, "SwimmingRingVisual");
				return;
			}
			GameObject visualPrefab = SwimmingRingAssets.GetVisualPrefab();
			if (!((Object)(object)visualPrefab == (Object)null))
			{
				GameObject obj = Object.Instantiate<GameObject>(visualPrefab, transform, false);
				((Object)obj).name = "SwimmingRingVisual";
				ApplyWorldVisualTransform(obj.transform);
				SwimmingRingVisualUtility.PrepareVisual(obj.transform, "SwimmingRingVisual");
				GameApi.Debug("Instantiated SwimmingRingVisual for Inflatable Swimming Ring: " + ((Object)itemInstance).name + ".");
			}
		}

		private static bool IsSwimmingRingInstance(ItemInstance itemInstance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return ItemRegistry.IsSwimmingRingIndex(itemInstance.InstanceData.itemIndex);
		}

		private static void HideDefaultRenderers(Transform root, Transform existingVisual)
		{
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsInsideVisual(((Component)val).transform, existingVisual))
				{
					val.enabled = false;
				}
			}
		}

		private static bool IsInsideVisual(Transform candidate, Transform existingVisual)
		{
			if ((Object)(object)existingVisual == (Object)null)
			{
				return false;
			}
			if (!((Object)(object)candidate == (Object)(object)existingVisual))
			{
				return candidate.IsChildOf(existingVisual);
			}
			return true;
		}

		private static Transform FindExistingVisual(Transform root)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)(object)root && ((Object)val).name == "SwimmingRingVisual")
				{
					return val;
				}
			}
			return null;
		}

		private static void ApplyWorldVisualTransform(Transform visual)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			visual.localPosition = Vector3.up * PluginConfig.VisualHeightOffset.Value;
			visual.localRotation = Quaternion.identity;
			visual.localScale = Vector3.one * PluginConfig.VisualScale.Value;
		}
	}
}
namespace Joive.BurglinGnomes.SwimmingRing.Gameplay
{
	internal static class SwimmingRingMovement
	{
		private const int WaterSurfaceDetectionMask = 1;

		private const int WaterMask = 16;

		private const float InputRiseThreshold = 0.35f;

		private const float IdleInputSqrThreshold = 0.01f;

		private const float SwimAnimationMinSpeed = 0.1f;

		private static readonly int SwimSpeedParameter = Animator.StringToHash("SwimSpeed");

		internal static void Apply(NormalMovement movement, float dt)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (!GameApi.IsEnabled || !GameApi.TryGetPlayer((Component)(object)movement, out var player))
			{
				return;
			}
			SwimmingRingVisualApplier.ApplyToPlayer(player);
			if (GameApi.HasEquippedSwimmingRing(player))
			{
				if (!Utils.CheckIsInWater(player.Actor.Center, ((Component)player).transform.position, LayerMask.op_Implicit(1), LayerMask.op_Implicit(16), 0.2f))
				{
					ResetSwimAnimation(player, dt);
					return;
				}
				player.Actor.ForceNotGrounded(3);
				ApplyHorizontalSwim(player, dt);
				ApplySwimAnimation(player, dt);
				Vector3 verticalVelocity = ((PhysicsActor)player.Actor).VerticalVelocity;
				verticalVelocity.y = Mathf.Max(verticalVelocity.y, 0f - PluginConfig.MaxSinkSpeed.Value);
				verticalVelocity.y = Mathf.Min(PluginConfig.MaxRiseSpeed.Value, verticalVelocity.y + GetRiseForce(player) * dt);
				((PhysicsActor)player.Actor).VerticalVelocity = verticalVelocity;
			}
		}

		private static void ApplyHorizontalSwim(PlayerNetworking player, float dt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Vector3 inputMovementReference = player.StateController.InputMovementReference;
			Vector3 planarVelocity = ((PhysicsActor)player.Actor).PlanarVelocity;
			if (((Vector3)(ref inputMovementReference)).sqrMagnitude > 0.01f)
			{
				Vector3 val = ((Vector3)(ref inputMovementReference)).normalized * PluginConfig.SwimSpeed.Value;
				((PhysicsActor)player.Actor).PlanarVelocity = Vector3.MoveTowards(planarVelocity, val, PluginConfig.SwimAcceleration.Value * dt);
			}
			else
			{
				((PhysicsActor)player.Actor).PlanarVelocity = planarVelocity * PluginConfig.SwimSpeedMultiplier.Value;
			}
		}

		private static void ApplySwimAnimation(PlayerNetworking player, float dt)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			Animator animator = ((PhysicsActor)player.Actor).Animator;
			if (!((Object)(object)animator == (Object)null))
			{
				CharacterActions characterActions = player.Controller.Brain.CharacterActions;
				float sqrMagnitude = ((Vector2)(ref characterActions.movement.value)).sqrMagnitude;
				float value = PluginConfig.SwimSpeed.Value;
				Vector3 planarVelocity = ((PhysicsActor)player.Actor).PlanarVelocity;
				float num = Mathf.InverseLerp(0.1f, value, ((Vector3)(ref planarVelocity)).magnitude);
				float num2 = ((Mathf.Max(sqrMagnitude, num) > 0.01f) ? PluginConfig.SwimAnimationSpeed.Value : 0f);
				float num3 = animator.GetFloat(SwimSpeedParameter);
				animator.SetFloat(SwimSpeedParameter, Mathf.Lerp(num3, num2, PluginConfig.SwimAnimationLerp.Value * dt));
			}
		}

		private static void ResetSwimAnimation(PlayerNetworking player, float dt)
		{
			Animator animator = ((PhysicsActor)player.Actor).Animator;
			if (!((Object)(object)animator == (Object)null))
			{
				float num = animator.GetFloat(SwimSpeedParameter);
				animator.SetFloat(SwimSpeedParameter, Mathf.Lerp(num, 0f, PluginConfig.SwimAnimationLerp.Value * dt));
			}
		}

		private static float GetRiseForce(PlayerNetworking player)
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			float num = PluginConfig.BuoyancyForce.Value;
			CharacterBrain brain = player.Controller.Brain;
			if (brain.CharacterActions.jump.value || brain.CharacterActions.movement.value.y > 0.35f)
			{
				num += PluginConfig.ActiveRiseForce.Value;
			}
			return num;
		}
	}
}
namespace Joive.BurglinGnomes.SwimmingRing.Config
{
	internal static class PluginConfig
	{
		private const int DefaultPlasticCost = 4;

		private const float DefaultSwimSpeedMultiplier = 0.85f;

		private const float DefaultSwimSpeed = 4.8f;

		private const float DefaultSwimAcceleration = 18f;

		private const float DefaultSwimAnimationSpeed = 1.15f;

		private const float DefaultSwimAnimationLerp = 8f;

		private const float DefaultBuoyancyForce = 18f;

		private const float DefaultActiveRiseForce = 16f;

		private const float DefaultMaxRiseSpeed = 5.5f;

		private const float DefaultMaxSinkSpeed = 0.4f;

		private const float DefaultWorldVisualScale = 6f;

		private const float DefaultWorldVisualHeightOffset = 0.25f;

		private const float DefaultPlayerVisualScale = 9f;

		private const float DefaultPlayerVisualHeightOffset = 0.35f;

		private const float DefaultPlayerVisualForwardOffset = -0.08f;

		internal static ConfigEntry<bool> EnableMod { get; private set; }

		internal static ConfigEntry<int> PlasticCost { get; private set; }

		internal static ConfigEntry<float> SwimSpeedMultiplier { get; private set; }

		internal static ConfigEntry<float> SwimSpeed { get; private set; }

		internal static ConfigEntry<float> SwimAcceleration { get; private set; }

		internal static ConfigEntry<float> SwimAnimationSpeed { get; private set; }

		internal static ConfigEntry<float> SwimAnimationLerp { get; private set; }

		internal static ConfigEntry<float> BuoyancyForce { get; private set; }

		internal static ConfigEntry<float> ActiveRiseForce { get; private set; }

		internal static ConfigEntry<float> MaxRiseSpeed { get; private set; }

		internal static ConfigEntry<float> MaxSinkSpeed { get; private set; }

		internal static ConfigEntry<float> VisualScale { get; private set; }

		internal static ConfigEntry<float> VisualHeightOffset { get; private set; }

		internal static ConfigEntry<float> PlayerVisualScale { get; private set; }

		internal static ConfigEntry<float> PlayerVisualHeightOffset { get; private set; }

		internal static ConfigEntry<float> PlayerVisualForwardOffset { get; private set; }

		internal static ConfigEntry<bool> ForceRuntimeOrangeMaterial { get; private set; }

		internal static ConfigEntry<bool> DebugLogs { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			EnableMod = config.Bind<bool>("General", "EnableMod", true, "Turns the mod on.");
			PlasticCost = config.Bind<int>("Crafting", "PlasticCost", 4, "Plastic cost for the recipe.");
			SwimSpeedMultiplier = config.Bind<float>("Swimming", "SwimSpeedMultiplier", 0.85f, "Speed kept when there is no swim input.");
			SwimSpeed = config.Bind<float>("Swimming", "SwimSpeed", 4.8f, "Swim speed with the ring equipped.");
			SwimAcceleration = config.Bind<float>("Swimming", "SwimAcceleration", 18f, "How fast swim movement catches up.");
			SwimAnimationSpeed = config.Bind<float>("Swimming", "SwimAnimationSpeed", 1.15f, "Swim animation value while moving.");
			SwimAnimationLerp = config.Bind<float>("Swimming", "SwimAnimationLerp", 8f, "Swim animation blend speed.");
			BuoyancyForce = config.Bind<float>("Swimming", "BuoyancyForce", 18f, "Upward force in water.");
			ActiveRiseForce = config.Bind<float>("Swimming", "ActiveRiseForce", 16f, "Extra lift from jump or forward input.");
			MaxRiseSpeed = config.Bind<float>("Swimming", "MaxRiseSpeed", 5.5f, "Top upward speed from the ring.");
			MaxSinkSpeed = config.Bind<float>("Swimming", "MaxSinkSpeed", 0.4f, "Sink speed limit while floating.");
			VisualScale = config.Bind<float>("Visual", "VisualScale", 6f, "World item visual size.");
			VisualHeightOffset = config.Bind<float>("Visual", "VisualHeightOffset", 0.25f, "World item visual height.");
			PlayerVisualScale = config.Bind<float>("Visual", "PlayerVisualScale", 9f, "Player visual size.");
			PlayerVisualHeightOffset = config.Bind<float>("Visual", "PlayerVisualHeightOffset", 0.35f, "Player visual height.");
			PlayerVisualForwardOffset = config.Bind<float>("Visual", "PlayerVisualForwardOffset", -0.08f, "Player visual forward offset.");
			ForceRuntimeOrangeMaterial = config.Bind<bool>("Visual", "ForceRuntimeOrangeMaterial", true, "Use the runtime orange material.");
			DebugLogs = config.Bind<bool>("General", "DebugLogs", false, "Write extra setup logs.");
			if (PlayerVisualScale.Value < 9f)
			{
				PlayerVisualScale.Value = 9f;
			}
		}
	}
}