Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MovementStats v0.1.8
plugins/MovementStats/MovementStats.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MovementStats")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.8.0")] [assembly: AssemblyInformationalVersion("0.1.8")] [assembly: AssemblyProduct("MovementStats")] [assembly: AssemblyTitle("MovementStats")] [assembly: AssemblyVersion("0.1.8.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 MovementStats { public static class MovementMath { public static float HorizontalSpeed(float x, float z) { return (float)Math.Sqrt(x * x + z * z); } public static float ConvertSpeed(float metersPerSecond, string unit) { if (!(unit == "km/h")) { if (unit == "mph") { return metersPerSecond / 0.44704f; } return metersPerSecond; } return metersPerSecond * 3.6f; } public static string FormatSpeed(float metersPerSecond, string unit) { string text = ((unit == "km/h" || unit == "mph") ? unit : "m/s"); return ConvertSpeed(metersPerSecond, text).ToString("0.00", CultureInfo.InvariantCulture) + " " + text; } public static float? EffectPercent(float before, float after) { if (float.IsNaN(before) || float.IsInfinity(before) || float.IsNaN(after) || float.IsInfinity(after) || Math.Abs(before) < 0.001f) { return null; } return (after / before - 1f) * 100f; } public static float? SurfacePercent(float before, float after, float liquidFactor) { float? num = EffectPercent(before, after); if (!num.HasValue || float.IsNaN(liquidFactor) || float.IsInfinity(liquidFactor)) { return null; } return ((1f + num.Value / 100f) * liquidFactor - 1f) * 100f; } public static float LavaFactor(float proximity, float height, float slowHeight, float slowMax) { if (!(proximity > 0.33f) || !(height > slowHeight)) { return 1f; } return 1f - (proximity - 0.33f) * 1.4925374f * slowMax; } public static float SnowFactor(float thickness, float startHeight, float maxHeight, float slowMax, float groundY, float playerY) { if (slowMax == 0f || thickness <= startHeight || groundY + thickness <= playerY || maxHeight <= startHeight) { return 1f; } return 1f - (groundY + thickness - playerY - startHeight) / (maxHeight - startHeight) * slowMax; } public static float CornerAlpha(float x, float y, float size, float radius) { return RectangleCornerAlpha(x, y, size, size, radius); } public static float RectangleCornerAlpha(float x, float y, float width, float height, float radius) { float num = Math.Max(Math.Max(radius - x, x - (width - radius)), 0f); float num2 = Math.Max(Math.Max(radius - y, y - (height - radius)), 0f); return Math.Max(0f, Math.Min(1f, radius + 0.5f - (float)Math.Sqrt(num * num + num2 * num2))); } public static string EquipmentColor(float percent) { if (float.IsNaN(percent) || float.IsInfinity(percent)) { return "#FFFFFF"; } if (percent > 0.05f) { return "#89E8A1"; } return (int)Math.Min(5.0, Math.Floor((Math.Max(0.0, 0.0 - (double)percent) + 1E-05) / 5.0)) switch { 1 => "#FFCCCC", 2 => "#FF9999", 3 => "#FF6666", 4 => "#FF3333", 5 => "#FF0000", _ => "#FFFFFF", }; } public static string Percent(float value) { return ((Math.Abs(value) < 0.05f) ? 0f : value).ToString("+0.0;-0.0;0.0", CultureInfo.InvariantCulture) + " %"; } } [BepInPlugin("cz.misaweb.valheim.movementstats", "Movement Stats", "0.1.8")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal static Plugin Instance; private Harmony harmony; private ConfigEntry<bool> modEnabled; private ConfigEntry<bool> showRunIcon; private ConfigEntry<bool> showEquipmentIcon; private ConfigEntry<bool> surfaceDiagnostics; private SpeedyPathsReader speedyReader; private Type speedyType; private string lastSurfaceDiagnostic; private bool speedyErrorLogged; private ConfigEntry<float> backgroundTransparency; private ConfigEntry<int> widthStep; private ConfigEntry<string> speedUnit; private Texture2D roundedBackground; private Sprite runIcon; private Sprite equipmentIcon; private bool equipmentIconFailed; private bool fallbackLogged; private bool iconFailed; private float playerFirstSeen; private ConfigEntry<float> left; private ConfigEntry<float> top; private Player trackedPlayer; private string equipmentText = "V: —"; private string speedText = "— m/s"; private string surfaceText = "P: —"; private float nextUpdate; private float surfaceTime = -100f; private float liquidTime = -100f; private float tarTime = -100f; private float? terrainBefore; private float? terrainPercent; private float? liquidPercent; private float? tarPercent; private float liquidBefore; private float liquidAfter; private float tileSide = 80f; private Type guiType; private Type styleType; private Type contentType; private object style; private MethodInfo label; private MethodInfo drawTexture; private MethodInfo drawTextureCoords; private MethodInfo calcSize; private PropertyInfo guiColor; private bool guiFailed; private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4]; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Expected O, but got Unknown Instance = this; ((BaseUnityPlugin)this).Config.Remove(new ConfigDefinition("1. Display", "Font size")); ((BaseUnityPlugin)this).Config.Remove(new ConfigDefinition("1. Display", "Test effects row")); modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Display", "Enabled", true, "Zobrazit ukazatel pohybu. Pismo se automaticky vejde do velikosti slotu rychleho vyberu."); backgroundTransparency = ((BaseUnityPlugin)this).Config.Bind<float>("1. Display", "Background transparency", 75f, new ConfigDescription("Pruhlednost pozadi v procentech: 0 = nepruhledne, 100 = uplne pruhledne. Text a ikona zustavaji citelne.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); showRunIcon = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Display", "Show running icon", true, "Zobrazit puvodni ikonu dovednosti Beh u rychlosti."); surfaceDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Diagnostics", "Surface diagnostics", false, "Zapisovat do LogOutput.log zmeny hodnoty a zdroje modifikatoru povrchu (SpeedyPaths nebo zakladni hra)."); widthStep = ((BaseUnityPlugin)this).Config.Bind<int>("2. Position", "Width step", 1, new ConfigDescription("Sirka panelu ve trech krocich: 1 = puvodni ctverec (100 %), 2 = 150 %, 3 = 200 %. Vyska zustava stejna.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>())); showEquipmentIcon = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Display", "Show equipment icon", true, "Zobrazit misto V puvodni stavebni ikonu D.U.B. (piece_TrainingDummy)."); speedUnit = ((BaseUnityPlugin)this).Config.Bind<string>("1. Display", "Speed unit", "m/s", new ConfigDescription("Jednotka zobrazovane rychlosti: m/s, km/h nebo mph.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "m/s", "km/h", "mph" }), Array.Empty<object>())); speedUnit.SettingChanged += delegate { nextUpdate = 0f; }; left = ((BaseUnityPlugin)this).Config.Bind<float>("2. Position", "Left percent", 2f, new ConfigDescription("Vodorovna pozice v procentech obrazovky.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); top = ((BaseUnityPlugin)this).Config.Bind<float>("2. Position", "Top percent", 28f, new ConfigDescription("Svisla pozice v procentech obrazovky.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); harmony = new Harmony("cz.misaweb.valheim.movementstats"); Type[] array = new Type[3] { typeof(GroundSpeedPatch), typeof(LiquidResistancePatch), typeof(TarSpeedPatch) }; foreach (Type type in array) { try { harmony.CreateClassProcessor(type).Patch(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Installed " + type.Name)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)(type.Name + " unavailable: " + ex)); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Movement Stats 0.1.8 loaded. Refresh 1 s."); } private void Update() { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)(object)trackedPlayer) { trackedPlayer = localPlayer; surfaceTime = (liquidTime = (tarTime = -100f)); terrainPercent = (terrainBefore = (liquidPercent = (tarPercent = null))); runIcon = (equipmentIcon = null); equipmentIconFailed = false; fallbackLogged = (iconFailed = false); playerFirstSeen = Time.unscaledTime; nextUpdate = 0f; } if (!Object.op_Implicit((Object)(object)localPlayer) || !modEnabled.Value || Time.unscaledTime < nextUpdate) { return; } nextUpdate = Time.unscaledTime + 1f; LoadEquipmentIcon(); float num = ((Character)localPlayer).GetEquipmentMovementModifier() * 100f; equipmentText = ((showEquipmentIcon.Value && Object.op_Implicit((Object)(object)equipmentIcon)) ? "" : "V: ") + "<color=" + MovementMath.EquipmentColor(num) + ">" + MovementMath.Percent(num) + "</color>"; Vector3 velocity = ((Character)localPlayer).GetVelocity(); speedText = MovementMath.FormatSpeed(MovementMath.HorizontalSpeed(velocity.x, velocity.z), speedUnit.Value); UpdateSurfaceText(localPlayer); if (showRunIcon.Value && !iconFailed && !Object.op_Implicit((Object)(object)runIcon)) { try { Skills skills = ((Character)localPlayer).GetSkills(); object? obj = AccessTools.Method(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null).Invoke(skills, new object[1] { (object)(SkillType)102 }); SkillDef val = (SkillDef)((obj is SkillDef) ? obj : null); if (val != null) { runIcon = val.m_icon; } } catch (Exception ex) { iconFailed = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Running icon unavailable: " + ex.Message)); } } MeasureHotbar(); } private void LoadEquipmentIcon() { if (!showEquipmentIcon.Value || Object.op_Implicit((Object)(object)equipmentIcon) || equipmentIconFailed || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } try { GameObject prefab = ZNetScene.instance.GetPrefab("piece_TrainingDummy"); if (Object.op_Implicit((Object)(object)prefab)) { Piece component = prefab.GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_icon)) { equipmentIcon = component.m_icon; } } } catch (Exception ex) { equipmentIconFailed = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("D.U.B. equipment icon unavailable: " + ex.Message)); } } private void UpdateSurfaceText(Player player) { PluginInfo value; bool flag = Chainloader.PluginInfos.TryGetValue("nex.SpeedyPaths", out value) && Object.op_Implicit((Object)(object)value.Instance); bool flag2 = ((Character)player).InLiquid(); SurfaceMode surfaceMode = SurfaceReadout.Select(((Character)player).IsSwimming(), flag2, flag); if (surfaceMode == SurfaceMode.Swimming) { surfaceText = "Plavání"; LogSurface("Swimming; wading resistance not displayed as a walking modifier"); return; } bool flag3 = false; foreach (StatusEffect statusEffect in ((Character)player).GetSEMan().GetStatusEffects()) { if (Object.op_Implicit((Object)(object)statusEffect) && (((Object)statusEffect).name == "Tared" || ((Object)statusEffect).name == "Tared(Clone)")) { flag3 = true; } } float? num = 0f; string surface = "none"; if (flag) { Type type = ((object)value.Instance).GetType(); if (speedyReader == null || speedyType != type) { speedyType = type; speedyReader = new SpeedyPathsReader(type); speedyErrorLogged = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Surface source: native terrain plus live SpeedyPaths " + value.Metadata.Version)); } if (speedyReader.TryRead(out var percent, out surface, out var error)) { num = percent; } else { num = null; if (!speedyErrorLogged) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("SpeedyPaths integration unavailable: " + error)); speedyErrorLogged = true; } } } float? num2 = SurfaceReadout.FreshPercent(terrainPercent, Time.unscaledTime - surfaceTime); bool flag4 = !num2.HasValue; if (flag4) { num2 = ReadNativeTerrain(player); } float? num3 = SurfaceReadout.ActivePercent(surfaceMode == SurfaceMode.Wading, liquidPercent, Time.unscaledTime - liquidTime); float? num4 = SurfaceReadout.ActivePercent(flag3, tarPercent, Time.unscaledTime - tarTime); float? value2 = SurfaceReadout.Combine(num, num2, num3, num4); string text = ReadGroundMaterial(player); bool lavaActive = false; try { Func<string, float> func = (string name) => Convert.ToSingle(AccessTools.Field(typeof(Character), name).GetValue(player)); lavaActive = MovementMath.LavaFactor(func("m_lavaProximity"), func("m_lavaHeightFactor"), func("m_lavaSlowHeight"), func("m_lavaSlowMax")) != 1f; if (flag2 && func("m_tarLevel") > func("m_waterLevel")) { text = "Tar"; } } catch { } string text2 = SurfaceReadout.Label(text, flag2, flag3, lavaActive); if (!flag2 && !((Character)player).IsOnGround()) { surfaceText = "P: vzduch"; } else { surfaceText = (value2.HasValue ? Colored(text2 + (flag4 ? "≈ " : ": "), value2.Value) : (text2 + ": ?")); } LogSurface("material=" + text + "; SpeedyPaths(" + surface + ")=" + Describe(num) + "; terrain=" + Describe(num2) + (flag4 ? " fallback" : " observed") + "; liquid=" + Describe(num3) + "; tar=" + Describe(num4) + "; total=" + Describe(value2) + "; liquid speed=" + liquidBefore.ToString("0.000", CultureInfo.InvariantCulture) + " -> " + liquidAfter.ToString("0.000", CultureInfo.InvariantCulture)); if (flag4 && !fallbackLogged && Time.unscaledTime - playerFirstSeen > 3f) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Native terrain observer has no fresh sample; using the native lava/snow fallback when available."); fallbackLogged = true; } } private static string Describe(float? value) { if (!value.HasValue) { return "unavailable"; } return MovementMath.Percent(value.Value); } private string ReadGroundMaterial(Player player) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { FootStep componentInChildren = ((Component)player).GetComponentInChildren<FootStep>(true); if (!Object.op_Implicit((Object)(object)componentInChildren)) { return "Unknown"; } return AccessTools.Method(typeof(FootStep), "GetGroundMaterial", (Type[])null, (Type[])null).Invoke(componentInChildren, new object[2] { player, ((Component)player).transform.position })?.ToString() ?? "Unknown"; } catch { return "Unknown"; } } private void LogSurface(string diagnostic) { if (!surfaceDiagnostics.Value) { lastSurfaceDiagnostic = null; } else if (!(lastSurfaceDiagnostic == diagnostic)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Surface: " + diagnostic)); lastSurfaceDiagnostic = diagnostic; } } private float? ReadNativeTerrain(Player player) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (((Character)player).IsSwimming()) { return null; } try { Func<string, float> func = (string name) => Convert.ToSingle(AccessTools.Field(typeof(Character), name).GetValue(player)); float num = MovementMath.LavaFactor(func("m_lavaProximity"), func("m_lavaHeightFactor"), func("m_lavaSlowHeight"), func("m_lavaSlowMax")); if (Convert.ToInt32(AccessTools.Field(typeof(Character), "m_lastBiome").GetValue(player)) == 64) { object? value = AccessTools.Field(typeof(Character), "m_lastHeightmap").GetValue(player); Heightmap val = (Heightmap)((value is Heightmap) ? value : null); if (Object.op_Implicit((Object)(object)val)) { float num2 = func("m_deepSnowSlowMaxHeight"); float thickness = val.GetCultivationMask(((Component)player).transform.position) * num2; Vector3 val2 = (Vector3)AccessTools.Field(typeof(Character), "m_lastGroundHeight").GetValue(player); num *= MovementMath.SnowFactor(thickness, func("m_deepSnowSlowStartHeight"), num2, func("m_deepSnowSlowMax"), val2.y, ((Component)player).transform.position.y); } num *= MovementMath.LavaFactor(func("m_lavaProximity"), func("m_lavaHeightFactor"), func("m_lavaSlowHeight"), func("m_lavaSlowMax")); } return (num - 1f) * 100f; } catch (Exception ex) { if (!fallbackLogged) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Native terrain fallback unavailable: " + ex.Message)); } return null; } } private static string Colored(string prefix, float value) { string text = ((value < -0.05f) ? "#FF8585" : ((value > 0.05f) ? "#89E8A1" : "#FFFFFF")); return prefix + "<color=" + text + ">" + MovementMath.Percent(value) + "</color>"; } private void MeasureHotbar() { HotkeyBar[] array = Object.FindObjectsByType<HotkeyBar>((FindObjectsSortMode)0); foreach (HotkeyBar val in array) { if (!((Component)val).gameObject.activeInHierarchy || !(AccessTools.Field(typeof(HotkeyBar), "m_elements")?.GetValue(val) is IEnumerable enumerable)) { continue; } foreach (object item in enumerable) { object? obj = AccessTools.Field(item.GetType(), "m_go")?.GetValue(item); GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); if (!Object.op_Implicit((Object)(object)val2) || !val2.activeInHierarchy) { continue; } Transform transform = val2.transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (Object.op_Implicit((Object)(object)val3)) { val3.GetWorldCorners(corners); float num = Mathf.Abs(corners[2].x - corners[0].x); if (num >= 20f && num <= (float)Screen.width / 3f) { tileSide = num; return; } } } } } internal static void BeginSurface(Character character, float speed) { Plugin instance = Instance; if ((Object)(object)instance != (Object)null && (Object)(object)character == (Object)(object)Player.m_localPlayer) { instance.terrainBefore = speed; } } internal static void EndSurface(Character character, float speed) { Plugin instance = Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && instance.terrainBefore.HasValue) { instance.terrainPercent = MovementMath.EffectPercent(instance.terrainBefore.Value, speed); instance.surfaceTime = Time.unscaledTime; instance.terrainBefore = null; } } internal static void CaptureLiquid(Character character, float before, float after) { Plugin instance = Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)character != (Object)(object)Player.m_localPlayer)) { float? num = MovementMath.EffectPercent(before, after); instance.liquidBefore = before; instance.liquidAfter = after; instance.liquidPercent = num; instance.liquidTime = Time.unscaledTime; } } internal static void CaptureTar(SE_Stats effect, Character character, float before, float after) { Plugin instance = Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && (!(((Object)effect).name != "Tared") || !(((Object)effect).name != "Tared(Clone)"))) { float? num = MovementMath.EffectPercent(before, after); instance.tarPercent = num; instance.tarTime = Time.unscaledTime; } } private void InitializeGui() { guiType = Type.GetType("UnityEngine.GUI, UnityEngine.IMGUIModule", throwOnError: true); styleType = Type.GetType("UnityEngine.GUIStyle, UnityEngine.IMGUIModule", throwOnError: true); contentType = Type.GetType("UnityEngine.GUIContent, UnityEngine.IMGUIModule", throwOnError: true); object value = guiType.GetProperty("skin").GetValue(null, null); object value2 = value.GetType().GetProperty("label").GetValue(value, null); style = Activator.CreateInstance(styleType, value2); styleType.GetProperty("richText").SetValue(style, true, null); styleType.GetProperty("wordWrap").SetValue(style, false, null); styleType.GetProperty("alignment").SetValue(style, Enum.ToObject(styleType.GetProperty("alignment").PropertyType, 4), null); label = guiType.GetMethod("Label", new Type[3] { typeof(Rect), typeof(string), styleType }); drawTexture = guiType.GetMethod("DrawTexture", new Type[2] { typeof(Rect), typeof(Texture) }); drawTextureCoords = guiType.GetMethod("DrawTextureWithTexCoords", new Type[3] { typeof(Rect), typeof(Texture), typeof(Rect) }); calcSize = styleType.GetMethod("CalcSize", new Type[1] { contentType }); guiColor = guiType.GetProperty("color"); if (label == null || drawTexture == null || calcSize == null) { throw new MissingMethodException("Unity IMGUI methods not found"); } } private void EnsureBackground(float width, float height) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) int num = Mathf.Max(1, Mathf.RoundToInt(64f * width / height)); if (Object.op_Implicit((Object)(object)roundedBackground) && ((Texture)roundedBackground).width == num) { return; } if (Object.op_Implicit((Object)(object)roundedBackground)) { Object.Destroy((Object)(object)roundedBackground); } roundedBackground = new Texture2D(num, 64, (TextureFormat)4, false); ((Object)roundedBackground).name = "MovementStats rounded background"; ((Texture)roundedBackground).wrapMode = (TextureWrapMode)1; ((Texture)roundedBackground).filterMode = (FilterMode)1; Color[] array = (Color[])(object)new Color[num * 64]; for (int i = 0; i < 64; i++) { for (int j = 0; j < num; j++) { array[i * num + j] = new Color(1f, 1f, 1f, MovementMath.RectangleCornerAlpha((float)j + 0.5f, (float)i + 0.5f, num, 64f, 9f)); } } roundedBackground.SetPixels(array); roundedBackground.Apply(false, true); } private void OnGUI() { //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!modEnabled.Value || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || guiFailed) { return; } Hud instance = Hud.instance; if (Object.op_Implicit((Object)(object)instance) && !((Component)instance).gameObject.activeInHierarchy) { return; } GameObject val = (GameObject)(Object.op_Implicit((Object)(object)instance) ? /*isinst with value type is only supported in some contexts*/: null); if (Object.op_Implicit((Object)(object)val) && !val.activeInHierarchy) { return; } try { if (style == null) { InitializeGui(); } float num = Mathf.Min(tileSide, (float)Mathf.Min(Screen.width, Screen.height)); float num2 = Mathf.Min((float)Screen.width, num * (1f + (float)(widthStep.Value - 1) * 0.5f)); EnsureBackground(num2, num); float num3 = Mathf.Max(2f, num * 0.04f); float num4 = (num - 2f * num3) / 3f; string[] array = new string[3] { equipmentText, speedText, surfaceText }; Sprite[] array2 = (Sprite[])(object)new Sprite[3] { (showEquipmentIcon.Value && Object.op_Implicit((Object)(object)equipmentIcon) && drawTextureCoords != null) ? equipmentIcon : null, (showRunIcon.Value && Object.op_Implicit((Object)(object)runIcon) && drawTextureCoords != null) ? runIcon : null, default(Sprite) }; float num5 = num4 * 0.8f; for (int num6 = Mathf.Max(6, Mathf.FloorToInt(num4 * 0.85f)); num6 >= 6; num6--) { styleType.GetProperty("fontSize").SetValue(style, num6, null); bool flag = true; for (int i = 0; i < array.Length; i++) { object obj = Activator.CreateInstance(contentType, array[i]); Vector2 val2 = (Vector2)calcSize.Invoke(style, new object[1] { obj }); if (val2.x > num2 - 2f * num3 - (Object.op_Implicit((Object)(object)array2[i]) ? (num5 + 1f) : 0f) || val2.y > num4) { flag = false; } } if (flag || num6 == 6) { break; } } float num7 = Mathf.Clamp((float)Screen.width * left.Value / 100f, 0f, Mathf.Max(0f, (float)Screen.width - num2)); float num8 = Mathf.Clamp((float)Screen.height * top.Value / 100f, 0f, Mathf.Max(0f, (float)Screen.height - num)); object value = guiColor.GetValue(null, null); try { guiColor.SetValue(null, (object)new Color(0f, 0f, 0f, 1f - backgroundTransparency.Value / 100f), null); drawTexture.Invoke(null, new object[2] { (object)new Rect(num7, num8, num2, num), roundedBackground }); guiColor.SetValue(null, Color.white, null); for (int j = 0; j < array.Length; j++) { float num9 = (Object.op_Implicit((Object)(object)array2[j]) ? (num5 + 1f) : 0f); label.Invoke(null, new object[3] { (object)new Rect(num7 + num3 + num9, num8 + num3 + (float)j * num4, num2 - num3 * 2f - num9, num4), array[j], style }); } for (int k = 0; k < array2.Length; k++) { Sprite val3 = array2[k]; if (!Object.op_Implicit((Object)(object)val3)) { continue; } try { Rect textureRect = val3.textureRect; ((Rect)(ref textureRect))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)val3.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)val3.texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)val3.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)val3.texture).height); drawTextureCoords.Invoke(null, new object[3] { (object)new Rect(num7 + num3, num8 + num3 + (float)k * num4 + (num4 - num5) / 2f, num5, num5), val3.texture, textureRect }); } catch (Exception ex) { if (k == 0) { equipmentIconFailed = true; equipmentIcon = null; } else { iconFailed = true; runIcon = null; } ((BaseUnityPlugin)this).Logger.LogWarning((object)("HUD icon could not be drawn (row " + k + "): " + ex.Message)); } } } finally { guiColor.SetValue(null, value, null); } } catch (Exception ex2) { guiFailed = true; ((BaseUnityPlugin)this).Logger.LogError((object)("Movement Stats HUD failed: " + ex2)); } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } if (Object.op_Implicit((Object)(object)roundedBackground)) { Object.Destroy((Object)(object)roundedBackground); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(SE_Stats), "ModifySpeed")] internal static class TarSpeedPatch { private static void Prefix(float __1, out float __state) { __state = __1; } private static void Postfix(SE_Stats __instance, Character __2, float __1, float __state) { Plugin.CaptureTar(__instance, __2, __state, __1); } } [HarmonyPatch(typeof(Character), "ApplyLiquidResistance")] internal static class LiquidResistancePatch { private static void Prefix(float __0, out float __state) { __state = __0; } private static void Postfix(Character __instance, float __0, float __state) { Plugin.CaptureLiquid(__instance, __state, __0); } } [HarmonyPatch(typeof(Character), "UpdateWalking")] internal static class GroundSpeedPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return SurfaceInstrumentation.Inject(instructions, AccessTools.Method(typeof(SEMan), "ApplyStatusEffectSpeedMods", (Type[])null, (Type[])null), AccessTools.Method(typeof(Character), "CanMove", (Type[])null, (Type[])null), AccessTools.Field(typeof(Character), "m_lavaProximity"), AccessTools.Method(typeof(Plugin), "BeginSurface", (Type[])null, (Type[])null), AccessTools.Method(typeof(Plugin), "EndSurface", (Type[])null, (Type[])null)); } } internal sealed class SpeedyPathsReader { private readonly FieldInfo modifier; private readonly FieldInfo ground; internal SpeedyPathsReader(Type pluginType) { modifier = pluginType.GetField("_activeSpeedModifier", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); ground = pluginType.GetField("m_cachedGroundType", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); } internal bool TryRead(out float percent, out string surface, out string error) { percent = 0f; surface = "unknown"; error = null; if (modifier == null || modifier.FieldType != typeof(float)) { error = "SpeedyPaths._activeSpeedModifier (float) is unavailable"; return false; } try { float num = (float)modifier.GetValue(null); if (float.IsNaN(num) || float.IsInfinity(num) || num < 0f) { error = "SpeedyPaths returned an invalid speed factor"; return false; } percent = (num - 1f) * 100f; if (ground != null) { surface = ground.GetValue(null)?.ToString() ?? "unknown"; } return true; } catch (Exception ex) { error = ex.Message; return false; } } } internal static class SurfaceInstrumentation { internal static IEnumerable<CodeInstruction> Inject(IEnumerable<CodeInstruction> input, MethodInfo effects, MethodInfo canMove, FieldInfo terrainField, MethodInfo begin, MethodInfo end) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown List<CodeInstruction> list = input.ToList(); int num = list.FindIndex((CodeInstruction i) => CodeInstructionExtensions.Calls(i, effects)); int num2 = list.FindIndex(num + 1, (CodeInstruction i) => CodeInstructionExtensions.Calls(i, canMove)); if (num < 2 || num2 <= num + 3 || (list[num - 2].opcode != OpCodes.Ldloca_S && list[num - 2].opcode != OpCodes.Ldloca) || list[num + 1].opcode != OpCodes.Ldarg_0 || !CodeInstructionExtensions.LoadsField(list[num + 2], terrainField, false) || list[num2 - 1].opcode != OpCodes.Ldarg_0) { throw new InvalidOperationException("Surface observer: unsupported Character.UpdateWalking layout; no surface value available."); } object operand = list[num - 2].operand; CodeInstruction[] collection = (CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc, operand), new CodeInstruction(OpCodes.Call, (object)begin) }; CodeInstruction[] array = (CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc, operand), new CodeInstruction(OpCodes.Call, (object)end) }; FieldInfo? field = typeof(CodeInstruction).GetField("labels"); IList list2 = (IList)field.GetValue(list[num2 - 1]); IList list3 = (IList)field.GetValue(array[0]); foreach (object item in list2) { list3.Add(item); } list2.Clear(); list.InsertRange(num2 - 1, array); list.InsertRange(num + 1, collection); return list; } } internal enum SurfaceMode { Swimming, Wading, SpeedyPaths, Native } internal static class SurfaceReadout { internal static SurfaceMode Select(bool swimming, bool inLiquid, bool hasSpeedyPaths) { if (!swimming) { if (!inLiquid) { if (!hasSpeedyPaths) { return SurfaceMode.Native; } return SurfaceMode.SpeedyPaths; } return SurfaceMode.Wading; } return SurfaceMode.Swimming; } internal static float? ActivePercent(bool applies, float? percent, float age) { if (!applies) { return 0f; } return FreshPercent(percent, age); } internal static float? Combine(params float?[] percentages) { float num = 1f; for (int i = 0; i < percentages.Length; i++) { float? num2 = percentages[i]; if (!num2.HasValue || float.IsNaN(num2.Value) || float.IsInfinity(num2.Value)) { return null; } num *= 1f + num2.Value / 100f; } if (!float.IsNaN(num) && !float.IsInfinity(num)) { return (num - 1f) * 100f; } return null; } internal static string Label(string material, bool inLiquid, bool tared, bool lavaActive) { if (tared || material == "Tar") { return "Dehet"; } if (inLiquid || material == "Water") { return "Voda"; } if (lavaActive || material == "Lava") { return "Láva"; } if (material != null && material.StartsWith("Snow", StringComparison.Ordinal)) { return "Sníh"; } if (!(material == "Ice")) { return "P"; } return "Led"; } internal static float? FreshPercent(float? percent, float age) { if (!percent.HasValue || age < 0f || age > 1.5f || float.IsNaN(age) || float.IsInfinity(age) || float.IsNaN(percent.Value) || float.IsInfinity(percent.Value)) { return null; } return percent; } } }