Decompiled source of HarpoonLooter v1.1.1

HarpoonLooter.dll

Decompiled 2 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 Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HarpoonLooter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HarpoonLooter")]
[assembly: AssemblyTitle("HarpoonLooter")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HarpoonLooter
{
	[BepInPlugin("com.harpoonlooter.harpoonlooter", "Harpoon Looter", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class HarpoonLooterPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.harpoonlooter.harpoonlooter";

		public const string PluginName = "Harpoon Looter";

		public const string PluginVersion = "1.1.1";

		public const string PrefabName = "TurretHarpoonLooter";

		private const string BaseTurretName = "fuling_turret";

		internal static bool PrefabRegistered;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> AddBuildPiece;

		internal static ConfigEntry<bool> ShowTether;

		internal static ConfigEntry<float> CollectionRange;

		internal static ConfigEntry<float> ReelSpeed;

		internal static ConfigEntry<float> PileRadius;

		internal static ConfigEntry<float> HarpoonFlightTime;

		internal static ConfigEntry<int> MaxTargets;

		internal static ConfigEntry<float> Cooldown;

		internal static ConfigEntry<float> Scale;

		internal static ConfigEntry<string> IgnoredItems;

		internal static readonly HashSet<string> IgnoredItemSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private void Awake()
		{
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle. When false the Harpoon Looter does nothing.");
			AddBuildPiece = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AddBuildPiece", true, "Add the 'Harpoon Looter' piece to the Hammer build menu. Requires a game restart.");
			ShowTether = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowTether", true, "Show the harpoon rope line while an item is being reeled in.");
			CollectionRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CollectionRange", 20f, "Max distance (meters) at which dropped items are detected.");
			ReelSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ReelSpeed", 8f, "How fast (m/s) reeled items are pulled toward the turret.");
			PileRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PileRadius", 2.5f, "Items are reeled to this radius around the turret base and then released.");
			HarpoonFlightTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HarpoonFlightTime", 0.45f, "Seconds the harpoon visual takes to fly to the target item.");
			MaxTargets = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxTargets", 1, "How many items the turret can harpoon at the same time.");
			MaxTargets.Value = Mathf.Clamp(MaxTargets.Value, 1, 6);
			Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Cooldown", 1f, "Seconds the turret waits after collecting an item before acquiring the next one.");
			Scale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Scale", 0.5f, "Uniform scale applied to the turret model (0.5 = half size). Requires a game restart.");
			Scale.Value = Mathf.Clamp(Scale.Value, 0.25f, 2f);
			IgnoredItems = ((BaseUnityPlugin)this).Config.Bind<string>("General", "IgnoredItems", "", "Comma-separated list of dropped items the turret will NEVER collect (e.g. Wood, Stone, Amber). Matches the item prefab name or name token, case-insensitive.");
			IgnoredItems.SettingChanged += delegate
			{
				RefreshIgnoredItems();
			};
			RefreshIgnoredItems();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harpoon Looter 1.1.1 loading...");
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
			PieceManager.OnPiecesRegistered += OnPiecesRegistered;
			if (IsVanillaPrefabReady())
			{
				OnVanillaPrefabsAvailable();
			}
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			PieceManager.OnPiecesRegistered -= OnPiecesRegistered;
		}

		private void OnVanillaPrefabsAvailable()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (PrefabRegistered || !Enabled.Value || !AddBuildPiece.Value)
			{
				return;
			}
			try
			{
				GameObject val = FindBaseTurretPrefab();
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Harpoon Looter: could not find a vanilla Ballista prefab to clone. The build piece was not registered.");
					return;
				}
				GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("TurretHarpoonLooter", val);
				if ((Object)(object)val2 == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Harpoon Looter: failed to clone the Ballista prefab '" + ((Object)val).name + "'."));
					return;
				}
				Turret component = val2.GetComponent<Turret>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				float value = Scale.Value;
				val2.transform.localScale = new Vector3(value, value, value);
				val2.AddComponent<HarpoonLooterTurret>();
				PrefabManager.Instance.AddPrefab(val2);
				PrefabRegistered = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Harpoon Looter: registered 'TurretHarpoonLooter' cloned from '" + ((Object)val).name + "'."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Harpoon Looter: failed to register the Harpoon Looter prefab: " + ex));
			}
		}

		private void OnPiecesRegistered()
		{
			//IL_0027: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (!PrefabRegistered)
			{
				return;
			}
			try
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("TurretHarpoonLooter");
				if (!((Object)(object)prefab == (Object)null))
				{
					PieceConfig val = new PieceConfig
					{
						Name = "Harpoon Looter",
						Description = "Automatically harpoons dropped items in range and reels them into a pile at its base.",
						PieceTable = "Hammer",
						Category = "Furniture",
						Enabled = true
					};
					val.AddRequirement("FineWood", 10, true);
					val.AddRequirement("Iron", 5, true);
					PieceManager.Instance.AddPiece(new CustomPiece(prefab, false, val));
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Harpoon Looter: added 'Harpoon Looter' build piece to the Hammer menu.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Harpoon Looter: failed to add the build piece to the Hammer menu: " + ex));
			}
		}

		internal static void RefreshIgnoredItems()
		{
			IgnoredItemSet.Clear();
			if (string.IsNullOrWhiteSpace(IgnoredItems?.Value))
			{
				return;
			}
			string[] array = IgnoredItems.Value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0)
				{
					if (text.StartsWith("$"))
					{
						text = text.Substring(1);
					}
					IgnoredItemSet.Add(text);
				}
			}
		}

		internal static bool IsIgnored(ItemDrop item)
		{
			if (IgnoredItemSet.Count == 0 || (Object)(object)item == (Object)null)
			{
				return false;
			}
			ZNetView component = ((Component)item).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.GetZDO() != null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(component.GetZDO().GetPrefab());
				if ((Object)(object)prefab != (Object)null && IgnoredItemSet.Contains(((Object)prefab).name))
				{
					return true;
				}
			}
			if (item.m_itemData != null && item.m_itemData.m_shared != null)
			{
				string text = item.m_itemData.m_shared.m_name;
				if (!string.IsNullOrEmpty(text))
				{
					if (text.StartsWith("$"))
					{
						text = text.Substring(1);
					}
					if (IgnoredItemSet.Contains(text))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool IsVanillaPrefabReady()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null && ZNetScene.instance.m_prefabs.Count > 0)
			{
				return true;
			}
			return (Object)(object)FindBaseTurretPrefab() != (Object)null;
		}

		private static GameObject FindBaseTurretPrefab()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null)
			{
				GameObject val = FindTurretInList(ZNetScene.instance.m_prefabs);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			string[] array = new string[4] { "fuling_turret", "piece_Charred_Balista", "charred_ballista", "TurretOldFuling" };
			foreach (string text in array)
			{
				PrefabManager instance = PrefabManager.Instance;
				GameObject val2 = ((instance != null) ? instance.GetPrefab(text) : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponent<Turret>() != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static GameObject FindTurretInList(List<GameObject> prefabs)
		{
			GameObject val = null;
			foreach (GameObject prefab in prefabs)
			{
				if (!((Object)(object)prefab == (Object)null) && !((Object)(object)prefab.GetComponent<Turret>() == (Object)null))
				{
					if ((Object)(object)val == (Object)null)
					{
						val = prefab;
					}
					if (string.Equals(((Object)prefab).name, "fuling_turret", StringComparison.OrdinalIgnoreCase))
					{
						return prefab;
					}
				}
			}
			foreach (GameObject prefab2 in prefabs)
			{
				if (!((Object)(object)prefab2 == (Object)null) && !((Object)(object)prefab2.GetComponent<Turret>() == (Object)null))
				{
					string text = ((Object)prefab2).name.ToLowerInvariant();
					if (text.Contains("ballista") || text.Contains("turret"))
					{
						return prefab2;
					}
				}
			}
			return val;
		}
	}
	public class HarpoonLooterTurret : MonoBehaviour
	{
		private class Target
		{
			public ItemDrop Item;

			public Vector3 PilePoint;

			public int State;

			public float StateTimer;

			public Vector3 BoltStart;

			public Vector3 BoltEnd;

			public GameObject BoltObject;

			public LineRenderer Tether;

			public float CooldownUntil;
		}

		private class RecentCollect
		{
			public ItemDrop Item;

			public float Time;
		}

		private const float AimDelay = 0.25f;

		private static Material s_tetherMaterial;

		private static Material s_boltMaterial;

		private ZNetView m_nview;

		private Transform m_turretBody;

		private Transform m_turretNeck;

		private Transform m_eye;

		private Quaternion m_baseBodyRotation;

		private Quaternion m_baseNeckRotation;

		private float m_turnRate = 20f;

		private readonly List<Target> m_targets = new List<Target>();

		private readonly List<RecentCollect> m_recentCollects = new List<RecentCollect>();

		private float m_scanTimer;

		private Vector3 m_pileCenter;

		private bool m_pileCenterDirty = true;

		private void Awake()
		{
			Init();
		}

		private void Init()
		{
			//IL_00fc: 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_0109: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			m_nview = ((Component)this).GetComponent<ZNetView>();
			Turret component = ((Component)this).GetComponent<Turret>();
			if ((Object)(object)component != (Object)null)
			{
				m_turretBody = (((Object)(object)component.m_turretBody != (Object)null) ? component.m_turretBody.transform : null);
				m_turretNeck = (((Object)(object)component.m_turretNeck != (Object)null) ? component.m_turretNeck.transform : null);
				m_eye = (((Object)(object)component.m_eye != (Object)null) ? component.m_eye.transform : null);
				m_turnRate = Mathf.Max(1f, component.m_turnRate);
			}
			if ((Object)(object)m_turretBody == (Object)null && (Object)(object)m_turretNeck == (Object)null)
			{
				m_turretBody = ((Component)this).transform;
			}
			if ((Object)(object)m_eye == (Object)null)
			{
				m_eye = ((Component)this).transform;
			}
			m_baseBodyRotation = (((Object)(object)m_turretBody != (Object)null && (Object)(object)m_turretBody != (Object)(object)((Component)this).transform) ? m_turretBody.localRotation : Quaternion.identity);
			m_baseNeckRotation = (((Object)(object)m_turretNeck != (Object)null) ? m_turretNeck.localRotation : Quaternion.identity);
			EnsureMaterials();
		}

		private void Update()
		{
			if (!HarpoonLooterPlugin.Enabled.Value || (Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			if (!m_nview.IsOwner())
			{
				UpdateIdleLook(deltaTime);
				return;
			}
			UpdatePileCenter();
			PruneDoneTargets();
			PruneRecentCollects();
			m_scanTimer += deltaTime;
			if (m_scanTimer >= 0.3f)
			{
				m_scanTimer = 0f;
				AcquireTargets();
			}
			foreach (Target target in m_targets)
			{
				Advance(target, deltaTime);
			}
			UpdateAim(deltaTime);
			UpdateVisuals();
		}

		private static void EnsureMaterials()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_tetherMaterial == (Object)null)
			{
				Shader val = Shader.Find("Unlit/Color");
				if ((Object)(object)val == (Object)null)
				{
					val = Shader.Find("Sprites/Default");
				}
				if ((Object)(object)val != (Object)null)
				{
					s_tetherMaterial = new Material(val);
					s_tetherMaterial.color = new Color(0.78f, 0.7f, 0.52f, 0.95f);
				}
			}
			if ((Object)(object)s_boltMaterial == (Object)null)
			{
				Shader val2 = Shader.Find("Unlit/Color");
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = Shader.Find("Sprites/Default");
				}
				if ((Object)(object)val2 != (Object)null)
				{
					s_boltMaterial = new Material(val2);
					s_boltMaterial.color = new Color(0.45f, 0.38f, 0.28f, 1f);
				}
			}
		}

		private void UpdatePileCenter()
		{
			//IL_0010: 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_0030: 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)
			if (m_pileCenterDirty)
			{
				m_pileCenter = ((Component)this).transform.position + ((Component)this).transform.forward * (1.2f * HarpoonLooterPlugin.Scale.Value);
				m_pileCenterDirty = false;
			}
		}

		private Vector3 GetPilePoint(ItemDrop item)
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)item).transform.position;
			float num = (float)(Mathf.Abs((int)(position.x * 127.1f + position.z * 311.7f)) % 360) * (MathF.PI / 180f);
			float num2 = HarpoonLooterPlugin.PileRadius.Value * 0.6f;
			Vector3 val = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * num2;
			Vector3 result = m_pileCenter + val;
			result.y = ((Component)this).transform.position.y;
			return result;
		}

		private void AcquireTargets()
		{
			//IL_0033: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, HarpoonLooterPlugin.MaxTargets.Value);
			if (m_targets.Count >= num)
			{
				return;
			}
			float value = HarpoonLooterPlugin.CollectionRange.Value;
			float num2 = value * value;
			Vector3 position = ((Component)this).transform.position;
			ItemDrop val = null;
			float num3 = num2;
			ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0);
			if (array == null)
			{
				return;
			}
			foreach (ItemDrop val2 in array)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid() && val2.m_itemData != null && val2.m_itemData.m_shared != null && !val2.IsPiece() && !HarpoonLooterPlugin.IsIgnored(val2) && !IsTargeted(val2) && !IsRecentlyCollected(val2))
				{
					Vector3 val3 = ((Component)val2).transform.position - position;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (!(sqrMagnitude > num2) && sqrMagnitude < num3)
					{
						num3 = sqrMagnitude;
						val = val2;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				string text = ((val.m_itemData != null && val.m_itemData.m_shared != null) ? val.m_itemData.m_shared.m_name : ((Object)((Component)val).gameObject).name);
				Logger.LogInfo((object)("Harpoon Looter: harpooning " + text + " at " + Mathf.RoundToInt(Mathf.Sqrt(num3)) + "m"));
				m_targets.Add(CreateTarget(val));
			}
		}

		private Target CreateTarget(ItemDrop item)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Target target = new Target
			{
				Item = item,
				PilePoint = GetPilePoint(item),
				State = 0,
				StateTimer = 0f,
				BoltStart = GetMuzzlePosition(),
				BoltEnd = ((Component)item).transform.position
			};
			EnsureVisuals(target);
			return target;
		}

		private void EnsureVisuals(Target t)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t.Tether == (Object)null)
			{
				GameObject val = new GameObject("HarpoonTether");
				val.transform.SetParent(((Component)this).transform, false);
				LineRenderer val2 = val.AddComponent<LineRenderer>();
				val2.useWorldSpace = true;
				val2.positionCount = 2;
				val2.startWidth = 0.18f;
				val2.endWidth = 0.04f;
				val2.numCapVertices = 4;
				if ((Object)(object)s_tetherMaterial != (Object)null)
				{
					((Renderer)val2).sharedMaterial = s_tetherMaterial;
				}
				val.SetActive(false);
				t.Tether = val2;
			}
			if ((Object)(object)t.BoltObject == (Object)null)
			{
				GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)2);
				((Object)val3).name = "HarpoonBolt";
				Collider component = val3.GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				val3.transform.SetParent(((Component)this).transform, false);
				val3.transform.localScale = new Vector3(0.14f, 0.6f, 0.14f);
				MeshRenderer component2 = val3.GetComponent<MeshRenderer>();
				if ((Object)(object)component2 != (Object)null && (Object)(object)s_boltMaterial != (Object)null)
				{
					((Renderer)component2).sharedMaterial = s_boltMaterial;
				}
				val3.SetActive(false);
				t.BoltObject = val3;
			}
		}

		private void Advance(Target t, float dt)
		{
			//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_00c9: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			switch (t.State)
			{
			case 0:
				t.StateTimer += dt;
				if (t.StateTimer >= 0.25f)
				{
					t.State = 1;
					t.StateTimer = 0f;
					t.BoltStart = GetMuzzlePosition();
					if ((Object)(object)t.Item != (Object)null)
					{
						t.BoltEnd = ((Component)t.Item).transform.position;
					}
				}
				break;
			case 1:
			{
				t.StateTimer += dt;
				float num = Mathf.Max(0.1f, HarpoonLooterPlugin.HarpoonFlightTime.Value);
				float num2 = Mathf.Clamp01(t.StateTimer / num);
				if ((Object)(object)t.BoltObject != (Object)null)
				{
					t.BoltObject.transform.position = Vector3.Lerp(t.BoltStart, t.BoltEnd, num2);
				}
				if (num2 >= 1f)
				{
					t.State = 2;
					t.StateTimer = 0f;
					if ((Object)(object)t.BoltObject != (Object)null)
					{
						t.BoltObject.SetActive(false);
					}
				}
				break;
			}
			case 2:
				ReelTarget(t, dt);
				break;
			}
		}

		private void ReelTarget(Target t, float dt)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0046: 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_0110: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			ItemDrop item = t.Item;
			if ((Object)(object)item == (Object)null)
			{
				Complete(t);
				return;
			}
			ZNetView component = ((Component)item).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				Complete(t);
				return;
			}
			Vector3 position = ((Component)item).transform.position;
			float num = Vector3.Distance(position, t.PilePoint);
			float num2 = Mathf.Max(0.5f, HarpoonLooterPlugin.PileRadius.Value * 0.85f);
			float value = HarpoonLooterPlugin.CollectionRange.Value;
			if (num <= num2 || num > value * 1.75f)
			{
				string text = ((item.m_itemData != null && item.m_itemData.m_shared != null) ? item.m_itemData.m_shared.m_name : ((Object)((Component)item).gameObject).name);
				Logger.LogInfo((object)("Harpoon Looter: collected " + text + " into the pile."));
				Complete(t);
				return;
			}
			if (!component.IsOwner())
			{
				component.ClaimOwnership();
			}
			if (component.IsOwner())
			{
				float num3 = Mathf.Max(1f, HarpoonLooterPlugin.ReelSpeed.Value);
				((Component)item).transform.position = Vector3.MoveTowards(position, t.PilePoint, num3 * dt);
				Rigidbody component2 = ((Component)item).GetComponent<Rigidbody>();
				if ((Object)(object)component2 != (Object)null && component2.linearVelocity != Vector3.zero)
				{
					component2.linearVelocity = Vector3.zero;
				}
			}
		}

		private void Complete(Target t)
		{
			if ((Object)(object)t.Item != (Object)null)
			{
				m_recentCollects.Add(new RecentCollect
				{
					Item = t.Item,
					Time = Time.time
				});
			}
			t.State = 3;
			t.CooldownUntil = Time.time;
			if ((Object)(object)t.BoltObject != (Object)null)
			{
				t.BoltObject.SetActive(false);
			}
			if ((Object)(object)t.Tether != (Object)null)
			{
				((Component)t.Tether).gameObject.SetActive(false);
			}
		}

		private void PruneDoneTargets()
		{
			for (int num = m_targets.Count - 1; num >= 0; num--)
			{
				Target target = m_targets[num];
				if (target.State == 3 && Time.time - target.CooldownUntil >= HarpoonLooterPlugin.Cooldown.Value)
				{
					m_targets.RemoveAt(num);
				}
				else if ((Object)(object)target.Item == (Object)null)
				{
					Complete(target);
					m_targets.RemoveAt(num);
				}
			}
		}

		private void PruneRecentCollects()
		{
			for (int num = m_recentCollects.Count - 1; num >= 0; num--)
			{
				if (Time.time - m_recentCollects[num].Time > 30f)
				{
					m_recentCollects.RemoveAt(num);
				}
			}
		}

		private bool IsTargeted(ItemDrop item)
		{
			foreach (Target target in m_targets)
			{
				if ((Object)(object)target.Item == (Object)(object)item)
				{
					return true;
				}
			}
			return false;
		}

		private bool IsRecentlyCollected(ItemDrop item)
		{
			for (int i = 0; i < m_recentCollects.Count; i++)
			{
				if ((Object)(object)m_recentCollects[i].Item == (Object)(object)item)
				{
					return true;
				}
			}
			return false;
		}

		private void UpdateAim(float dt)
		{
			//IL_0070: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_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)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			//IL_010b: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			Target target = null;
			for (int i = 0; i < m_targets.Count; i++)
			{
				Target target2 = m_targets[i];
				if (target2.State == 1 || target2.State == 2)
				{
					target = target2;
					break;
				}
			}
			if (target == null)
			{
				UpdateIdleLook(dt);
				return;
			}
			Vector3 val = (((Object)(object)target.Item != (Object)null) ? ((Component)target.Item).transform.position : target.BoltEnd) - m_eye.position;
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.001f))
			{
				Quaternion val2 = Quaternion.LookRotation(val, Vector3.up);
				Quaternion val3 = Quaternion.Inverse(((Component)this).transform.rotation) * val2;
				Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles;
				float y = eulerAngles.y;
				float num = Mathf.Clamp(EulerToSigned(eulerAngles.x), -35f, 25f);
				if ((Object)(object)m_turretBody != (Object)null)
				{
					Quaternion val4 = m_baseBodyRotation * Quaternion.Euler(0f, y, 0f);
					m_turretBody.localRotation = Quaternion.Slerp(m_turretBody.localRotation, val4, Mathf.Clamp01(m_turnRate * dt));
				}
				if ((Object)(object)m_turretNeck != (Object)null && (Object)(object)m_turretNeck != (Object)(object)((Component)this).transform)
				{
					Quaternion val5 = m_baseNeckRotation * Quaternion.Euler(num, 0f, 0f);
					m_turretNeck.localRotation = Quaternion.Slerp(m_turretNeck.localRotation, val5, Mathf.Clamp01(m_turnRate * dt * 0.7f));
				}
			}
		}

		private void UpdateIdleLook(float dt)
		{
			//IL_002e: 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)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			if ((Object)(object)m_turretBody != (Object)null && (Object)(object)m_turretBody != (Object)(object)((Component)this).transform)
			{
				m_turretBody.localRotation = m_baseBodyRotation * Quaternion.Euler(0f, Mathf.Sin(time * 0.3f) * 18f, 0f);
			}
			if ((Object)(object)m_turretNeck != (Object)null && (Object)(object)m_turretNeck != (Object)(object)((Component)this).transform)
			{
				m_turretNeck.localRotation = m_baseNeckRotation * Quaternion.Euler(Mathf.Sin(time * 0.2f + 1f) * 8f, 0f, 0f);
			}
		}

		private void UpdateVisuals()
		{
			//IL_0085: 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)
			for (int i = 0; i < m_targets.Count; i++)
			{
				Target target = m_targets[i];
				if ((Object)(object)target.BoltObject != (Object)null)
				{
					target.BoltObject.SetActive(target.State == 1);
				}
				if ((Object)(object)target.Tether != (Object)null)
				{
					bool flag = target.State == 2 && HarpoonLooterPlugin.ShowTether.Value;
					((Component)target.Tether).gameObject.SetActive(flag);
					if (flag && (Object)(object)target.Item != (Object)null)
					{
						target.Tether.SetPosition(0, GetMuzzlePosition());
						target.Tether.SetPosition(1, ((Component)target.Item).transform.position);
					}
				}
			}
		}

		private Vector3 GetMuzzlePosition()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m_eye != (Object)null))
			{
				return ((Component)this).transform.position;
			}
			return m_eye.position;
		}

		private static float EulerToSigned(float euler)
		{
			if (euler > 180f)
			{
				euler -= 360f;
			}
			return euler;
		}
	}
}