Decompiled source of ProcessProgress v1.0.1

ProcessProgress.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ProcessProgress
{
	[BepInPlugin("com.michal.valheim.processprogress", "Process Progress", "1.0.1")]
	public class ProcessProgressPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.michal.valheim.processprogress";

		public const string PluginName = "Process Progress";

		public const string PluginVersion = "1.0.1";

		private const float ScanInterval = 1f;

		private const float RefreshInterval = 0.5f;

		internal static ManualLogSource Log;

		private ConfigEntry<float> _range;

		private ConfigEntry<bool> _showPlants;

		private ConfigEntry<bool> _showPickables;

		private ConfigEntry<bool> _showFermenters;

		private ConfigEntry<bool> _showBeehives;

		private IProgressProvider[] _providers;

		private ProgressBarLayer _bars;

		private const int InitialScanBufferSize = 256;

		private Collider[] _scanBuffer = (Collider[])(object)new Collider[256];

		private readonly Dictionary<Component, IProgressProvider> _targets = new Dictionary<Component, IProgressProvider>();

		private float _scanTimer = 1f;

		private float _refreshTimer;

		private bool _faulted;

		private void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Game.isModded = true;
			_range = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range", 10f, new ConfigDescription("How far from you (meters) progress bars are shown.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 40f), Array.Empty<object>()));
			_showPlants = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPlants", true, "Growing plants: crops and tree saplings.");
			_showPickables = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPickables", true, "Picked bushes and plants regrowing: berries, mushrooms, herbs.");
			_showFermenters = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowFermenters", true, "Fermenters.");
			_showBeehives = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowBeehives", true, "Beehives: honey stored and time to the next one.");
			_providers = new IProgressProvider[4]
			{
				new PlantProgress(() => _showPlants.Value),
				new PickableProgress(() => _showPickables.Value),
				new FermenterProgress(() => _showFermenters.Value),
				new BeehiveProgress(() => _showBeehives.Value)
			};
		}

		private void Update()
		{
			if (_faulted)
			{
				return;
			}
			try
			{
				RunUpdate();
			}
			catch (Exception e)
			{
				Fault(e);
			}
		}

		private void LateUpdate()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (_faulted || _bars == null || !_bars.IsAlive || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			try
			{
				Camera mainCamera = Utils.GetMainCamera();
				if ((Object)(object)mainCamera != (Object)null)
				{
					_bars.UpdatePositions(mainCamera, ((Component)Player.m_localPlayer).transform.position, _range.Value);
				}
			}
			catch (Exception e)
			{
				Fault(e);
			}
		}

		private void Fault(Exception e)
		{
			_faulted = true;
			_bars?.Clear();
			Log.LogError((object)$"Process Progress wylaczony po nieoczekiwanym bledzie: {e}");
		}

		private void RunUpdate()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				_bars?.Clear();
				_targets.Clear();
				return;
			}
			if (_bars == null || !_bars.IsAlive)
			{
				_bars = ProgressBarLayer.TryCreate(FindGameFont());
				if (_bars == null)
				{
					return;
				}
			}
			_scanTimer += Time.deltaTime;
			if (_scanTimer >= 1f)
			{
				_scanTimer = 0f;
				Scan();
				_bars.Sync(_targets);
				_refreshTimer = 0.5f;
			}
			_refreshTimer += Time.deltaTime;
			if (_refreshTimer >= 0.5f)
			{
				_refreshTimer = 0f;
				_bars.Refresh();
			}
		}

		private void Scan()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_005e: 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)
			_targets.Clear();
			if (!_providers.Any((IProgressProvider p) => p.Enabled))
			{
				return;
			}
			Vector3 val = ((Component)Player.m_localPlayer).transform.position + Vector3.up;
			float value = _range.Value;
			int num = Physics.OverlapSphereNonAlloc(val, value, _scanBuffer);
			if (num >= _scanBuffer.Length)
			{
				Array.Resize(ref _scanBuffer, _scanBuffer.Length * 2);
				num = Physics.OverlapSphereNonAlloc(val, value, _scanBuffer);
			}
			for (int num2 = 0; num2 < num; num2++)
			{
				Collider val2 = _scanBuffer[num2];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				IProgressProvider[] providers = _providers;
				foreach (IProgressProvider progressProvider in providers)
				{
					if (progressProvider.Enabled)
					{
						Component componentInParent = ((Component)val2).GetComponentInParent(progressProvider.ComponentType);
						if (!((Object)(object)componentInParent == (Object)null))
						{
							_targets[componentInParent] = progressProvider;
							break;
						}
					}
				}
			}
		}

		private static TMP_FontAsset FindGameFont()
		{
			TextMeshProUGUI val = Object.FindAnyObjectByType<TextMeshProUGUI>();
			if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null)
			{
				return ((TMP_Text)val).font;
			}
			return TMP_Settings.defaultFontAsset;
		}
	}
	internal sealed class ProgressBarLayer
	{
		private sealed class BarView
		{
			public GameObject Root;

			public RectTransform Rect;

			public RectTransform FillRect;

			public Image Fill;

			public TextMeshProUGUI Text;

			public Component Target;

			public IProgressProvider Provider;

			public float AnchorHeight;

			public bool HasInfo;
		}

		private const float TextWidth = 220f;

		private const float TextHeight = 32f;

		private const float BarWidth = 92f;

		private const float BarHeight = 8f;

		private const float MaxAnchorHeight = 4f;

		private const float AnchorGap = 0.15f;

		private static readonly Color ProgressColor = new Color(0.45f, 0.78f, 0.32f, 1f);

		private static readonly Color ReadyColor = new Color(1f, 0.78f, 0.25f, 1f);

		private static readonly Color WarningColor = new Color(0.9f, 0.3f, 0.22f, 1f);

		private static readonly Color TextColor = new Color(0.8529f, 0.725f, 0.5331f, 1f);

		private static readonly Color WarningTextColor = new Color(1f, 0.55f, 0.45f, 1f);

		private readonly RectTransform _root;

		private readonly TMP_FontAsset _font;

		private readonly Stack<BarView> _pool = new Stack<BarView>();

		private readonly Dictionary<Component, BarView> _bars = new Dictionary<Component, BarView>();

		private readonly List<Component> _toRelease = new List<Component>();

		public bool IsAlive => (Object)(object)_root != (Object)null;

		private ProgressBarLayer(RectTransform root, TMP_FontAsset font)
		{
			_root = root;
			_font = font;
		}

		public static ProgressBarLayer TryCreate(TMP_FontAsset font)
		{
			//IL_0037: 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_005f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			EnemyHud instance = EnemyHud.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_hudRoot == (Object)null)
			{
				return null;
			}
			RectTransform component = new GameObject("ProcessProgressBars", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(instance.m_hudRoot.transform, false);
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			return new ProgressBarLayer(component, font);
		}

		public void Sync(Dictionary<Component, IProgressProvider> targets)
		{
			_toRelease.Clear();
			foreach (KeyValuePair<Component, BarView> bar in _bars)
			{
				if ((Object)(object)bar.Key == (Object)null || !targets.ContainsKey(bar.Key))
				{
					_toRelease.Add(bar.Key);
				}
			}
			foreach (Component item in _toRelease)
			{
				Release(item);
			}
			foreach (KeyValuePair<Component, IProgressProvider> target in targets)
			{
				if (!((Object)(object)target.Key == (Object)null) && !_bars.ContainsKey(target.Key))
				{
					BarView barView = ((_pool.Count > 0) ? _pool.Pop() : CreateBar());
					barView.Target = target.Key;
					barView.Provider = target.Value;
					barView.AnchorHeight = AnchorHeight(target.Key);
					barView.HasInfo = false;
					_bars[target.Key] = barView;
				}
			}
		}

		public void Refresh()
		{
			_toRelease.Clear();
			foreach (KeyValuePair<Component, BarView> bar in _bars)
			{
				BarView value = bar.Value;
				if ((Object)(object)bar.Key == (Object)null)
				{
					_toRelease.Add(bar.Key);
					continue;
				}
				ProgressInfo info = default(ProgressInfo);
				value.HasInfo = value.Provider.Enabled && value.Provider.TryGetProgress(bar.Key, out info);
				if (value.HasInfo)
				{
					Apply(value, info);
				}
			}
			foreach (Component item in _toRelease)
			{
				Release(item);
			}
		}

		public void UpdatePositions(Camera camera, Vector3 playerPos, float range)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006b: 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_0075: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Component, BarView> bar in _bars)
			{
				BarView value = bar.Value;
				if ((Object)(object)bar.Key == (Object)null || !value.HasInfo)
				{
					SetActive(value, active: false);
					continue;
				}
				Vector3 val = bar.Key.transform.position + Vector3.up * value.AnchorHeight;
				float num = Vector3.Distance(playerPos, val);
				Vector3 val2 = Utils.WorldToScreenPointScaled(camera, val);
				bool flag = num <= range && val2.z > 0f && val2.x >= 0f && val2.x <= (float)Screen.width && val2.y >= 0f && val2.y <= (float)Screen.height;
				SetActive(value, flag);
				if (flag)
				{
					((Transform)value.Rect).position = val2;
					float num2 = Mathf.Lerp(1f, 0.75f, num / Mathf.Max(range, 0.01f));
					((Transform)value.Rect).localScale = new Vector3(num2, num2, 1f);
				}
			}
		}

		public void Clear()
		{
			_toRelease.Clear();
			_toRelease.AddRange(_bars.Keys);
			foreach (Component item in _toRelease)
			{
				Release(item);
			}
		}

		private void Release(Component target)
		{
			if (_bars.TryGetValue(target, out var value))
			{
				_bars.Remove(target);
				value.Target = null;
				value.Provider = null;
				value.HasInfo = false;
				SetActive(value, active: false);
				_pool.Push(value);
			}
		}

		private static void SetActive(BarView bar, bool active)
		{
			if (bar.Root.activeSelf != active)
			{
				bar.Root.SetActive(active);
			}
		}

		private static void Apply(BarView bar, ProgressInfo info)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00fa: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			Color color = TextColor;
			Color color2;
			string text;
			if (info.Warning != null)
			{
				color2 = WarningColor;
				color = WarningTextColor;
				text = info.Title + "\n" + info.Warning;
			}
			else if (info.Ready)
			{
				color2 = ReadyColor;
				text = info.Title + ": " + ProgressText.Localize("$piece_fermenter_ready");
			}
			else
			{
				color2 = ProgressColor;
				string text2 = ((info.SecondsLeft >= 0.0) ? (" · " + FormatDuration(info.SecondsLeft)) : "");
				string text3 = info.Detail ?? $"{Mathf.FloorToInt(info.Fraction * 100f)}%";
				text = info.Title + " " + text3 + text2;
			}
			if (((TMP_Text)bar.Text).text != text)
			{
				((TMP_Text)bar.Text).text = text;
			}
			((Graphic)bar.Text).color = color;
			((Graphic)bar.Fill).color = color2;
			bar.FillRect.anchorMax = new Vector2((info.Warning != null && !info.Ready) ? Mathf.Max(info.Fraction, 0.02f) : info.Fraction, 1f);
		}

		private static string FormatDuration(double seconds)
		{
			int num = Mathf.CeilToInt((float)seconds);
			if (num >= 3600)
			{
				return $"{num / 3600}h {num % 3600 / 60}m";
			}
			if (num >= 60)
			{
				return $"{Mathf.CeilToInt((float)num / 60f)}m";
			}
			return $"{num}s";
		}

		private static float AnchorHeight(Component target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			float y = target.transform.position.y;
			float num = float.NegativeInfinity;
			Renderer[] componentsInChildren = target.GetComponentsInChildren<Renderer>();
			Bounds bounds;
			foreach (Renderer val in componentsInChildren)
			{
				if (val.enabled && ((Component)val).gameObject.activeInHierarchy && (val is MeshRenderer || val is SkinnedMeshRenderer))
				{
					float num2 = num;
					bounds = val.bounds;
					num = Mathf.Max(num2, ((Bounds)(ref bounds)).max.y);
				}
			}
			if (float.IsNegativeInfinity(num))
			{
				Collider[] componentsInChildren2 = target.GetComponentsInChildren<Collider>();
				foreach (Collider val2 in componentsInChildren2)
				{
					if (val2.enabled && !val2.isTrigger)
					{
						float num3 = num;
						bounds = val2.bounds;
						num = Mathf.Max(num3, ((Bounds)(ref bounds)).max.y);
					}
				}
			}
			return Mathf.Min(float.IsNegativeInfinity(num) ? 0.5f : Mathf.Max(num - y, 0.3f), 4f) + 0.15f;
		}

		private BarView CreateBar()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0053: 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_008c: 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_00b1: 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_00d8: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ProgressBar", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_root, false);
			Vector2 val2 = (component.anchorMin = (component.anchorMax = Vector2.zero));
			component.pivot = new Vector2(0.5f, 0f);
			component.sizeDelta = new Vector2(220f, 42f);
			RectTransform val4 = CreateImage("Background", component, new Color(0f, 0f, 0f, 0.7f));
			((Vector2)(ref val2))..ctor(0.5f, 0f);
			val4.anchorMax = val2;
			val4.anchorMin = val2;
			val4.pivot = new Vector2(0.5f, 0f);
			val4.sizeDelta = new Vector2(92f, 8f);
			val4.anchoredPosition = Vector2.zero;
			RectTransform val5 = CreateImage("Fill", val4, ProgressColor);
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = new Vector2(0f, 1f);
			val5.pivot = new Vector2(0f, 0.5f);
			val5.offsetMin = new Vector2(1f, 1f);
			val5.offsetMax = new Vector2(-1f, -1f);
			GameObject val6 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
			RectTransform component2 = val6.GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)component, false);
			((Vector2)(ref val2))..ctor(0.5f, 0f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(0.5f, 0f);
			component2.sizeDelta = new Vector2(220f, 32f);
			component2.anchoredPosition = new Vector2(0f, 9f);
			TextMeshProUGUI val7 = val6.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)_font != (Object)null)
			{
				((TMP_Text)val7).font = _font;
			}
			((TMP_Text)val7).fontSize = 13f;
			((TMP_Text)val7).enableAutoSizing = true;
			((TMP_Text)val7).fontSizeMin = 9f;
			((TMP_Text)val7).fontSizeMax = 13f;
			((TMP_Text)val7).fontStyle = (FontStyles)1;
			((TMP_Text)val7).alignment = (TextAlignmentOptions)1026;
			((TMP_Text)val7).overflowMode = (TextOverflowModes)0;
			((TMP_Text)val7).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)val7).outlineWidth = 0.2f;
			((TMP_Text)val7).outlineColor = new Color32((byte)20, (byte)12, (byte)5, byte.MaxValue);
			((Graphic)val7).raycastTarget = false;
			val.SetActive(false);
			return new BarView
			{
				Root = val,
				Rect = component,
				FillRect = val5,
				Fill = ((Component)val5).GetComponent<Image>(),
				Text = val7
			};
		}

		private static RectTransform CreateImage(string name, RectTransform parent, Color color)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).color = color;
			((Graphic)obj).raycastTarget = false;
			return component;
		}
	}
	internal struct ProgressInfo
	{
		public string Title;

		public string Detail;

		public float Fraction;

		public double SecondsLeft;

		public string Warning;

		public bool Ready;
	}
	internal interface IProgressProvider
	{
		Type ComponentType { get; }

		bool Enabled { get; }

		bool TryGetProgress(Component target, out ProgressInfo info);
	}
	internal static class ProgressText
	{
		public static string Localize(string text)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}

		public static double SecondsSince(long ticks)
		{
			return (ZNet.instance.GetTime() - new DateTime(ticks)).TotalSeconds;
		}

		public static bool TryGetZdo(Component target, out ZDO zdo)
		{
			ZNetView component = target.GetComponent<ZNetView>();
			zdo = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null);
			return zdo != null;
		}
	}
	internal sealed class PlantProgress : IProgressProvider
	{
		private static readonly Func<Plant, float> GetGrowTime = AccessTools.MethodDelegate<Func<Plant, float>>(AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Plant, double> TimeSincePlanted = AccessTools.MethodDelegate<Func<Plant, double>>(AccessTools.Method(typeof(Plant), "TimeSincePlanted", (Type[])null, (Type[])null), (object)null, true);

		private static readonly FieldRef<Plant, Status> StatusRef = AccessTools.FieldRefAccess<Plant, Status>("m_status");

		private readonly Func<bool> _enabled;

		public Type ComponentType => typeof(Plant);

		public bool Enabled => _enabled();

		public PlantProgress(Func<bool> enabled)
		{
			_enabled = enabled;
		}

		public bool TryGetProgress(Component target, out ProgressInfo info)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			info = default(ProgressInfo);
			Plant val = (Plant)target;
			if (!ProgressText.TryGetZdo((Component)(object)val, out var _))
			{
				return false;
			}
			float num = GetGrowTime(val);
			double num2 = TimeSincePlanted(val);
			info.Title = ProgressText.Localize(val.m_name);
			info.Fraction = ((num > 0f) ? Mathf.Clamp01((float)(num2 / (double)num)) : 1f);
			info.SecondsLeft = Math.Max(0.0, (double)num - num2);
			info.Ready = info.Fraction >= 1f;
			info.Warning = StatusWarning(StatusRef.Invoke(val));
			return true;
		}

		private static string StatusWarning(Status status)
		{
			//IL_0000: 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)
			//IL_0024: Expected I4, but got Unknown
			string text = (status - 1) switch
			{
				1 => "$piece_plant_nospace", 
				0 => "$piece_plant_nosun", 
				2 => "$piece_plant_wrongbiome", 
				3 => "$piece_plant_notcultivated", 
				5 => "$piece_plant_toohot", 
				6 => "$piece_plant_toocold", 
				4 => "$piece_plant_nowall", 
				_ => null, 
			};
			if (text == null)
			{
				return null;
			}
			return ProgressText.Localize(text);
		}
	}
	internal sealed class PickableProgress : IProgressProvider
	{
		private readonly Func<bool> _enabled;

		public Type ComponentType => typeof(Pickable);

		public bool Enabled => _enabled();

		public PickableProgress(Func<bool> enabled)
		{
			_enabled = enabled;
		}

		public bool TryGetProgress(Component target, out ProgressInfo info)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			info = default(ProgressInfo);
			Pickable val = (Pickable)target;
			if (val.m_respawnTimeMinutes <= 0f || val.GetEnabled == 0)
			{
				return false;
			}
			if (!ProgressText.TryGetZdo((Component)(object)val, out var zdo) || !zdo.GetBool(ZDOVars.s_picked, val.m_defaultPicked))
			{
				return false;
			}
			long num = zdo.GetLong(ZDOVars.s_pickedTime, 0L);
			if (num <= 1)
			{
				return false;
			}
			double num2 = (double)val.m_respawnTimeMinutes * 60.0;
			double num3 = ProgressText.SecondsSince(num);
			info.Title = PickableName(val);
			info.Fraction = Mathf.Clamp01((float)(num3 / num2));
			info.SecondsLeft = Math.Max(0.0, num2 - num3);
			info.Ready = info.Fraction >= 1f;
			return true;
		}

		private static string PickableName(Pickable pickable)
		{
			if (!string.IsNullOrEmpty(pickable.m_overrideName))
			{
				return ProgressText.Localize(pickable.m_overrideName);
			}
			ItemDrop val = (((Object)(object)pickable.m_itemPrefab != (Object)null) ? pickable.m_itemPrefab.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val != (Object)null))
			{
				return ((Object)pickable).name;
			}
			return ProgressText.Localize(val.m_itemData.m_shared.m_name);
		}
	}
	internal sealed class BeehiveProgress : IProgressProvider
	{
		private static readonly Func<Beehive, bool> CheckBiome = AccessTools.MethodDelegate<Func<Beehive, bool>>(AccessTools.Method(typeof(Beehive), "CheckBiome", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Beehive, bool> HaveFreeSpace = AccessTools.MethodDelegate<Func<Beehive, bool>>(AccessTools.Method(typeof(Beehive), "HaveFreeSpace", (Type[])null, (Type[])null), (object)null, true);

		private readonly Func<bool> _enabled;

		public Type ComponentType => typeof(Beehive);

		public bool Enabled => _enabled();

		public BeehiveProgress(Func<bool> enabled)
		{
			_enabled = enabled;
		}

		public bool TryGetProgress(Component target, out ProgressInfo info)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			info = default(ProgressInfo);
			Beehive val = (Beehive)target;
			if (!ProgressText.TryGetZdo((Component)(object)val, out var zdo) || val.m_maxHoney <= 0 || val.m_secPerUnit <= 0f)
			{
				return false;
			}
			int num = Mathf.Clamp(zdo.GetInt(ZDOVars.s_level, 0), 0, val.m_maxHoney);
			info.Title = ProgressText.Localize(val.m_name);
			info.Detail = $"{num}/{val.m_maxHoney}";
			if (num >= val.m_maxHoney)
			{
				info.Fraction = 1f;
				info.Ready = true;
				return true;
			}
			if (!CheckBiome(val))
			{
				info.Warning = ProgressText.Localize(val.m_areaText);
			}
			else if (!HaveFreeSpace(val))
			{
				info.Warning = ProgressText.Localize(val.m_freespaceText);
			}
			double num2 = 0.0;
			long num3 = zdo.GetLong(ZDOVars.s_lastTime, 0L);
			if (info.Warning == null && num3 > 0)
			{
				num2 = Math.Max(0.0, ProgressText.SecondsSince(num3));
			}
			double num4 = Math.Min((double)zdo.GetFloat(ZDOVars.s_product, 0f) + num2, val.m_secPerUnit);
			info.Fraction = Mathf.Clamp01((float)(((double)num + num4 / (double)val.m_secPerUnit) / (double)val.m_maxHoney));
			info.SecondsLeft = ((info.Warning == null) ? Math.Max(0.0, (double)val.m_secPerUnit - num4) : (-1.0));
			return true;
		}
	}
	internal sealed class FermenterProgress : IProgressProvider
	{
		private static readonly Func<Fermenter, double> GetFermentationTime = AccessTools.MethodDelegate<Func<Fermenter, double>>(AccessTools.Method(typeof(Fermenter), "GetFermentationTime", (Type[])null, (Type[])null), (object)null, true);

		private static readonly FieldRef<Fermenter, bool> HasRoofRef = AccessTools.FieldRefAccess<Fermenter, bool>("m_hasRoof");

		private static readonly FieldRef<Fermenter, bool> ExposedRef = AccessTools.FieldRefAccess<Fermenter, bool>("m_exposed");

		private readonly Func<bool> _enabled;

		public Type ComponentType => typeof(Fermenter);

		public bool Enabled => _enabled();

		public FermenterProgress(Func<bool> enabled)
		{
			_enabled = enabled;
		}

		public bool TryGetProgress(Component target, out ProgressInfo info)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			info = default(ProgressInfo);
			Fermenter val = (Fermenter)target;
			if (!ProgressText.TryGetZdo((Component)(object)val, out var zdo))
			{
				return false;
			}
			if (zdo.GetInt(ZDOVars.s_content, 0) == 0)
			{
				return false;
			}
			double num = GetFermentationTime(val);
			if (num < 0.0)
			{
				return false;
			}
			info.Title = ProgressText.Localize(val.m_name);
			info.Fraction = ((val.m_fermentationDuration > 0f) ? Mathf.Clamp01((float)(num / (double)val.m_fermentationDuration)) : 1f);
			info.SecondsLeft = Math.Max(0.0, (double)val.m_fermentationDuration - num);
			info.Ready = info.Fraction >= 1f;
			if (!info.Ready)
			{
				if (!HasRoofRef.Invoke(val))
				{
					info.Warning = ProgressText.Localize("$piece_fermenter_needroof");
				}
				else if (ExposedRef.Invoke(val))
				{
					info.Warning = ProgressText.Localize("$piece_fermenter_exposed");
				}
			}
			return true;
		}
	}
}