Decompiled source of BigBalloons v1.0.0

Big Balloons.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Big Balloons")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Go Go Gadget Big Balloons")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("Big Balloons")]
[assembly: AssemblyTitle("Big Balloons")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[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 BigWalkLightOrbMod
{
	[BepInPlugin("com.gogogadgetjustice.bigwalk.bigballoon", "Big Balloon Orbs", "3.3.0")]
	public class LightOrbMod : BasePlugin
	{
		internal static ManualLogSource Logger;

		public static ConfigEntry<KeyCode> CollectKey;

		public static ConfigEntry<KeyCode> ReleaseKey;

		public static ConfigEntry<float> AttachRadius;

		public static ConfigEntry<float> BuoyancyForcePerOrb;

		public static ConfigEntry<float> TerminalDescentSpeedPerOrb;

		public static ConfigEntry<float> HoverHeightAboveAnchor;

		public static ConfigEntry<float> HoverBackwardOffset;

		public static ConfigEntry<float> OrbSpreadRadius;

		public static ConfigEntry<float> OrbSpreadRadiusGrowth;

		public static ConfigEntry<float> VerticalStackPerOrb;

		public static ConfigEntry<float> FollowLerpSpeed;

		public static ConfigEntry<int> MaxTetheredOrbs;

		public static ConfigEntry<float> StringWidth;

		public override void Load()
		{
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			CollectKey = ((BasePlugin)this).Config.Bind<KeyCode>("Controls", "Collect Key", (KeyCode)56, "Starts/resumes auto-tethering nearby loose buoys by proximity.");
			ReleaseKey = ((BasePlugin)this).Config.Bind<KeyCode>("Controls", "Release Key", (KeyCode)55, "Releases the most recently tethered buoy and stops collecting until Collect Key is pressed again.");
			AttachRadius = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Attach Radius", 2f, "Distance (meters) within which a loose buoy auto-tethers to the player, while collecting is active.");
			BuoyancyForcePerOrb = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Buoyancy Force Per Orb", 3.5f, "Continuous upward acceleration added per tethered orb - raises jump apex and slows ascent/descent.");
			TerminalDescentSpeedPerOrb = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Terminal Descent Speed Per Orb", 0.6f, "Additional clamp (m/s) subtracted from max downward fall speed per tethered orb - more orbs = longer hang time coming down.");
			HoverHeightAboveAnchor = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Hover Height Above Anchor", 1.4f, "Base height above the torso anchor for the bouquet of tethered orbs.");
			HoverBackwardOffset = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Hover Backward Offset", 0.3f, "How far behind the player's facing direction the bouquet sits, so it reads as coming off the back, not floating directly overhead.");
			OrbSpreadRadius = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Orb Spread Radius", 0.28f, "Base horizontal radius (meters) of the golden-angle spread ring, so orbs don't overlap.");
			OrbSpreadRadiusGrowth = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Orb Spread Radius Growth", 0.03f, "Extra radius added per orb index, so later orbs sit slightly further out.");
			VerticalStackPerOrb = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Vertical Stack Per Orb", 0.12f, "Small height increase per additional orb, layered on top of the horizontal spread.");
			FollowLerpSpeed = ((BasePlugin)this).Config.Bind<float>("Physics Tuning", "Follow Lerp Speed", 8f, "How quickly a tethered orb catches up to its hover slot (higher = snappier).");
			MaxTetheredOrbs = ((BasePlugin)this).Config.Bind<int>("Features", "Max Tethered Orbs", 8, "Hard cap on simultaneously tethered orbs.");
			StringWidth = ((BasePlugin)this).Config.Bind<float>("Visuals", "String Width", 0.03f, "Width of the tether string line renderer.");
			ClassInjector.RegisterTypeInIl2Cpp<LightOrbManager>();
			GameObject val = new GameObject("LightOrbModHost")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<LightOrbManager>();
			Logger.LogInfo((object)"==================================================");
			Logger.LogInfo((object)"  Big Walk Light Orb Mod Loaded! (v3.3 - BodyBall torso anchor, fixed string color)");
			Logger.LogInfo((object)"  [8] Start/resume collecting   [7] Release last orb (stops collecting)");
			Logger.LogInfo((object)"==================================================");
		}
	}
	public class TetheredOrb
	{
		public Prop OrbProp;

		public Rigidbody OrbRigidbody;

		public LineRenderer StringLine;

		public bool WasKinematicBeforeTether;

		public bool WasGravityEnabledBeforeTether;
	}
	public class LightOrbManager : MonoBehaviour
	{
		private const float GoldenAngleRadians = 2.3999631f;

		private static readonly string[] AnchorBlacklist = new string[8] { "Camera", "UI", "Menu", "Navigation", "Helper", "HUD", "Canvas", "Hanger" };

		private static readonly string[] UnlitShaderCandidates = new string[5] { "Universal Render Pipeline/2D/Sprite-Unlit-Default", "Universal Render Pipeline/Unlit", "HDRP/Unlit", "Sprites/Default", "Legacy Shaders/Diffuse" };

		private Rigidbody _targetedPlayerRb;

		private Transform _anchorTransform;

		private float _searchTimer = 0f;

		private float _heartbeatTimer = 0f;

		private bool _loggedRigidbodyDump = false;

		private float _scanTimer = 0f;

		private const float ScanInterval = 0.25f;

		private bool _isCollecting = false;

		private readonly List<TetheredOrb> _tetheredOrbs = new List<TetheredOrb>();

		private readonly HashSet<IntPtr> _tetheredPropPointers = new HashSet<IntPtr>();

		public LightOrbManager(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Start()
		{
			LocatePlayer();
		}

		public void Update()
		{
			//IL_009c: 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)
			if ((Object)(object)_targetedPlayerRb == (Object)null)
			{
				_searchTimer -= Time.deltaTime;
				_heartbeatTimer -= Time.deltaTime;
				if (_heartbeatTimer <= 0f)
				{
					_heartbeatTimer = 5f;
					LightOrbMod.Logger.LogInfo((object)"[LightOrbMod] Still searching for player Rigidbody...");
				}
				if (_searchTimer <= 0f)
				{
					LocatePlayer();
					_searchTimer = 1.5f;
				}
				return;
			}
			if (Input.GetKeyDown(LightOrbMod.CollectKey.Value))
			{
				_isCollecting = true;
				LightOrbMod.Logger.LogInfo((object)"[LightOrbMod] Collecting started - walk near buoys to tether them.");
			}
			else if (Input.GetKeyDown(LightOrbMod.ReleaseKey.Value))
			{
				ReleaseMostRecentOrb();
			}
			if (_isCollecting)
			{
				_scanTimer -= Time.deltaTime;
				if (_scanTimer <= 0f)
				{
					_scanTimer = 0.25f;
					ScanForNearbyLooseBuoys();
				}
			}
		}

		public void FixedUpdate()
		{
			if (!((Object)(object)_targetedPlayerRb == (Object)null) && _tetheredOrbs.Count != 0)
			{
				UpdateTetherPositionsAndStrings();
				ApplyFloatiness();
			}
		}

		private void LocatePlayer()
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			Rigidbody[] array = Il2CppArrayBase<Rigidbody>.op_Implicit(Object.FindObjectsOfType<Rigidbody>());
			Rigidbody[] array2 = array;
			bool flag = default(bool);
			foreach (Rigidbody val in array2)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null && ((Object)((Component)val).gameObject).name.IndexOf("PlayerCharacter", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					_targetedPlayerRb = val;
					_anchorTransform = FindAnchorTransform(((Component)val).transform);
					ManualLogSource logger = LightOrbMod.Logger;
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[LightOrbMod] Connected to player '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)((Component)val).gameObject).name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'. Anchored orbs to '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)_anchorTransform).name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'.");
					}
					logger.LogInfo(val2);
					return;
				}
			}
			if (_loggedRigidbodyDump)
			{
				return;
			}
			_loggedRigidbodyDump = true;
			ManualLogSource logger2 = LightOrbMod.Logger;
			BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(79, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[LightOrbMod] No Rigidbody matched 'PlayerCharacter'. Found ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array.Length);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" Rigidbodies total:");
			}
			logger2.LogWarning(val3);
			for (int j = 0; j < array.Length; j++)
			{
				if ((Object)(object)array[j] != (Object)null)
				{
					ManualLogSource logger3 = LightOrbMod.Logger;
					val3 = new BepInExWarningLogInterpolatedStringHandler(8, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("    - '");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)((Component)array[j]).gameObject).name);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'");
					}
					logger3.LogWarning(val3);
				}
			}
		}

		private static bool IsBlacklisted(string name)
		{
			for (int i = 0; i < AnchorBlacklist.Length; i++)
			{
				if (name.IndexOf(AnchorBlacklist[i], StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private Transform FindAnchorTransform(Transform playerRoot)
		{
			Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)playerRoot).GetComponentsInChildren<Transform>(true));
			Transform val = null;
			Transform val2 = null;
			Transform val3 = null;
			Transform val4 = null;
			Transform val5 = null;
			Transform[] array2 = array;
			foreach (Transform val6 in array2)
			{
				if ((Object)(object)val6 == (Object)null)
				{
					continue;
				}
				string name = ((Object)val6).name;
				if (IsBlacklisted(name))
				{
					continue;
				}
				bool flag = name.IndexOf("BodyBall", StringComparison.OrdinalIgnoreCase) >= 0;
				bool flag2 = name.IndexOf("torso", StringComparison.OrdinalIgnoreCase) >= 0;
				if (flag && flag2)
				{
					if (name.IndexOf("LOD1", StringComparison.OrdinalIgnoreCase) >= 0 && (Object)(object)val == (Object)null)
					{
						val = val6;
					}
					else if (name.IndexOf("LOD0", StringComparison.OrdinalIgnoreCase) >= 0 && (Object)(object)val2 == (Object)null)
					{
						val2 = val6;
					}
				}
				else if ((Object)(object)val3 == (Object)null && name.IndexOf("chest_bone", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val3 = val6;
				}
				else if ((Object)(object)val4 == (Object)null && name.IndexOf("torso_mesh", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val4 = val6;
				}
				else if ((Object)(object)val5 == (Object)null && name.IndexOf("head_bone", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val5 = val6;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			if ((Object)(object)val3 != (Object)null)
			{
				return val3;
			}
			if ((Object)(object)val4 != (Object)null)
			{
				LightOrbMod.Logger.LogInfo((object)"[LightOrbMod] No BodyBall torso anchor found, falling back to torso_mesh (may not track live position well).");
				return val4;
			}
			if ((Object)(object)val5 != (Object)null)
			{
				LightOrbMod.Logger.LogInfo((object)"[LightOrbMod] No torso anchor found, falling back to head_bone.");
				return val5;
			}
			LightOrbMod.Logger.LogInfo((object)"[LightOrbMod] No suitable anchor found, using player root.");
			return playerRoot;
		}

		private void ScanForNearbyLooseBuoys()
		{
			//IL_0041: 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_00fb: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (_tetheredOrbs.Count >= LightOrbMod.MaxTetheredOrbs.Value)
			{
				return;
			}
			List<Prop> allProps = Prop.allProps;
			if (allProps == null)
			{
				return;
			}
			Vector3 position = _targetedPlayerRb.position;
			float num = LightOrbMod.AttachRadius.Value * LightOrbMod.AttachRadius.Value;
			int count = allProps.Count;
			for (int i = 0; i < count; i++)
			{
				Prop val = allProps[i];
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || ((Object)((Component)val).gameObject).name.IndexOf("buoy", StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				IntPtr pointer = ((Il2CppObjectBase)val).Pointer;
				if (_tetheredPropPointers.Contains(pointer) || (Object)(object)val.exclusiveHolder != (Object)null)
				{
					continue;
				}
				Vector3 val2 = ((Component)val).transform.position - position;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude <= num)
				{
					TetherOrb(val);
					if (_tetheredOrbs.Count >= LightOrbMod.MaxTetheredOrbs.Value)
					{
						break;
					}
				}
			}
		}

		private void TetherOrb(Prop orb)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			Rigidbody component = ((Component)orb).GetComponent<Rigidbody>();
			TetheredOrb tetheredOrb = new TetheredOrb
			{
				OrbProp = orb,
				OrbRigidbody = component
			};
			if ((Object)(object)component != (Object)null)
			{
				tetheredOrb.WasKinematicBeforeTether = component.isKinematic;
				tetheredOrb.WasGravityEnabledBeforeTether = component.useGravity;
				component.useGravity = false;
				component.isKinematic = true;
			}
			tetheredOrb.StringLine = BuildStringLine();
			_tetheredOrbs.Add(tetheredOrb);
			_tetheredPropPointers.Add(((Il2CppObjectBase)orb).Pointer);
			ManualLogSource logger = LightOrbMod.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[LightOrbMod] Auto-tethered buoy '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)((Component)orb).gameObject).name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'. ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_tetheredOrbs.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" now tethered.");
			}
			logger.LogInfo(val);
		}

		private void ReleaseMostRecentOrb()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			_isCollecting = false;
			if (_tetheredOrbs.Count == 0)
			{
				LightOrbMod.Logger.LogInfo((object)"[LightOrbMod] Release pressed but no orbs are tethered. Collecting stopped.");
				return;
			}
			int index = _tetheredOrbs.Count - 1;
			TetheredOrb tetheredOrb = _tetheredOrbs[index];
			_tetheredOrbs.RemoveAt(index);
			_tetheredPropPointers.Remove(((Il2CppObjectBase)tetheredOrb.OrbProp).Pointer);
			if ((Object)(object)tetheredOrb.OrbRigidbody != (Object)null)
			{
				tetheredOrb.OrbRigidbody.isKinematic = tetheredOrb.WasKinematicBeforeTether;
				tetheredOrb.OrbRigidbody.useGravity = true;
			}
			if ((Object)(object)tetheredOrb.StringLine != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)tetheredOrb.StringLine).gameObject);
			}
			ManualLogSource logger = LightOrbMod.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(87, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[LightOrbMod] Released orb '");
				Prop orbProp = tetheredOrb.OrbProp;
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((orbProp != null) ? ((Object)((Component)orbProp).gameObject).name : null);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'. ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_tetheredOrbs.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" still tethered. Collecting stopped - press 8 to resume.");
			}
			logger.LogInfo(val);
		}

		private void UpdateTetherPositionsAndStrings()
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)_anchorTransform != (Object)null) ? _anchorTransform : ((Component)_targetedPlayerRb).transform);
			Vector3 forward = ((Component)_targetedPlayerRb).transform.forward;
			Vector3 val2 = val.position + Vector3.up * LightOrbMod.HoverHeightAboveAnchor.Value - forward * LightOrbMod.HoverBackwardOffset.Value;
			float value = LightOrbMod.OrbSpreadRadius.Value;
			float value2 = LightOrbMod.OrbSpreadRadiusGrowth.Value;
			float value3 = LightOrbMod.VerticalStackPerOrb.Value;
			float num = 1f - Mathf.Exp((0f - LightOrbMod.FollowLerpSpeed.Value) * Time.fixedDeltaTime);
			for (int i = 0; i < _tetheredOrbs.Count; i++)
			{
				TetheredOrb tetheredOrb = _tetheredOrbs[i];
				if (!((Object)(object)tetheredOrb.OrbProp == (Object)null) && !((Object)(object)((Component)tetheredOrb.OrbProp).gameObject == (Object)null))
				{
					float num2 = (float)i * 2.3999631f;
					float num3 = value + (float)i * value2;
					Vector3 val3 = new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num3;
					float num4 = (float)i * value3;
					Vector3 val4 = val2 + val3 + Vector3.up * num4;
					Transform transform = ((Component)tetheredOrb.OrbProp).transform;
					transform.position = Vector3.Lerp(transform.position, val4, num);
					if ((Object)(object)tetheredOrb.StringLine != (Object)null)
					{
						tetheredOrb.StringLine.SetPosition(0, val2);
						tetheredOrb.StringLine.SetPosition(1, transform.position);
					}
				}
			}
		}

		private LineRenderer BuildStringLine()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("LightOrbTetherString");
			Object.DontDestroyOnLoad((Object)(object)val);
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.positionCount = 2;
			val2.startWidth = LightOrbMod.StringWidth.Value;
			val2.endWidth = LightOrbMod.StringWidth.Value;
			val2.useWorldSpace = true;
			try
			{
				Shader val3 = null;
				string[] unlitShaderCandidates = UnlitShaderCandidates;
				foreach (string text in unlitShaderCandidates)
				{
					val3 = Shader.Find(text);
					if ((Object)(object)val3 != (Object)null)
					{
						break;
					}
				}
				if ((Object)(object)val3 != (Object)null)
				{
					Material val4 = new Material(val3);
					if (val4.HasProperty("_BaseColor"))
					{
						val4.SetColor("_BaseColor", Color.white);
					}
					if (val4.HasProperty("_Color"))
					{
						val4.SetColor("_Color", Color.white);
					}
					((Renderer)val2).material = val4;
				}
				else
				{
					LightOrbMod.Logger.LogWarning((object)"[LightOrbMod] No working shader found for tether string - it will render invisible/default.");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = LightOrbMod.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(54, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[LightOrbMod] Failed to build tether string material: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val5);
			}
			val2.startColor = Color.white;
			val2.endColor = Color.white;
			return val2;
		}

		private void ApplyFloatiness()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0054: 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)
			int count = _tetheredOrbs.Count;
			float num = (float)count * LightOrbMod.BuoyancyForcePerOrb.Value;
			_targetedPlayerRb.AddForce(Vector3.up * num, (ForceMode)5);
			float num2 = 0f - (1f + (float)count * LightOrbMod.TerminalDescentSpeedPerOrb.Value);
			Vector3 linearVelocity = _targetedPlayerRb.linearVelocity;
			if (linearVelocity.y < num2)
			{
				linearVelocity.y = num2;
				_targetedPlayerRb.linearVelocity = linearVelocity;
			}
		}
	}
}