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 Odins Stagger Home v0.1.0
plugins/OdinsStaggerHome.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [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("OdinsStaggerHome")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+67fbd5ecf50f1d96978a873234f778d4adf3995c")] [assembly: AssemblyProduct("OdinsStaggerHome")] [assembly: AssemblyTitle("OdinsStaggerHome")] [assembly: AssemblyVersion("0.1.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 OdinsStaggerHome { internal static class HudText { private sealed class Scale : MonoBehaviour { private const float ReferenceWidth = 1920f; private const float ReferenceHeight = 1080f; private static readonly FieldRef<float> GameGuiScale = TryFindGuiScale(); internal CanvasScaler Scaler; private float _logged = -1f; private void Update() { if (!((Object)(object)Scaler == (Object)null)) { float num = ((GameGuiScale != null) ? GameGuiScale.Invoke() : 1f); if (num <= 0f) { num = 1f; } float num2 = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * num * Plugin.TextScale.Value; if (Mathf.Abs(Scaler.scaleFactor - num2) > 0.0001f) { Scaler.scaleFactor = num2; } if (Plugin.DebugLog.Value && Mathf.Abs(_logged - num2) > 0.0001f) { _logged = num2; Plugin.Log.LogInfo((object)$"Text scale {num2:0.###}: screen {Screen.width}x{Screen.height}, game GUI scale {num:0.##}, TextScale {Plugin.TextScale.Value:0.##}."); } } } private static FieldRef<float> TryFindGuiScale() { FieldInfo fieldInfo = AccessTools.Field(typeof(GuiScaler), "m_largeGuiScale"); if (fieldInfo == null || fieldInfo.FieldType != typeof(float) || !fieldInfo.IsStatic) { Plugin.Log.LogWarning((object)"Couldn't find the game's GUI scale; text follows the screen size only."); return null; } return AccessTools.StaticFieldRefAccess<float>(fieldInfo); } } private static Canvas _canvas; public static TMP_Text Create(string name, Transform owner) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = (((Object)(object)MessageHud.instance != (Object)null) ? MessageHud.instance.m_messageCenterText : null); if ((Object)(object)val == (Object)null || (Object)(object)val.font == (Object)null || !EnsureCanvas(owner)) { return null; } GameObject val2 = new GameObject(name, new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(((Component)_canvas).transform, false); TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = val.font; ((TMP_Text)obj).fontSharedMaterial = val.fontSharedMaterial; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj).textWrappingMode = (TextWrappingModes)1; ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).outlineWidth = 0.15f; ((TMP_Text)obj).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)200); RectTransform val3 = (RectTransform)val2.transform; val3.pivot = new Vector2(0.5f, 0.5f); val3.anchoredPosition = Vector2.zero; return (TMP_Text)(object)obj; } private static bool EnsureCanvas(Transform owner) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_004b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_canvas != (Object)null) { return true; } GameObject val = new GameObject("OdinsStaggerHome_Canvas"); val.transform.SetParent(owner, false); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 5000; CanvasScaler val2 = val.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)0; val.AddComponent<Scale>().Scaler = val2; Plugin.Log.LogInfo((object)"On-screen text layer created."); return true; } } internal class OdinLine : MonoBehaviour { private const float ScreenY = 0.72f; private const float FadeIn = 0.2f; private const float Hold = 3.5f; private const float FadeOut = 0.8f; private const float TextSize = 21f; private static readonly Color Tint = new Color(1f, 0.86f, 0.62f); private TMP_Text _text; private float _elapsed = -1f; public void Show(string line) { if (EnsureText()) { _text.text = line; _elapsed = 0f; SetAlpha(0f); ((Component)_text).gameObject.SetActive(true); } } private void Update() { if (_elapsed < 0f || (Object)(object)_text == (Object)null) { return; } _elapsed += Time.deltaTime; float num = 4.5f; if (_elapsed >= num) { _elapsed = -1f; ((Component)_text).gameObject.SetActive(false); return; } float num2 = Mathf.Min(Mathf.Clamp01(_elapsed / 0.2f), Mathf.Clamp01((num - _elapsed) / 0.8f)); if (!HudVisible()) { num2 = 0f; } SetAlpha(Mathf.SmoothStep(0f, 1f, num2)); } private void SetAlpha(float alpha) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) Color tint = Tint; tint.a = alpha; ((Graphic)_text).color = tint; } private bool EnsureText() { //IL_0041: 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) //IL_0051: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_text != (Object)null) { return true; } _text = HudText.Create("OdinsStaggerHome_Line", ((Component)this).transform); if ((Object)(object)_text == (Object)null) { return false; } RectTransform val = (RectTransform)_text.transform; val.anchorMin = new Vector2(0.5f, 0.72f); val.anchorMax = new Vector2(0.5f, 0.72f); val.sizeDelta = new Vector2(1400f, 160f); _text.fontSize = 21f; return true; } private static bool HudVisible() { if ((Object)(object)Hud.instance != (Object)null && !Hud.IsUserHidden()) { return Hud.instance.IsVisible(); } return false; } private void OnDestroy() { if ((Object)(object)_text != (Object)null) { Object.Destroy((Object)(object)((Component)_text).gameObject); } } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class SetControlsPatch { private static void Prefix(Player __instance, Vector3 movedir, bool attack, bool attackHold, bool secondaryAttack, bool secondaryAttackHold, bool block, bool blockHold, bool jump, bool crouch, bool autoRun, bool dodge) { //IL_0027: 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) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)StaggerHome.Instance == (Object)null) && StaggerHome.Instance.Active && (movedir != Vector3.zero || attack || attackHold || secondaryAttack || secondaryAttackHold || block || blockHold || jump || crouch || autoRun || dodge)) { StaggerHome.Instance.OnPlayerInput(); } } private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { StaggerHome.Instance?.Drive(__instance); } } } [HarmonyPatch(typeof(Game), "Shutdown")] internal static class ShutdownPatch { private static void Prefix() { StaggerHome.Instance?.OnLogout(); } } [HarmonyPatch(typeof(Player), "OnDamaged")] internal static class DamagedPatch { private static void Postfix(Player __instance, HitData hit) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)StaggerHome.Instance != (Object)null && StaggerHome.Instance.Active) { StaggerHome.Instance.OnDamaged(hit); } } } [BepInPlugin("hevyh2o.valheim.odinsstaggerhome", "Odin's Stagger Home", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "hevyh2o.valheim.odinsstaggerhome"; public const string Name = "Odin's Stagger Home"; public const string Version = "0.1.0"; internal static ManualLogSource Log; internal static Harmony Patcher; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyboardShortcut> ToggleKey; internal static ConfigEntry<string> Destination; internal static ConfigEntry<string> ThreadRoute; internal static ConfigEntry<bool> CloserHomeWins; internal static ConfigEntry<bool> DrunkCamWhileWalking; internal static ConfigEntry<string> Gait; internal static ConfigEntry<float> MixRestBelow; internal static ConfigEntry<float> LegLength; internal static ConfigEntry<bool> JumpObstacles; internal static ConfigEntry<float> EnemyRadius; internal static ConfigEntry<string> OnDanger; internal static ConfigEntry<bool> Remarks; internal static ConfigEntry<float> TextScale; internal static ConfigEntry<bool> DebugLog; private StaggerHome _staggerHome; private void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Expected O, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Expected O, but got Unknown //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)92, Array.Empty<KeyCode>()), "Press to set off home; press again to stop. Any movement, attack, block, jump, dodge or crouch also stops it."); Destination = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Destination", "Bed", new ConfigDescription("Where home is. Bed: the bed you last slept in (falls back to LastSpawn if you have none). LastSpawn: where you last spawned, bed or world start. WorldStart: the stones where you first arrived.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Bed", "LastSpawn", "WorldStart" }), Array.Empty<object>())); ThreadRoute = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ThreadRoute", "StartPoint", new ConfigDescription("With Odin's Thread installed. StartPoint: head for where the current stretch of your trail began (your last login, respawn or portal), by the most direct route the ground allows, not along the trail. FollowTrail: walk the trail itself back, step by step (gives up on the trail and goes direct if it gets stuck). Off: ignore Thread and use Destination.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "StartPoint", "FollowTrail", "Off" }), Array.Empty<object>())); CloserHomeWins = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CloserHomeWins", true, "With ThreadRoute = StartPoint or FollowTrail: if Destination (your bed, say) is closer than the start of your thread, go there instead. Off = always the thread start when there is one."); DrunkCamWhileWalking = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DrunkCamWhileWalking", true, "With Odin's Drunk Cam installed, the camera sways while Odin walks you home, mead or no mead. Never while Drunk Cam's own Enabled is off (its motion-sickness switch, F4): that always wins. Off = no sway from this mod."); Gait = ((BaseUnityPlugin)this).Config.Bind<string>("Walking", "Gait", "Mix", new ConfigDescription("How you go. Walk: slow and steady, no stamina. Run: runs, and drops to a jog when stamina runs out, as usual. Mix: runs until stamina is low (MixRestBelow), then walks until it's full again.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Walk", "Run", "Mix" }), Array.Empty<object>())); MixRestBelow = ((BaseUnityPlugin)this).Config.Bind<float>("Walking", "MixRestBelow", 0.25f, new ConfigDescription("Mix only: start walking when stamina falls below this share of your maximum, 0.05 to 0.9. Running starts again when it's full.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.9f), Array.Empty<object>())); LegLength = ((BaseUnityPlugin)this).Config.Bind<float>("Walking", "LegLength", 35f, new ConfigDescription("The route is planned in legs of about this many metres, 20 to 40, using the same pathfinding the game's creatures use. The game only maps paths near you, so longer legs don't help.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 40f), Array.Empty<object>())); JumpObstacles = ((BaseUnityPlugin)this).Config.Bind<bool>("Walking", "JumpObstacles", true, "Jump over knee-high things in the way (a log, a low wall, a rock step). Off = walk round everything."); OnDanger = ((BaseUnityPlugin)this).Config.Bind<string>("Walking", "OnDanger", "KeepWalking", new ConfigDescription("What happens when you're hit, or an enemy within EnemyRadius notices you. KeepWalking: Odin remarks on it and keeps walking you home. HandBack: you stop and get control back at once. Your own keys, death, teleporting, sitting or taking the helm always stop the walk.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "KeepWalking", "HandBack" }), Array.Empty<object>())); EnemyRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Walking", "EnemyRadius", 25f, new ConfigDescription("How close, in metres, an enemy that has noticed you has to be to count as danger (see OnDanger), 0 to 60. 0 = ignore enemies; being hit still counts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); Remarks = ((BaseUnityPlugin)this).Config.Bind<bool>("Messages", "Remarks", true, "Odin says one line when he sets off, arrives, gives up or lets go. Off = he walks you home in silence."); TextScale = ((BaseUnityPlugin)this).Config.Bind<float>("Messages", "TextScale", 1f, new ConfigDescription("Size of Odin's line, 0.5 to 2. 1 = sized to match the game's own HUD, which already follows your screen height and the game's GUI scale setting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "Write each trip (where to, how far, which route), each leg Odin plans, jumps, water and ledge stops, stuck recoveries, why a trip ended, and the text scale to the BepInEx log."); Patcher = new Harmony("hevyh2o.valheim.odinsstaggerhome"); Patcher.PatchAll(typeof(Plugin).Assembly); _staggerHome = ((Component)this).gameObject.AddComponent<StaggerHome>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Odin's Stagger Home 0.1.0 loaded. Odin has your elbow."); } private void OnDestroy() { Harmony patcher = Patcher; if (patcher != null) { patcher.UnpatchSelf(); } if ((Object)(object)_staggerHome != (Object)null) { Object.Destroy((Object)(object)_staggerHome); } } } internal static class Route { public const string Bed = "Bed"; public const string LastSpawn = "LastSpawn"; public const string WorldStart = "WorldStart"; private const string ThreadGuid = "hevyh2o.valheim.odinsthread"; private const string DrunkCamGuid = "hevyh2o.valheim.odinsdrunkcam"; private const uint ThreadMagic = 1380471887u; private const int ThreadFormat = 1; private const byte StretchEnds = 7; public const float JoinTrail = 60f; public const float JoinStart = 450f; private static MethodInfo s_setSway; private static PropertyInfo s_isEnabled; internal static bool Home(string wanted, out Vector3 pos, out string name) { //IL_001c: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); pos = Vector3.zero; name = null; if (val == null || (Object)(object)ZNet.instance == (Object)null) { return false; } if (wanted == "Bed" && val.HaveCustomSpawnPoint()) { pos = val.GetCustomSpawnPoint(); name = "your bed"; return true; } if (wanted != "WorldStart") { Vector3 homePoint = val.GetHomePoint(); if (homePoint != Vector3.zero) { pos = homePoint; name = "where you last woke up"; return true; } } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetLocationIcon("StartTemple", ref pos)) { name = "the world's starting stones"; return true; } return false; } internal static bool Thread(Vector3 from, float joinDistance, List<Vector3> trail, out string why) { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) trail.Clear(); why = null; if (!Chainloader.PluginInfos.ContainsKey("hevyh2o.valheim.odinsthread")) { why = "Odin's Thread isn't installed"; return false; } string text = ThreadFile(); if (text == null || !File.Exists(text)) { why = "no Odin's Thread file for this character and world" + ((text != null) ? (" (" + Path.GetFileName(text) + ")") : ""); return false; } List<float> list = new List<float>(); List<float> list2 = new List<float>(); List<byte> list3 = new List<byte>(); try { using BinaryReader binaryReader = new BinaryReader(File.Open(text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); if (binaryReader.ReadUInt32() != 1380471887) { throw new InvalidDataException("not an Odin's Thread file"); } int num = binaryReader.ReadInt32(); if (num != 1) { throw new InvalidDataException($"file version {num}, this build reads {1}"); } int num2 = binaryReader.ReadInt32(); if (num2 < 0 || num2 > 10000000) { throw new InvalidDataException($"implausible point count {num2}"); } for (int i = 0; i < num2; i++) { list.Add(binaryReader.ReadSingle()); list2.Add(binaryReader.ReadSingle()); binaryReader.ReadDouble(); list3.Add(binaryReader.ReadByte()); } } catch (Exception ex) { why = "couldn't read " + Path.GetFileName(text) + ": " + ex.Message; return false; } if (list.Count == 0) { why = "the Odin's Thread file is empty"; return false; } int num3 = list.Count - 1; while (num3 > 0 && (list3[num3] & 7) == 0) { num3--; } int num4 = -1; float num5 = joinDistance * joinDistance; for (int num6 = list.Count - 1; num6 >= num3; num6--) { float num7 = list[num6] - from.x; float num8 = list2[num6] - from.z; float num9 = num7 * num7 + num8 * num8; if (num9 < num5) { num5 = num9; num4 = num6; } } if (num4 < 0) { why = $"your trail's current stretch ({list.Count - num3} points) doesn't pass within {joinDistance:0} m of you"; return false; } for (int num10 = num4; num10 >= num3; num10--) { trail.Add(Ground(new Vector3(list[num10], 0f, list2[num10]))); } why = $"{Path.GetFileName(text)}: {list.Count} points, current stretch {list.Count - num3}, joined {Mathf.Sqrt(num5):0} m from you, {trail.Count} points to walk"; return true; } internal static bool DrunkCamSway(bool on, out string why) { why = null; if (s_setSway == null) { if (!Chainloader.PluginInfos.TryGetValue("hevyh2o.valheim.odinsdrunkcam", out var value) || (Object)(object)value.Instance == (Object)null) { why = "Odin's Drunk Cam isn't installed"; return false; } Type type = ((object)value.Instance).GetType().Assembly.GetType("OdinsDrunkCam.Api"); s_setSway = type?.GetMethod("SetExternalSway", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(string), typeof(bool) }, null); s_isEnabled = type?.GetProperty("IsEnabled", BindingFlags.Static | BindingFlags.Public); if (s_setSway == null) { why = $"Odin's Drunk Cam {value.Metadata.Version} has no sway API (OdinsDrunkCam.Api.SetExternalSway)"; return false; } } try { s_setSway.Invoke(null, new object[2] { "Odin's Stagger Home", on }); bool flag = s_isEnabled == null || (bool)s_isEnabled.GetValue(null, null); why = (flag ? "Drunk Cam is on" : "Drunk Cam's Enabled is off, so it won't sway"); return true; } catch (Exception ex) { why = "Odin's Drunk Cam's sway API failed: " + ex.GetBaseException().Message; s_setSway = null; return false; } } internal static Vector3 Ground(Vector3 p) { //IL_0024: 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) float y = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(p, ref y)) { p.y = y; } return p; } private static string ThreadFile() { PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); ZNet instance = ZNet.instance; if (val == null || (Object)(object)instance == (Object)null) { return null; } string worldName = instance.GetWorldName(); if (string.IsNullOrEmpty(worldName)) { return null; } string text = val.GetFilename(); if (string.IsNullOrEmpty(text)) { text = val.GetName(); } string path = $"{Clean(text)}__{Clean(worldName)}_{instance.GetWorldUID():x}.thread"; return Path.Combine(Path.Combine(Paths.ConfigPath, "OdinsThread"), path); } private static string Clean(string s) { StringBuilder stringBuilder = new StringBuilder(s.Length); char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char c in s) { stringBuilder.Append((Array.IndexOf(invalidFileNameChars, c) >= 0) ? '-' : c); } return stringBuilder.ToString().Trim(); } } internal sealed class StaggerHome : MonoBehaviour { private enum Recovery { None, Jump, BackUp, Sidestep } public const string Walk = "Walk"; public const string Run = "Run"; public const string Mix = "Mix"; public const string StartPoint = "StartPoint"; public const string FollowTrail = "FollowTrail"; public const string ThreadOff = "Off"; public const string KeepWalking = "KeepWalking"; public const string HandBack = "HandBack"; private const float ReplanEvery = 1.5f; private const float OffLine = 2f; private const float CornerReached = 1f; private const float ArriveRadius = 3f; private const float ThreadPassed = 4f; private const int ThreadLookahead = 16; private const float NoPathGiveUp = 10f; private const float StuckWindow = 3f; private const float StuckMinMove = 0.5f; private const int MaxRecoveries = 3; private const float ProgressResets = 8f; private const float JumpEvery = 1f; private const float KneeHeight = 0.4f; private const float ChestHeight = 1.6f; private const float ObstacleReach = 1f; private const float MaxHop = 1.2f; private const float ProbeAhead = 2.5f; private const float SwimMargin = 0.6f; private const float SafeDrop = 4f; private const float EnemyCheckEvery = 0.5f; private const float MixFull = 0.95f; private const float BankSearch = 30f; private const float SlideSlope = 0.78f; private const float SlopeRun = 2f; private const float SlopeStep = 0.5f; private const float DetourFor = 8f; private const float DangerRemarkEvery = 10f; private static readonly MethodInfo SetCrouch = AccessTools.Method(typeof(Character), "SetCrouch", (Type[])null, (Type[])null); private static readonly string[] StartLines = new string[4] { "Home it is. {0} to {1}, give or take a wrong turn.", "Left foot. Right foot. {0} to {1}.", "Odin has your elbow. {0} to {1}. Try not to sing.", "{0} to {1}. Odin has walked further for worse company." }; private static readonly string[] ThreadLines = new string[3] { "Back along your own thread, {0} of it. Odin remembers the way, even if you don't.", "Following your footsteps back, {0}. They wander a bit. So did you.", "{0} of thread to wind back in. Odin will hold the ball." }; private static readonly string[] StartPointLines = new string[2] { "Back to where your thread starts, {0} as the raven flies. Odin isn't retracing your wobbles.", "The start of your thread, {0} off. Odin knows a shorter way than the one you took." }; private static readonly string[] ArriveLines = new string[4] { "Home. Mostly in one piece.", "Here we are. Odin will not be carrying you upstairs.", "Home. The mead can stay where it is.", "Arrived. Odin has walked worse, but not recently." }; private static readonly string[] ThreadEndLines = new string[2] { "That's where the thread starts. Odin's end of the bargain is done.", "End of the thread. Where you go from here is your business." }; private static readonly string[] StuckLines = new string[3] { "Odin has tried three ways round this. Your turn.", "Stuck. Odin blames the scenery.", "This is as far as Odin's patience goes. Take the reins." }; private static readonly string[] NoWayLines = new string[2] { "Odin can't see a way from here. He's looked.", "No path Odin trusts from here. Walk a little, then ask again." }; private static readonly string[] EnemyLines = new string[3] { "Company. Odin hands you back your legs.", "Something has noticed you. Odin suggests you notice it back.", "Not alone. Odin lets go of your elbow." }; private static readonly string[] NoticedLines = new string[4] { "Something's taken an interest. Odin's ignoring it.", "You've been spotted. Odin is pretending he hasn't seen it.", "Company. Odin isn't stopping for it, and neither are you.", "Something with teeth is watching. Odin walks on, with dignity." }; private static readonly string[] WalkOnHurtLines = new string[4] { "That'll bruise. Odin walks on.", "Ouch. Home is still that way.", "You're bleeding. Odin assumes it's a flesh wound.", "Hit. Odin has seen worse, mostly on you." }; private static readonly string[] HurtLines = new string[2] { "Ouch. Odin lets go.", "You're bleeding. Odin assumed you'd want to deal with that yourself." }; private static readonly string[] AshoreLines = new string[2] { "Dry land. Odin hands you back, damp.", "Out of the water. Odin isn't asking how you got in." }; private static readonly string[] LetGoLines = new string[3] { "Your legs, then.", "Odin lets go of your elbow.", "As you wish. Odin will be at the bar." }; private static readonly string[] NoHomeLines = new string[1] { "No bed, no spawn, no idea. Odin can't walk you home if you haven't got one." }; private static readonly string[] AlreadyHomeLines = new string[2] { "You're already home. Odin checked twice.", "This is home. Odin suggests sitting down." }; private OdinLine _line; private int _solidMask; private int _groundMask; private Vector3 _target; private string _targetName; private readonly List<Vector3> _trail = new List<Vector3>(); private int _trailIndex; private bool _thread; private bool _threadGoal; private float _detourUntil; private int _detourSign = 1; private bool _walkBefore; private readonly List<Vector3> _path = new List<Vector3>(); private int _corner; private bool _havePath; private float _nextPlan; private float _lastLeg; private int _planTurn; private Vector3 _steer; private bool _resting; private float _nextJump; private bool _bank; private Vector3 _bankPoint; private float _nextEnemyCheck; private readonly List<Character> _danger = new List<Character>(); private readonly HashSet<Character> _noticed = new HashSet<Character>(); private float _nextNoticedRemark; private float _nextHurtRemark; private float _stuckCheckAt; private Vector3 _stuckFrom; private int _recoveries; private Vector3 _recoveredAt; private Recovery _recovery; private float _recoveryUntil; private Vector3 _recoveryDir; private bool _recoveryJumped; private int _sideSign = 1; private float _blockedSince = -1f; private float _nextBlockedLog; private bool _swaying; private bool _swayFailed; private string _lastRemark; internal static StaggerHome Instance { get; private set; } internal bool Active { get; private set; } private void Awake() { Instance = this; _line = ((Component)this).gameObject.AddComponent<OdinLine>(); _solidMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); _groundMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "terrain", "blocker", "vehicle" }); } private void OnDestroy() { Sway(want: false); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } internal void OnLogout() { Stop(Player.m_localPlayer, "you logged out", null); Sway(want: false); } private void Update() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Active = false; Sway(want: false); return; } if (Plugin.Enabled.Value && !Typing() && Pressed(Plugin.ToggleKey.Value)) { if (Active) { Stop(localPlayer, "you pressed the key again", LetGoLines); } else { Begin(localPlayer); } } if (!Active) { return; } if (!Plugin.Enabled.Value) { Stop(localPlayer, "the mod was switched off", null); return; } Sway(Plugin.DrunkCamWhileWalking.Value); if (((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsDebugFlying()) { Stop(localPlayer, "you died, teleported, flew or a cutscene started", null); return; } if (((Character)localPlayer).IsAttached()) { Stop(localPlayer, "you sat down, took a ship's helm or something else took hold of you", null); return; } if (localPlayer.m_autoRun) { Stop(localPlayer, "auto-run came on (the game's or another mod's)", null); return; } if (Time.time >= _nextEnemyCheck) { _nextEnemyCheck = Time.time + 0.5f; if (EnemiesNear(localPlayer, _danger)) { if (Plugin.OnDanger.Value == "HandBack") { Stop(localPlayer, Describe(localPlayer, _danger[0]) + " has noticed you", EnemyLines); return; } foreach (Character item in _danger) { if (_noticed.Add(item)) { Note(Describe(localPlayer, item) + " has noticed you; walking on (OnDanger = KeepWalking)."); if (Time.time >= _nextNoticedRemark) { _nextNoticedRemark = Time.time + 10f; Remark(NoticedLines); } } } } } Vector3 position = ((Component)localPlayer).transform.position; if (((Character)localPlayer).IsSwimming()) { if (!_bank) { _bank = true; _bankPoint = FindBank(position); Note("Swimming at " + Fmt(position) + ": heading for the bank at " + Fmt(_bankPoint) + "."); } return; } if (_bank) { if (((Character)localPlayer).IsOnGround()) { Stop(localPlayer, "you swam ashore", AshoreLines); } return; } Vector3 val = Flat(position - _target); if (((Vector3)(ref val)).magnitude <= 3f) { Stop(localPlayer, "arrived", _threadGoal ? ThreadEndLines : ArriveLines); } else { if (Paused()) { return; } if (_recovery != Recovery.None) { StepRecovery(localPlayer); return; } AdvanceCorners(position); if (Time.time >= _nextPlan || (_havePath && OffPath(position))) { Plan(localPlayer); } if (!_havePath && Time.time - _lastLeg > 10f) { Stop(localPlayer, $"no leg found for {10f:0} s", NoWayLines); } else if (_blockedSince >= 0f && Time.time - _blockedSince > 10f) { Stop(localPlayer, $"water or a drop in the way of every leg for {10f:0} s", NoWayLines); } else { CheckStuck(localPlayer, position); } } } private void Begin(Player player) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00f7: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) if (Busy(player) || ((Character)player).IsAttached()) { return; } Vector3 position = ((Component)player).transform.position; ResetTrip(); string value = Plugin.ThreadRoute.Value; Vector3 pos; string name; bool flag = Route.Home(Plugin.Destination.Value, out pos, out name); _thread = false; _threadGoal = false; Vector3 val2; if (value != "Off") { if (Route.Thread(position, (value == "FollowTrail") ? 60f : 450f, _trail, out var why)) { Vector3 val = _trail[_trail.Count - 1]; if (flag && Plugin.CloserHomeWins.Value) { val2 = Flat(pos - position); float magnitude = ((Vector3)(ref val2)).magnitude; val2 = Flat(val - position); if (magnitude < ((Vector3)(ref val2)).magnitude) { object[] array = new object[4]; val2 = Flat(val - position); array[0] = ((Vector3)(ref val2)).magnitude; array[1] = name; val2 = Flat(pos - position); array[2] = ((Vector3)(ref val2)).magnitude; array[3] = why; Note(string.Format("Thread start {0:0} m away, {1} {2:0} m: the closer one wins (CloserHomeWins). {3}.", array)); _trail.Clear(); goto IL_01c3; } } _threadGoal = true; _thread = value == "FollowTrail"; _target = val; _targetName = "the start of your thread"; Note("Odin's Thread (" + value + "): " + why + "."); } else { Note("Not using a thread: " + why + "."); } } goto IL_01c3; IL_01c3: if (!_threadGoal) { _trail.Clear(); if (!flag) { Note("No destination: Destination is " + Plugin.Destination.Value + ", and there's no bed, last spawn point or world start to fall back on."); Remark(NoHomeLines); return; } _target = pos; _targetName = name; } float num; if (!_thread) { val2 = Flat(_target - position); num = ((Vector3)(ref val2)).magnitude; } else { num = TrailLength(position); } float num2 = num; val2 = Flat(_target - position); if (((Vector3)(ref val2)).magnitude <= 3f) { Remark(AlreadyHomeLines); return; } Active = true; _walkBefore = ((Character)player).GetWalk(); if (((Character)player).IsCrouching() && SetCrouch != null) { SetCrouch.Invoke(player, new object[1] { false }); } _lastLeg = Time.time; _stuckFrom = position; _recoveredAt = position; _stuckCheckAt = Time.time + 3f; _swayFailed = false; Sway(want: true); Note($"Off to {_targetName} at {Fmt(_target)}, {num2:0} m, gait {Plugin.Gait.Value}, from {Fmt(position)}."); if (_thread) { Remark(ThreadLines, Distance(num2)); } else if (_threadGoal) { Remark(StartPointLines, Distance(num2)); } else { Remark(StartLines, Distance(num2), _targetName); } } private void Stop(Player player, string why, string[] lines) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (Active) { Active = false; Sway(want: false); if ((Object)(object)player != (Object)null) { ((Character)player).SetWalk(_walkBefore); ((Character)player).SetRun(false); ((Character)player).SetMoveDir(Vector3.zero); } Note("Stopped: " + why + "."); if (lines != null) { Remark(lines); } ResetTrip(); } } private void ResetTrip() { //IL_003e: 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) _trail.Clear(); _trailIndex = 0; _path.Clear(); _corner = 0; _havePath = false; _nextPlan = 0f; _planTurn = 0; _steer = Vector3.zero; _resting = false; _bank = false; _recovery = Recovery.None; _recoveries = 0; _blockedSince = -1f; _detourUntil = 0f; _danger.Clear(); _noticed.Clear(); _nextNoticedRemark = 0f; _nextHurtRemark = 0f; } internal void OnPlayerInput() { Stop(Player.m_localPlayer, "you moved, attacked, blocked, jumped, dodged or crouched", LetGoLines); } internal void OnDamaged(HitData hit) { if (Plugin.OnDanger.Value == "HandBack") { Stop(Player.m_localPlayer, $"you took {hit.GetTotalDamage():0.#} damage", HurtLines); return; } Note($"You took {hit.GetTotalDamage():0.#} damage; walking on (OnDanger = KeepWalking)."); if (!(Time.time < _nextHurtRemark)) { _nextHurtRemark = Time.time + 10f; Remark(WalkOnHurtLines); } } internal void Drive(Player player) { //IL_0016: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) if (!Active || Paused()) { return; } Vector3 position = ((Component)player).transform.position; Vector3 val = Steering(position); bool flag = val != Vector3.zero && !_bank && Plugin.JumpObstacles.Value && HopAhead(position, val); if (val != Vector3.zero && !_bank && _recovery != Recovery.BackUp && Blocked(player, position, val, flag, out var what)) { if (Time.time >= _nextBlockedLog) { _nextBlockedLog = Time.time + 1f; _planTurn++; Note(what + " ahead at " + Fmt(position + val * 2.5f) + ": stopping and re-planning."); } if (_blockedSince < 0f) { _blockedSince = Time.time; } val = Vector3.zero; _nextPlan = 0f; if (_recovery == Recovery.Sidestep) { _recoveryUntil = 0f; } } else if (val != Vector3.zero) { _blockedSince = -1f; } _steer = val; bool flag2 = false; bool walk = false; if (!_bank && _recovery != Recovery.BackUp) { string value = Plugin.Gait.Value; if (value == "Walk") { walk = true; } else if (value == "Run") { flag2 = true; } else { float maxStamina = ((Character)player).GetMaxStamina(); float num = ((maxStamina > 0f) ? (player.GetStamina() / maxStamina) : 1f); if (!_resting && num < Plugin.MixRestBelow.Value) { _resting = true; } else if (_resting && num >= 0.95f) { _resting = false; } walk = _resting; flag2 = !_resting; } } player.m_autoRun = false; ((Character)player).SetMoveDir(val); ((Character)player).SetRun(flag2 && val != Vector3.zero); ((Character)player).SetWalk(walk); bool flag3 = _recovery == Recovery.Jump && !_recoveryJumped; if (!flag3 && val != Vector3.zero) { flag3 = flag; } if (flag3 && Time.time >= _nextJump && ((Character)player).IsOnGround()) { _nextJump = Time.time + 1f; if (_recovery == Recovery.Jump) { _recoveryJumped = true; } Note("Jump at " + Fmt(position) + "."); ((Character)player).Jump(false); } } private Vector3 Steering(Vector3 pos) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) if (_bank) { Vector3 val = Flat(_bankPoint - pos); return ((Vector3)(ref val)).normalized; } if (_recovery != Recovery.None) { return _recoveryDir; } if (!_havePath || _corner >= _path.Count) { return Vector3.zero; } Vector3 val2 = Flat(_path[_corner] - pos); if (!(((Vector3)(ref val2)).sqrMagnitude > 0.0001f)) { return Vector3.zero; } return ((Vector3)(ref val2)).normalized; } private void Plan(Player player) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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) //IL_0047: 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) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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) _nextPlan = Time.time + 1.5f; Vector3 position = ((Component)player).transform.position; Pathfinding instance = Pathfinding.instance; if ((Object)(object)instance == (Object)null) { _havePath = false; return; } foreach (Vector3 item in Goals(position)) { if (!instance.GetPath(position, item, _path, (AgentType)6, false, true, false) || _path.Count < 2) { continue; } Vector3 val = _path[_path.Count - 1]; Vector3 val2 = Flat(val - position); if (((Vector3)(ref val2)).magnitude < 1.5f) { val2 = Flat(_target - position); if (((Vector3)(ref val2)).magnitude > 4.5f) { continue; } } if (SteepClimb(_path, out var where)) { if (Plugin.DebugLog.Value) { Note("Leg to " + Fmt(item) + " climbs a slope too steep to walk at " + Fmt(where) + ": trying another."); } continue; } _havePath = true; _corner = 1; _lastLeg = Time.time; if (Plugin.DebugLog.Value) { object[] obj = new object[5] { _path.Count - 1, null, null, null, null }; val2 = Flat(val - position); obj[1] = ((Vector3)(ref val2)).magnitude; obj[2] = Fmt(val); obj[3] = Fmt(item); val2 = Flat(_target - position); obj[4] = ((Vector3)(ref val2)).magnitude; Note(string.Format("Leg: {0} corners, {1:0.#} m to {2} (asked for {3}), {4:0} m to go.", obj)); } return; } _path.Clear(); _havePath = false; if (_thread) { _thread = false; _nextPlan = 0f; Note("No leg along the trail from " + Fmt(position) + ": heading straight for the thread's start instead."); return; } _planTurn++; if (Plugin.DebugLog.Value) { Note("No leg from " + Fmt(position) + " yet (the navmesh may still be building here, or every way is steep, wet or a drop)."); } } private bool SteepClimb(List<Vector3> path, out Vector3 where) { //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_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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0041: 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) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0081: 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_0089: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_0115: Unknown result type (might be due to invalid IL or missing references) where = Vector3.zero; int num = Mathf.RoundToInt(4f); List<float> list = new List<float>(); List<Vector3> list2 = new List<Vector3>(); Vector3 val3; for (int i = 1; i < path.Count; i++) { Vector3 val = path[i - 1]; Vector3 val2 = path[i]; val3 = Flat(val2 - val); float magnitude = ((Vector3)(ref val3)).magnitude; int num2 = Mathf.Max(1, Mathf.CeilToInt(magnitude / 0.5f)); for (int j = ((i != 1) ? 1 : 0); j <= num2; j++) { Vector3 val4 = Vector3.Lerp(val, val2, (float)j / (float)num2); list2.Add(val4); list.Add(GroundAt(val4)); } } for (int k = num; k < list.Count; k++) { val3 = Flat(list2[k] - list2[k - num]); float magnitude2 = ((Vector3)(ref val3)).magnitude; if (magnitude2 > 0.5f && list[k] - list[k - num] > 0.78f * magnitude2) { where = list2[k]; return true; } } return false; } private IEnumerable<Vector3> Goals(Vector3 from) { //IL_000f: 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) float leg = Plugin.LegLength.Value; if (_thread) { Vector3 val; while (_trailIndex < _trail.Count - 1) { val = Flat(_trail[_trailIndex] - from); if (!(((Vector3)(ref val)).magnitude < 4f) && !Wet(_trail[_trailIndex])) { break; } _trailIndex++; } int num = Mathf.Min(_trailIndex + 16, _trail.Count - 1); int tried = 0; int i = num; while (i >= _trailIndex && tried < 5) { val = Flat(_trail[i] - from); if (!(((Vector3)(ref val)).magnitude > leg) && !Wet(_trail[i])) { tried++; yield return _trail[i]; } i--; } if (tried > 0) { yield break; } foreach (Vector3 item in Towards(from, _trail[_trailIndex], leg)) { yield return item; } yield break; } foreach (Vector3 item2 in Towards(from, _target, leg)) { yield return item2; } } private IEnumerable<Vector3> Towards(Vector3 from, Vector3 to, float leg) { //IL_000f: 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_0016: 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) Vector3 flat = Flat(to - from); float distance = ((Vector3)(ref flat)).magnitude; bool detour = Time.time < _detourUntil; if (distance <= leg && !detour) { yield return to; if (_planTurn == 0) { yield break; } } Vector3 dir = ((distance > 0.01f) ? (flat / distance) : Vector3.forward); int sign = (detour ? _detourSign : (((_planTurn & 1) == 0) ? 1 : (-1))); if (detour) { foreach (Vector3 item in Offsets(from, dir, sign, new float[4] { 60f, -60f, 90f, -90f }, 15f)) { yield return item; } } float num = Mathf.Min(leg, distance); float[] array = new float[2] { num, num * 0.5f }; foreach (float length in array) { foreach (Vector3 item2 in Offsets(from, dir, sign, new float[5] { 0f, 25f, -25f, 50f, -50f }, length)) { yield return item2; } } foreach (Vector3 item3 in Offsets(from, dir, sign, new float[2] { 90f, -90f }, 15f)) { yield return item3; } foreach (Vector3 item4 in Offsets(from, dir, sign, new float[2] { 135f, -135f }, 10f)) { yield return item4; } if (distance <= leg && detour) { yield return to; } } private IEnumerable<Vector3> Offsets(Vector3 from, Vector3 dir, int sign, float[] turns, float length) { //IL_000f: 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_0016: 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) foreach (float num in turns) { Vector3 val = Route.Ground(from + Quaternion.Euler(0f, num * (float)sign, 0f) * dir * length); if (!Wet(val)) { yield return val; } } } private void AdvanceCorners(Vector3 pos) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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 (!_havePath) { return; } while (_corner < _path.Count) { Vector3 val = Flat(_path[_corner] - pos); if (!(((Vector3)(ref val)).magnitude < 1f)) { break; } _corner++; } if (_corner >= _path.Count) { _nextPlan = 0f; } } private bool OffPath(Vector3 pos) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) //IL_0054: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) //IL_0072: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (_corner <= 0 || _corner >= _path.Count) { return false; } Vector3 val = Flat(_path[_corner - 1]); Vector3 val2 = Flat(_path[_corner]); Vector3 val3 = Flat(pos); Vector3 val4 = val2 - val; float num = ((((Vector3)(ref val4)).sqrMagnitude > 0.0001f) ? Mathf.Clamp01(Vector3.Dot(val3 - val, val4) / ((Vector3)(ref val4)).sqrMagnitude) : 0f); Vector3 val5 = val3 - (val + val4 * num); return ((Vector3)(ref val5)).magnitude > 2f; } private float TrailLength(Vector3 from) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) float num = 0f; Vector3 val = from; foreach (Vector3 item in _trail) { float num2 = num; Vector3 val2 = Flat(item - val); num = num2 + ((Vector3)(ref val2)).magnitude; val = item; } return num; } private bool Blocked(Player player, Vector3 pos, Vector3 dir, bool hop, out string what) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) //IL_0035: 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_0044: 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_00d2: Unknown result type (might be due to invalid IL or missing references) what = null; if (!hop) { float num = GroundAt(pos + dir * 2f + Vector3.up * 0.5f) - GroundAt(pos + Vector3.up * 0.5f); if (num > 1.56f) { what = $"A slope too steep to walk ({Mathf.Atan2(num, 2f) * 57.29578f:0} degrees)"; return true; } } Vector3 p = pos + dir * 2.5f; float num2 = Mathf.Max(0.5f, ((Character)player).m_swimDepth - 0.6f); if (WaterDepth(p, out var ground) > num2) { what = "Deep water"; return true; } if (pos.y - ground > 4f) { what = $"A {pos.y - ground:0.#} m drop"; return true; } return false; } private float GroundAt(Vector3 p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) WaterDepth(p, out var ground); return ground; } private float WaterDepth(Vector3 p, out float ground) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0020: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) ground = p.y - 60f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Vector3(p.x, p.y + 6f, p.z), Vector3.down, ref val, 70f, _groundMask)) { ground = ((RaycastHit)(ref val)).point.y; RaycastHit val2 = default(RaycastHit); if (ground > p.y + 1.5f && Physics.Raycast(new Vector3(p.x, p.y + 1.2f, p.z), Vector3.down, ref val2, 60f, _groundMask)) { ground = ((RaycastHit)(ref val2)).point.y; } } float num = Floating.GetLiquidLevel(new Vector3(p.x, ground + 0.2f, p.z), 1f, (LiquidType)10); if (num < -1000f && (Object)(object)ZoneSystem.instance != (Object)null) { num = ((ground < ZoneSystem.instance.m_waterLevel - 0.5f) ? ZoneSystem.instance.m_waterLevel : num); } return Mathf.Max(0f, num - ground); } private bool Wet(Vector3 p) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; float num = (((Object)(object)localPlayer != (Object)null) ? Mathf.Max(0.5f, ((Character)localPlayer).m_swimDepth - 0.6f) : 1f); float ground; return WaterDepth(p, out ground) > num; } private bool HopAhead(Vector3 pos, Vector3 dir) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_004c: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (!Physics.Raycast(pos + Vector3.up * 0.4f, dir, ref val, 1f, _solidMask)) { return false; } if (((RaycastHit)(ref val)).normal.y > 0.6f) { return false; } if (Physics.Raycast(pos + Vector3.up * 1.6f, dir, 1.4f, _solidMask)) { return false; } RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(pos + dir * (((RaycastHit)(ref val)).distance + 0.3f) + Vector3.up * 1.8000001f, Vector3.down, ref val2, 2.6f, _solidMask)) { return false; } float num = ((RaycastHit)(ref val2)).point.y - pos.y; if (num > 0.3f) { return num <= 1.2f; } return false; } private Vector3 FindBank(Vector3 pos) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) for (float num = 3f; num <= 30f; num += 3f) { Vector3 result = Vector3.zero; float num2 = float.MinValue; for (int i = 0; i < 16; i++) { Vector3 val = pos + Quaternion.Euler(0f, (float)i * 22.5f, 0f) * Vector3.forward * num; if (!(WaterDepth(val, out var ground) > 0.3f) && ground > num2) { num2 = ground; result = val; } } if (num2 > float.MinValue) { return result; } } return _target; } private static bool EnemiesNear(Player player, List<Character> found) { //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_0072: 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) found.Clear(); float value = Plugin.EnemyRadius.Value; if (value <= 0f) { return false; } Vector3 position = ((Component)player).transform.position; bool flag = player.IsTargeted(); foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)player) && !allCharacter.IsDead() && BaseAI.IsEnemy((Character)(object)player, allCharacter) && !(Vector3.Distance(((Component)allCharacter).transform.position, position) > value)) { BaseAI baseAI = allCharacter.GetBaseAI(); if (((Object)(object)baseAI != (Object)null && baseAI.IsAlerted()) || flag) { found.Add(allCharacter); } } } return found.Count > 0; } private static string Describe(Player player, Character c) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) return $"{c.m_name} {Vector3.Distance(((Component)c).transform.position, ((Component)player).transform.position):0} m away"; } private void CheckStuck(Player player, Vector3 pos) { //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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_003e: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0178: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (_steer == Vector3.zero || !_havePath) { _stuckFrom = pos; _stuckCheckAt = Time.time + 3f; return; } Vector3 val; if (_recoveries > 0) { val = Flat(pos - _recoveredAt); if (((Vector3)(ref val)).magnitude > 8f) { _recoveries = 0; } } if (Time.time < _stuckCheckAt) { return; } val = Flat(pos - _stuckFrom); float magnitude = ((Vector3)(ref val)).magnitude; _stuckFrom = pos; _stuckCheckAt = Time.time + 3f; if (magnitude >= 0.5f) { return; } if (_recoveries >= 3) { Stop(player, $"stuck at {Fmt(pos)} after {3} tries", StuckLines); return; } _recoveries++; _recoveredAt = pos; _recoveryJumped = false; _sideSign = -_sideSign; if (Plugin.JumpObstacles.Value && HopAhead(pos, _steer)) { _recoveryDir = _steer; _recovery = Recovery.Jump; _recoveryUntil = Time.time + 0.6f; } else { _recoveryDir = -_steer; _recovery = Recovery.BackUp; _recoveryUntil = Time.time + 1f; } Note($"Stuck at {Fmt(pos)} (moved {magnitude:0.##} m in {3f:0} s): recovery {_recoveries} of {3}, starting with {_recovery}."); } private void StepRecovery(Player 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_002f: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0106: 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) if (_recovery == Recovery.Jump && Time.time < _recoveryUntil) { return; } Vector3 recoveryDir = _recoveryDir; if (_recovery == Recovery.Jump) { _recovery = Recovery.BackUp; _recoveryDir = -recoveryDir; _recoveryUntil = Time.time + 1f; } else { if (Time.time < _recoveryUntil) { return; } if (_recovery == Recovery.BackUp) { _recovery = Recovery.Sidestep; _recoveryDir = Quaternion.Euler(0f, 45f * (float)_sideSign, 0f) * -recoveryDir; _recoveryUntil = Time.time + 1.2f; return; } _recovery = Recovery.None; _nextPlan = 0f; _planTurn++; _detourUntil = Time.time + 8f; _detourSign = _sideSign; if (_thread) { _thread = false; Note("Stuck on the trail: heading straight for the thread's start instead."); } _stuckFrom = ((Component)player).transform.position; _stuckCheckAt = Time.time + 3f; } } private void Sway(bool want) { want = want && Active && Plugin.DrunkCamWhileWalking.Value; if (want != _swaying && (!want || !_swayFailed)) { string why; bool flag = Route.DrunkCamSway(want, out why); _swaying = want && flag; _swayFailed = want && !flag; if (want || flag) { Note(flag ? ("Drunk Cam sway " + (want ? "requested" : "released") + ": " + why + ".") : ("No Drunk Cam sway: " + why + ".")); } } } private static bool Busy(Player player) { if (!((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).InCutscene() && !((Character)player).InIntro() && !((Character)player).IsDebugFlying()) { return Menu.IsVisible(); } return true; } private static bool Paused() { if (!Typing()) { return GameCamera.InFreeFly(); } return true; } private static bool Typing() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.InTextInput()) { return Menu.IsVisible(); } return true; } private static bool Pressed(KeyboardShortcut key) { //IL_0002: 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_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref key)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey, false)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers) { if (!ZInput.GetKey(modifier, false)) { return false; } } return true; } private void Remark(string[] lines, params object[] args) { if (!Plugin.Remarks.Value || lines == null || lines.Length == 0) { return; } string text = null; for (int i = 0; i < 8; i++) { if (text != null && !(text == _lastRemark)) { break; } text = lines[Random.Range(0, lines.Length)]; } _lastRemark = text; _line.Show((args.Length != 0) ? string.Format(text, args) : text); } private static string Distance(float metres) { if (!(metres < 1000f)) { return $"{metres / 1000f:0.0} km"; } return $"{Mathf.Round(metres / 10f) * 10f:0} m"; } private static Vector3 Flat(Vector3 v) { //IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v.x, 0f, v.z); } private static string Fmt(Vector3 p) { //IL_0005: 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) return $"({p.x:0}, {p.y:0}, {p.z:0})"; } private static void Note(string message) { if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)message); } } } internal static class BuildInfo { public const string Version = "0.1.0"; } }