Decompiled source of RopePreview v0.4.5

plugins/RopePreview.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using pworld.Scripts.Extensions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("0.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 RopePreview
{
	public static class HeldItemHider
	{
		private static readonly List<Renderer> _hidden = new List<Renderer>();

		private static readonly List<bool> _previousEnabled = new List<bool>();

		public static void Hide(GameObject itemRoot)
		{
			Restore();
			if ((Object)(object)itemRoot == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = itemRoot.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					_hidden.Add(val);
					_previousEnabled.Add(val.enabled);
					val.enabled = false;
				}
			}
		}

		public static void Restore()
		{
			for (int i = 0; i < _hidden.Count; i++)
			{
				if ((Object)(object)_hidden[i] != (Object)null)
				{
					_hidden[i].enabled = _previousEnabled[i];
				}
			}
			_hidden.Clear();
			_previousEnabled.Clear();
		}
	}
	public class PreviewBinder : MonoBehaviour
	{
		private bool _wasDown;

		private float _releaseTime;

		private bool _isPreviewing;

		private GameObject _previewItem;

		private void Update()
		{
			if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.EnablePreview.Value)
			{
				if (_isPreviewing)
				{
					StopPreview();
				}
				return;
			}
			bool flag = IsPreviewKeyHeld();
			if (flag && !_wasDown && !_isPreviewing)
			{
				StartPreview();
			}
			if (_isPreviewing && !IsHoldingPreviewItem())
			{
				StopPreview();
			}
			if (!flag && _wasDown && _isPreviewing)
			{
				_releaseTime = Time.time;
			}
			if (_isPreviewing && !flag && Time.time - _releaseTime >= Plugin.ReleaseBuffer.Value)
			{
				StopPreview();
			}
			_wasDown = flag;
			if (_isPreviewing)
			{
				RopePreviewSimulator.Tick();
				VinePreviewSimulator.Tick();
				PreviewVisualizer.Update();
			}
		}

		private static bool IsPreviewKeyHeld()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.PreviewKey == null)
			{
				return false;
			}
			KeyboardShortcut value = Plugin.PreviewKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return false;
			}
			IEnumerable<KeyCode> modifiers = ((KeyboardShortcut)(ref value)).Modifiers;
			if (modifiers != null)
			{
				foreach (KeyCode item in modifiers)
				{
					if (!IsKeyHeld(item))
					{
						return false;
					}
				}
			}
			return IsKeyHeld(((KeyboardShortcut)(ref value)).MainKey);
		}

		private static bool IsKeyHeld(KeyCode key)
		{
			//IL_0000: 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)
			if ((int)key == 0)
			{
				return false;
			}
			try
			{
				IInputSystem current = UnityInput.Current;
				return current != null && current.GetKey(key);
			}
			catch
			{
				return false;
			}
		}

		private void StartPreview()
		{
			Player localPlayer = Player.localPlayer;
			if ((Object)(object)((localPlayer != null) ? localPlayer.character : null) == (Object)null)
			{
				return;
			}
			CharacterData data = localPlayer.character.data;
			Item val = ((data != null) ? data.currentItem : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			RopeShooter componentInChildren = ((Component)val).GetComponentInChildren<RopeShooter>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				if (!RopePreviewSimulator.StartPreview(componentInChildren))
				{
					return;
				}
			}
			else
			{
				VineShooter componentInChildren2 = ((Component)val).GetComponentInChildren<VineShooter>(true);
				if ((Object)(object)componentInChildren2 == (Object)null || !VinePreviewSimulator.StartPreview(componentInChildren2))
				{
					return;
				}
			}
			_isPreviewing = true;
			_releaseTime = 0f;
			_previewItem = ((Component)val).gameObject;
			if (Plugin.HideHeldItem.Value)
			{
				HeldItemHider.Hide(_previewItem);
			}
			PreviewVisualizer.ShowMarker();
		}

		private void StopPreview()
		{
			_isPreviewing = false;
			_previewItem = null;
			HeldItemHider.Restore();
			RopePreviewSimulator.StopPreview();
			VinePreviewSimulator.StopPreview();
			PreviewVisualizer.HideMarker();
		}

		private bool IsHoldingPreviewItem()
		{
			if ((Object)(object)_previewItem == (Object)null)
			{
				return false;
			}
			Player localPlayer = Player.localPlayer;
			object obj;
			if (localPlayer == null)
			{
				obj = null;
			}
			else
			{
				Character character = localPlayer.character;
				if (character == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = character.data;
					obj = ((data != null) ? data.currentItem : null);
				}
			}
			Item val = (Item)obj;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			return (Object)(object)((Component)val).gameObject == (Object)(object)_previewItem;
		}

		private void OnDestroy()
		{
			if (_isPreviewing)
			{
				StopPreview();
			}
			else
			{
				HeldItemHider.Restore();
			}
		}
	}
	public static class PreviewVisualizer
	{
		private static GameObject _markerObj;

		private static Transform _markerTransform;

		private static LineRenderer _lineRenderer;

		private static GameObject _lineObj;

		private static bool _isVisible;

		private static readonly List<Vector3> _segmentBuffer = new List<Vector3>(64);

		private static readonly Color RopeLineColor = new Color(1f, 0.92f, 0.35f, 0.95f);

		public static void ShowMarker()
		{
			if ((Object)(object)_markerObj == (Object)null)
			{
				CreateMarker();
			}
			if ((Object)(object)_lineObj == (Object)null)
			{
				CreateLine();
			}
			_markerObj.SetActive(true);
			_lineObj.SetActive(true);
			_isVisible = true;
		}

		public static void HideMarker()
		{
			if ((Object)(object)_markerObj != (Object)null)
			{
				_markerObj.SetActive(false);
			}
			if ((Object)(object)_lineObj != (Object)null)
			{
				_lineObj.SetActive(false);
			}
			_isVisible = false;
		}

		public static void Update()
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			if (!_isVisible)
			{
				return;
			}
			if (VinePreviewSimulator.IsActive)
			{
				if ((Object)(object)_lineRenderer != (Object)null)
				{
					_lineRenderer.positionCount = 0;
				}
				SetMarkerActive(active: false);
				return;
			}
			SetMarkerActive(active: true);
			Vector3? anchorPosition = RopePreviewSimulator.GetAnchorPosition();
			Vector3? endPosition = RopePreviewSimulator.GetEndPosition();
			Vector3? targetPoint = RopePreviewSimulator.GetTargetPoint();
			if ((Object)(object)_lineRenderer != (Object)null)
			{
				int num = RopePreviewSimulator.FillSegmentPositions(_segmentBuffer);
				if (num < 2)
				{
					Vector3? val = anchorPosition;
					Vector3? val2 = endPosition ?? targetPoint;
					if (val.HasValue && val2.HasValue)
					{
						_segmentBuffer.Clear();
						_segmentBuffer.Add(val.Value);
						_segmentBuffer.Add(val2.Value);
						num = 2;
					}
					else
					{
						num = 0;
					}
				}
				EnsureLinePoints(num);
				for (int i = 0; i < num; i++)
				{
					_lineRenderer.SetPosition(i, _segmentBuffer[i]);
				}
			}
			Vector3? val3 = endPosition ?? targetPoint;
			if (val3.HasValue && (Object)(object)_markerTransform != (Object)null)
			{
				_markerTransform.position = val3.Value;
			}
		}

		private static void SetMarkerActive(bool active)
		{
			if ((Object)(object)_markerObj != (Object)null && _markerObj.activeSelf != active)
			{
				_markerObj.SetActive(active);
			}
		}

		private static void EnsureLinePoints(int count)
		{
			if ((Object)(object)_lineRenderer != (Object)null && _lineRenderer.positionCount != count)
			{
				_lineRenderer.positionCount = count;
			}
		}

		private static void CreateMarker()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			_markerObj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)_markerObj).name = "[RopePreview]Marker";
			_markerTransform = _markerObj.transform;
			Collider component = _markerObj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Renderer component2 = _markerObj.GetComponent<Renderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				Material material = component2.material;
				material.color = (((Object)(object)Plugin.Instance != (Object)null && Plugin.MarkerColor != null) ? Plugin.MarkerColor.Value : Color.yellow);
				material.SetFloat("_Mode", 3f);
				material.EnableKeyword("_ALPHABLEND_ON");
				material.renderQueue = 3000;
				material.color = new Color(material.color.r, material.color.g, material.color.b, 0.8f);
			}
			float num = (((Object)(object)Plugin.Instance != (Object)null && Plugin.MarkerSize != null) ? Plugin.MarkerSize.Value : 0.3f);
			_markerTransform.localScale = Vector3.one * num;
		}

		private static void CreateLine()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			_lineObj = new GameObject("[RopePreview]Line");
			_lineRenderer = _lineObj.AddComponent<LineRenderer>();
			_lineRenderer.startWidth = 0.1f;
			_lineRenderer.endWidth = 0.1f;
			_lineRenderer.positionCount = 0;
			_lineRenderer.useWorldSpace = true;
			_lineRenderer.startColor = RopeLineColor;
			_lineRenderer.endColor = RopeLineColor;
			_lineRenderer.numCapVertices = 4;
			_lineRenderer.numCornerVertices = 4;
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Color");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Hidden/Internal-Colored");
			}
			if ((Object)(object)val != (Object)null)
			{
				((Renderer)_lineRenderer).material = new Material(val);
			}
		}

		public static void Dispose()
		{
			HideMarker();
			_segmentBuffer.Clear();
			if ((Object)(object)_markerObj != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)_markerObj);
				_markerObj = null;
				_markerTransform = null;
			}
			if ((Object)(object)_lineObj != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)_lineObj);
				_lineObj = null;
				_lineRenderer = null;
			}
		}
	}
	[HarmonyPatch(typeof(PhotonView), "get_IsMine")]
	public static class RopePhysicsBypassPatch
	{
		public static bool Prefix(PhotonView __instance, ref bool __result)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null)
			{
				return true;
			}
			if (RopePreviewSimulator.IsPreviewObjectOrChild(((Component)__instance).gameObject))
			{
				__result = true;
				return false;
			}
			return true;
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "RopePreview";

		public const string Name = "绳索炮预览";

		public const string Version = "0.4.5";
	}
	[BepInPlugin("RopePreview", "绳索炮预览", "0.4.5")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigEntry<KeyboardShortcut> PreviewKey;

		public static ConfigEntry<bool> EnablePreview;

		public static ConfigEntry<float> ReleaseBuffer;

		public static ConfigEntry<bool> HideHeldItem;

		public static ConfigEntry<Color> MarkerColor;

		public static ConfigEntry<float> MarkerSize;

		internal static ManualLogSource Log { get; private set; }

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Log.LogInfo((object)"[绳索炮预览] v0.4.5 加载完成");
			BindConfig();
			new Harmony("RopePreview").PatchAll(Assembly.GetExecutingAssembly());
			GameObject val = new GameObject("[RopePreview]Binder");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<PreviewBinder>();
			Log.LogInfo((object)$"[绳索炮预览] 已就绪,按住预览键(当前:{PreviewKey.Value})即可预览绳索/锁链落点");
			Log.LogInfo((object)("[绳索炮预览] 输入后端: " + DescribeInputBackend()));
		}

		private static string DescribeInputBackend()
		{
			try
			{
				IInputSystem current = UnityInput.Current;
				return (current != null) ? ((object)current).GetType().Name : "null";
			}
			catch
			{
				return "不可用";
			}
		}

		private void BindConfig()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			PreviewKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Preview Key", new KeyboardShortcut((KeyCode)324, Array.Empty<KeyCode>()), "按住此键预览绳索炮落点(默认鼠标右键)");
			EnablePreview = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Preview", true, "启用绳索炮预览");
			ReleaseBuffer = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Release Buffer", 0.5f, "松开按键后延迟多少秒才停止预览(避免抖动)");
			HideHeldItem = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Hide Held Item", true, "预览时隐藏手中的发射器(绳索炮/反重绳索炮/锁链发射器),避免遮挡视线");
			MarkerColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "Marker Color", Color.yellow, "绳索末端落点标记的颜色");
			MarkerSize = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Marker Size", 0.3f, "绳索末端落点标记的大小");
		}

		private void OnDestroy()
		{
			HeldItemHider.Restore();
			RopePreviewSimulator.Dispose();
			VinePreviewSimulator.StopPreview();
			PreviewVisualizer.Dispose();
		}
	}
	public static class RopePreviewSimulator
	{
		private static readonly HashSet<GameObject> _previewObjects = new HashSet<GameObject>();

		private static GameObject _anchorObj;

		private static GameObject _ropeObj;

		private static Rope _currentRope;

		private static RopeAnchor _currentAnchor;

		private static Vector3 _targetPoint;

		private static bool _hasTarget;

		private static float _diagTimer;

		public static bool StartPreview(RopeShooter shooter)
		{
			//IL_0029: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			StopPreview();
			if (!RaycastAnchor(shooter, out var hit))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[绳索炮预览] 射线未命中任何地面,不显示预览");
				}
				return false;
			}
			Quaternion rotation = ComputeAnchorRotation(shooter, ((RaycastHit)(ref hit)).normal);
			_targetPoint = ((RaycastHit)(ref hit)).point;
			_hasTarget = true;
			return CreatePreviewRope(shooter, ((RaycastHit)(ref hit)).point, rotation);
		}

		private static bool RaycastAnchor(RopeShooter shooter, out RaycastHit hit)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			hit = default(RaycastHit);
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return false;
			}
			return Physics.Raycast(((Component)main).transform.position, ((Component)main).transform.forward, ref hit, shooter.maxLength, LayerMask.op_Implicit(HelperExtensions.ToLayerMask((LayerType)1)), (QueryTriggerInteraction)0);
		}

		private static Quaternion ComputeAnchorRotation(RopeShooter shooter, Vector3 normal)
		{
			//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = ExtQuaternion.FromUpAndRightPrioUp(((Component)shooter).transform.forward, normal);
			if (Vector3.Dot(normal, Vector3.up) < 0.5f)
			{
				val *= Quaternion.Euler(0f, 180f, 0f);
			}
			return val;
		}

		private static bool CreatePreviewRope(RopeShooter shooter, Vector3 hitPoint, Quaternion rotation)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)shooter.ropeAnchorWithRopePref == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)"[绳索炮预览] ropeAnchorWithRopePref 为空");
				}
				return false;
			}
			_anchorObj = Object.Instantiate<GameObject>(shooter.ropeAnchorWithRopePref, hitPoint, rotation);
			_previewObjects.Add(_anchorObj);
			RopeAnchorWithRope component = _anchorObj.GetComponent<RopeAnchorWithRope>();
			_currentAnchor = _anchorObj.GetComponent<RopeAnchor>();
			if ((Object)(object)component == (Object)null || (Object)(object)_currentAnchor == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)"[绳索炮预览] 无法获取 RopeAnchorWithRope 或 RopeAnchor");
				}
				StopPreview();
				return false;
			}
			if ((Object)(object)component.anchor == (Object)null)
			{
				component.anchor = _currentAnchor;
			}
			component.ropeSegmentLength = shooter.length;
			if ((Object)(object)component.ropePrefab == (Object)null)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)"[绳索炮预览] ropePrefab 为空");
				}
				StopPreview();
				return false;
			}
			_ropeObj = Object.Instantiate<GameObject>(component.ropePrefab, _currentAnchor.anchorPoint.position, _currentAnchor.anchorPoint.rotation);
			_previewObjects.Add(_ropeObj);
			_currentRope = _ropeObj.GetComponent<Rope>();
			if ((Object)(object)_currentRope == (Object)null)
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogError((object)"[绳索炮预览] 无法获取 Rope 组件");
				}
				StopPreview();
				return false;
			}
			_currentRope.Segments = shooter.length;
			_currentRope.AttachToAnchor_Rpc(_currentAnchor.photonView, shooter.length);
			component.ropeInstance = _ropeObj;
			component.rope = _currentRope;
			return true;
		}

		public static Vector3? GetEndPosition()
		{
			//IL_0050: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_currentRope == (Object)null || (Object)(object)_currentAnchor == (Object)null)
			{
				return null;
			}
			List<Transform> ropeSegments = _currentRope.GetRopeSegments();
			if (ropeSegments == null || ropeSegments.Count == 0)
			{
				return null;
			}
			Vector3 position = _currentAnchor.anchorPoint.position;
			Transform val = null;
			float num = -1f;
			for (int i = 0; i < ropeSegments.Count; i++)
			{
				Transform val2 = ropeSegments[i];
				if (!((Object)(object)val2 == (Object)null))
				{
					Vector3 val3 = val2.position - position;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude > num)
					{
						num = sqrMagnitude;
						val = val2;
					}
				}
			}
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.position;
		}

		public static Vector3? GetAnchorPosition()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_currentAnchor == (Object)null)
			{
				return null;
			}
			return _currentAnchor.anchorPoint.position;
		}

		public static Vector3? GetTargetPoint()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasTarget)
			{
				return null;
			}
			return _targetPoint;
		}

		public static void Tick()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_currentRope == (Object)null || (Object)(object)_currentAnchor == (Object)null)
			{
				return;
			}
			_diagTimer += Time.deltaTime;
			if (_diagTimer < 0.5f)
			{
				return;
			}
			_diagTimer = 0f;
			List<Transform> ropeSegments = _currentRope.GetRopeSegments();
			Vector3 position = _currentAnchor.anchorPoint.position;
			Vector3? endPosition = GetEndPosition();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				object arg = ropeSegments?.Count ?? 0;
				object arg2 = position;
				object arg3;
				if (!endPosition.HasValue)
				{
					arg3 = "无";
				}
				else
				{
					Vector3 value = endPosition.Value;
					arg3 = ((Vector3)(ref value)).ToString("F2");
				}
				log.LogInfo((object)$"[绳索炮预览] 诊断 段数={arg} 锚点={arg2:F2} 末端={arg3}");
			}
		}

		public static int FillSegmentPositions(List<Vector3> buffer)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			buffer.Clear();
			if ((Object)(object)_currentRope == (Object)null || (Object)(object)_currentAnchor == (Object)null)
			{
				return 0;
			}
			List<Transform> ropeSegments = _currentRope.GetRopeSegments();
			if (ropeSegments == null || ropeSegments.Count == 0)
			{
				return 0;
			}
			Vector3 position = _currentAnchor.anchorPoint.position;
			for (int i = 0; i < ropeSegments.Count; i++)
			{
				Transform val = ropeSegments[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Vector3 position2 = val.position;
				Vector3 val2 = position2 - position;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				int num;
				for (num = buffer.Count; num > 0; num--)
				{
					val2 = buffer[num - 1] - position;
					if (!(((Vector3)(ref val2)).sqrMagnitude > sqrMagnitude))
					{
						break;
					}
				}
				if (num == buffer.Count)
				{
					buffer.Add(position2);
				}
				else
				{
					buffer.Insert(num, position2);
				}
			}
			return buffer.Count;
		}

		public static void StopPreview()
		{
			foreach (GameObject previewObject in _previewObjects)
			{
				if ((Object)(object)previewObject != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)previewObject);
				}
			}
			_previewObjects.Clear();
			_anchorObj = null;
			_ropeObj = null;
			_currentRope = null;
			_currentAnchor = null;
			_hasTarget = false;
			_diagTimer = 0f;
		}

		public static bool IsPreviewObjectOrChild(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return false;
			}
			Transform val = go.transform;
			while ((Object)(object)val != (Object)null)
			{
				if (_previewObjects.Contains(((Component)val).gameObject))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		public static void Dispose()
		{
			StopPreview();
		}
	}
	public static class VinePreviewSimulator
	{
		private static GameObject _preview;

		private static JungleVine _vine;

		private static Renderer _renderer;

		private static Material _material;

		private static Transform _meshT;

		private static Transform _hangCenter;

		private static float _meshLength = 40f;

		private static VineShooter _shooter;

		private static bool _active;

		private static float _hang;

		private static Vector3 _to;

		public static bool IsActive => _active;

		public static bool StartPreview(VineShooter shooter)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			StopPreview();
			if ((Object)(object)shooter == (Object)null)
			{
				return false;
			}
			if ((Object)(object)shooter.vinePrefab == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[绳索炮预览] 锁链发射器 vinePrefab 为空");
				}
				return false;
			}
			JungleVine componentInChildren = shooter.vinePrefab.GetComponentInChildren<JungleVine>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("[绳索炮预览] 锁链预制体 " + ((Object)shooter.vinePrefab).name + " 上没有 JungleVine 组件"));
				}
				return false;
			}
			if (!TryGetTarget(shooter, out var hit))
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"[绳索炮预览] 锁链发射器射线未命中有效目标");
				}
				return false;
			}
			Vector3 val = ComputeFrom();
			if (!TryPickHang(componentInChildren, val, ((RaycastHit)(ref hit)).point, out _hang))
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)"[绳索炮预览] 锁链路径被地形阻挡,无可放置的形态");
				}
				return false;
			}
			if (!CreatePreview(shooter.vinePrefab, val, ((RaycastHit)(ref hit)).point, _hang))
			{
				return false;
			}
			_shooter = shooter;
			_active = true;
			_to = ((RaycastHit)(ref hit)).point;
			return true;
		}

		private static bool CreatePreview(GameObject prefab, Vector3 from, Vector3 to, float hang)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			_preview = Object.Instantiate<GameObject>(prefab);
			if ((Object)(object)_preview == (Object)null)
			{
				return false;
			}
			((Object)_preview).name = "[RopePreview]Chain";
			_preview.transform.SetPositionAndRotation(from, Quaternion.identity);
			StripExtras(_preview);
			_vine = _preview.GetComponentInChildren<JungleVine>(true);
			_renderer = _preview.GetComponentInChildren<Renderer>(true);
			if ((Object)(object)_vine == (Object)null || (Object)(object)_renderer == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[绳索炮预览] 锁链预制体缺少 JungleVine 或 Renderer");
				}
				CleanupPreview();
				return false;
			}
			_material = _renderer.material;
			_meshT = _preview.transform.Find("Mesh");
			if ((Object)(object)_meshT == (Object)null)
			{
				_meshT = ((Component)_renderer).transform;
			}
			_hangCenter = _vine.hangCenter;
			_meshLength = ((_vine.meshLength > 0.01f) ? _vine.meshLength : 40f);
			Vector3 val = Vector3.Lerp(from, to, 0.5f);
			val.y += hang;
			_vine.ForceBuildVine(from, to, hang, val);
			StripColliders(_preview);
			return true;
		}

		public static void Tick()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			if (_active && !((Object)(object)_shooter == (Object)null) && !((Object)(object)_preview == (Object)null) && TryGetTarget(_shooter, out var hit))
			{
				ApplyShape(ComputeFrom(), ((RaycastHit)(ref hit)).point, _hang);
				_to = ((RaycastHit)(ref hit)).point;
			}
		}

		private static void ApplyShape(Vector3 from, Vector3 to, float hang)
		{
			//IL_0018: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_preview == (Object)null))
			{
				_preview.transform.SetPositionAndRotation(from, Quaternion.identity);
				float num = Vector3.Distance(from, to) / _meshLength;
				Vector3 val = Vector3.Lerp(from, to, 0.5f);
				val.y += hang;
				if ((Object)(object)_material != (Object)null)
				{
					_material.SetFloat("_Hang", hang);
					_material.SetFloat("_LengthScale", (num < 0.5f) ? (num * 2f) : 1f);
				}
				if ((Object)(object)_hangCenter != (Object)null)
				{
					_hangCenter.position = QuadraticBezier(from, val, to, 0.5f);
				}
				if ((Object)(object)_meshT != (Object)null)
				{
					_meshT.rotation = Quaternion.LookRotation(to - from);
					_meshT.localScale = Vector3.one * num;
				}
				if ((Object)(object)_renderer != (Object)null)
				{
					Bounds localBounds = _renderer.localBounds;
					((Bounds)(ref localBounds)).Encapsulate(((Component)_renderer).transform.InverseTransformPoint(val));
					_renderer.localBounds = localBounds;
				}
			}
		}

		private static void StripColliders(GameObject preview)
		{
			Collider[] componentsInChildren = preview.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Rigidbody[] componentsInChildren2 = preview.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
		}

		private static void StripExtras(GameObject preview)
		{
			Component[] componentsInChildren = preview.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				switch (((object)val).GetType().Name)
				{
				case "PhotonView":
				{
					Behaviour val3 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if (val3 != null && val3.enabled)
					{
						val3.enabled = false;
					}
					break;
				}
				case "AudioSource":
				case "ParticleSystem":
				case "ParticleSystemRenderer":
					Object.DestroyImmediate((Object)(object)val);
					break;
				case "JungleVine":
				{
					Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if (val2 != null)
					{
						val2.enabled = false;
					}
					break;
				}
				}
			}
			for (int num = preview.transform.childCount - 1; num >= 0; num--)
			{
				Transform child = preview.transform.GetChild(num);
				string name = ((Object)child).name;
				if (name.StartsWith("VFX") || name.StartsWith("SFX"))
				{
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
		}

		private static void CleanupPreview()
		{
			Material material = _material;
			if ((Object)(object)_preview != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)_preview);
			}
			if ((Object)(object)material != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)material);
			}
			_preview = null;
			_vine = null;
			_renderer = null;
			_meshT = null;
			_hangCenter = null;
			_material = null;
		}

		private static Vector3 QuadraticBezier(Vector3 start, Vector3 control, Vector3 end, float t)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f - t;
			return num * num * start + 2f * num * t * control + t * t * end;
		}

		private static bool TryGetTarget(VineShooter shooter, out RaycastHit hit)
		{
			//IL_0001: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			hit = default(RaycastHit);
			Transform cameraTransform = GetCameraTransform();
			if ((Object)(object)cameraTransform == (Object)null)
			{
				return false;
			}
			if (!Physics.Raycast(cameraTransform.position, cameraTransform.forward, ref hit, shooter.maxLength, LayerMask.op_Implicit(HelperExtensions.ToLayerMask((LayerType)1)), (QueryTriggerInteraction)0))
			{
				return false;
			}
			Vector3 up = Vector3.up;
			Vector3 val = ((RaycastHit)(ref hit)).point - cameraTransform.position;
			float num = Vector3.Dot(up, ((Vector3)(ref val)).normalized);
			if (num > 0.6f || num < -0.7f)
			{
				return false;
			}
			if (num > 0.5f)
			{
				return false;
			}
			return true;
		}

		private static Transform GetCameraTransform()
		{
			if ((Object)(object)MainCamera.instance != (Object)null)
			{
				return ((Component)MainCamera.instance).transform;
			}
			if (!((Object)(object)Camera.main != (Object)null))
			{
				return null;
			}
			return ((Component)Camera.main).transform;
		}

		private static Vector3 ComputeFrom()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			//IL_002f: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			Transform cameraTransform = GetCameraTransform();
			if ((Object)(object)cameraTransform == (Object)null)
			{
				return Vector3.zero;
			}
			Vector3 result = cameraTransform.position - Vector3.up * 0.2f;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(cameraTransform.position + cameraTransform.forward, Vector3.down, ref val, 4f, LayerMask.op_Implicit(HelperExtensions.ToLayerMask((LayerType)1)), (QueryTriggerInteraction)0))
			{
				result = ((RaycastHit)(ref val)).point + Vector3.up * 1.5f;
			}
			return result;
		}

		private static bool TryPickHang(JungleVine vine, Vector3 from, Vector3 to, out float hang)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			hang = 0f;
			Vector3 val = default(Vector3);
			for (int i = 0; i < 10; i++)
			{
				float num = (float)i / 9f;
				float num2 = Mathf.Lerp(vine.minDown, 0f, num);
				float num3 = Mathf.Lerp(vine.maxDown, 0f, num);
				float num4 = 0f - Random.Range(Mathf.Min(num2, num3), Mathf.Max(num2, num3));
				if (JungleVine.CheckVinePath(from, to, num4, ref val, 0f))
				{
					hang = num4;
					return true;
				}
			}
			return false;
		}

		public static void StopPreview()
		{
			_active = false;
			_shooter = null;
			_hang = 0f;
			CleanupPreview();
		}
	}
}