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 Knot v0.1.3
plugins/OdinsKnot.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; 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("OdinsKnot")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.3.0")] [assembly: AssemblyInformationalVersion("0.1.3+fa48d092a3f42bb3cd633149ecfaa21059f55fa9")] [assembly: AssemblyProduct("OdinsKnot")] [assembly: AssemblyTitle("OdinsKnot")] [assembly: AssemblyVersion("0.1.3.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 OdinsKnot { internal sealed class Knot : MonoBehaviour { private sealed class NoteReceiver : TextReceiver { private readonly Player _player; private readonly Action<string> _onSet; public NoteReceiver(Player player, Action<string> onSet) { _player = player; _onSet = onSet; } public string GetText() { return GetNote(_player); } public void SetText(string text) { SetNote(_player, text); _onSet?.Invoke(GetNote(_player)); } } private const string NoteKey = "OdinsKnot.Note"; private const string LastSeenKey = "OdinsKnot.LastSeen"; private const int MaxLength = 120; private const float RecapDelay = 3f; private const float ClearFor = 3f; private const float GiveUpAfter = 600f; private const float ScanInterval = 0.25f; private const float StickDeadZone = 0.2f; private RecapScroll _scroll; private bool _asking; private bool _leaving; private long _recapPlayerId; private float _recapAt = -1f; private TimeSpan? _away; private int _recappedGame; private float _recapGiveUpAt; private float _clearSince = -1f; private float _nextScan; private bool _held; internal static Knot Instance { get; private set; } private void Awake() { Instance = this; } private void OnDestroy() { _scroll?.Hide(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (_scroll != null) { if (_scroll.IsOpen && MovePressed()) { _scroll.Dismiss(); } _scroll.Tick(Blocked()); } Player localPlayer = Player.m_localPlayer; if (Plugin.Enabled.Value && !((Object)(object)localPlayer == (Object)null) && !_asking) { if (Pressed(Plugin.KnotKey.Value) && CanOpen(localPlayer)) { _scroll?.Hide(); Edit(localPlayer); } else if (_recapAt >= 0f && Time.unscaledTime >= _recapAt && localPlayer.GetPlayerID() == _recapPlayerId) { TryRecap(localPlayer); } } } internal void OnLocalDamaged() { _scroll?.Dismiss(); } private void TryRecap(Player player) { float unscaledTime = Time.unscaledTime; if (unscaledTime >= _recapGiveUpAt) { _recapAt = -1f; Plugin.Log.LogInfo((object)"Enemies stayed near; the login scroll was dropped. Press the knot key to read your knot."); } else { if (unscaledTime < _nextScan) { return; } _nextScan = unscaledTime + 0.25f; if (EnemyNear(player, Plugin.SafeRadius.Value)) { if (!_held) { Plugin.Log.LogInfo((object)"Enemies near at login; the scroll will wait until it's safe."); } _held = true; _clearSince = -1f; } else { if (!CanShowRecap(player)) { return; } if (_held) { if (_clearSince < 0f) { _clearSince = unscaledTime; } if (unscaledTime - _clearSince < 3f) { return; } } _recapAt = -1f; ShowRecap(player); } } } private static bool EnemyNear(Player player, float radius) { //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_004f: 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) if (radius <= 0f) { return false; } float num = radius * radius; Vector3 position = ((Component)player).transform.position; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)player) && !allCharacter.IsDead()) { Vector3 val = ((Component)allCharacter).transform.position - position; if (!(((Vector3)(ref val)).sqrMagnitude > num) && BaseAI.IsEnemy((Character)(object)player, allCharacter)) { return true; } } } return false; } private static bool MovePressed() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (Typing() || Blocked()) { return false; } if (!ZInput.GetButton("Forward") && !ZInput.GetButton("Backward") && !ZInput.GetButton("Left") && !ZInput.GetButton("Right") && !ZInput.GetButton("Jump") && !ZInput.GetButtonDown("JoyJump")) { Vector2 joyLeftStick = ZInput.GetJoyLeftStick(); return ((Vector2)(ref joyLeftStick)).sqrMagnitude > 0.040000003f; } return true; } internal static string GetNote(Player player) { if (!((Object)(object)player != (Object)null) || !player.m_customData.TryGetValue("OdinsKnot.Note", out var value)) { return ""; } return value; } internal static void SetNote(Player player, string text) { if (!((Object)(object)player == (Object)null)) { string text2 = (text ?? "").Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ') .Trim(); if (text2.Length > 120) { text2 = text2.Substring(0, 120); } if (text2.Length == 0) { player.m_customData.Remove("OdinsKnot.Note"); } else { player.m_customData["OdinsKnot.Note"] = text2; } } } internal static void Stamp(Player player) { if ((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer) { player.m_customData["OdinsKnot.LastSeen"] = DateTime.UtcNow.Ticks.ToString(); } } private void Edit(Player player) { if ((Object)(object)TextInput.instance == (Object)null) { return; } string before = GetNote(player); TextInput.instance.RequestText((TextReceiver)(object)new NoteReceiver(player, delegate(string note) { if (!(note == before)) { string text = ((note.Length == 0) ? "Knot untied." : ("Knot tied: " + note)); MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false, true); } } }), "Odin's Knot: what are you doing?", 120); } internal bool BeforeLeave(Action leave) { if (_leaving) { return true; } if (_asking) { return false; } Player localPlayer = Player.m_localPlayer; if (!Plugin.Enabled.Value || !Plugin.AskOnLogout.Value || (Object)(object)localPlayer == (Object)null || (Object)(object)TextInput.instance == (Object)null || (Object)(object)Game.instance == (Object)null || Game.instance.IsShuttingDown()) { return true; } Menu instance = Menu.instance; if (instance != null) { instance.Hide(); } _scroll?.Hide(); ((MonoBehaviour)this).StartCoroutine(AskThenLeave(localPlayer, leave)); return false; } private IEnumerator AskThenLeave(Player player, Action leave) { _asking = true; TextInput.instance.RequestText((TextReceiver)(object)new NoteReceiver(player, null), "Odin asks: what were you doing?", 120); yield return null; while ((Object)(object)TextInput.instance != (Object)null && (Object)(object)TextInput.instance.m_panel != (Object)null && TextInput.instance.m_panel.activeSelf) { yield return null; } _asking = false; Plugin.Log.LogInfo((object)((GetNote(player).Length > 0) ? "Knot tied for next time." : "Left without a knot.")); _leaving = true; try { leave(); } finally { _leaving = false; } } internal void OnSpawned(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || (Object)(object)Game.instance == (Object)null) { return; } int instanceID = ((Object)Game.instance).GetInstanceID(); if (instanceID == _recappedGame) { return; } _recappedGame = instanceID; _recapAt = -1f; _held = false; _clearSince = -1f; _away = null; if (player.m_customData.TryGetValue("OdinsKnot.LastSeen", out var value) && long.TryParse(value, out var result)) { TimeSpan timeSpan = DateTime.UtcNow - new DateTime(result, DateTimeKind.Utc); if (timeSpan > TimeSpan.Zero) { _away = timeSpan; } } if (Plugin.Enabled.Value && Plugin.ShowRecap.Value && (GetNote(player).Length != 0 || _away.HasValue)) { _recapPlayerId = player.GetPlayerID(); _recapAt = Time.unscaledTime + 3f; _recapGiveUpAt = _recapAt + 600f; } } private void ShowRecap(Player player) { if (_scroll == null) { _scroll = RecapScroll.Create(((Component)this).transform); } if (_scroll == null) { _recapAt = Time.unscaledTime + 1f; } else { _scroll.Show(BuildRecap(player), Plugin.RecapSeconds.Value); } } private string BuildRecap(Player player) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<size=21><color=#E8C27A>Odin's Knot</color></size>\n"); string note = GetNote(player); if (note.Length > 0) { stringBuilder.Append("<size=19>“").Append(Escape(note)).Append("”</size>\n\n"); } else { stringBuilder.Append("<i>You tied no knot last time.</i>\n\n"); } stringBuilder.Append("<size=15>"); stringBuilder.Append("You're in ").Append(BiomeName(player.GetCurrentBiome())); PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if (val != null && val.HaveCustomSpawnPoint()) { stringBuilder.Append(", ").Append(Distance(Vector3.Distance(((Component)player).transform.position, val.GetCustomSpawnPoint()))).Append(" from your bed.\n"); } else { stringBuilder.Append(". You have no bed in this world.\n"); } Inventory inventory = ((Humanoid)player).GetInventory(); List<ItemData> list = ((inventory != null) ? (from i in inventory.GetAllItems() where i != null && i.m_shared != null && i.GetWeight(-1) > 0f orderby i.GetWeight(-1) descending select i).Take(3).ToList() : null); if (list != null && list.Count > 0) { stringBuilder.Append("In your bag: ").Append(string.Join(", ", list.Select(Describe))).Append(".\n"); } else { stringBuilder.Append("Your bag is light.\n"); } if (_away.HasValue) { stringBuilder.Append("You've been away ").Append(Duration(_away.Value)).Append('.'); } stringBuilder.Append("</size>"); return stringBuilder.ToString().TrimEnd(new char[1] { '\n' }); } private static string Describe(ItemData item) { string arg = Escape((Localization.instance != null) ? Localization.instance.Localize(item.m_shared.m_name) : item.m_shared.m_name); string arg2 = ((item.m_stack > 1) ? (" ×" + item.m_stack) : ""); return $"{arg}{arg2} <color=#BFAE8E>({item.GetWeight(-1):0.#} weight)</color>"; } private unsafe static string BiomeName(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)biome == 0) { return "the wilds"; } string text = "$biome_" + ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant(); string text2 = ((Localization.instance != null) ? Localization.instance.Localize(text) : text); return "the " + ((text2.StartsWith("[") || text2.StartsWith("$")) ? ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString() : text2); } private static string Distance(float meters) { if (!(meters >= 1000f)) { return $"{Mathf.RoundToInt(meters)} m"; } return $"{meters / 1000f:0.0} km"; } private static string Duration(TimeSpan t) { if (t.TotalMinutes < 1.0) { return "only a moment"; } if (t.TotalHours < 1.0) { return Plural((int)t.TotalMinutes, "minute"); } if (t.TotalDays < 1.0) { return Plural((int)t.TotalHours, "hour") + ((t.Minutes > 0) ? (", " + Plural(t.Minutes, "minute")) : ""); } return Plural((int)t.TotalDays, "day") + ((t.Hours > 0) ? (", " + Plural(t.Hours, "hour")) : ""); } private static string Plural(int n, string word) { if (n != 1) { return $"{n} {word}s"; } return "1 " + word; } private static string Escape(string s) { return s.Replace("<", "<noparse><</noparse>"); } private static bool Blocked() { if (!Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !TextInput.IsVisible()) { return Console.IsVisible(); } return true; } private static bool Typing() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible()) { return TextInput.IsVisible(); } return true; } private static bool CanOpen(Player player) { if (!((Character)player).IsDead() && !Blocked() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !StoreGui.IsVisible()) { return !Hud.IsPieceSelectionVisible(); } return false; } private static bool CanShowRecap(Player player) { if (!((Character)player).IsDead() && !((Character)player).InIntro() && !Blocked() && (Object)(object)Hud.instance != (Object)null && Hud.instance.IsVisible()) { return !Hud.IsUserHidden(); } return false; } 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; } } [HarmonyPatch(typeof(Menu), "Logout")] internal static class LogoutPatch { private static bool Prefix(Menu __instance) { if (!((Object)(object)Knot.Instance == (Object)null)) { return Knot.Instance.BeforeLeave((Action)__instance.Logout); } return true; } } [HarmonyPatch(typeof(Menu), "QuitGame")] internal static class QuitPatch { private static bool Prefix(Menu __instance) { if (!((Object)(object)Knot.Instance == (Object)null)) { return Knot.Instance.BeforeLeave(delegate { Traverse.Create((object)__instance).Method("QuitGame", Array.Empty<object>()).GetValue(); }); } return true; } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class SpawnPatch { private static void Postfix(Player __instance) { Knot.Instance?.OnSpawned(__instance); } } [HarmonyPatch(typeof(Character), "ApplyDamage")] internal static class DamagePatch { private static void Postfix(Character __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Knot.Instance?.OnLocalDamaged(); } } } [HarmonyPatch(typeof(Player), "Save")] internal static class SavePatch { private static void Prefix(Player __instance) { Knot.Stamp(__instance); } } [BepInPlugin("hevyh2o.valheim.odinsknot", "Odin's Knot", "0.1.3")] public class Plugin : BaseUnityPlugin { public const string Guid = "hevyh2o.valheim.odinsknot"; public const string Name = "Odin's Knot"; public const string Version = "0.1.3"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyboardShortcut> KnotKey; internal static ConfigEntry<bool> AskOnLogout; internal static ConfigEntry<bool> ShowRecap; internal static ConfigEntry<float> RecapSeconds; internal static ConfigEntry<float> SafeRadius; internal static ConfigEntry<float> TextScale; private Harmony _harmony; private Knot _knot; private void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch."); KnotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "KnotKey", new KeyboardShortcut((KeyCode)39, Array.Empty<KeyCode>()), "Read or edit your knot at any time. Enter keeps the text, Esc leaves it as it was."); AskOnLogout = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AskOnLogout", true, "When you log out or quit from the menu, Odin asks what you were doing. Esc skips it and keeps your previous knot."); ShowRecap = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowRecap", true, "Show the scroll when you log in: your knot, your biome, the distance to your bed, the three heaviest stacks in your bag and how long you've been away."); RecapSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RecapSeconds", 12f, new ConfigDescription("How long the login scroll stays up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 30f), Array.Empty<object>())); SafeRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SafeRadius", 30f, new ConfigDescription("If an enemy is this close when you log in, in metres, the scroll waits until none has been near for a few seconds (for up to 10 minutes). 0 shows it straight away, enemies or not.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); TextScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TextScale", 1f, new ConfigDescription("Size of the login scroll, 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>())); _harmony = new Harmony("hevyh2o.valheim.odinsknot"); _harmony.PatchAll(typeof(Plugin).Assembly); _knot = ((Component)this).gameObject.AddComponent<Knot>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Odin's Knot 0.1.3 loaded. Tie a knot before you go."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)_knot != (Object)null) { Object.Destroy((Object)(object)_knot); } } } internal sealed class RecapScroll { 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 (_logged < 0f) { _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 const float Width = 476f; private const float Padding = 20f; private const float FadeIn = 0.6f; private const float FadeOut = 1.2f; private const float QuickFade = 0.2f; private static Canvas _canvas; private readonly CanvasGroup _group; private readonly RectTransform _panel; private readonly TMP_Text _text; private float _shownAt; private float _seconds; private float _dismissedAt = -1f; private float _dismissAlpha; public bool IsOpen { get; private set; } private RecapScroll(CanvasGroup group, RectTransform panel, TMP_Text text) { _group = group; _panel = panel; _text = text; } public static RecapScroll Create(Transform owner) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0163: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022d: 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) 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("OdinsKnot_Scroll", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(((Component)_canvas).transform, false); RectTransform val3 = (RectTransform)val2.transform; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0.5f, 1f); val3.anchorMax = val4; val3.anchorMin = val4; val3.pivot = new Vector2(0.5f, 1f); val3.anchoredPosition = new Vector2(0f, -150f); Image obj = val2.AddComponent<Image>(); ((Graphic)obj).color = new Color(0.13f, 0.09f, 0.05f, 0.86f); ((Graphic)obj).raycastTarget = false; Outline obj2 = val2.AddComponent<Outline>(); ((Shadow)obj2).effectColor = new Color(0.78f, 0.6f, 0.3f, 0.75f); ((Shadow)obj2).effectDistance = new Vector2(3f, -3f); CanvasGroup val5 = val2.AddComponent<CanvasGroup>(); val5.alpha = 0f; val5.interactable = false; val5.blocksRaycasts = false; GameObject val6 = new GameObject("OdinsKnot_ScrollText", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent((Transform)(object)val3, false); TextMeshProUGUI val7 = val6.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val7).font = val.font; ((TMP_Text)val7).fontSharedMaterial = val.fontSharedMaterial; ((TMP_Text)val7).fontSize = 17f; ((Graphic)val7).color = new Color(0.96f, 0.9f, 0.76f); ((TMP_Text)val7).alignment = (TextAlignmentOptions)258; ((TMP_Text)val7).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)val7).richText = true; ((Graphic)val7).raycastTarget = false; ((TMP_Text)val7).outlineWidth = 0.15f; ((TMP_Text)val7).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)200); RectTransform val8 = (RectTransform)val6.transform; val8.anchorMin = Vector2.zero; val8.anchorMax = Vector2.one; val8.offsetMin = new Vector2(20f, 20f); val8.offsetMax = new Vector2(-20f, -20f); val2.SetActive(false); return new RecapScroll(val5, val3, (TMP_Text)(object)val7); } public void Show(string body, float seconds) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_003a: Unknown result type (might be due to invalid IL or missing references) _text.text = body; Vector2 preferredValues = _text.GetPreferredValues(body, 436f, 0f); _panel.sizeDelta = new Vector2(476f, preferredValues.y + 40f); _shownAt = Time.unscaledTime; _seconds = seconds; _group.alpha = 0f; _dismissedAt = -1f; ((Component)_panel).gameObject.SetActive(true); IsOpen = true; } public void Hide() { if ((Object)(object)_panel != (Object)null) { ((Component)_panel).gameObject.SetActive(false); } IsOpen = false; } public void Dismiss() { if (IsOpen && !(_dismissedAt >= 0f)) { _dismissedAt = Time.unscaledTime; _dismissAlpha = _group.alpha; } } public void Tick(bool blocked) { if (!IsOpen) { return; } if (_dismissedAt >= 0f) { float num = (Time.unscaledTime - _dismissedAt) / 0.2f; if (num >= 1f) { Hide(); } else { _group.alpha = (blocked ? 0f : (_dismissAlpha * (1f - num))); } return; } float num2 = Time.unscaledTime - _shownAt; if (num2 >= _seconds) { Hide(); return; } float num3 = Mathf.Min(new float[3] { 1f, num2 / 0.6f, (_seconds - num2) / 1.2f }); _group.alpha = (blocked ? 0f : Mathf.Clamp01(num3)); } 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("OdinsKnot_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 scroll layer created."); return true; } } internal static class BuildInfo { public const string Version = "0.1.3"; } }