Decompiled source of HarvestTurrets v1.0.0

HarvestTurrets.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 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("HarvestTurrets")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HarvestTurrets")]
[assembly: AssemblyTitle("HarvestTurrets")]
[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 HarvestTurrets
{
	public class HarvestTurret : MonoBehaviour
	{
		private sealed class HarvesterTarget
		{
			public Component Damageable;

			public Collider Collider;

			public Vector3 FallbackAim;
		}

		private sealed class Shot
		{
			public Vector3 Start;

			public Vector3 End;

			public float Time;

			public float Duration;

			public HarvesterTarget Target;
		}

		public int KindIndex;

		private const int MaxOverlap = 512;

		private const float ScanInterval = 0.4f;

		private static readonly Collider[] s_hits = (Collider[])(object)new Collider[512];

		private static Material s_boltMaterial;

		private ZNetView m_nview;

		private Transform m_body;

		private Transform m_neck;

		private Transform m_eye;

		private Quaternion m_baseBodyRotation = Quaternion.identity;

		private Quaternion m_baseNeckRotation = Quaternion.identity;

		private bool m_initialized;

		private HarvesterTarget m_target;

		private float m_scanTimer;

		private float m_attackTimer;

		private float m_warmup;

		private Shot m_shot;

		private GameObject m_bolt;

		private float m_idleLogTimer;

		private HarvestKind Kind => (HarvestKind)Mathf.Clamp(KindIndex, 0, 2);

		private TurretSettings Settings => HarvestTurretsPlugin.Settings[Mathf.Clamp(KindIndex, 0, 2)];

		private void Update()
		{
			if (!HarvestTurretsPlugin.Enabled.Value)
			{
				return;
			}
			EnsureInitialized();
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			if (!m_nview.IsOwner())
			{
				UpdateIdleLook(deltaTime);
				return;
			}
			TurretSettings settings = Settings;
			if (settings == null)
			{
				return;
			}
			m_attackTimer -= deltaTime;
			m_idleLogTimer -= deltaTime;
			UpdateShot(deltaTime);
			ValidateTarget(settings);
			m_scanTimer -= deltaTime;
			if (m_target == null && m_scanTimer <= 0f)
			{
				m_scanTimer = 0.4f;
				AcquireTarget(settings);
			}
			if (m_target != null)
			{
				UpdateAim(deltaTime, settings);
				if (m_shot == null && m_attackTimer <= 0f)
				{
					m_warmup += deltaTime;
					if (m_warmup >= Mathf.Max(0.05f, settings.Warmup.Value))
					{
						m_warmup = 0f;
						Fire(settings);
					}
				}
				else
				{
					m_warmup = 0f;
				}
			}
			else
			{
				m_warmup = 0f;
				UpdateIdleLook(deltaTime);
			}
		}

		private void EnsureInitialized()
		{
			//IL_00c8: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			if (!m_initialized)
			{
				m_initialized = true;
				m_nview = ((Component)this).GetComponent<ZNetView>();
				Turret component = ((Component)this).GetComponent<Turret>();
				if ((Object)(object)component != (Object)null)
				{
					m_body = (((Object)(object)component.m_turretBody != (Object)null) ? component.m_turretBody.transform : null);
					m_neck = (((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);
				}
				if ((Object)(object)m_eye == (Object)null)
				{
					m_eye = ((Component)this).transform;
				}
				m_baseBodyRotation = (((Object)(object)m_body != (Object)null) ? m_body.localRotation : Quaternion.identity);
				m_baseNeckRotation = (((Object)(object)m_neck != (Object)null) ? m_neck.localRotation : Quaternion.identity);
				EnsureBolt();
				TurretSettings settings = Settings;
				Log(string.Format("init kind={0} range={1} mask={2} body={3} neck={4} eye={5}", Kind, settings?.Range.Value ?? (-1f), HarvestTurretsPlugin.GetMask(Kind), ((Object)(object)m_body != (Object)null) ? ((Object)m_body).name : "null", ((Object)(object)m_neck != (Object)null) ? ((Object)m_neck).name : "null", ((Object)(object)m_eye != (Object)null) ? ((Object)m_eye).name : "null"));
			}
		}

		private void EnsureBolt()
		{
			//IL_00cd: 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_005b: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_bolt != (Object)null || !HarvestTurretsPlugin.ShowProjectile.Value)
			{
				return;
			}
			if ((Object)(object)s_boltMaterial == (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_boltMaterial = new Material(val);
					s_boltMaterial.color = new Color(0.85f, 0.8f, 0.6f, 1f);
				}
			}
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)2);
			((Object)val2).name = "HarvestBolt";
			Collider component = val2.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			val2.transform.SetParent(((Component)this).transform, false);
			val2.transform.localScale = new Vector3(0.08f, 0.45f, 0.08f);
			MeshRenderer component2 = val2.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)s_boltMaterial != (Object)null)
			{
				((Renderer)component2).sharedMaterial = s_boltMaterial;
			}
			val2.SetActive(false);
			m_bolt = val2;
		}

		private void AcquireTarget(TurretSettings cfg)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_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_0038: Unknown result type (might be due to invalid IL or missing references)
			float value = cfg.Range.Value;
			Vector3 position = ((Component)this).transform.position;
			int mask = HarvestTurretsPlugin.GetMask(Kind);
			int colliderCount;
			HarvesterTarget harvesterTarget = FindNearest(position, value, mask, out colliderCount);
			if (harvesterTarget == null && mask != -1)
			{
				harvesterTarget = FindNearest(position, value, -1, out colliderCount);
			}
			if (harvesterTarget != null)
			{
				m_target = harvesterTarget;
				m_warmup = 0f;
				m_idleLogTimer = 0f;
				Log($"acquired {Label(harvesterTarget)} at {Mathf.RoundToInt(Vector3.Distance(harvesterTarget.FallbackAim, position))}m");
			}
			else if (m_idleLogTimer <= 0f)
			{
				m_idleLogTimer = 10f;
				Log($"no targets in range {Mathf.RoundToInt(value)}m (mask={mask}, colliders={colliderCount})");
			}
		}

		private HarvesterTarget FindNearest(Vector3 origin, float range, int mask, out int colliderCount)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_00af: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(origin, range, s_hits, mask, (QueryTriggerInteraction)1);
			Collider[] array = s_hits;
			if (num >= 512)
			{
				array = Physics.OverlapSphere(origin, range, mask, (QueryTriggerInteraction)1);
				num = array.Length;
				Log($"overlap buffer full ({512}); rescanned with {num} colliders");
			}
			colliderCount = num;
			HarvesterTarget result = null;
			float num2 = range * range;
			for (int i = 0; i < num; i++)
			{
				Collider val = array[i];
				if ((Object)(object)val == (Object)null || ((Component)val).transform.IsChildOf(((Component)this).transform))
				{
					continue;
				}
				Vector3 aimPoint;
				Component val2 = ResolveDamageable(val, out aimPoint);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				HarvesterTarget harvesterTarget = new HarvesterTarget
				{
					Damageable = val2,
					Collider = val,
					FallbackAim = aimPoint
				};
				if (IsTargetValid(harvesterTarget))
				{
					Vector3 val3 = aimPoint - origin;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude < num2)
					{
						num2 = sqrMagnitude;
						result = harvesterTarget;
					}
				}
			}
			return result;
		}

		private Component ResolveDamageable(Collider col, out Vector3 aimPoint)
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0089: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_0059: 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_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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			Bounds bounds;
			switch (Kind)
			{
			case HarvestKind.Wood:
			{
				TreeBase componentInParent2 = ((Component)col).GetComponentInParent<TreeBase>();
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					bounds = col.bounds;
					aimPoint = ((Bounds)(ref bounds)).center;
					return (Component)(object)componentInParent2;
				}
				TreeLog componentInParent3 = ((Component)col).GetComponentInParent<TreeLog>();
				if ((Object)(object)componentInParent3 != (Object)null)
				{
					bounds = col.bounds;
					aimPoint = ((Bounds)(ref bounds)).center;
					return (Component)(object)componentInParent3;
				}
				break;
			}
			case HarvestKind.Stone:
			{
				MineRock5 componentInParent4 = ((Component)col).GetComponentInParent<MineRock5>();
				if ((Object)(object)componentInParent4 != (Object)null)
				{
					bounds = col.bounds;
					aimPoint = ((Bounds)(ref bounds)).center;
					return (Component)(object)componentInParent4;
				}
				MineRock componentInParent5 = ((Component)col).GetComponentInParent<MineRock>();
				if ((Object)(object)componentInParent5 != (Object)null)
				{
					bounds = col.bounds;
					aimPoint = ((Bounds)(ref bounds)).center;
					return (Component)(object)componentInParent5;
				}
				break;
			}
			case HarvestKind.Hunt:
			{
				Character componentInParent = ((Component)col).GetComponentInParent<Character>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					aimPoint = componentInParent.GetCenterPoint();
					return (Component)(object)componentInParent;
				}
				break;
			}
			}
			bounds = col.bounds;
			aimPoint = ((Bounds)(ref bounds)).center;
			return null;
		}

		private bool IsTargetValid(HarvesterTarget target)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00d1: Invalid comparison between Unknown and I4
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if (target == null || (Object)(object)target.Damageable == (Object)null)
			{
				return false;
			}
			GameObject gameObject = target.Damageable.gameObject;
			if ((Object)(object)gameObject == (Object)null || !gameObject.activeInHierarchy)
			{
				return false;
			}
			if ((Object)(object)target.Collider == (Object)null || !target.Collider.enabled || !((Component)target.Collider).gameObject.activeInHierarchy)
			{
				return false;
			}
			ZNetView component = target.Damageable.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			if (Kind != HarvestKind.Hunt)
			{
				return true;
			}
			Component damageable = target.Damageable;
			Character val = (Character)(object)((damageable is Character) ? damageable : null);
			if ((Object)(object)val == (Object)null || val.IsDead() || val.IsPlayer())
			{
				return false;
			}
			if (val.IsTamed() && !HarvestTurretsPlugin.HuntTargetTamed.Value)
			{
				return false;
			}
			Faction faction = val.GetFaction();
			if ((int)faction == 1)
			{
				return HarvestTurretsPlugin.HuntTargetAnimals.Value;
			}
			if ((int)faction == 0)
			{
				return false;
			}
			return HarvestTurretsPlugin.HuntTargetMonsters.Value;
		}

		private void ValidateTarget(TurretSettings cfg)
		{
			if (m_target != null && !IsTargetValid(m_target))
			{
				Log("lost target " + Label(m_target));
				m_target = null;
				m_warmup = 0f;
			}
		}

		private Vector3 GetAimPoint(HarvesterTarget target)
		{
			//IL_0048: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Kind == HarvestKind.Hunt)
			{
				Component damageable = target.Damageable;
				Character val = (Character)(object)((damageable is Character) ? damageable : null);
				if (val != null && !val.IsDead())
				{
					return val.GetCenterPoint();
				}
			}
			if ((Object)(object)target.Collider != (Object)null)
			{
				return target.Collider.ClosestPoint(MuzzlePosition());
			}
			return target.FallbackAim;
		}

		private void Fire(TurretSettings cfg)
		{
			//IL_0015: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			HarvesterTarget target = m_target;
			if (target == null || !IsTargetValid(target))
			{
				return;
			}
			Vector3 val = MuzzlePosition();
			Vector3 aimPoint = GetAimPoint(target);
			m_shot = new Shot
			{
				Start = val,
				End = aimPoint,
				Time = 0f,
				Duration = Mathf.Max(0.05f, cfg.ProjectileFlightTime.Value),
				Target = target
			};
			if ((Object)(object)m_bolt != (Object)null)
			{
				m_bolt.SetActive(true);
				m_bolt.transform.position = val;
				Vector3 val2 = aimPoint - val;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
				{
					m_bolt.transform.rotation = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up) * Quaternion.Euler(90f, 0f, 0f);
				}
			}
			Log("firing at " + Label(target));
		}

		private void UpdateShot(float dt)
		{
			//IL_0058: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			if (m_shot == null)
			{
				return;
			}
			m_shot.Time += dt;
			float num = Mathf.Clamp01(m_shot.Time / m_shot.Duration);
			if ((Object)(object)m_bolt != (Object)null)
			{
				m_bolt.transform.position = Vector3.Lerp(m_shot.Start, m_shot.End, num);
			}
			if (!(num < 1f))
			{
				ApplyDamage(m_shot.Target, Settings);
				if ((Object)(object)m_bolt != (Object)null)
				{
					m_bolt.SetActive(false);
				}
				m_shot = null;
				m_attackTimer = Mathf.Max(0.05f, Settings.AttackInterval.Value);
			}
		}

		private void ApplyDamage(HarvesterTarget target, TurretSettings cfg)
		{
			//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_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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0081: 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_0089: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: 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_0066: 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 (target == null || (Object)(object)target.Damageable == (Object)null)
			{
				return;
			}
			Vector3 val = MuzzlePosition();
			Vector3 val2 = (((Object)(object)target.Collider != (Object)null) ? target.Collider.ClosestPoint(val) : target.FallbackAim);
			Vector3 dir = val2 - val;
			if (((Vector3)(ref dir)).sqrMagnitude < 0.001f)
			{
				dir = (((Object)(object)m_eye != (Object)null) ? m_eye.forward : ((Component)this).transform.forward);
			}
			dir = ((Vector3)(ref dir)).normalized;
			HitData val3 = new HitData
			{
				m_hitType = (HitType)16,
				m_ranged = true,
				m_dodgeable = false,
				m_blockable = false,
				m_toolTier = (short)Mathf.Clamp(cfg.ToolTier.Value, 0, 6),
				m_point = val2,
				m_dir = dir,
				m_hitCollider = target.Collider,
				m_skillRaiseAmount = 0f
			};
			float value = cfg.Damage.Value;
			switch (Kind)
			{
			case HarvestKind.Wood:
			{
				val3.m_skill = (SkillType)13;
				val3.m_damage.m_chop = value;
				Component damageable2 = target.Damageable;
				TreeBase val5 = (TreeBase)(object)((damageable2 is TreeBase) ? damageable2 : null);
				if (val5 != null)
				{
					val5.Damage(val3);
					break;
				}
				Component damageable3 = target.Damageable;
				TreeLog val6 = (TreeLog)(object)((damageable3 is TreeLog) ? damageable3 : null);
				if (val6 != null)
				{
					val6.Damage(val3);
				}
				break;
			}
			case HarvestKind.Stone:
			{
				val3.m_skill = (SkillType)12;
				val3.m_damage.m_pickaxe = value;
				Component damageable4 = target.Damageable;
				MineRock5 val7 = (MineRock5)(object)((damageable4 is MineRock5) ? damageable4 : null);
				if (val7 != null)
				{
					val7.Damage(val3);
					break;
				}
				Component damageable5 = target.Damageable;
				MineRock val8 = (MineRock)(object)((damageable5 is MineRock) ? damageable5 : null);
				if (val8 != null)
				{
					val8.Damage(val3);
				}
				break;
			}
			case HarvestKind.Hunt:
			{
				val3.m_skill = (SkillType)8;
				val3.m_damage.m_pierce = value;
				Component damageable = target.Damageable;
				Character val4 = (Character)(object)((damageable is Character) ? damageable : null);
				if (val4 != null)
				{
					val4.Damage(val3);
				}
				break;
			}
			}
		}

		private void UpdateAim(float dt, TurretSettings cfg)
		{
			//IL_0007: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0054: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = GetAimPoint(m_target) - m_eye.position;
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.001f))
			{
				float num = Mathf.Max(1f, cfg.TurnRate.Value);
				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 num2 = Mathf.Clamp(EulerToSigned(eulerAngles.x), -40f, 30f);
				if ((Object)(object)m_body != (Object)null && (Object)(object)m_body != (Object)(object)((Component)this).transform)
				{
					Quaternion val4 = m_baseBodyRotation * Quaternion.Euler(0f, y, 0f);
					m_body.localRotation = Quaternion.Slerp(m_body.localRotation, val4, Mathf.Clamp01(num * dt));
				}
				if ((Object)(object)m_neck != (Object)null && (Object)(object)m_neck != (Object)(object)((Component)this).transform)
				{
					Quaternion val5 = m_baseNeckRotation * Quaternion.Euler(num2, 0f, 0f);
					m_neck.localRotation = Quaternion.Slerp(m_neck.localRotation, val5, Mathf.Clamp01(num * 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_body != (Object)null && (Object)(object)m_body != (Object)(object)((Component)this).transform)
			{
				m_body.localRotation = m_baseBodyRotation * Quaternion.Euler(0f, Mathf.Sin(time * 0.3f) * 18f, 0f);
			}
			if ((Object)(object)m_neck != (Object)null && (Object)(object)m_neck != (Object)(object)((Component)this).transform)
			{
				m_neck.localRotation = m_baseNeckRotation * Quaternion.Euler(Mathf.Sin(time * 0.2f + 1f) * 8f, 0f, 0f);
			}
		}

		private Vector3 MuzzlePosition()
		{
			//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 string Label(HarvesterTarget target)
		{
			if (target == null || (Object)(object)target.Damageable == (Object)null)
			{
				return "<null>";
			}
			Component damageable = target.Damageable;
			Character val = (Character)(object)((damageable is Character) ? damageable : null);
			if ((Object)(object)val != (Object)null)
			{
				return val.m_name;
			}
			return ((Object)target.Damageable.gameObject).name;
		}

		private void Log(string message)
		{
			if (HarvestTurretsPlugin.DebugLogging.Value)
			{
				Logger.LogInfo((object)string.Format("[{0} {1}] {2}", "Harvest Turrets", Kind, message));
			}
		}

		private static float EulerToSigned(float euler)
		{
			if (euler > 180f)
			{
				euler -= 360f;
			}
			return euler;
		}
	}
	public enum HarvestKind
	{
		Wood,
		Stone,
		Hunt
	}
	[BepInPlugin("com.harvestturrets.harvestturrets", "Harvest Turrets", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class HarvestTurretsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.harvestturrets.harvestturrets";

		public const string PluginName = "Harvest Turrets";

		public const string PluginVersion = "1.0.0";

		private const string BaseTurretName = "fuling_turret";

		internal static readonly string[] PrefabNames = new string[3] { "TurretHarvestLumberjack", "TurretHarvestQuarry", "TurretHarvestHuntsman" };

		internal static readonly string[] PieceNames = new string[3] { "Lumberjack Turret", "Quarry Turret", "Huntsman Turret" };

		internal static readonly string[] PieceDescriptions = new string[3] { "Automatically fells trees and chops logs it can see. Fires chopping bolts.", "Automatically mines rocks and ore deposits. Fires pickaxe bolts.", "Automatically hunts wild animals. Fires piercing bolts." };

		internal static readonly Color[] Tints = (Color[])(object)new Color[3]
		{
			new Color(0.72f, 1f, 0.72f),
			new Color(0.78f, 0.84f, 0.95f),
			new Color(1f, 0.78f, 0.68f)
		};

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> AddBuildPieces;

		internal static ConfigEntry<bool> ShowProjectile;

		internal static ConfigEntry<bool> DebugLogging;

		internal static ConfigEntry<bool> TintModels;

		internal static ConfigEntry<float> Scale;

		internal static ConfigEntry<bool> HuntTargetAnimals;

		internal static ConfigEntry<bool> HuntTargetMonsters;

		internal static ConfigEntry<bool> HuntTargetTamed;

		internal static readonly TurretSettings[] Settings = new TurretSettings[3];

		internal static readonly bool[] PrefabRegistered = new bool[3];

		private void Awake()
		{
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle. When false the harvest turrets do nothing.");
			AddBuildPieces = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AddBuildPieces", true, "Add the three harvest turret pieces to the Hammer build menu. Requires a game restart.");
			ShowProjectile = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowProjectile", true, "Show a bolt flying from the turret to its target when it fires.");
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", true, "Log target acquisition and shots to the BepInEx log. Turn off once the turrets behave.");
			TintModels = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TintModels", true, "Tint each turret model so the three variants are visually distinct. Requires a game restart.");
			Scale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Scale", 0.5f, "Uniform scale applied to the turret models (0.5 = half size). Requires a game restart.");
			Scale.Value = Mathf.Clamp(Scale.Value, 0.25f, 2f);
			HuntTargetAnimals = ((BaseUnityPlugin)this).Config.Bind<bool>("Huntsman", "TargetAnimals", true, "Hunt non-tamed animals (deer, boar, etc).");
			HuntTargetMonsters = ((BaseUnityPlugin)this).Config.Bind<bool>("Huntsman", "TargetMonsters", false, "Also hunt hostile monsters.");
			HuntTargetTamed = ((BaseUnityPlugin)this).Config.Bind<bool>("Huntsman", "TargetTamed", false, "Also hunt tamed animals (WARNING: will shoot your livestock).");
			Settings[0] = new TurretSettings(((BaseUnityPlugin)this).Config, "Lumberjack", 40f, 60f, 1.5f, 4, 0.4f, 0.25f, 30f);
			Settings[1] = new TurretSettings(((BaseUnityPlugin)this).Config, "Quarry", 40f, 60f, 1.5f, 4, 0.4f, 0.25f, 30f);
			Settings[2] = new TurretSettings(((BaseUnityPlugin)this).Config, "Huntsman", 45f, 90f, 1.2f, 0, 0.3f, 0.2f, 40f);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harvest Turrets 1.0.0 loading...");
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
			PieceManager.OnPiecesRegistered += OnPiecesRegistered;
			if (IsVanillaPrefabReady())
			{
				OnVanillaPrefabsAvailable();
			}
		}

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

		private void OnVanillaPrefabsAvailable()
		{
			if (!Enabled.Value || !AddBuildPieces.Value)
			{
				return;
			}
			GameObject val = FindBaseTurretPrefab();
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Harvest Turrets: could not find a vanilla Ballista prefab to clone. No build pieces were registered.");
				return;
			}
			for (int i = 0; i < PrefabNames.Length; i++)
			{
				if (!PrefabRegistered[i])
				{
					try
					{
						RegisterPrefab(i, val);
					}
					catch (Exception arg)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)$"Harvest Turrets: failed to register '{PieceNames[i]}': {arg}");
					}
				}
			}
		}

		private void RegisterPrefab(int kind, GameObject baseTurret)
		{
			//IL_0069: 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)
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(PrefabNames[kind], baseTurret);
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Harvest Turrets: failed to clone the Ballista prefab for '" + PieceNames[kind] + "'."));
				return;
			}
			Turret component = val.GetComponent<Turret>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			float value = Scale.Value;
			val.transform.localScale = new Vector3(value, value, value);
			if (TintModels.Value)
			{
				Tint(val, Tints[kind]);
			}
			val.AddComponent<HarvestTurret>().KindIndex = kind;
			PrefabManager.Instance.AddPrefab(val);
			PrefabRegistered[kind] = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Harvest Turrets: registered '" + PrefabNames[kind] + "' (" + PieceNames[kind] + ") cloned from '" + ((Object)baseTurret).name + "'."));
		}

		private static void Tint(GameObject prefab, Color tint)
		{
			//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_003f: 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_004d: 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_005b: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Material material = val.material;
					if (!((Object)(object)material == (Object)null) && material.HasProperty("_Color"))
					{
						Color color = material.color;
						material.color = new Color(color.r * tint.r, color.g * tint.g, color.b * tint.b, color.a);
					}
				}
			}
		}

		private void OnPiecesRegistered()
		{
			if (!Enabled.Value || !AddBuildPieces.Value)
			{
				return;
			}
			for (int i = 0; i < PrefabNames.Length; i++)
			{
				if (PrefabRegistered[i])
				{
					try
					{
						AddPiece(i);
					}
					catch (Exception arg)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)$"Harvest Turrets: failed to add '{PieceNames[i]}' to the Hammer menu: {arg}");
					}
				}
			}
		}

		private void AddPiece(int kind)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_003b: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			GameObject prefab = PrefabManager.Instance.GetPrefab(PrefabNames[kind]);
			if (!((Object)(object)prefab == (Object)null))
			{
				PieceConfig val = new PieceConfig
				{
					Name = PieceNames[kind],
					Description = PieceDescriptions[kind],
					PieceTable = "Hammer",
					Category = "Misc",
					Enabled = true
				};
				switch ((HarvestKind)kind)
				{
				case HarvestKind.Wood:
					val.AddRequirement("Wood", 20, true);
					val.AddRequirement("FineWood", 10, true);
					val.AddRequirement("Iron", 5, true);
					break;
				case HarvestKind.Stone:
					val.AddRequirement("Stone", 30, true);
					val.AddRequirement("Iron", 10, true);
					val.AddRequirement("Bronze", 5, true);
					break;
				case HarvestKind.Hunt:
					val.AddRequirement("FineWood", 15, true);
					val.AddRequirement("Iron", 10, true);
					val.AddRequirement("LeatherScraps", 10, true);
					break;
				}
				PieceManager.Instance.AddPiece(new CustomPiece(prefab, false, val));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Harvest Turrets: added '" + PieceNames[kind] + "' build piece to the Hammer menu."));
			}
		}

		internal static int GetMask(HarvestKind kind)
		{
			int num = ((kind == HarvestKind.Hunt) ? LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" }) : LayerMask.GetMask(new string[4] { "Default", "static_solid", "terrain", "piece" }));
			if (num != 0)
			{
				return num;
			}
			return -1;
		}

		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;
		}
	}
	internal sealed class TurretSettings
	{
		public readonly ConfigEntry<float> Range;

		public readonly ConfigEntry<float> Damage;

		public readonly ConfigEntry<float> AttackInterval;

		public readonly ConfigEntry<float> Warmup;

		public readonly ConfigEntry<float> ProjectileFlightTime;

		public readonly ConfigEntry<float> TurnRate;

		public readonly ConfigEntry<int> ToolTier;

		public TurretSettings(ConfigFile config, string section, float range, float damage, float attackInterval, int toolTier, float warmup, float projectileFlightTime, float turnRate)
		{
			Range = config.Bind<float>(section, "Range", range, "Detection range in meters.");
			Damage = config.Bind<float>(section, "Damage", damage, "Damage per shot.");
			AttackInterval = config.Bind<float>(section, "AttackInterval", attackInterval, "Seconds between shots.");
			ToolTier = config.Bind<int>(section, "ToolTier", toolTier, "Tool tier used by each shot. Must be high enough to fell the tree / mine the rock.");
			Warmup = config.Bind<float>(section, "Warmup", warmup, "Seconds the turret must hold its aim before firing.");
			ProjectileFlightTime = config.Bind<float>(section, "ProjectileFlightTime", projectileFlightTime, "Seconds the bolt takes to reach the target.");
			TurnRate = config.Bind<float>(section, "TurnRate", turnRate, "How quickly the turret swings toward a target.");
		}
	}
}