Decompiled source of SpeedyPaths v1.0.9

SpeedyPaths.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AuthoritativeConfig;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SpeedyPaths.Properties;
using UnityEngine;

[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("SpeedyPaths")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5090c3d21d604919daa0938d9667ce68c93ce100")]
[assembly: AssemblyProduct("SpeedyPaths")]
[assembly: AssemblyTitle("SpeedyPaths")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AuthoritativeConfig
{
	public class Config
	{
		private static Config _instance;

		public Dictionary<string, ConfigBaseEntry> _configEntries;

		public BaseUnityPlugin _mod;

		private static ConfigEntry<bool> _ServerIsAuthoritative;

		private static bool _DefaultBindAuthority;

		public static ManualLogSource Logger;

		public static Config Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new Config();
				}
				return _instance;
			}
			set
			{
			}
		}

		public static ZNet ZNet => ZNet.instance;

		public static string GUID => Instance._mod.Info.Metadata.GUID;

		public static string RPC_SYNC_GUID => "AuthoritativeConfig_" + GUID;

		public void init(BaseUnityPlugin mod, bool defaultBindServerAuthority = false)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			_mod = mod;
			Logger = new ManualLogSource(RPC_SYNC_GUID);
			Logger.Sources.Add((ILogSource)(object)Logger);
			_configEntries = new Dictionary<string, ConfigBaseEntry>();
			_DefaultBindAuthority = defaultBindServerAuthority;
			_ServerIsAuthoritative = _mod.Config.Bind<bool>("ServerAuthoritativeConfig", "ServerIsAuthoritative", true, "<Server Only> Forces Clients to use Server defined configs.");
			Harmony.CreateAndPatchAll(typeof(Config), (string)null);
			Logger.LogInfo((object)"Initialized Server Authoritative Config Manager.");
		}

		[HarmonyPatch(typeof(Game), "Start")]
		[HarmonyPostfix]
		private static void RegisterSyncConfigRPC()
		{
			Logger.LogInfo((object)("Authoritative Config Registered -> " + RPC_SYNC_GUID));
			ZRoutedRpc.instance.Register<ZPackage>(RPC_SYNC_GUID, (Action<long, ZPackage>)RPC_SyncServerConfig);
			foreach (ConfigBaseEntry value in Instance._configEntries.Values)
			{
				value.ClearServerValue();
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[HarmonyPostfix]
		private static void RequestConfigFromServer()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			if (!ZNet.IsServer() && (int)ZNet.GetConnectionStatus() == 2)
			{
				long? num = AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null).Invoke(ZRoutedRpc.instance, null) as long?;
				ZRoutedRpc.instance.InvokeRoutedRPC(num.Value, RPC_SYNC_GUID, new object[1] { (object)new ZPackage() });
				Logger.LogInfo((object)("Authoritative Config Registered -> " + RPC_SYNC_GUID));
				Debug.Log((object)(Instance._mod.Info.Metadata.Name + ": Authoritative Config Requested -> " + RPC_SYNC_GUID));
			}
			else if (!ZNet.IsServer())
			{
				Logger.LogWarning((object)"Failed to Request Configs. Bad Peer? Too Early?");
			}
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null, bool? serverAuthoritative = null)
		{
			ConfigEntry<T> configEntry = new ConfigEntry<T>(_mod.Config.Bind<T>(section, key, defaultValue, configDescription), serverAuthoritative.HasValue ? serverAuthoritative.Value : _DefaultBindAuthority);
			_configEntries[((object)configEntry.BaseEntry.Definition).ToString()] = configEntry;
			return configEntry;
		}

		public ConfigEntry<T> Bind<T>(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null, bool? serverAuthoritative = null)
		{
			ConfigEntry<T> configEntry = new ConfigEntry<T>(_mod.Config.Bind<T>(configDefinition, defaultValue, configDescription), serverAuthoritative.HasValue ? serverAuthoritative.Value : _DefaultBindAuthority);
			_configEntries[((object)configEntry.BaseEntry.Definition).ToString()] = configEntry;
			return configEntry;
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, bool? serverAuthoritative = null)
		{
			ConfigEntry<T> configEntry = new ConfigEntry<T>(_mod.Config.Bind<T>(section, key, defaultValue, description), serverAuthoritative.HasValue ? serverAuthoritative.Value : _DefaultBindAuthority);
			_configEntries[((object)configEntry.BaseEntry.Definition).ToString()] = configEntry;
			return configEntry;
		}

		public static void SendConfigToClient(long sender)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			if (!ZNet.IsServer())
			{
				return;
			}
			ZPackage val = new ZPackage();
			int num = 0;
			foreach (KeyValuePair<string, ConfigBaseEntry> configEntry in Instance._configEntries)
			{
				if (configEntry.Value.ServerAuthoritative)
				{
					val.Write(configEntry.Key);
					val.Write(configEntry.Value.BaseEntry.GetSerializedValue());
					num++;
					Logger.LogInfo((object)("Sending Config " + configEntry.Key + ": " + configEntry.Value.BaseEntry.GetSerializedValue()));
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, RPC_SYNC_GUID, new object[1] { val });
			Logger.LogInfo((object)$"Sent {num} config pairs to client {sender}");
		}

		public static void ReadConfigPkg(ZPackage pkg)
		{
			if (ZNet.IsServer())
			{
				return;
			}
			int num = 0;
			while (pkg.GetPos() != pkg.Size())
			{
				string text = pkg.ReadString();
				string text2 = pkg.ReadString();
				num++;
				if (Instance._configEntries.ContainsKey(text))
				{
					Instance._configEntries[text].SetSerializedValue(text2);
					Logger.LogInfo((object)("Applied Server Authoritative config pair => " + text + ": " + text2));
				}
				else
				{
					Logger.LogError((object)("Recieved config key we dont have locally. Possible Version Mismatch. " + text + ": " + text2));
				}
			}
			Logger.LogInfo((object)$"Applied {num} config pairs");
		}

		public static void RPC_SyncServerConfig(long sender, ZPackage pkg)
		{
			if (ZNet.IsServer() && _ServerIsAuthoritative.Value)
			{
				SendConfigToClient(sender);
			}
			else if (!ZNet.IsServer() && pkg != null && pkg.Size() > 0 && AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null).Invoke(ZRoutedRpc.instance, null) as long? == sender)
			{
				ReadConfigPkg(pkg);
			}
		}
	}
	public class ConfigBaseEntry
	{
		protected object _serverValue;

		public ConfigEntryBase BaseEntry;

		public bool ServerAuthoritative;

		protected bool _didError;

		internal ConfigBaseEntry(ConfigEntryBase configEntry, bool serverAuthoritative)
		{
			BaseEntry = configEntry;
			ServerAuthoritative = serverAuthoritative;
		}

		public void SetSerializedValue(string value)
		{
			try
			{
				_serverValue = TomlTypeConverter.ConvertToValue(value, BaseEntry.SettingType);
				_didError = false;
			}
			catch (Exception ex)
			{
				Config.Logger.LogWarning((object)$"Config value of setting \"{BaseEntry.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
			}
		}

		public void ClearServerValue()
		{
			_serverValue = null;
			_didError = false;
		}
	}
	public class ConfigEntry<T> : ConfigBaseEntry
	{
		private ConfigEntry<T> _configEntry;

		public T ServerValue => (T)_serverValue;

		public T Value
		{
			get
			{
				if (ServerAuthoritative && !Config.ZNet.IsServer())
				{
					if (_serverValue != null)
					{
						return ServerValue;
					}
					if (!_didError)
					{
						Config.Logger.LogWarning((object)("No Recieved value for Server Authoritative Config. " + ((object)BaseEntry.Definition).ToString() + ". Falling Back to Client Config."));
						_didError = true;
					}
					return _configEntry.Value;
				}
				return _configEntry.Value;
			}
			set
			{
				_configEntry.Value = value;
			}
		}

		internal ConfigEntry(ConfigEntry<T> configEntry, bool serverAuthoritative)
			: base((ConfigEntryBase)(object)configEntry, serverAuthoritative)
		{
			_configEntry = configEntry;
		}
	}
}
namespace SpeedyPaths
{
	[BepInPlugin("nex.SpeedyPaths", "Speedy Paths Mod", "1.0.9")]
	public class SpeedyPathsClientMod : BaseUnityPlugin
	{
		public enum GroundType
		{
			Untamed,
			PathDirt,
			PathStone,
			Cultivated,
			StructureWood,
			StructureHardWood,
			StructureStone,
			StructureIron,
			StructureMarble,
			StructureGrausten
		}

		private static Dictionary<GroundType, ConfigEntry<float>> _speedModifiers = new Dictionary<GroundType, ConfigEntry<float>>();

		private static Dictionary<GroundType, ConfigEntry<float>> _staminaModifiers = new Dictionary<GroundType, ConfigEntry<float>>();

		private static Dictionary<Biome, ConfigEntry<float>> _untamedSpeedModifiers = new Dictionary<Biome, ConfigEntry<float>>();

		private static Dictionary<Biome, ConfigEntry<float>> _untamedStaminaModifiers = new Dictionary<Biome, ConfigEntry<float>>();

		private static ConfigEntry<bool> _showHudStatus;

		private static ConfigEntry<string> _hudStatusText;

		private static ConfigEntry<bool> _hudDynamicStatusText;

		private static ConfigEntry<bool> _hudShowEffectPercent;

		private static List<ConfigEntry<float>> _hudPosIconThresholds = new List<ConfigEntry<float>>();

		private static List<ConfigEntry<float>> _hudNegIconThresholds = new List<ConfigEntry<float>>();

		private static ConfigEntry<float> _groundSensorUpdateInterval;

		private static ConfigEntry<int> _groundSensorRadius;

		private static Dictionary<GroundType, ConfigEntry<string>> _groundTypeStrings = new Dictionary<GroundType, ConfigEntry<string>>();

		private static Dictionary<Biome, ConfigEntry<string>> _biomeTypeStrings = new Dictionary<Biome, ConfigEntry<string>>();

		private static int m_pieceLayer;

		private static object[] _worldToVertexArgs = new object[3]
		{
			Vector3.zero,
			null,
			null
		};

		private static List<Sprite> _speedSprites = new List<Sprite>();

		private AssetBundle _speedyassets;

		private static float m_sensorTime;

		private static GroundType m_cachedGroundType;

		public static ManualLogSource Logger;

		private static float _activeSpeedModifier = 1f;

		private static float _activeStaminaModifier = 1f;

		private static string _activeStatusText;

		private static Sprite _activeStatusSprite;

		private static StatusEffect _pathBuffSEDummy;

		private static float _prevModValue = 1f;

		public Config Config
		{
			get
			{
				return Config.Instance;
			}
			set
			{
			}
		}

		private void Awake()
		{
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			_speedyassets = AssetBundle.LoadFromMemory(Resources.speedyassets);
			if (!Object.op_Implicit((Object)(object)_speedyassets))
			{
				Logger.LogError((object)"Failed to read AssetBundle stream");
				return;
			}
			Config.init((BaseUnityPlugin)(object)this, defaultBindServerAuthority: true);
			_hudDynamicStatusText = Config.Bind("Hud", "EnableDynamicStatusText", defaultValue: true, "Show surface type text as status effect name", false);
			_hudShowEffectPercent = Config.Bind("Hud", "ShowStatusEffectPercent", defaultValue: true, "Show the status effect buff/debuff %", false);
			_showHudStatus = Config.Bind("Hud", "ShowStatusIcon", defaultValue: true, "Show the speedypaths status icon in the hud", false);
			_hudStatusText = Config.Bind("Hud", "StatusText", "Speedy Path", "Text shown above the status icon", false);
			_hudPosIconThresholds.Add(Config.Bind("Hud", "BuffIcon +1", 1f, "Speed buff threshold to show lvl 1 buff icon"));
			_hudPosIconThresholds.Add(Config.Bind("Hud", "BuffIcon +2", 1.39f, "Speed buff threshold to show lvl 2 buff icon"));
			_hudNegIconThresholds.Add(Config.Bind("Hud", "DebuffIcon -1", 1f, "Speed buff threshold to show lvl 1 debuff icon"));
			_hudNegIconThresholds.Add(Config.Bind("Hud", "DebuffIcon -2", 0.79f, "Speed buff threshold to show lvl 2 debuff icon"));
			_groundSensorUpdateInterval = Config.Bind("Performance", "Ground Sensor Interval", 1f, "Interval between in seconds between ground type checks. Lower number, more accute ground detection.", true);
			_groundSensorRadius = Config.Bind("Performance", "Ground Sensor Radius", 1, "Radius of ground pixels to sample when checking under the player", true);
			_speedModifiers[GroundType.PathDirt] = Config.Bind("SpeedModifiers", "DirtPathSpeed", 1.15f, "Modifier for speed while on dirt paths");
			_speedModifiers[GroundType.PathStone] = Config.Bind("SpeedModifiers", "StonePathSpeed", 1.4f, "Modifier for speed while on stone paths");
			_speedModifiers[GroundType.Cultivated] = Config.Bind("SpeedModifiers", "CultivatedSpeed", 1f, "Modifier for speed while on Cultivated land");
			_speedModifiers[GroundType.StructureWood] = Config.Bind("SpeedModifiers", "StructureWoodSpeed", 1.15f, "Modifier for speed while on wood structures");
			_speedModifiers[GroundType.StructureHardWood] = Config.Bind("SpeedModifiers", "StructureHardWoodSpeed", 1.15f, "Modifier for speed while on core wood structures");
			_speedModifiers[GroundType.StructureStone] = Config.Bind("SpeedModifiers", "StructureStoneSpeed", 1.4f, "Modifier for speed while on stone structures");
			_speedModifiers[GroundType.StructureIron] = Config.Bind("SpeedModifiers", "StructureIronSpeed", 1.4f, "Modifier for speed while on ironwood structures");
			_speedModifiers[GroundType.StructureMarble] = Config.Bind("SpeedModifiers", "StructureMarbleSpeed", 1.4f, "Modifier for speed while on black marble structures");
			_speedModifiers[GroundType.StructureGrausten] = Config.Bind("SpeedModifiers", "StructureGraustenSpeed", 1.4f, "Modifier for speed while on grausten structures");
			_staminaModifiers[GroundType.PathDirt] = Config.Bind("StaminaModifiers", "DirtPathStamina", 0.8f, "Modifier for stamina while on dirt paths");
			_staminaModifiers[GroundType.PathStone] = Config.Bind("StaminaModifiers", "StonePathStamina", 0.7f, "Modifier for stamina while on stone paths");
			_staminaModifiers[GroundType.Cultivated] = Config.Bind("StaminaModifiers", "CultivatedStamina", 1f, "Modifier for stamina while on Cultivated land");
			_staminaModifiers[GroundType.StructureWood] = Config.Bind("StaminaModifiers", "StructureWoodStamina", 0.8f, "Modifier for stamina while on wood structures");
			_staminaModifiers[GroundType.StructureHardWood] = Config.Bind("StaminaModifiers", "StructureHardWoodStamina", 0.8f, "Modifier for stamina while on core wood structures");
			_staminaModifiers[GroundType.StructureStone] = Config.Bind("StaminaModifiers", "StructureStoneStamina", 0.7f, "Modifier for stamina while on stone structures");
			_staminaModifiers[GroundType.StructureIron] = Config.Bind("StaminaModifiers", "StructureIronStamina", 0.7f, "Modifier for stamina while on ironwood structures");
			_staminaModifiers[GroundType.StructureMarble] = Config.Bind("StaminaModifiers", "StructureMarbleStamina", 0.7f, "Modifier for stamina while on black marble structures");
			_staminaModifiers[GroundType.StructureGrausten] = Config.Bind("StaminaModifiers", "StructureGraustenStamina", 0.7f, "Modifier for stamina while on grausten structures");
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				Biome key = value;
				_untamedSpeedModifiers[key] = Config.Bind("SpeedModifiers_Biomes", "Untamed_" + ((object)(Biome)(ref key)).ToString() + "_Speed", 1f, "Speed modifier for uncleared ground in " + ((object)(Biome)(ref key)).ToString() + " Biomes");
				_untamedStaminaModifiers[key] = Config.Bind("StaminaModifiers_Biomes", "Untamed_" + ((object)(Biome)(ref key)).ToString() + "_Stamina", 1f, "Stamina modifier for uncleared ground in " + ((object)(Biome)(ref key)).ToString() + " Biomes");
				_biomeTypeStrings[key] = Config.Bind("Strings", "Biome_" + ((object)(Biome)(ref key)).ToString(), "default", "Dynamic status mapping for " + ((object)(Biome)(ref key)).ToString() + " groundcover. 'default' uses localized biome name.");
			}
			_groundTypeStrings[GroundType.PathDirt] = Config.Bind("Strings", "PathDirt", "Dirt Path", "Dynamic status mapping for dirt paths");
			_groundTypeStrings[GroundType.PathStone] = Config.Bind("Strings", "PathStone", "Stone Path", "Dynamic status mapping for stone paths");
			_groundTypeStrings[GroundType.Cultivated] = Config.Bind("Strings", "Cultivated", "Cultivated", "Dynamic status mapping for Cultivated land");
			_groundTypeStrings[GroundType.StructureWood] = Config.Bind("Strings", "StructureWood", "Wood", "Dynamic status mapping for wood structures");
			_groundTypeStrings[GroundType.StructureHardWood] = Config.Bind("Strings", "StructureHardWood", "Hardwood", "Dynamic status mapping for core wood structures");
			_groundTypeStrings[GroundType.StructureStone] = Config.Bind("Strings", "StructureStone", "Stone", "MDynamic status mapping for stone structures");
			_groundTypeStrings[GroundType.StructureIron] = Config.Bind("Strings", "StructureIron", "Iron", "Dynamic status mapping for ironwood structures");
			_groundTypeStrings[GroundType.StructureMarble] = Config.Bind("Strings", "StructureMarble", "Marble", "Dynamic status mapping for black marble structures");
			_groundTypeStrings[GroundType.StructureGrausten] = Config.Bind("Strings", "StructureGrausten", "Grausten", "Dynamic status mapping for grausten structures");
			if (m_pieceLayer == 0)
			{
				m_pieceLayer = LayerMask.NameToLayer("piece");
			}
			_speedSprites.Add(_speedyassets.LoadAsset<Sprite>("assets/nex.speedypaths/speedypaths_1.png"));
			_speedSprites.Add(_speedyassets.LoadAsset<Sprite>("assets/nex.speedypaths/speedypaths_2.png"));
			_speedSprites.Add(_speedyassets.LoadAsset<Sprite>("assets/nex.speedypaths/speedypaths_n1.png"));
			_speedSprites.Add(_speedyassets.LoadAsset<Sprite>("assets/nex.speedypaths/speedypaths_n2.png"));
			m_sensorTime = 0f;
			m_cachedGroundType = GroundType.Untamed;
			Harmony.CreateAndPatchAll(typeof(SpeedyPathsClientMod), (string)null);
		}

		[HarmonyPatch(typeof(Player), "FixedUpdate")]
		[HarmonyPrefix]
		private static void UpdateModifiers(Player __instance)
		{
			m_sensorTime -= Time.fixedDeltaTime;
			if (!((Object)(object)Player.m_localPlayer == (Object)(object)__instance) || ((Character)__instance).IsDead())
			{
				return;
			}
			UpdateGroundTypeCache(__instance);
			_activeSpeedModifier = GetSpeedyPathModifier(__instance);
			_activeStaminaModifier = GetSpeedyPathStaminaModifier(__instance);
			if (_activeSpeedModifier > 1f)
			{
				for (int i = 0; i < _hudPosIconThresholds.Count; i++)
				{
					if (_activeSpeedModifier > _hudPosIconThresholds[i].Value)
					{
						_activeStatusSprite = _speedSprites[i];
					}
				}
				return;
			}
			for (int j = 0; j < _hudNegIconThresholds.Count; j++)
			{
				if (_activeSpeedModifier < _hudNegIconThresholds[j].Value)
				{
					_activeStatusSprite = _speedSprites[_hudPosIconThresholds.Count + j];
				}
			}
		}

		[HarmonyPatch(typeof(Player), "CheckRun")]
		[HarmonyPrefix]
		private static void CheckRunPrefixStaminaMod(Player __instance, out float __state)
		{
			__state = __instance.m_runStaminaDrain;
			__instance.m_runStaminaDrain *= _activeStaminaModifier;
		}

		[HarmonyPatch(typeof(Player), "CheckRun")]
		[HarmonyPostfix]
		private static void CheckRunPostfixStaminaMod(Player __instance, float __state)
		{
			__instance.m_runStaminaDrain = __state;
		}

		[HarmonyPatch(typeof(Player), "GetJogSpeedFactor")]
		[HarmonyPostfix]
		private static void JogSpeedPathFactor(Player __instance, ref float __result)
		{
			__result *= _activeSpeedModifier;
		}

		[HarmonyPatch(typeof(Player), "GetRunSpeedFactor")]
		[HarmonyPostfix]
		private static void RunSpeedPathFactor(Player __instance, ref float __result)
		{
			__result *= _activeSpeedModifier;
		}

		[HarmonyPatch(typeof(Hud), "UpdateStatusEffects")]
		[HarmonyPrefix]
		private static void UpdatePathIcon(Hud __instance, List<StatusEffect> statusEffects)
		{
			if (((Character)Player.m_localPlayer).IsDead() || !_showHudStatus.Value || _activeSpeedModifier == 1f)
			{
				return;
			}
			if ((Object)(object)_pathBuffSEDummy == (Object)null)
			{
				ScriptableObject obj = ScriptableObject.CreateInstance(typeof(StatusEffect));
				_pathBuffSEDummy = (StatusEffect)(object)((obj is StatusEffect) ? obj : null);
			}
			_pathBuffSEDummy.m_name = (_hudDynamicStatusText.Value ? _activeStatusText : _hudStatusText.Value);
			_pathBuffSEDummy.m_icon = _activeStatusSprite;
			if (_activeSpeedModifier != 1f)
			{
				if (_activeSpeedModifier != _prevModValue)
				{
					_pathBuffSEDummy.m_isNew = true;
				}
				statusEffects.Add(_pathBuffSEDummy);
			}
			_prevModValue = _activeSpeedModifier;
		}

		[HarmonyPatch(typeof(StatusEffect), "GetIconText")]
		[HarmonyPostfix]
		private static void SpeedyPathsStatusEffect_GetIconText(StatusEffect __instance, ref string __result)
		{
			if ((Object)(object)__instance == (Object)(object)_pathBuffSEDummy && _hudShowEffectPercent.Value)
			{
				__result = (_activeSpeedModifier - 1f).ToString("P0");
			}
		}

		private static float GetSpeedyPathModifier(Player player)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)player).IsSwimming() && !((Character)player).InInterior())
			{
				if (_speedModifiers.ContainsKey(m_cachedGroundType))
				{
					_activeStatusText = _groundTypeStrings[m_cachedGroundType].Value;
					return _speedModifiers[m_cachedGroundType].Value;
				}
				Biome key = player.GetCurrentBiome();
				if (!_untamedSpeedModifiers.ContainsKey(key))
				{
					Logger.LogWarning((object)("New biome " + ((object)(Biome)(ref key)).ToString() + ". Unsure how to Handle. Falling back to None."));
					key = (Biome)0;
				}
				_activeStatusText = "$biome_" + ((object)(Biome)(ref key)).ToString().ToLower();
				if (_biomeTypeStrings.ContainsKey(key) && _biomeTypeStrings[key].Value != "default")
				{
					_activeStatusText = _biomeTypeStrings[key].Value;
				}
				return _untamedSpeedModifiers[key].Value;
			}
			return 1f;
		}

		private static float GetSpeedyPathStaminaModifier(Player player)
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)player).IsSwimming() && !((Character)player).InInterior())
			{
				if (_staminaModifiers.ContainsKey(m_cachedGroundType))
				{
					return _staminaModifiers[m_cachedGroundType].Value;
				}
				Biome key = player.GetCurrentBiome();
				if (!_untamedStaminaModifiers.ContainsKey(key))
				{
					Logger.LogWarning((object)("New biome " + ((object)(Biome)(ref key)).ToString() + ". Unsure how to Handle. Falling back to None."));
					key = (Biome)0;
				}
				return _untamedStaminaModifiers[key].Value;
			}
			return 1f;
		}

		private static void UpdateGroundTypeCache(Player player)
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected I4, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			if (m_sensorTime > 0f)
			{
				return;
			}
			m_sensorTime = _groundSensorUpdateInterval.Value;
			Collider lastGroundCollider = ((Character)player).GetLastGroundCollider();
			if (Object.op_Implicit((Object)(object)lastGroundCollider))
			{
				if (((Component)lastGroundCollider).gameObject.layer == m_pieceLayer)
				{
					WearNTear componentInParent = ((Component)lastGroundCollider).GetComponentInParent<WearNTear>();
					if (Object.op_Implicit((Object)(object)componentInParent))
					{
						MaterialType materialType = componentInParent.m_materialType;
						switch ((int)materialType)
						{
						case 0:
							m_cachedGroundType = GroundType.StructureWood;
							return;
						case 1:
							m_cachedGroundType = GroundType.StructureStone;
							return;
						case 3:
							m_cachedGroundType = GroundType.StructureHardWood;
							return;
						case 2:
							m_cachedGroundType = GroundType.StructureIron;
							return;
						case 4:
							m_cachedGroundType = GroundType.StructureMarble;
							return;
						case 5:
							m_cachedGroundType = GroundType.StructureGrausten;
							return;
						}
					}
				}
				Heightmap component = ((Component)lastGroundCollider).GetComponent<Heightmap>();
				if ((Object)(object)component != (Object)null)
				{
					object value = Traverse.Create((object)component).Field("m_paintMask").GetValue();
					Texture2D val = (Texture2D)((value is Texture2D) ? value : null);
					_worldToVertexArgs[0] = Traverse.Create((object)player).Field("m_lastGroundPoint").GetValue() as Vector3?;
					AccessTools.Method(typeof(Heightmap), "WorldToVertex", (Type[])null, (Type[])null).Invoke(component, _worldToVertexArgs);
					int value2 = _groundSensorRadius.Value;
					Color val2 = default(Color);
					int num = Math.Max((int)_worldToVertexArgs[1] - value2, 0);
					int num2 = value2 * 2;
					if (num2 + (int)_worldToVertexArgs[1] >= ((Texture)val).width)
					{
						num2 = ((Texture)val).width - num - 1;
					}
					int num3 = Math.Max((int)_worldToVertexArgs[2] - value2, 0);
					int num4 = value2 * 2;
					if (num4 + (int)_worldToVertexArgs[2] >= ((Texture)val).height)
					{
						num4 = ((Texture)val).height - num3 - 1;
					}
					Color[] pixels = val.GetPixels(num, num3, num2, num4, 0);
					Color[] array = pixels;
					foreach (Color val3 in array)
					{
						val2 += val3;
					}
					((Color)(ref val2))..ctor(val2.r / (float)pixels.Length, val2.g / (float)pixels.Length, val2.b / (float)pixels.Length);
					if (val2.b > 0.4f)
					{
						m_cachedGroundType = GroundType.PathStone;
						return;
					}
					if (val2.r > 0.4f)
					{
						m_cachedGroundType = GroundType.PathDirt;
						return;
					}
					if (val2.g > 0.4f)
					{
						m_cachedGroundType = GroundType.Cultivated;
						return;
					}
				}
			}
			m_cachedGroundType = GroundType.Untamed;
		}
	}
}
namespace SpeedyPaths.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("SpeedyPaths.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] speedyassets => (byte[])ResourceManager.GetObject("speedyassets", resourceCulture);

		internal Resources()
		{
		}
	}
}