Decompiled source of RopePreview v0.3.1

plugins/com.fufu.RopePreview.dll

Decompiled 4 days 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;

		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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!_isVisible)
			{
				return;
			}
			Vector3? val = null;
			if (VinePreviewSimulator.IsActive)
			{
				IReadOnlyList<Vector3> curvePoints = VinePreviewSimulator.GetCurvePoints();
				if (curvePoints != null && curvePoints.Count >= 2 && (Object)(object)_lineRenderer != (Object)null)
				{
					EnsureLinePoints(curvePoints.Count);
					for (int i = 0; i < curvePoints.Count; i++)
					{
						_lineRenderer.SetPosition(i, curvePoints[i]);
					}
					val = curvePoints[curvePoints.Count - 1];
				}
			}
			else
			{
				Vector3? anchorPosition = RopePreviewSimulator.GetAnchorPosition();
				val = RopePreviewSimulator.GetEndPosition();
				if ((Object)(object)_lineRenderer != (Object)null && anchorPosition.HasValue && val.HasValue)
				{
					EnsureLinePoints(2);
					_lineRenderer.SetPosition(0, anchorPosition.Value);
					_lineRenderer.SetPosition(1, val.Value);
				}
			}
			if (val.HasValue && (Object)(object)_markerTransform != (Object)null)
			{
				_markerTransform.position = val.Value;
			}
		}

		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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			_lineObj = new GameObject("[RopePreview]Line");
			_lineRenderer = _lineObj.AddComponent<LineRenderer>();
			_lineRenderer.startWidth = 0.1f;
			_lineRenderer.endWidth = 0.1f;
			_lineRenderer.positionCount = 2;
			_lineRenderer.useWorldSpace = true;
			_lineRenderer.startColor = new Color(1f, 1f, 0f, 0.6f);
			_lineRenderer.endColor = new Color(1f, 1f, 0f, 0.6f);
			((Renderer)_lineRenderer).material = new Material(Shader.Find("Sprites/Default"));
		}

		public static void Dispose()
		{
			HideMarker();
			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 = "com.fufu.RopePreview";

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

		public const string Version = "0.3.1";
	}
	[BepInPlugin("com.fufu.RopePreview", "绳索炮预览", "0.3.1")]
	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.3.1 加载完成");
			BindConfig();
			new Harmony("com.fufu.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 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_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)
			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);
			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)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: 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;
			ManualLogSource log5 = Plugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"[绳索炮预览] 生成预览 hit={hitPoint:F3} anchorRot={((Quaternion)(ref rotation)).eulerAngles:F1} anchorPoint={_currentAnchor.anchorPoint.position:F3} ropePos={_ropeObj.transform.position:F3} length={shooter.length:F2} prefab={((Object)shooter.ropeAnchorWithRopePref).name}");
			}
			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 void Tick()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_00a1: 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_0123: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_currentRope == (Object)null)
			{
				return;
			}
			_diagTimer += Time.deltaTime;
			if (_diagTimer < 0.5f)
			{
				return;
			}
			_diagTimer = 0f;
			List<Transform> ropeSegments = _currentRope.GetRopeSegments();
			Vector3 val = (((Object)(object)_currentAnchor != (Object)null) ? _currentAnchor.anchorPoint.position : Vector3.zero);
			Vector3? endPosition = GetEndPosition();
			string text = "无";
			Vector3 val2;
			if (ropeSegments != null && ropeSegments.Count > 0)
			{
				object obj;
				if (!((Object)(object)ropeSegments[0] != (Object)null))
				{
					obj = "null";
				}
				else
				{
					val2 = ropeSegments[0].position;
					obj = ((Vector3)(ref val2)).ToString("F2");
				}
				text = "[0]=" + (string?)obj;
				if (ropeSegments.Count > 1 && (Object)(object)ropeSegments[1] != (Object)null)
				{
					string text2 = text;
					val2 = ropeSegments[1].position;
					text = text2 + "[1]=" + ((Vector3)(ref val2)).ToString("F2");
				}
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				object[] obj2 = new object[4]
				{
					ropeSegments?.Count ?? 0,
					val,
					null,
					null
				};
				object obj3;
				if (!endPosition.HasValue)
				{
					obj3 = "无";
				}
				else
				{
					val2 = endPosition.Value;
					obj3 = ((Vector3)(ref val2)).ToString("F2");
				}
				obj2[2] = obj3;
				obj2[3] = text;
				log.LogInfo((object)string.Format("[绳索炮预览] 诊断 段数={0} 锚点={1:F2} 末端={2} {3}", obj2));
			}
		}

		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;
			_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 readonly List<Vector3> _curvePoints = new List<Vector3>(50);

		private static VineShooter _shooter;

		private static bool _active;

		private static float _hang;

		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_00d6: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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;
			}
			_shooter = shooter;
			_active = true;
			RebuildCurve(val, ((RaycastHit)(ref hit)).point, _hang);
			ManualLogSource log5 = Plugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"[绳索炮预览] 锁链预览 from={val:F2} to={((RaycastHit)(ref hit)).point:F2} hang={_hang:F2} 末端={GetEndPosition():F2} vinePrefab={((Object)shooter.vinePrefab).name}");
			}
			return true;
		}

		public static void Tick()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (_active && !((Object)(object)_shooter == (Object)null) && TryGetTarget(_shooter, out var hit))
			{
				RebuildCurve(ComputeFrom(), ((RaycastHit)(ref hit)).point, _hang);
			}
		}

		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;
		}

		private static void RebuildCurve(Vector3 from, Vector3 to, float hang)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0035: 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_0037: 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)
			Vector3 control = Vector3.Lerp(from, to, 0.5f);
			control.y += hang;
			_curvePoints.Clear();
			for (int i = 0; i < 50; i++)
			{
				float t = (float)i / 49f;
				_curvePoints.Add(QuadraticBezier(from, control, to, t));
			}
		}

		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;
		}

		public static IReadOnlyList<Vector3> GetCurvePoints()
		{
			return _curvePoints;
		}

		public static Vector3? GetEndPosition()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (_curvePoints.Count == 0)
			{
				return null;
			}
			return _curvePoints[_curvePoints.Count - 1];
		}

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