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 HearthstoneMod v1.0.5
HearthstoneMod.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("HearthstoneMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HearthstoneMod")] [assembly: AssemblyTitle("HearthstoneMod")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HearthstoneMod { public class HearthstoneBurstEffect : MonoBehaviour { private Light _light; private float _elapsed; private float _duration; private float _peakIntensity; private const float RiseFraction = 0.12f; public static void Spawn(Vector3 position, Color color, float peakIntensity = 14f, float duration = 0.9f) { //IL_0005: 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_0016: 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) GameObject val = new GameObject("HearthstoneBurst"); val.transform.position = position; Light val2 = val.AddComponent<Light>(); val2.type = (LightType)2; val2.color = color; val2.range = 8f; val2.shadows = (LightShadows)0; val2.intensity = 0f; HearthstoneBurstEffect hearthstoneBurstEffect = val.AddComponent<HearthstoneBurstEffect>(); hearthstoneBurstEffect._light = val2; hearthstoneBurstEffect._duration = duration; hearthstoneBurstEffect._peakIntensity = peakIntensity; } private void Update() { _elapsed += Time.deltaTime; float num = Mathf.Clamp01(_elapsed / _duration); _light.intensity = ((num < 0.12f) ? Mathf.Lerp(0f, _peakIntensity, num / 0.12f) : Mathf.Lerp(_peakIntensity, 0f, (num - 0.12f) / 0.88f)); if (_elapsed >= _duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } [BepInPlugin("com.ricky.hearthstonemod", "HearthstoneMod", "1.0.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class HearthstonePlugin : BaseUnityPlugin { public const string PluginGUID = "com.ricky.hearthstonemod"; public const string PluginName = "HearthstoneMod"; public const string PluginVersion = "1.0.5"; public const string ItemPrefabName = "Hearthstone"; internal static ManualLogSource LogInstance; public static ConfigEntry<float> CooldownSeconds; public static ConfigEntry<int> CostFineWood; public static ConfigEntry<int> CostLeatherScraps; public static ConfigEntry<int> CostGreydwarfEye; public static ConfigEntry<bool> RequireBedSpawnPoint; private void Awake() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) LogInstance = ((BaseUnityPlugin)this).Logger; CooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CooldownSeconds", 600f, "Seconds between Hearthstone uses (default 600 = 10 minutes)."); CostFineWood = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "FineWood", 5, "Fine Wood required to craft a Hearthstone."); CostLeatherScraps = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "LeatherScraps", 5, "Leather Scraps required to craft a Hearthstone. Swapped in for Silver in 1.0.4 - Silver is a Mountain-tier material, way too late-game for a convenience item meant to be craftable early."); CostGreydwarfEye = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "GreydwarfEye", 5, "Greydwarf Eye required to craft a Hearthstone."); RequireBedSpawnPoint = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RequireBedSpawnPoint", true, "If true, the Hearthstone refuses to activate until you've slept in / set a bed spawn point. Turn off only if you want it to work with no bed set (it then has nowhere to send you, so leave this on)."); PrefabManager.OnVanillaPrefabsAvailable += AddHearthstoneItem; new Harmony("com.ricky.hearthstonemod").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"HearthstoneMod v1.0.5 loaded."); } private void AddHearthstoneItem() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= AddHearthstoneItem; GameObject val = PrefabManager.Instance.CreateClonedPrefab("Hearthstone", "AmberPearl"); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to clone base prefab for Hearthstone - is Jotunn/game version compatible?"); return; } SharedData shared = val.GetComponent<ItemDrop>().m_itemData.m_shared; shared.m_name = "$item_hearthstone"; shared.m_description = "$item_hearthstone_desc"; shared.m_maxStackSize = 1; shared.m_weight = 1f; shared.m_value = 0; shared.m_questItem = false; shared.m_teleportable = true; shared.m_itemType = (ItemType)2; string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".", "Assets", "hearthstone_icon.png"); if (File.Exists(text)) { Sprite val2 = AssetUtils.LoadSpriteFromFile(text); if ((Object)(object)val2 != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 }; } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Icon not found at " + text + "; item will use the cloned prefab's original icon.")); } LocalizationManager.Instance.AddLocalization("English", new Dictionary<string, string> { ["item_hearthstone"] = "Hearthstone", ["item_hearthstone_desc"] = "A rune-carved stone bound to your hearth-fire.\nActivate to return to your bed instantly, gear and all.\n" + $"Cooldown: {CooldownSeconds.Value / 60f:0.#} minutes." }); ItemConfig val3 = new ItemConfig(); val3.Name = "$item_hearthstone"; val3.Description = "$item_hearthstone_desc"; val3.CraftingStation = CraftingStations.Workbench.ToString(); val3.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig { Item = "FineWood", Amount = CostFineWood.Value }, new RequirementConfig { Item = "LeatherScraps", Amount = CostLeatherScraps.Value }, new RequirementConfig { Item = "GreydwarfEye", Amount = CostGreydwarfEye.Value } }; ItemConfig val4 = val3; CustomItem val5 = new CustomItem(val, false, val4); ItemManager.Instance.AddItem(val5); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Hearthstone item + recipe registered."); } } [HarmonyPatch] public static class Humanoid_UseItem_HearthstonePatch { private const string CooldownDataKey = "hearthstone_last_use_utc_ticks"; private static readonly Color HearthstoneBurstColor = new Color(1f, 0.55f, 0.15f); private static FieldInfo _teleportEffectsField; private static bool _teleportEffectsFieldResolved; [HarmonyTargetMethods] private static IEnumerable<MethodBase> TargetMethods() { Type[] paramTypes = new Type[3] { typeof(Inventory), typeof(ItemData), typeof(bool) }; HashSet<MethodBase> seen = new HashSet<MethodBase>(); Type[] array = new Type[2] { typeof(Humanoid), typeof(Player) }; for (int i = 0; i < array.Length; i++) { MethodInfo methodInfo = AccessTools.Method(array[i], "UseItem", paramTypes, (Type[])null); if (methodInfo != null && seen.Add(methodInfo)) { yield return methodInfo; } } } [HarmonyPrefix] public static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, bool fromInventoryGui) { ManualLogSource logInstance = HearthstonePlugin.LogInstance; if (logInstance != null) { string[] obj = new string[6] { "[HearthstoneMod] UseItem prefix fired - instance=", ((object)__instance)?.GetType().Name, ", item=", item?.m_shared?.m_name, ", dropPrefab=", null }; object obj2; if (item == null) { obj2 = null; } else { GameObject dropPrefab = item.m_dropPrefab; obj2 = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } obj[5] = (string)obj2; logInstance.LogInfo((object)string.Concat(obj)); } if ((Object)(object)item?.m_dropPrefab == (Object)null || ((Object)item.m_dropPrefab).name != "Hearthstone") { return true; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } TryActivateHearthstone(val, item); return false; } private static bool TryActivateHearthstone(Player player, ItemData item) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) if (item.m_customData == null) { item.m_customData = new Dictionary<string, string>(); } float value = HearthstonePlugin.CooldownSeconds.Value; if (item.m_customData.TryGetValue("hearthstone_last_use_utc_ticks", out var value2) && long.TryParse(value2, out var result)) { double totalSeconds = (DateTime.UtcNow - new DateTime(result, DateTimeKind.Utc)).TotalSeconds; if (totalSeconds < (double)value) { double seconds = (double)value - totalSeconds; ShowMessage(player, "Hearthstone is still warming up (" + FormatRemaining(seconds) + " left)."); return false; } } PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if (val == null) { ShowMessage(player, "Can't reach your player profile right now."); return false; } if (!val.HaveCustomSpawnPoint() && HearthstonePlugin.RequireBedSpawnPoint.Value) { ShowMessage(player, "You have no bed spawn point set - sleep in or claim a bed first."); return false; } Vector3 customSpawnPoint = val.GetCustomSpawnPoint(); item.m_customData["hearthstone_last_use_utc_ticks"] = DateTime.UtcNow.Ticks.ToString(); PlayTeleportEffect(player, ((Component)player).transform.position, ((Component)player).transform.rotation); Quaternion rotation = ((Component)player).transform.rotation; bool num = ((Character)player).TeleportTo(customSpawnPoint, rotation, true); if (num) { PlayTeleportEffect(player, customSpawnPoint, rotation); ShowMessage(player, "The hearth-fire pulls you home."); return num; } item.m_customData.Remove("hearthstone_last_use_utc_ticks"); ShowMessage(player, "Something interrupted the teleport - try again."); return num; } private static void PlayTeleportEffect(Player player, Vector3 pos, Quaternion rot) { //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_009a: 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) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) HearthstoneBurstEffect.Spawn(pos, HearthstoneBurstColor); if (!_teleportEffectsFieldResolved) { _teleportEffectsFieldResolved = true; _teleportEffectsField = typeof(Player).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => f.FieldType == typeof(EffectList) && f.Name.IndexOf("eleport", StringComparison.OrdinalIgnoreCase) >= 0); if (_teleportEffectsField == null) { ManualLogSource logInstance = HearthstonePlugin.LogInstance; if (logInstance != null) { logInstance.LogWarning((object)"Couldn't find a teleport EffectList field on Player - using only our own burst effect (teleport itself still works fine either way)."); } } } object? obj = _teleportEffectsField?.GetValue(player); EffectList val = (EffectList)((obj is EffectList) ? obj : null); if (val != null) { val.Create(pos, rot, (Transform)null, 1f, -1, default(ZDOID)); } } private static void ShowMessage(Player player, string text) { ((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false); } private static string FormatRemaining(double seconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); if (!(timeSpan.TotalMinutes >= 1.0)) { return $"{Mathf.CeilToInt((float)timeSpan.TotalSeconds)}s"; } return $"{Mathf.CeilToInt((float)timeSpan.TotalMinutes)}m"; } } }