using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet.Connection; using FishNet.Object; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [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("HTFTorch")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HTFTorch")] [assembly: AssemblyTitle("HTFTorch")] [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; } } } [BepInPlugin("yoxi.htf.torch", "HTF Torch", "2.2.0")] public class TorchPlugin : BaseUnityPlugin { public const string Id = "yoxi.htf.torch"; internal static ManualLogSource Log; private ConfigEntry _key; private GameObject _rig; private float _poll; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; _key = ((BaseUnityPlugin)this).Config.Bind("Torch", "SpawnKey", (KeyCode)116, "Host only: spawn a torch item at your feet."); } private void Update() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0074: 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) _poll -= Time.deltaTime; if (!(_poll > 0f)) { _poll = 2f; bool flag = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0).Length != 0; if (flag && (Object)(object)_rig == (Object)null) { _rig = new GameObject("HTFTorch"); Object.DontDestroyOnLoad((Object)(object)_rig); _rig.AddComponent().SpawnKey = _key.Value; } else if (!flag && (Object)(object)_rig != (Object)null) { Object.Destroy((Object)(object)_rig); _rig = null; } } } } public class TorchKeeper : MonoBehaviour { public KeyCode SpawnKey = (KeyCode)116; private static readonly Vector3 HeldShift = new Vector3(0.3f, -0.25f, 0.28f); private static readonly Vector3 GripAnchorPos = new Vector3(0.04f, -0.04f, -0.1f); private static readonly Vector3 GripAnchorEuler = new Vector3(375f, -270f, 90f); private const float FingerCurl = 0.8f; private static Quaternion[] _looseCurl; private static Quaternion[] _tightCurl; public static byte TorchId; private static Harmony _harmony; private AssetBundle _bundle; private GameObject _visualPrefab; private GameObject _holder; private GameObject _template; private float _forgeRetry; private bool _forgeFailed; private readonly List> _droppedLights = new List>(); private float _flameScan; private static readonly int GlowProp = Shader.PropertyToID("_Glow"); private MaterialPropertyBlock _mpb; private bool? _lastHeldState; private Item _heldTorch; private float _heldScan; private static readonly Vector3 CarryLean = new Vector3(-8f, 0f, 0f); private static int _handLayer = -1; private static int _visualLayer; private static readonly FieldInfo HeldRotF = AccessTools.Field(typeof(Item), "_heldRot"); private static int _inputMode; private void Start() { LoadBundle(); WakeAdditionalLights(); } private void LoadBundle() { string text = Path.Combine(Path.GetDirectoryName(typeof(TorchPlugin).Assembly.Location), "htftorch.bundle"); string text2 = Path.Combine(Paths.PluginPath, "htftorch.bundle"); string text3 = (File.Exists(text) ? text : (File.Exists(text2) ? text2 : null)); if (text3 == null) { TorchPlugin.Log.LogWarning((object)"htftorch.bundle not found - the torch item would be invisible, so it will not be forged."); return; } _bundle = AssetBundle.LoadFromFile(text3); if ((Object)(object)_bundle != (Object)null) { _visualPrefab = _bundle.LoadAsset("TorchProp"); } if ((Object)(object)_visualPrefab == (Object)null) { TorchPlugin.Log.LogError((object)"TorchProp missing from the bundle."); } } private void LateUpdate() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_template == (Object)null && !_forgeFailed && (Object)(object)_visualPrefab != (Object)null) { _forgeRetry -= Time.deltaTime; if (_forgeRetry <= 0f) { _forgeRetry = 1f; TryForge(); } } if ((Object)(object)_template != (Object)null && Pressed(SpawnKey)) { ((MonoBehaviour)this).StartCoroutine(SpawnTorch()); } KeepTorchUpright(); BreatheFlames(); FollowDroppedLights(); } private void FollowDroppedLights() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0070: Unknown result type (might be due to invalid IL or missing references) for (int num = _droppedLights.Count - 1; num >= 0; num--) { KeyValuePair keyValuePair = _droppedLights[num]; if ((Object)(object)keyValuePair.Key == (Object)null || (Object)(object)keyValuePair.Value == (Object)null) { _droppedLights.RemoveAt(num); } else { ((Component)keyValuePair.Value).transform.position = keyValuePair.Key.position + Vector3.up * 0.55f; } } } private void BreatheFlames() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_00a2: 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) //IL_016f: Unknown result type (might be due to invalid IL or missing references) if (TorchId == 0) { return; } _flameScan -= Time.deltaTime; if (_flameScan > 0f) { return; } _flameScan = 0.4f; if (_mpb == null) { _mpb = new MaterialPropertyBlock(); } _droppedLights.Clear(); Item[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Item val in array) { if (val.ID != TorchId) { continue; } bool flag = (Object)(object)val.SyncedHolder != (Object)null; Transform val2 = ((Component)val).transform.Find("TorchVisual/FlameAnchor"); if ((Object)(object)val2 == (Object)null) { continue; } val2.localScale = Vector3.one * (flag ? 1f : 0.5f); Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren(); foreach (Renderer val3 in componentsInChildren) { if (val3 is MeshRenderer) { val3.GetPropertyBlock(_mpb); _mpb.SetFloat(GlowProp, flag ? 0.95f : 0.35f); val3.SetPropertyBlock(_mpb); } } Light componentInChildren = ((Component)val2).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.intensity = (flag ? 2.6f : 1.2f); componentInChildren.range = (flag ? 12f : 9f); if (flag) { ((Component)componentInChildren).transform.localPosition = Vector3.zero; } else { _droppedLights.Add(new KeyValuePair(val2, componentInChildren)); } } if (!_lastHeldState.HasValue || _lastHeldState != flag) { _lastHeldState = flag; TorchPlugin.Log.LogInfo((object)("Torch flame state: " + (flag ? "BLAZING (held)" : "embers (dropped)") + ".")); } } } private static Quaternion[] BlendCurl(float t) { //IL_0029: 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) //IL_003b: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) Quaternion[] tightCurl = _tightCurl; Quaternion[] looseCurl = _looseCurl; if (tightCurl == null) { return looseCurl; } Quaternion[] array = (Quaternion[])(object)new Quaternion[tightCurl.Length]; for (int i = 0; i < tightCurl.Length; i++) { Quaternion val = ((looseCurl != null && looseCurl.Length == tightCurl.Length) ? looseCurl[i] : Quaternion.identity); array[i] = Quaternion.Slerp(val, tightCurl[i], t); } return array; } private void KeepTorchUpright() { //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: 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_0208: 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_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) if (TorchId == 0 || HeldRotF == null) { return; } _heldScan -= Time.deltaTime; if (_heldScan <= 0f) { _heldScan = 0.5f; if (_handLayer < 0) { PlayerHands val = Object.FindFirstObjectByType(); Renderer val2 = (Renderer)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val2 != (Object)null) { _handLayer = ((Component)val2).gameObject.layer; int cullingMask = ~((1 << _visualLayer) | (1 << _handLayer)); Light[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Light val3 in array) { if (((Object)val3).name == "TorchLight") { val3.cullingMask = cullingMask; } } TorchPlugin.Log.LogInfo((object)("Torch light now ignores hand layer " + _handLayer + " (" + LayerMask.LayerToName(_handLayer) + ").")); } } _heldTorch = null; Item[] array2 = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Item val4 in array2) { if (val4.ID == TorchId) { Player syncedHolder = val4.SyncedHolder; if (!((Object)(object)syncedHolder == (Object)null) && !(((NetworkBehaviour)syncedHolder).Owner == (NetworkConnection)null) && ((NetworkBehaviour)syncedHolder).Owner.IsLocalClient) { _heldTorch = val4; break; } } } } if (!((Object)(object)_heldTorch == (Object)null)) { Camera val5 = Eye(); if (!((Object)(object)val5 == (Object)null)) { Quaternion rotation = ((Component)val5).transform.rotation; Quaternion val6 = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f) * Quaternion.Euler(CarryLean); Quaternion val7 = Quaternion.Inverse(rotation) * val6; HeldRotF.SetValue(_heldTorch, ((Quaternion)(ref val7)).eulerAngles); } } } private void TryForge() { //IL_0a65: Unknown result type (might be due to invalid IL or missing references) //IL_0aa0: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0e98: Unknown result type (might be due to invalid IL or missing references) //IL_0ea2: Expected O, but got Unknown //IL_0edb: Unknown result type (might be due to invalid IL or missing references) //IL_0ee9: Expected O, but got Unknown //IL_0f24: Unknown result type (might be due to invalid IL or missing references) //IL_0f31: Expected O, but got Unknown //IL_0f6b: Unknown result type (might be due to invalid IL or missing references) //IL_0f79: Expected O, but got Unknown //IL_09e2: Unknown result type (might be due to invalid IL or missing references) //IL_09e8: Expected O, but got Unknown //IL_0fb3: Unknown result type (might be due to invalid IL or missing references) //IL_0fc1: Expected O, but got Unknown //IL_0ce7: Unknown result type (might be due to invalid IL or missing references) //IL_0cec: Unknown result type (might be due to invalid IL or missing references) //IL_0cf1: Unknown result type (might be due to invalid IL or missing references) //IL_0cf6: Unknown result type (might be due to invalid IL or missing references) //IL_0cff: Unknown result type (might be due to invalid IL or missing references) //IL_0d12: Unknown result type (might be due to invalid IL or missing references) //IL_0d96: Unknown result type (might be due to invalid IL or missing references) //IL_0da7: Unknown result type (might be due to invalid IL or missing references) //IL_0dac: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Expected O, but got Unknown //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Expected O, but got Unknown //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0627: Unknown result type (might be due to invalid IL or missing references) //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) try { IDictionary dictionary = AccessTools.Field(typeof(GameInfo), "_allItems").GetValue(null) as IDictionary; IDictionary dictionary2 = AccessTools.Field(typeof(GameInfo), "_idToSpawnable").GetValue(null) as IDictionary; IDictionary dictionary3 = AccessTools.Field(typeof(GameInfo), "_nameToSpawnable").GetValue(null) as IDictionary; if (dictionary == null || dictionary.Count == 0) { return; } byte b = 230; while (dictionary.Contains(b) && b < byte.MaxValue) { b++; } if (dictionary.Contains(b)) { TorchPlugin.Log.LogError((object)"No free item ID for the torch."); _forgeFailed = true; return; } TorchId = b; _holder = new GameObject("TorchTemplateHolder"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); _template = new GameObject("Torch"); _template.transform.SetParent(_holder.transform, false); _template.AddComponent(); Item val = null; foreach (DictionaryEntry item in dictionary) { object? value = item.Value; Item val2 = (Item)((value is Item) ? value : null); if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponent() != (Object)null && (Object)(object)((Component)val2).GetComponentInChildren(true) != (Object)null) { val = val2; break; } } int num = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject.layer : Mathf.Max(0, LayerMask.NameToLayer("Item"))); int num2 = num; if ((Object)(object)val != (Object)null) { Renderer componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { num2 = ((Component)componentInChildren).gameObject.layer; } } int num3 = num; if ((Object)(object)val != (Object)null && AccessTools.Field(typeof(Item), "_worldColliders").GetValue(val) is Collider[] array && array.Length != 0 && (Object)(object)array[0] != (Object)null) { num3 = ((Component)array[0]).gameObject.layer; } TorchPlugin.Log.LogInfo((object)("Vanilla item conventions from '" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "(none - fallback)") + "': root layer " + num + " (" + LayerMask.LayerToName(num) + "), colliders " + num3 + " (" + LayerMask.LayerToName(num3) + "), visuals " + num2 + " (" + LayerMask.LayerToName(num2) + ")")); Rigidbody val3 = _template.AddComponent(); val3.mass = 1.2f; val3.collisionDetectionMode = (CollisionDetectionMode)2; Rigidbody val4 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val3.interpolation = val4.interpolation; val3.collisionDetectionMode = val4.collisionDetectionMode; val3.linearDamping = val4.linearDamping; val3.angularDamping = val4.angularDamping; } GameObject val5 = new GameObject("TorchBody"); val5.transform.SetParent(_template.transform, false); CapsuleCollider val6 = val5.AddComponent(); val6.direction = 1; val6.radius = 0.05f; val6.height = 0.55f; val6.center = new Vector3(0f, 0.05f, 0f); GameObject val7 = new GameObject("TorchGrab"); val7.transform.SetParent(_template.transform, false); CapsuleCollider val8 = val7.AddComponent(); val8.direction = 1; val8.radius = 0.16f; val8.height = 0.7f; val8.center = new Vector3(0f, 0.08f, 0f); GameObject val9 = Object.Instantiate(_visualPrefab, _template.transform); ((Object)val9).name = "TorchVisual"; val9.transform.localPosition = new Vector3(0f, -0.15f, 0f); val9.transform.localRotation = Quaternion.identity; int num4 = 0; List list = new List(); Transform[] componentsInChildren = val9.GetComponentsInChildren(true); foreach (Transform val10 in componentsInChildren) { if (((Object)val10).name == "Arm" || ((Object)val10).name == "Fist" || ((Object)val10).name == "Forearm") { list.Add(((Component)val10).gameObject); } } foreach (GameObject item2 in list) { if (!((Object)(object)item2 == (Object)null)) { num4++; Object.DestroyImmediate((Object)(object)item2); } } TorchPlugin.Log.LogInfo((object)((num4 > 0) ? ("Removed " + num4 + " fake-arm part(s) from the visual.") : "NOTE: no fake-arm parts found in the visual - if a glowing fist still shows, the bundle names them differently.")); List list2 = new List(val9.GetComponentsInChildren(true)); foreach (Renderer item3 in list2) { Material[] sharedMaterials = item3.sharedMaterials; foreach (Material val11 in sharedMaterials) { if ((Object)(object)val11 != (Object)null && val11.HasProperty("_Glow")) { val11.SetFloat("_Glow", 0.95f); } } } Light val12 = null; Transform val13 = val9.transform.Find("FlameAnchor"); if ((Object)(object)val13 != (Object)null) { GameObject val14 = new GameObject("TorchLight"); val14.transform.SetParent(val13, false); val12 = val14.AddComponent(); val12.type = (LightType)2; val12.color = new Color(1f, 0.62f, 0.32f); val12.intensity = 2.6f; val12.range = 12f; val12.shadows = (LightShadows)2; val12.shadowStrength = 0.85f; } Collider val15 = null; Collider val16 = null; if ((Object)(object)val != (Object)null) { object? value2 = AccessTools.Field(typeof(Item), "_pickUpCollider").GetValue(val); val15 = (Collider)((value2 is Collider) ? value2 : null); if (AccessTools.Field(typeof(Item), "_worldColliders").GetValue(val) is Collider[] array2 && array2.Length != 0) { val16 = array2[0]; } } try { if ((Object)(object)val != (Object)null) { _template.tag = ((Component)val).gameObject.tag; } val5.tag = (((Object)(object)val16 != (Object)null) ? ((Component)val16).gameObject.tag : "Item"); val7.tag = (((Object)(object)val15 != (Object)null) ? ((Component)val15).gameObject.tag : "Item"); } catch (Exception ex) { TorchPlugin.Log.LogWarning((object)("Could not tag the torch: " + ex.Message)); } _template.layer = num; val5.layer = (((Object)(object)val16 != (Object)null) ? ((Component)val16).gameObject.layer : num3); val7.layer = (((Object)(object)val15 != (Object)null) ? ((Component)val15).gameObject.layer : num); componentsInChildren = val9.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = num2; } if ((Object)(object)val12 != (Object)null) { val12.cullingMask = ~(1 << num2); } _visualLayer = num2; TorchPlugin.Log.LogInfo((object)("Torch anatomy: root layer " + _template.layer + " tag '" + _template.tag + "', body layer " + val5.layer + " tag '" + val5.tag + "', grab layer " + val7.layer + " tag '" + val7.tag + "'.")); Item val17 = _template.AddComponent(); Set(val17, "_id", b); Set(val17, "_cost", 150); Set(val17, "_worth", 50); Set(val17, "_worldColliders", new Collider[1] { (Collider)val6 }); Set(val17, "_pickUpCollider", val8); Set(val17, "_extraRigs", new ItemExtraRigidbody[0]); Set(val17, "_renderers", list2); Set(val17, "_skinRenderers", new List()); Set(val17, "_trailEffects", new List()); Set(val17, "_modelForwardLength", 0.15f); Set(val17, "_modelHeight", 0.5f); try { object obj = Activator.CreateInstance(typeof(FloatInfo)); Set(obj, "_rig", val3); FloatInfo[] array3 = (FloatInfo[])Array.CreateInstance(typeof(FloatInfo), 1); array3[0] = (FloatInfo)obj; Set(val17, "_floatInfos", array3); } catch (Exception ex2) { Set(val17, "_floatInfos", new FloatInfo[0]); TorchPlugin.Log.LogWarning((object)("No float info (torch will sink): " + ex2.Message)); } MeshFilter val18 = FindStickMesh(val9); if ((Object)(object)val18 != (Object)null) { Set(val17, "_mesh", val18.sharedMesh); } Set(val17, "_inventoryMeshRot", (object)new Vector3(0f, 0f, -45f)); Set(val17, "_inventoryMeshScale", 1.3f); Set(val17, "_inventoryMeshPos", (object)new Vector3(-0.15f, -0.15f, 0f)); ImpactSoundType val19 = PickImpactSound(); if ((Object)(object)val19 != (Object)null) { Set(val17, "_impactSoundType", val19); } else { TorchPlugin.Log.LogWarning((object)"No ImpactSoundType asset found yet - collisions may complain."); } try { Item val20 = null; Item val21 = null; FieldInfo fieldInfo = AccessTools.Field(typeof(Item), "_handTransformsRight"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Item), "_handTransformsLeft"); foreach (DictionaryEntry item4 in dictionary) { object? value3 = item4.Value; Item val22 = (Item)((value3 is Item) ? value3 : null); if ((Object)(object)val22 == (Object)null) { continue; } object? value4 = fieldInfo.GetValue(val22); HandTransforms val23 = (HandTransforms)((value4 is HandTransforms) ? value4 : null); if (val23 != null && val23.Exists) { if ((Object)(object)val21 == (Object)null) { val21 = val22; } object? value5 = fieldInfo2.GetValue(val22); HandTransforms val24 = (HandTransforms)((value5 is HandTransforms) ? value5 : null); if (val24 == null || !val24.Exists) { val20 = val22; break; } } } if ((Object)(object)val20 == (Object)null) { val20 = val21; } Quaternion[] tightCurl = null; foreach (DictionaryEntry item5 in dictionary) { object? value6 = item5.Value; Item val25 = (Item)((value6 is Item) ? value6 : null); if (val25 is Melee) { object? value7 = fieldInfo.GetValue(val25); HandTransforms val26 = (HandTransforms)((value7 is HandTransforms) ? value7 : null); if (val26 != null && val26.Exists && val26.FingerRots != null && val26.FingerRots.Length != 0) { tightCurl = (Quaternion[])val26.FingerRots.Clone(); TorchPlugin.Log.LogInfo((object)("Finger curl borrowed from '" + ((Object)val25).name + "'.")); break; } } } _tightCurl = tightCurl; if ((Object)(object)val20 != (Object)null) { object? value8 = fieldInfo.GetValue(val20); HandTransforms val27 = (HandTransforms)((value8 is HandTransforms) ? value8 : null); if (val27 != null && val27.FingerRots != null) { _looseCurl = (Quaternion[])val27.FingerRots.Clone(); } } if ((Object)(object)val20 != (Object)null) { Vector3 val28 = (Vector3)AccessTools.Field(typeof(Item), "_heldPos").GetValue(val20) + HeldShift; Set(val17, "_heldPos", val28); Set(val17, "_heldRot", CarryLean); HandTransforms val29 = RebuildGrip(_template.transform, val20, "_handTransformsRight", "TorchGripR", BlendCurl(0.8f)); Set(val17, "_handTransformsRight", val29); Set(val17, "_handTransformsLeft", RebuildGrip(_template.transform, val20, "_handTransformsLeft", "TorchGripL", null)); if ((Object)(object)val29.Parent != (Object)null) { val29.Parent.localPosition = GripAnchorPos; val29.Parent.localRotation = Quaternion.Euler(GripAnchorEuler); } TorchPlugin.Log.LogInfo((object)("Torch grip built (pose from '" + ((Object)val20).name + "', sculpted values baked in).")); } else { TorchPlugin.Log.LogWarning((object)"No vanilla item with a hand grip found - the torch will float when held."); } } catch (Exception ex3) { TorchPlugin.Log.LogWarning((object)("Grip copy failed: " + ex3.Message)); } Set(_template.AddComponent(), "_extraHinges", new Rigidbody[0]); dictionary.Add(b, val17); if (dictionary2 != null && !dictionary2.Contains(b)) { dictionary2.Add(b, val17); } if (dictionary3 != null && !dictionary3.Contains("torch")) { dictionary3.Add("torch", val17); } if (!RegisterWithFishNet(_template)) { TorchPlugin.Log.LogWarning((object)"FishNet registration failed - the torch will exist but may not replicate to other players."); } if (_harmony == null) { _harmony = new Harmony("yoxi.htf.torch.item"); MethodInfo methodInfo = AccessTools.Method(typeof(Item), "GetName", (Type[])null, (Type[])null); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(TorchKeeper), "NamePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(AccessTools.TypeByName("SaveManager"), "SaveWorldItems", (Type[])null, (Type[])null); if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(TorchKeeper), "SaveFilterPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(Item), "Awake", (Type[])null, (Type[])null); if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(TorchKeeper), "ItemAwakeGuard", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo4 = AccessTools.Method(typeof(RigidbodySync), "Awake", (Type[])null, (Type[])null); if (methodInfo4 != null) { _harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(TorchKeeper), "RigSyncAwakeGuard", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } TorchPlugin.Log.LogInfo((object)("TORCH FORGED from scratch: item ID " + b + " (cost 150). Press " + ((object)Unsafe.As(ref SpawnKey)/*cast due to .constrained prefix*/).ToString() + " as host to spawn one at your feet.")); } catch (Exception ex4) { TorchPlugin.Log.LogError((object)("The forge failed: " + ex4)); _forgeFailed = true; } } private static void Set(object target, string field, object value) { FieldInfo fieldInfo = AccessTools.Field(target.GetType(), field); if (fieldInfo != null) { fieldInfo.SetValue(target, value); return; } TorchPlugin.Log.LogWarning((object)("No field '" + field + "' on " + target.GetType().Name + " - the game may have updated.")); } private static HandTransforms RebuildGrip(Transform ourRoot, Item reference, string field, string childName, Quaternion[] fingerOverride) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) Type typeFromHandle = typeof(HandTransforms); HandTransforms val = (HandTransforms)FormatterServices.GetUninitializedObject(typeFromHandle); object? value = AccessTools.Field(typeof(Item), field).GetValue(reference); HandTransforms val2 = (HandTransforms)((value is HandTransforms) ? value : null); if (val2 == null || !val2.Exists) { AccessTools.Field(typeFromHandle, "_exists").SetValue(val, false); AccessTools.Field(typeFromHandle, "_fingerRots").SetValue(val, new Quaternion[0]); AccessTools.Field(typeFromHandle, "_parent").SetValue(val, ourRoot); return val; } AccessTools.Field(typeFromHandle, "_exists").SetValue(val, true); AccessTools.Field(typeFromHandle, "_handPos").SetValue(val, Vector3.zero); AccessTools.Field(typeFromHandle, "_handRot").SetValue(val, Quaternion.identity); Quaternion[] array = ((fingerOverride != null) ? fingerOverride : val2.FingerRots); AccessTools.Field(typeFromHandle, "_fingerRots").SetValue(val, (array != null) ? ((Array)(Quaternion[])array.Clone()) : ((Array)new Quaternion[0])); GameObject val3 = new GameObject(childName); val3.transform.SetParent(ourRoot, false); if ((Object)(object)val2.Parent != (Object)null) { Transform transform = ((Component)reference).transform; val3.transform.localPosition = transform.InverseTransformPoint(val2.Parent.position); val3.transform.localRotation = Quaternion.Inverse(transform.rotation) * val2.Parent.rotation; } AccessTools.Field(typeFromHandle, "_parent").SetValue(val, val3.transform); return val; } private static MeshFilter FindStickMesh(GameObject visual) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0070: Unknown result type (might be due to invalid IL or missing references) MeshFilter val = null; MeshFilter[] componentsInChildren = visual.GetComponentsInChildren(true); foreach (MeshFilter val2 in componentsInChildren) { if ((Object)(object)val2.sharedMesh == (Object)null) { continue; } if (((Object)val2).name.IndexOf("torch", StringComparison.OrdinalIgnoreCase) >= 0) { return val2; } if (!((Object)(object)val == (Object)null)) { Bounds bounds = val2.sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude; bounds = val.sharedMesh.bounds; size = ((Bounds)(ref bounds)).size; if (!(sqrMagnitude > ((Vector3)(ref size)).sqrMagnitude)) { continue; } } val = val2; } return val; } private static ImpactSoundType PickImpactSound() { ImpactSoundType val = null; ImpactSoundType[] array = Resources.FindObjectsOfTypeAll(); foreach (ImpactSoundType val2 in array) { if ((Object)(object)val == (Object)null) { val = val2; } if (((Object)val2).name.IndexOf("wood", StringComparison.OrdinalIgnoreCase) >= 0) { return val2; } } return val; } private static bool NamePrefix(Item __instance, ref string __result) { if ((Object)(object)__instance != (Object)null && TorchId != 0 && __instance.ID == TorchId) { __result = "Torch"; return false; } return true; } private static void SaveFilterPostfix(object __result) { if (!(__result is IList list)) { return; } FieldInfo fieldInfo = null; FieldInfo fieldInfo2 = null; for (int num = list.Count - 1; num >= 0; num--) { object obj = list[num]; if (obj != null) { if (fieldInfo == null) { fieldInfo = obj.GetType().GetField("Item"); if (fieldInfo == null) { break; } } object value = fieldInfo.GetValue(obj); if (value != null) { if (fieldInfo2 == null) { fieldInfo2 = value.GetType().GetField("ItemID"); if (fieldInfo2 == null) { break; } } if ((byte)fieldInfo2.GetValue(value) == TorchId) { list.RemoveAt(num); } } } } } private static void ItemAwakeGuard(Item __instance) { try { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } Type typeFromHandle = typeof(Item); FillIfNull(__instance, typeFromHandle, "_extraRigs", new ItemExtraRigidbody[0]); FillIfNull(__instance, typeFromHandle, "_trailEffects", new List()); FillIfNull(__instance, typeFromHandle, "_skinRenderers", new List()); FillIfNull(__instance, typeFromHandle, "_floatInfos", new FloatInfo[0]); FillIfNull(__instance, typeFromHandle, "_renderers", new List(((Component)__instance).GetComponentsInChildren(true))); FieldInfo fieldInfo = AccessTools.Field(typeFromHandle, "_worldColliders"); if (fieldInfo != null && fieldInfo.GetValue(__instance) == null) { fieldInfo.SetValue(__instance, ((Component)__instance).GetComponentsInChildren(true)); } FieldInfo fieldInfo2 = AccessTools.Field(typeFromHandle, "_pickUpCollider"); if (fieldInfo2 != null && fieldInfo2.GetValue(__instance) == null) { Collider componentInChildren = ((Component)__instance).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { fieldInfo2.SetValue(__instance, componentInChildren); } } } catch (Exception) { } } private static void RigSyncAwakeGuard(RigidbodySync __instance) { try { FieldInfo fieldInfo = AccessTools.Field(typeof(RigidbodySync), "_extraHinges"); if (fieldInfo != null && fieldInfo.GetValue(__instance) == null) { fieldInfo.SetValue(__instance, new Rigidbody[0]); } } catch (Exception) { } } private static void FillIfNull(object target, Type t, string field, object value) { FieldInfo fieldInfo = AccessTools.Field(t, field); if (fieldInfo != null && fieldInfo.GetValue(target) == null) { fieldInfo.SetValue(target, value); } } private static bool RegisterWithFishNet(GameObject template) { try { Type type = Type.GetType("FishNet.Object.NetworkObject, FishNet.Runtime"); Type type2 = Type.GetType("FishNet.InstanceFinder, FishNet.Runtime"); if (type == null || type2 == null) { return false; } Component component = template.GetComponent(type); if ((Object)(object)component == (Object)null) { TorchPlugin.Log.LogWarning((object)"Template has no NetworkObject."); return false; } PropertyInfo property = type2.GetProperty("NetworkManager", BindingFlags.Static | BindingFlags.Public); object obj = ((property != null) ? property.GetValue(null, null) : null); if (obj == null) { return false; } PropertyInfo property2 = obj.GetType().GetProperty("SpawnablePrefabs"); object obj2 = ((property2 != null) ? property2.GetValue(obj, null) : null); if (obj2 == null) { return false; } MethodInfo methodInfo = null; MethodInfo[] methods = obj2.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "AddObject")) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length >= 1 && parameters[0].ParameterType == type) { methodInfo = methodInfo2; break; } } } if (methodInfo == null) { return false; } ParameterInfo[] parameters2 = methodInfo.GetParameters(); object[] array = new object[parameters2.Length]; array[0] = component; for (int j = 1; j < parameters2.Length; j++) { array[j] = (parameters2[j].HasDefaultValue ? parameters2[j].DefaultValue : ((parameters2[j].ParameterType == typeof(bool)) ? ((object)false) : null)); } methodInfo.Invoke(obj2, array); TorchPlugin.Log.LogInfo((object)("Torch prefab registered with FishNet (" + obj2.GetType().Name + ").")); return true; } catch (Exception ex) { TorchPlugin.Log.LogWarning((object)("FishNet registration: " + ex.Message)); return false; } } private IEnumerator SpawnTorch() { Type type = AccessTools.TypeByName("Server"); if (type == null) { yield break; } PropertyInfo propertyInfo = AccessTools.Property(type, "Instance"); object obj = ((propertyInfo != null) ? propertyInfo.GetValue(null, null) : null); if ((Object)((obj is Object) ? obj : null) == (Object)null) { TorchPlugin.Log.LogInfo((object)"Only the HOST can spawn torches - ask them nicely."); yield break; } MethodInfo methodInfo = null; Type type2 = type; while (type2 != null && methodInfo == null) { MethodInfo[] methods = type2.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "Spawn")) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length >= 1 && parameters[0].ParameterType == typeof(GameObject)) { methodInfo = methodInfo2; break; } } } type2 = type2.BaseType; } if (methodInfo == null) { TorchPlugin.Log.LogError((object)"No Spawn method on Server."); yield break; } Camera val = Eye(); Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : ((Component)this).transform.position) + (((Object)(object)val != (Object)null) ? ((Component)val).transform.forward : Vector3.forward) * 1.2f + Vector3.up * 0.3f; GameObject val3 = Object.Instantiate(_template, val2, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); ((Object)val3).name = "Torch"; val3.SetActive(true); try { methodInfo.Invoke(obj, (methodInfo.GetParameters().Length != 3) ? new object[2] { val3, null } : new object[3] { val3, null, (object)default(Scene) }); TorchPlugin.Log.LogInfo((object)"A torch clatters to the ground."); } catch (Exception ex) { TorchPlugin.Log.LogWarning((object)("Could not network-spawn the torch: " + ex.Message)); Object.Destroy((Object)(object)val3); } } private static void WakeAdditionalLights() { try { RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline; if ((Object)(object)currentRenderPipeline == (Object)null) { return; } Type type = ((object)currentRenderPipeline).GetType(); FieldInfo field = type.GetField("m_AdditionalLightsRenderingMode", BindingFlags.Instance | BindingFlags.NonPublic); if (!(field == null)) { int num = Convert.ToInt32(field.GetValue(currentRenderPipeline)); if (num != 1) { field.SetValue(currentRenderPipeline, Enum.ToObject(field.FieldType, 1)); TorchPlugin.Log.LogInfo((object)("Additional lights were mode " + num + " - set to per-pixel so fire can light the world.")); } FieldInfo field2 = type.GetField("m_AdditionalLightsPerObjectLimit", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 != null && Convert.ToInt32(field2.GetValue(currentRenderPipeline)) < 4) { field2.SetValue(currentRenderPipeline, 4); } FieldInfo field3 = type.GetField("m_AdditionalLightShadowsSupported", BindingFlags.Instance | BindingFlags.NonPublic); if (field3 != null && !(bool)field3.GetValue(currentRenderPipeline)) { field3.SetValue(currentRenderPipeline, true); TorchPlugin.Log.LogInfo((object)"Additional-light shadows switched on."); } FieldInfo field4 = type.GetField("m_AdditionalLightsShadowmapResolution", BindingFlags.Instance | BindingFlags.NonPublic); if (field4 != null && Convert.ToInt32(field4.GetValue(currentRenderPipeline)) < 1024) { field4.SetValue(currentRenderPipeline, Enum.ToObject(field4.FieldType.IsEnum ? field4.FieldType : typeof(int), 1024)); } } } catch (Exception) { } } private static Camera Eye() { Camera val = null; Camera[] allCameras = Camera.allCameras; foreach (Camera val2 in allCameras) { if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).isActiveAndEnabled && !((Object)(object)val2.targetTexture != (Object)null) && ((Object)(object)val == (Object)null || val2.depth > val.depth)) { val = val2; } } if (!((Object)(object)val != (Object)null)) { return Camera.main; } return val; } private unsafe static bool Pressed(KeyCode key) { //IL_0008: 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) if (_inputMode <= 1) { try { bool keyDown = Input.GetKeyDown(key); _inputMode = 1; return keyDown; } catch (Exception) { _inputMode = 2; } } if (_inputMode == 2) { try { Keyboard current = Keyboard.current; if (current == null) { return false; } if (!Enum.TryParse(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(), ignoreCase: true, out Key result)) { return false; } return ((ButtonControl)current[result]).wasPressedThisFrame; } catch (Exception) { _inputMode = -1; } } return false; } private void OnDestroy() { if ((Object)(object)_bundle != (Object)null) { _bundle.Unload(false); } } }