Decompiled source of EvuAreaHarvest v0.2.2

EvuAreaHarvest.Core.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 Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("evu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 imevul")]
[assembly: AssemblyDescription("Harvest everything in an area with a simple hotkey, even things planted under the ground.")]
[assembly: AssemblyFileVersion("0.2.2.0")]
[assembly: AssemblyInformationalVersion("0.2.2+e8c3dedd4087015645b6064f6bc6904e6214fc47")]
[assembly: AssemblyProduct("EvuAreaHarvest")]
[assembly: AssemblyTitle("EvuAreaHarvest.Core")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvuMods/EvuAreaHarvest")]
[assembly: AssemblyVersion("0.2.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 EvuAreaHarvest.Core
{
	public static class HarvestMath
	{
		public const float MinRange = 2f;

		public const float MaxRange = 32f;

		public const float DefaultRange = 8f;

		public static float ClampRange(float range)
		{
			if (float.IsNaN(range))
			{
				return 8f;
			}
			if (range < 2f)
			{
				return 2f;
			}
			if (range > 32f)
			{
				return 32f;
			}
			return range;
		}

		public static bool InRange(float distance, float range)
		{
			return distance <= range;
		}

		public static string FormatHarvest(int harvested, int inRange)
		{
			return "Harvested " + harvested + " out of " + inRange + " in range";
		}

		public static string FormatHighlight(bool on)
		{
			if (!on)
			{
				return "Highlight harvestables off";
			}
			return "Highlight harvestables on";
		}
	}
	public static class HarvestTally
	{
		public readonly struct Candidate
		{
			public float Distance { get; }

			public bool Ready { get; }

			public Candidate(float distance, bool ready)
			{
				Distance = distance;
				Ready = ready;
			}
		}

		public readonly struct Result
		{
			public int Harvested { get; }

			public int InRange { get; }

			public Result(int harvested, int inRange)
			{
				Harvested = harvested;
				InRange = inRange;
			}
		}

		public static Result Run(IReadOnlyList<Candidate> candidates, float range, Func<int, bool> tryHarvest)
		{
			int[] array = new int[candidates.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = i;
			}
			Array.Sort(array, (int a, int b) => candidates[a].Distance.CompareTo(candidates[b].Distance));
			int num = 0;
			int num2 = 0;
			int[] array2 = array;
			foreach (int num4 in array2)
			{
				Candidate candidate = candidates[num4];
				if (!HarvestMath.InRange(candidate.Distance, range))
				{
					break;
				}
				num2++;
				if (candidate.Ready && tryHarvest(num4))
				{
					num++;
				}
			}
			return new Result(num, num2);
		}
	}
}

EvuAreaHarvest.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EvuAreaHarvest.Core;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("evu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 imevul")]
[assembly: AssemblyDescription("Harvest everything in an area with a simple hotkey, even things planted under the ground.")]
[assembly: AssemblyFileVersion("0.2.2.0")]
[assembly: AssemblyInformationalVersion("0.2.2+e8c3dedd4087015645b6064f6bc6904e6214fc47")]
[assembly: AssemblyProduct("EvuAreaHarvest")]
[assembly: AssemblyTitle("EvuAreaHarvest")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvuMods/EvuAreaHarvest")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 EvuAreaHarvest
{
	internal static class GroundLine
	{
		public const float Lift = 0.08f;

		private static Material? _material;

		private static int _mask = int.MinValue;

		internal static Material Material => _material ?? (_material = CreateMaterial());

		public static LineRenderer Create(string name, Transform parent, float width)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Material material = Material;
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			LineRenderer obj = val.AddComponent<LineRenderer>();
			((Renderer)obj).material = material;
			obj.useWorldSpace = true;
			obj.loop = true;
			obj.widthMultiplier = width;
			obj.numCornerVertices = 2;
			obj.alignment = (LineAlignment)0;
			obj.textureMode = (LineTextureMode)0;
			obj.positionCount = 0;
			return obj;
		}

		public static void Circle(LineRenderer line, Vector3[] points, Color color)
		{
			//IL_0011: 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)
			line.positionCount = points.Length;
			line.loop = true;
			line.startColor = color;
			line.endColor = color;
			line.SetPositions(points);
		}

		public static void DestroyMaterial()
		{
			if ((Object)(object)_material != (Object)null)
			{
				Object.Destroy((Object)(object)_material);
				_material = null;
			}
		}

		public static float SurfaceY(float x, float z, float hintY)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(new Vector3(x, hintY + 12f, z), Vector3.down, ref val, 48f, Mask(), (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val)).point.y;
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				return ZoneSystem.instance.GetGroundHeight(new Vector3(x, hintY, z));
			}
			return hintY;
		}

		private static int Mask()
		{
			if (_mask != int.MinValue)
			{
				return _mask;
			}
			int mask = LayerMask.GetMask(new string[5] { "terrain", "Default", "static_solid", "piece", "piece_nonsolid" });
			_mask = ((mask == 0) ? (-5) : mask);
			return _mask;
		}

		private static Material CreateMaterial()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			LineRenderer[] array = Object.FindObjectsByType<LineRenderer>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				Material sharedMaterial = ((Renderer)array[i]).sharedMaterial;
				if ((Object)(object)sharedMaterial != (Object)null && (Object)(object)sharedMaterial.shader != (Object)null && ((Object)sharedMaterial.shader).name != "Hidden/InternalErrorShader")
				{
					return new Material(sharedMaterial);
				}
			}
			return new Material(Shader.Find("Sprites/Default") ?? Shader.Find("GUI/Text Shader") ?? Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Standard"));
		}
	}
	internal sealed class HarvestHighlight
	{
		private const float ScanInterval = 0.25f;

		private readonly RangeRing _range;

		private readonly HarvestMarkers _markers;

		private readonly Stopwatch _clock = new Stopwatch();

		private float _nextScan = -1f;

		private float _nextReport = -1f;

		private bool _shown;

		private int _frames;

		private long _scanMax;

		private long _scanSum;

		private long _markerMax;

		private long _markerSum;

		private int _scans;

		private int _lastVisited;

		private int _lastFound;

		private long _ringMax;

		private long _ringSum;

		public HarvestHighlight(Transform parent)
		{
			_range = new RangeRing(parent);
			_markers = new HarvestMarkers(parent);
		}

		public void Tick(Player player, bool show, float range, bool pickGuarded)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!show)
			{
				if (_shown)
				{
					Hide();
					_shown = false;
					_nextScan = -1f;
					_nextReport = -1f;
					ResetTimings();
				}
				return;
			}
			_shown = true;
			bool value = Plugin.Settings.LogHighlightTimings.Value;
			if (!value && (_frames > 0 || _scans > 0))
			{
				ResetTimings();
			}
			Vector3 position = ((Component)player).transform.position;
			bool flag = Time.time >= _nextScan;
			if (flag)
			{
				if (value)
				{
					_clock.Restart();
				}
				int visited;
				List<HarvestTarget> list = HarvestScan.Collect(position, range, pickGuarded, out visited);
				if (value)
				{
					_clock.Stop();
					Note(ref _scanMax, ref _scanSum, _clock.ElapsedTicks);
					_scans++;
					_lastVisited = visited;
					_lastFound = list.Count;
					_clock.Restart();
				}
				_markers.Show(list);
				if (value)
				{
					_clock.Stop();
					Note(ref _markerMax, ref _markerSum, _clock.ElapsedTicks);
				}
				_nextScan = Time.time + 0.25f;
			}
			if (value)
			{
				_clock.Restart();
			}
			_range.Show(position, range, flag);
			if (value)
			{
				_clock.Stop();
				Note(ref _ringMax, ref _ringSum, _clock.ElapsedTicks);
				_frames++;
				if (_nextReport < 0f)
				{
					_nextReport = Time.time + 1f;
				}
				else if (Time.time >= _nextReport)
				{
					Report();
					ResetTimings();
					_nextReport = Time.time + 1f;
				}
			}
		}

		public void Hide()
		{
			_range.Hide();
			_markers.Hide();
		}

		public void Destroy()
		{
			Hide();
			GroundLine.DestroyMaterial();
		}

		private static void Note(ref long max, ref long sum, long ticks)
		{
			sum += ticks;
			if (ticks > max)
			{
				max = ticks;
			}
		}

		private void Report()
		{
			double num = Stopwatch.Frequency;
			double num2 = ((_scans == 0) ? 0.0 : ((double)_scanSum / (double)_scans / num * 1000.0));
			double num3 = ((_scans == 0) ? 0.0 : ((double)_markerSum / (double)_scans / num * 1000.0));
			double num4 = ((_frames == 0) ? 0.0 : ((double)_ringSum / (double)_frames / num * 1000.0));
			Plugin.Log.LogInfo((object)("highlight: scan " + ((double)_scanMax / num * 1000.0).ToString("0.0") + " ms max (" + _lastFound + " in range of " + _lastVisited + "), markers " + ((double)_markerMax / num * 1000.0).ToString("0.0") + " ms, ring " + ((double)_ringMax / num * 1000.0).ToString("0.0") + " ms/frame max, " + _frames + " frames (avg scan " + num2.ToString("0.0") + ", markers " + num3.ToString("0.0") + ", ring " + num4.ToString("0.0") + ")"));
		}

		private void ResetTimings()
		{
			_frames = 0;
			_scans = 0;
			_scanMax = 0L;
			_scanSum = 0L;
			_markerMax = 0L;
			_markerSum = 0L;
			_ringMax = 0L;
			_ringSum = 0L;
		}
	}
	internal sealed class HarvestMarkers
	{
		private const int Segments = 16;

		private const float Outer = 0.4f;

		private const float Width = 0.1f;

		private static readonly Color ReadyColor = new Color(0.95f, 0.78f, 0.15f, 0.95f);

		private static readonly Color WaitingColor = new Color(0.55f, 0.42f, 0.12f, 0.4f);

		private readonly Transform _root;

		private readonly Mesh _mesh;

		private readonly MeshRenderer _renderer;

		private readonly List<Vector3> _vertices = new List<Vector3>();

		private readonly List<Color> _colors = new List<Color>();

		private readonly List<int> _triangles = new List<int>();

		public HarvestMarkers(Transform parent)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			GameObject val = new GameObject("EvuAreaHarvest Markers");
			_root = val.transform;
			_root.SetParent(parent, false);
			_root.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			_root.localScale = Vector3.one;
			MeshFilter obj = val.AddComponent<MeshFilter>();
			_renderer = val.AddComponent<MeshRenderer>();
			_mesh = new Mesh
			{
				name = "EvuAreaHarvest Markers"
			};
			_mesh.MarkDynamic();
			obj.sharedMesh = _mesh;
			((Renderer)_renderer).sharedMaterial = GroundLine.Material;
			((Renderer)_renderer).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)_renderer).receiveShadows = false;
			((Renderer)_renderer).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)_renderer).reflectionProbeUsage = (ReflectionProbeUsage)0;
			((Renderer)_renderer).enabled = false;
		}

		public void Hide()
		{
			_mesh.Clear();
			((Renderer)_renderer).enabled = false;
		}

		public void Show(IReadOnlyList<HarvestTarget> spots)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0070: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			_root.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			_root.localScale = Vector3.one;
			_vertices.Clear();
			_colors.Clear();
			_triangles.Clear();
			float num = 0.3f;
			for (int i = 0; i < spots.Count; i++)
			{
				HarvestTarget harvestTarget = spots[i];
				Color item = (harvestTarget.Ready ? ReadyColor : WaitingColor);
				float num2 = GroundLine.SurfaceY(harvestTarget.Position.x, harvestTarget.Position.z, harvestTarget.Position.y) + 0.08f;
				int count = _vertices.Count;
				for (int j = 0; j < 16; j++)
				{
					float num3 = (float)j / 16f * (float)Math.PI * 2f;
					float num4 = Mathf.Cos(num3);
					float num5 = Mathf.Sin(num3);
					_vertices.Add(new Vector3(harvestTarget.Position.x + num4 * num, num2, harvestTarget.Position.z + num5 * num));
					_vertices.Add(new Vector3(harvestTarget.Position.x + num4 * 0.4f, num2, harvestTarget.Position.z + num5 * 0.4f));
					_colors.Add(item);
					_colors.Add(item);
					int num6 = count + j * 2;
					int item2 = num6 + 1;
					int num7 = count + (j + 1) % 16 * 2;
					int item3 = num7 + 1;
					_triangles.Add(num6);
					_triangles.Add(item3);
					_triangles.Add(item2);
					_triangles.Add(num6);
					_triangles.Add(num7);
					_triangles.Add(item3);
				}
			}
			_mesh.Clear();
			if (_vertices.Count == 0)
			{
				((Renderer)_renderer).enabled = false;
				return;
			}
			_mesh.indexFormat = (IndexFormat)(_vertices.Count > 65000);
			_mesh.SetVertices(_vertices);
			_mesh.SetColors(_colors);
			_mesh.SetTriangles(_triangles, 0);
			_mesh.RecalculateBounds();
			((Renderer)_renderer).enabled = true;
		}
	}
	internal readonly struct HarvestTarget
	{
		private readonly Func<Player, bool>? _tryHarvest;

		public Vector3 Position { get; }

		public float Distance { get; }

		public bool Ready { get; }

		public HarvestTarget(Vector3 position, float distance, bool ready, Func<Player, bool>? tryHarvest)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Position = position;
			Distance = distance;
			Ready = ready;
			_tryHarvest = tryHarvest;
		}

		public bool TryHarvest(Player player)
		{
			if (_tryHarvest != null)
			{
				return _tryHarvest(player);
			}
			return false;
		}
	}
	internal static class HarvestScan
	{
		private enum PrefabKind
		{
			None,
			Pickable,
			PickableItem,
			Plant
		}

		private static readonly Dictionary<int, bool> GrowsIntoPickable = new Dictionary<int, bool>();

		private static readonly Dictionary<int, PrefabKind> PrefabKinds = new Dictionary<int, PrefabKind>();

		private static readonly HashSet<uint> SeenSlots = new HashSet<uint>();

		public static List<HarvestTarget> Collect(Vector3 origin, float range, bool pickGuarded, out int visited)
		{
			//IL_0051: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: 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_0104: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			List<HarvestTarget> list = new List<HarvestTarget>();
			visited = 0;
			SeenSlots.Clear();
			ZNetScene instance = ZNetScene.instance;
			ZDOMan instance2 = ZDOMan.instance;
			if ((Object)(object)instance == (Object)null || instance2 == null || instance2.m_objectsBySector == null)
			{
				return list;
			}
			float rangeSqr = range * range;
			float num = range + 2f;
			float num2 = num * num;
			List<ZDO>[] objectsBySector = instance2.m_objectsBySector;
			Vector2s zone = ZoneSystem.GetZone(origin - new Vector3(num, 0f, num));
			Vector2s zone2 = ZoneSystem.GetZone(origin + new Vector3(num, 0f, num));
			for (short num3 = zone.y; num3 <= zone2.y; num3++)
			{
				for (short num4 = zone.x; num4 <= zone2.x; num4++)
				{
					uint sector = ZoneSystem.SectorToIndex(new Vector2s(num4, num3)).Sector;
					if (sector < (uint)objectsBySector.Length && SeenSlots.Add(sector))
					{
						List<ZDO> list2 = objectsBySector[sector];
						if (list2 != null)
						{
							for (int i = 0; i < list2.Count; i++)
							{
								visited++;
								ZDO val = list2[i];
								if (val == null)
								{
									continue;
								}
								Vector3 val2 = val.GetPosition() - origin;
								if (!(((Vector3)(ref val2)).sqrMagnitude > num2) && instance.m_instances.TryGetValue(val, out var value) && !((Object)(object)value == (Object)null) && value.IsValid())
								{
									switch (Kind(instance, val.GetPrefab()))
									{
									case PrefabKind.Pickable:
										ConsiderPickable(value, origin, rangeSqr, pickGuarded, list);
										break;
									case PrefabKind.PickableItem:
										ConsiderItem(value, origin, rangeSqr, list);
										break;
									case PrefabKind.Plant:
										ConsiderPlant(value, origin, rangeSqr, list);
										break;
									}
								}
							}
						}
					}
				}
			}
			return list;
		}

		private static PrefabKind Kind(ZNetScene scene, int hash)
		{
			if (PrefabKinds.TryGetValue(hash, out var value))
			{
				return value;
			}
			GameObject prefab = scene.GetPrefab(hash);
			value = ((!((Object)(object)prefab == (Object)null)) ? (((Object)(object)prefab.GetComponentInChildren<Pickable>(true) != (Object)null) ? PrefabKind.Pickable : (((Object)(object)prefab.GetComponentInChildren<PickableItem>(true) != (Object)null) ? PrefabKind.PickableItem : (((Object)(object)prefab.GetComponentInChildren<Plant>(true) != (Object)null) ? PrefabKind.Plant : PrefabKind.None))) : PrefabKind.None);
			PrefabKinds[hash] = value;
			return value;
		}

		private static void ConsiderPickable(ZNetView view, Vector3 origin, float rangeSqr, bool pickGuarded, List<HarvestTarget> found)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Pickable component = ((Component)view).GetComponent<Pickable>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.m_itemPrefab == (Object)null || component.m_enabled == 0 || (!pickGuarded && component.m_aggravateRange > 0f))
			{
				return;
			}
			Vector3 position = ((Component)component).transform.position;
			Vector3 val = position - origin;
			if (!(((Vector3)(ref val)).sqrMagnitude > rangeSqr))
			{
				Pickable captured = component;
				found.Add(new HarvestTarget(position, ((Vector3)(ref val)).magnitude, Ready(captured), (Player player) => TryPick(captured, player)));
			}
		}

		private static void ConsiderItem(ZNetView view, Vector3 origin, float rangeSqr, List<HarvestTarget> found)
		{
			//IL_002b: 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_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_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_004c: Unknown result type (might be due to invalid IL or missing references)
			PickableItem component = ((Component)view).GetComponent<PickableItem>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.m_itemPrefab == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)component).transform.position;
			Vector3 val = position - origin;
			if (!(((Vector3)(ref val)).sqrMagnitude > rangeSqr))
			{
				PickableItem captured = component;
				found.Add(new HarvestTarget(position, ((Vector3)(ref val)).magnitude, !component.m_picked, (Player player) => TryPickItem(captured, player)));
			}
		}

		private static void ConsiderPlant(ZNetView view, Vector3 origin, float rangeSqr, List<HarvestTarget> found)
		{
			//IL_0011: 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_002c: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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)
			Plant component = ((Component)view).GetComponent<Plant>();
			if (!((Object)(object)component == (Object)null) && (int)component.m_status == 0 && WillBePickable(component))
			{
				Vector3 position = ((Component)component).transform.position;
				Vector3 val = position - origin;
				if (!(((Vector3)(ref val)).sqrMagnitude > rangeSqr))
				{
					found.Add(new HarvestTarget(position, ((Vector3)(ref val)).magnitude, ready: false, null));
				}
			}
		}

		private static bool Live(ZNetView? view)
		{
			if ((Object)(object)view != (Object)null)
			{
				return view.IsValid();
			}
			return false;
		}

		private static bool WillBePickable(Plant plant)
		{
			GameObject[] grownPrefabs = plant.m_grownPrefabs;
			if (grownPrefabs == null)
			{
				return false;
			}
			foreach (GameObject val in grownPrefabs)
			{
				if (!((Object)(object)val == (Object)null))
				{
					int instanceID = ((Object)val).GetInstanceID();
					if (!GrowsIntoPickable.TryGetValue(instanceID, out var value))
					{
						value = (Object)(object)val.GetComponentInChildren<Pickable>(true) != (Object)null;
						GrowsIntoPickable[instanceID] = value;
					}
					if (value)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool Ready(Pickable pickable)
		{
			if (Live(pickable.m_nview))
			{
				return pickable.CanBePicked();
			}
			return false;
		}

		private static bool StuckInTar(Pickable pickable)
		{
			if (!pickable.m_tarPreventsPicking)
			{
				return false;
			}
			Floating component = ((Component)pickable).GetComponent<Floating>();
			if ((Object)(object)component != (Object)null)
			{
				return component.IsInTar();
			}
			return false;
		}

		private static bool TryPick(Pickable pickable, Player player)
		{
			if ((Object)(object)pickable == (Object)null || !Ready(pickable) || StuckInTar(pickable))
			{
				return false;
			}
			pickable.Interact((Humanoid)(object)player, false, false);
			return true;
		}

		private static bool TryPickItem(PickableItem item, Player player)
		{
			if ((Object)(object)item == (Object)null || item.m_picked || !Live(item.m_nview))
			{
				return false;
			}
			return item.Interact((Humanoid)(object)player, false, false);
		}
	}
	[BepInPlugin("evu.evuareaharvest", "EvuAreaHarvest", "0.2.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private ConfigFileWatcher _configWatcher;

		private HarvestHighlight _highlight;

		internal static PluginConfig Settings { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new PluginConfig(((BaseUnityPlugin)this).Config);
			_configWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L);
			_highlight = new HarvestHighlight(((Component)this).transform);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"EvuAreaHarvest loaded.");
		}

		private void OnDestroy()
		{
			if (_highlight != null)
			{
				_highlight.Destroy();
			}
		}

		private void Update()
		{
			//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_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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				_highlight.Tick(null, show: false, 0f, pickGuarded: false);
				return;
			}
			if (AcceptsHotkeys(localPlayer))
			{
				KeyboardShortcut value = Settings.HarvestArea.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					HarvestNow(localPlayer);
				}
				value = Settings.ToggleHighlight.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Settings.HighlightHarvestables.Value = !Settings.HighlightHarvestables.Value;
					Say(localPlayer, HarvestMath.FormatHighlight(Settings.HighlightHarvestables.Value));
				}
			}
			_highlight.Tick(localPlayer, Settings.HighlightHarvestables.Value, HarvestMath.ClampRange(Settings.HarvestRange.Value), Settings.PickGuarded.Value);
		}

		private static void HarvestNow(Player player)
		{
			//IL_002e: 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_0099: 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)
			float num = HarvestMath.ClampRange(Settings.HarvestRange.Value);
			int visited;
			List<HarvestTarget> found = HarvestScan.Collect(((Component)player).transform.position, num, Settings.PickGuarded.Value, out visited);
			Candidate[] array = (Candidate[])(object)new Candidate[found.Count];
			for (int i = 0; i < found.Count; i++)
			{
				array[i] = new Candidate(found[i].Distance, found[i].Ready);
			}
			Result val = HarvestTally.Run((IReadOnlyList<Candidate>)array, num, (Func<int, bool>)((int index) => found[index].TryHarvest(player)));
			Say(player, HarvestMath.FormatHarvest(((Result)(ref val)).Harvested, ((Result)(ref val)).InRange));
		}

		private static void Say(Player player, string line)
		{
			Log.LogInfo((object)line);
			((Character)player).Message((MessageType)2, line, 0, (Sprite)null, false);
		}

		private static bool AcceptsHotkeys(Player player)
		{
			if (((Character)player).TakeInput() && !((Character)player).IsDead() && !((Character)player).InCutscene())
			{
				return !((Character)player).IsTeleporting();
			}
			return false;
		}
	}
	internal sealed class PluginConfig
	{
		public ConfigEntry<float> HarvestRange { get; }

		public ConfigEntry<bool> PickGuarded { get; }

		public ConfigEntry<bool> HighlightHarvestables { get; }

		public ConfigEntry<KeyboardShortcut> HarvestArea { get; }

		public ConfigEntry<KeyboardShortcut> ToggleHighlight { get; }

		public ConfigEntry<bool> LogHighlightTimings { get; }

		public PluginConfig(ConfigFile config)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			HarvestRange = config.Bind<float>("Server", "Harvest range", 8f, new ConfigDescription("Radius in meters, from 2 to 32. Harvest and the highlight use a sphere centered on you. When this mod is installed on the server, that server's value is the one used.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 32f), new object[1] { ConfigHints.Synced(100) }));
			PickGuarded = config.Bind<bool>("Server", "Pick guarded items", false, new ConfigDescription("When on, also picks items that aggravate nearby creatures when taken, such as Dvergr belongings. Off leaves them alone.", (AcceptableValueBase)null, new object[1] { ConfigHints.Synced(95) }));
			HighlightHarvestables = config.Bind<bool>("Local", "Highlight harvestables", false, new ConfigDescription("When on, draws the range on the ground and a marker on each harvestable in range.", (AcceptableValueBase)null, new object[1] { ConfigHints.Local(90) }));
			HarvestArea = config.Bind<KeyboardShortcut>("Local", "Harvest area", new KeyboardShortcut((KeyCode)266, Array.Empty<KeyCode>()), new ConfigDescription("Key that harvests everything in range. Unity calls numpad Delete KeypadPeriod.", (AcceptableValueBase)null, new object[1] { ConfigHints.Local(80) }));
			ToggleHighlight = config.Bind<KeyboardShortcut>("Local", "Toggle highlight", new KeyboardShortcut((KeyCode)279, Array.Empty<KeyCode>()), new ConfigDescription("Key that shows or hides the range ring and the harvestable markers.", (AcceptableValueBase)null, new object[1] { ConfigHints.Local(70) }));
			LogHighlightTimings = config.Bind<bool>("Local", "Log highlight timings", false, new ConfigDescription("When on, logs once per second how long the highlight scan, markers, and range ring took.", (AcceptableValueBase)null, new object[1] { ConfigHints.Local(60) }));
		}
	}
	internal static class ConfigHints
	{
		public static ConfigurationManagerAttributes Synced(int order)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0019: Expected O, but got Unknown
			return new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				Order = order
			};
		}

		public static ConfigurationManagerAttributes Local(int order)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0019: Expected O, but got Unknown
			return new ConfigurationManagerAttributes
			{
				IsAdminOnly = false,
				Order = order
			};
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "evu.evuareaharvest";

		public const string Name = "EvuAreaHarvest";

		public const string Version = "0.2.2";
	}
	internal sealed class RangeRing
	{
		private const int Segments = 64;

		private readonly LineRenderer _edge;

		private readonly LineRenderer _ripple;

		private readonly float[] _edgeY = new float[64];

		private readonly Vector3[] _points = (Vector3[])(object)new Vector3[64];

		private float _cachedRange = -1f;

		private float _centerY;

		public RangeRing(Transform parent)
		{
			_edge = GroundLine.Create("EvuAreaHarvest Range", parent, 0.12f);
			_ripple = GroundLine.Create("EvuAreaHarvest Ripple", parent, 0.07f);
		}

		public void Hide()
		{
			_edge.positionCount = 0;
			_ripple.positionCount = 0;
			_cachedRange = -1f;
		}

		public void Show(Vector3 center, float range, bool refresh)
		{
			//IL_0012: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (refresh || !Mathf.Approximately(range, _cachedRange))
			{
				Sample(center, range);
			}
			float num = 1f + 0.02f * Mathf.Sin(Time.time * 2.6f);
			Fill(center, range * num, 1f);
			GroundLine.Circle(_edge, _points, new Color(0.95f, 0.78f, 0.15f, 0.9f));
			float num2 = Mathf.Repeat(Time.time / 1.5f, 1f);
			float num3 = range * num2;
			if (num3 <= 0.05f)
			{
				_ripple.positionCount = 0;
				return;
			}
			Fill(center, num3, num2);
			GroundLine.Circle(_ripple, _points, new Color(0.95f, 0.82f, 0.25f, (1f - num2) * 0.75f));
		}

		private void Sample(Vector3 center, float range)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_003d: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			_cachedRange = range;
			_centerY = GroundLine.SurfaceY(center.x, center.z, center.y);
			for (int i = 0; i < 64; i++)
			{
				float num = (float)i / 64f * (float)Math.PI * 2f;
				float x = center.x + Mathf.Cos(num) * range;
				float z = center.z + Mathf.Sin(num) * range;
				_edgeY[i] = GroundLine.SurfaceY(x, z, center.y);
			}
		}

		private void Fill(Vector3 center, float radius, float t)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 64; i++)
			{
				float num = (float)i / 64f * (float)Math.PI * 2f;
				float num2 = center.x + Mathf.Cos(num) * radius;
				float num3 = center.z + Mathf.Sin(num) * radius;
				float num4 = Mathf.Lerp(_centerY, _edgeY[i], t) + 0.08f;
				_points[i] = new Vector3(num2, num4, num3);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}