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 HearthArrows v1.0.0
HearthArrows.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("blackhearthx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Pull your arrows and bolts back out of the world, and sometimes out of a creature.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HearthArrows")] [assembly: AssemblyTitle("HearthArrows")] [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 HearthArrows { public class ArrowPull : MonoBehaviour, Hoverable, Interactable { private static readonly FieldInfo AttachParentField = AccessTools.Field(typeof(Projectile), "m_attachParent"); private static int s_groundMask; public GameObject ItemPrefab; public GameObject ProjectileRoot; private bool _returned; private bool _inCreature; private bool _dropped; private Character _stuckIn; private Light _glow; private float _glowPhase; public void WatchCreature(Character character) { _inCreature = (Object)(object)character != (Object)null; _stuckIn = character; } private void Awake() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (PluginConfig.Glow.Value) { _glow = ((Component)this).gameObject.AddComponent<Light>(); _glow.type = (LightType)2; _glow.color = new Color(1f, 0.55f, 0.22f); _glow.range = 4.5f; _glow.intensity = 1.3f; _glow.shadows = (LightShadows)0; _glow.renderMode = (LightRenderMode)2; _glowPhase = Random.Range(0f, 6.28f); } } private void Update() { if ((Object)(object)_glow != (Object)null) { _glow.intensity = 1.15f + Mathf.Sin(Time.time * 2.4f + _glowPhase) * 0.25f; } if (_inCreature && !_dropped && !_returned && (!((Object)(object)_stuckIn != (Object)null) || _stuckIn.IsDead())) { DropToGround(); } } private void DropToGround() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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) //IL_00b0: 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_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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) _dropped = true; GameObject val = (((Object)(object)ProjectileRoot != (Object)null) ? ProjectileRoot : ((Component)this).gameObject); Projectile component = val.GetComponent<Projectile>(); if ((Object)(object)component != (Object)null && AttachParentField != null) { AttachParentField.SetValue(component, null); } Vector3 val2 = val.transform.position; if (s_groundMask == 0) { s_groundMask = LayerMask.GetMask(new string[6] { "terrain", "static_solid", "Default", "Default_small", "piece", "piece_nonsolid" }); } RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val2 + Vector3.up * 0.25f, Vector3.down, ref val3, 40f, s_groundMask, (QueryTriggerInteraction)1)) { val2 = ((RaycastHit)(ref val3)).point; } else if ((Object)(object)ZoneSystem.instance != (Object)null) { val2.y = ZoneSystem.instance.GetGroundHeight(val2); } val2.y += 0.06f; Vector3 forward = val.transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.001f) { forward = Vector3.forward; } val.transform.SetPositionAndRotation(val2, Quaternion.LookRotation(((Vector3)(ref forward)).normalized, Vector3.up)); } public string GetHoverName() { ItemDrop val = (((Object)(object)ItemPrefab != (Object)null) ? ItemPrefab.GetComponent<ItemDrop>() : null); if (!((Object)(object)val != (Object)null)) { return ""; } return val.m_itemData.m_shared.m_name; } public string GetHoverText() { return Localization.instance.Localize(GetHoverName() + "\n[<color=yellow><b>$KEY_Use</b></color>] $inventory_pickup"); } public float GetHoverOffset() { return 0.35f; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_007c: 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_0088: 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) if (hold || alt || _returned || (Object)(object)ItemPrefab == (Object)null || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } _returned = true; Collider component = ((Component)this).GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } Vector3 val = ((Component)user).transform.position + ((Component)user).transform.forward * 0.75f + Vector3.up * 0.2f; Object.Instantiate<GameObject>(ItemPrefab, val, Random.rotation); GameObject val2 = (((Object)(object)ProjectileRoot != (Object)null) ? ProjectileRoot : ((Component)this).gameObject); Projectile component2 = val2.GetComponent<Projectile>(); if ((Object)(object)component2 != (Object)null) { component2.SetStayTTL(0f); } if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(val2); } else { Object.Destroy((Object)(object)val2); } return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } } internal class ShotAmmo : MonoBehaviour { public GameObject ItemPrefab; public Character Owner; } [HarmonyPatch(typeof(Projectile), "Setup")] internal static class ProjectileSetupPatch { private static void Postfix(Projectile __instance, Character owner, ItemData ammo) { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if (!((Object)(object)__instance == (Object)null) && !((Object)(object)owner == (Object)null) && owner.IsPlayer() && ammo != null && ammo.m_shared != null) { ItemType itemType = ammo.m_shared.m_itemType; if (((int)itemType == 9 || (int)itemType == 23) && !((Object)(object)ammo.m_dropPrefab == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<ShotAmmo>() != (Object)null)) { ShotAmmo shotAmmo = ((Component)__instance).gameObject.AddComponent<ShotAmmo>(); shotAmmo.ItemPrefab = ammo.m_dropPrefab; shotAmmo.Owner = owner; } } } } [HarmonyPatch(typeof(Projectile), "OnHit")] internal static class ProjectileOnHitPatch { private sealed class HitState { public float StayTtl; public bool StayDynamic; public bool AttachBone; public Character Creature; } private static readonly FieldInfo DidHitField = AccessTools.Field(typeof(Projectile), "m_didHit"); private static void Prefix(Projectile __instance, Collider collider, bool water, out HitState __state) { __state = null; if (!PluginConfig.Enabled.Value || (Object)(object)__instance == (Object)null || water) { return; } ShotAmmo component = ((Component)__instance).GetComponent<ShotAmmo>(); if ((Object)(object)component == (Object)null || (Object)(object)component.ItemPrefab == (Object)null || (Object)(object)((Component)__instance).GetComponentInChildren<ArrowPull>(true) != (Object)null || SkipsThisHit(__instance, component, collider, out var creature)) { return; } if ((Object)(object)creature != (Object)null) { if (!Roll(PluginConfig.CreatureChance.Value)) { return; } } else if (!StaysInWorld(__instance, collider) || !Roll(PluginConfig.WorldChance.Value)) { return; } __state = new HitState { StayTtl = __instance.m_stayTTL, StayDynamic = __instance.m_stayAfterHitDynamic, AttachBone = __instance.m_attachToClosestBone, Creature = creature }; float value = PluginConfig.StaySeconds.Value; if (__instance.m_stayTTL < value) { __instance.m_stayTTL = value; } if ((Object)(object)creature != (Object)null) { __instance.m_stayAfterHitDynamic = true; __instance.m_attachToClosestBone = true; } } private static void Postfix(Projectile __instance, HitState __state) { //IL_006d: 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_0084: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (__state == null || (Object)(object)__instance == (Object)null) { return; } if (!ReadDidHit(__instance)) { __instance.m_stayTTL = __state.StayTtl; __instance.m_stayAfterHitDynamic = __state.StayDynamic; __instance.m_attachToClosestBone = __state.AttachBone; return; } ShotAmmo component = ((Component)__instance).GetComponent<ShotAmmo>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.ItemPrefab == (Object)null) && !((Object)(object)((Component)__instance).GetComponentInChildren<ArrowPull>(true) != (Object)null)) { GameObject val = new GameObject("heartharrows_pull"); val.transform.SetParent(((Component)__instance).transform, false); val.layer = 0; BoxCollider obj = val.AddComponent<BoxCollider>(); ((Collider)obj).isTrigger = true; obj.size = new Vector3(0.22f, 0.22f, 0.9f); obj.center = new Vector3(0f, 0f, -0.4f); ArrowPull arrowPull = val.AddComponent<ArrowPull>(); arrowPull.ItemPrefab = component.ItemPrefab; arrowPull.ProjectileRoot = ((Component)__instance).gameObject; if ((Object)(object)__state.Creature != (Object)null) { arrowPull.WatchCreature(__state.Creature); } } } private static bool ReadDidHit(Projectile projectile) { if (DidHitField == null) { return true; } try { return (bool)DidHitField.GetValue(projectile); } catch (Exception) { return true; } } private static bool Roll(float chance) { if (chance >= 1f) { return true; } if (chance <= 0f) { return false; } return Random.value < chance; } private static bool SkipsThisHit(Projectile projectile, ShotAmmo shot, Collider collider, out Character creature) { creature = null; if (projectile.m_onlyStopOnTerrain && ((Object)(object)collider == (Object)null || (Object)(object)((Component)collider).GetComponent<Heightmap>() == (Object)null)) { return true; } if ((Object)(object)collider != (Object)null && ((Component)collider).GetComponent<IHitProjectile>() != null) { return true; } if ((Object)(object)collider == (Object)null) { return false; } GameObject val = Projectile.FindHitObject(collider); IDestructible obj = (((Object)(object)val != (Object)null) ? val.GetComponent<IDestructible>() : null); Character val2 = (Character)(object)((obj is Character) ? obj : null); if ((Object)(object)val2 == (Object)null) { return false; } creature = val2; return !IsValidCreatureHit(projectile, shot, val2); } private static bool IsValidCreatureHit(Projectile projectile, ShotAmmo shot, Character character) { if ((Object)(object)character == (Object)(object)shot.Owner && !projectile.m_hitOwner) { return false; } if ((Object)(object)shot.Owner != (Object)null && !projectile.m_hitFriendly) { bool flag = BaseAI.IsEnemy(shot.Owner, character) || ((Object)(object)character.GetBaseAI() != (Object)null && character.GetBaseAI().IsAggravatable() && shot.Owner.IsPlayer()); if (!shot.Owner.IsPlayer() && !flag) { return false; } if (shot.Owner.IsPlayer() && !shot.Owner.IsPVPEnabled() && !flag) { return false; } } if (projectile.m_dodgeable && character.IsDodgeInvincible()) { return false; } return true; } private static bool StaysInWorld(Projectile projectile, Collider collider) { if ((Object)(object)collider != (Object)null && (Object)(object)collider.attachedRigidbody != (Object)null) { if (!projectile.m_stayAfterHitDynamic && !projectile.m_attachToClosestBone) { return projectile.m_attachToRigidBody; } return true; } return projectile.m_stayAfterHitStatic; } } [BepInPlugin("com.blackhearthx.heartharrows", "HearthArrows", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class HearthArrowsPlugin : BaseUnityPlugin { public const string PluginGUID = "com.blackhearthx.heartharrows"; public const string PluginName = "HearthArrows"; public const string PluginVersion = "1.0.0"; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) PluginConfig.Bind(((BaseUnityPlugin)this).Config); new Harmony("com.blackhearthx.heartharrows").PatchAll(typeof(HearthArrowsPlugin).Assembly); Logger.LogInfo((object)"HearthArrows 1.0.0 loaded"); } } internal static class PluginConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> WorldChance; internal static ConfigEntry<float> CreatureChance; internal static ConfigEntry<float> StaySeconds; internal static ConfigEntry<bool> Glow; internal static void Bind(ConfigFile cfg) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown Enabled = cfg.Bind<bool>("Arrows", "Enabled", true, "Pull spent arrows and bolts back."); WorldChance = cfg.Bind<float>("Arrows", "Chance when it sticks", 1f, new ConfigDescription("Chance to keep an arrow you can pull when it sticks in the world (ground, wood, stone). 1 = always.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); CreatureChance = cfg.Bind<float>("Arrows", "Chance when it hits a creature", 0.5f, new ConfigDescription("Chance the arrow stays in a creature so you can pull it out. 0 = never, 1 = always.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); StaySeconds = cfg.Bind<float>("Arrows", "Seconds it stays", 120f, new ConfigDescription("How long a recoverable arrow stays before it vanishes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), Array.Empty<object>())); Glow = cfg.Bind<bool>("Arrows", "Glow", true, "A small warm light on arrows you can still pull, so you can find them at night."); } } }