using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using PlantTimers.Patches;
using PlantTimers.Tooltips;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
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: AssemblyCompany("PlantTimers")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+14ca30930bac182b47b3f6145551e9ea44964942")]
[assembly: AssemblyProduct("Plant Timers")]
[assembly: AssemblyTitle("PlantTimers")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/csh/lens-island-plant-timers")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 PlantTimers
{
public static class FarmingExtensions
{
public static bool IsGrown(this Plant plant)
{
if (!Object.op_Implicit((Object)(object)plant))
{
return false;
}
if (plant.fullGrown)
{
return true;
}
Renderer[] componentsInChildren = ((Component)((Component)plant).transform).GetComponentsInChildren<Renderer>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
if (((Object)componentsInChildren[i]).name == "Plant_Sparkle")
{
return true;
}
}
return false;
}
public static bool HasGrowingPlants(this FarmPlot plot)
{
if (plot?.plantZones == null)
{
return false;
}
PlantZone[] plantZones = plot.plantZones;
for (int i = 0; i < plantZones.Length; i++)
{
Plant val = plantZones[i]?.plant;
if ((Object)(object)val != (Object)null && !val.isDead && !val.IsGrown())
{
return true;
}
}
return false;
}
}
[BepInPlugin("com.smrkn.island-plant-timers", "Plant Timers", "0.1.1")]
public class PlantTimerPlugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
internal static Color DryLabelColour = Color.red;
internal static Color HarvestLabelColour = Color.white;
private ConfigEntry<string> _harvestLabelColour;
private ConfigEntry<string> _dryLabelColour;
private Harmony _harmony;
private void Awake()
{
//IL_0075: 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_007a: 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_00e5: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Loading Plant Timers");
_harvestLabelColour = ((BaseUnityPlugin)this).Config.Bind<string>("Colour", "Harvest Timer", "1, 1, 1, 1", (ConfigDescription)null);
_harvestLabelColour.SettingChanged += UpdateHarvestLabelColour;
HarvestLabelColour = (Color)(((??)ParseColour(_harvestLabelColour.Value)) ?? Color.white);
_dryLabelColour = ((BaseUnityPlugin)this).Config.Bind<string>("Colour", "Watering Reminder", "0.95, 0.35, 0.45, 1.0", (ConfigDescription)null);
_dryLabelColour.SettingChanged += UpdateDryLabelColour;
DryLabelColour = (Color)(((??)ParseColour(_harvestLabelColour.Value)) ?? new Color(0.95f, 0.35f, 0.45f, 1f));
_harmony = new Harmony("com.smrkn.island-plant-timers");
_harmony.PatchAll(typeof(FarmPlotPatches));
_harmony.PatchAll(typeof(PlantPatches));
Logger.LogInfo((object)"Patches applied");
SceneManager.sceneLoaded += OnSceneLoaded;
}
private static Color? ParseColour(string colour)
{
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
try
{
string[] array = colour.Split(',');
if (array.Length != 3 && array.Length != 4)
{
return null;
}
if (!float.TryParse(array[0], out var result) || !float.TryParse(array[1], out var result2) || !float.TryParse(array[2], out var result3))
{
return null;
}
float result4 = 1f;
if (array.Length == 4 && !float.TryParse(array[3], out result4))
{
return null;
}
return new Color(result, result2, result3, result4);
}
catch
{
return null;
}
}
private static void UpdateExistingLabels<T>(ConfigEntry<string> configEntry, ref Color targetColor) where T : TooltipBase
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: 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)
Color? val = ParseColour(configEntry.Value);
if (!val.HasValue)
{
Logger.LogError((object)("Failed to parse colour for \"" + ((ConfigEntryBase)configEntry).Definition.Section + "/" + ((ConfigEntryBase)configEntry).Definition.Key + "\""));
}
else
{
targetColor = val.Value;
T[] array = Object.FindObjectsOfType<T>(true);
for (int i = 0; i < array.Length; i++)
{
array[i].LabelColour = val.Value;
}
}
}
private void UpdateHarvestLabelColour(object sender, EventArgs e)
{
UpdateExistingLabels<HarvestTooltip>(_harvestLabelColour, ref HarvestLabelColour);
}
private void UpdateDryLabelColour(object sender, EventArgs e)
{
UpdateExistingLabels<DryPlotTooltip>(_dryLabelColour, ref DryLabelColour);
}
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (((Scene)(ref scene)).name == "MainMenu")
{
DestroyAllTooltips();
}
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
if (_harvestLabelColour != null)
{
_harvestLabelColour.SettingChanged -= UpdateHarvestLabelColour;
}
if (_dryLabelColour != null)
{
_dryLabelColour.SettingChanged -= UpdateDryLabelColour;
}
DestroyAllTooltips();
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private static void DestroyAllTooltips()
{
HarvestTooltip[] array = Object.FindObjectsOfType<HarvestTooltip>(true);
foreach (HarvestTooltip harvestTooltip in array)
{
Logger.LogDebug((object)("Destroying " + ((Object)harvestTooltip).name));
Object.Destroy((Object)(object)harvestTooltip);
}
DryPlotTooltip[] array2 = Object.FindObjectsOfType<DryPlotTooltip>(true);
foreach (DryPlotTooltip dryPlotTooltip in array2)
{
Logger.LogDebug((object)("Destroying " + ((Object)dryPlotTooltip).name));
Object.Destroy((Object)(object)dryPlotTooltip);
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.smrkn.island-plant-timers";
public const string PLUGIN_NAME = "Plant Timers";
public const string PLUGIN_VERSION = "0.1.1";
}
}
namespace PlantTimers.Tooltips
{
[DisallowMultipleComponent]
public class DryPlotTooltip : TooltipBase
{
private FarmPlot _plot;
public void SetFarmPlot(FarmPlot plot)
{
_plot = plot;
}
private void Start()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
base.LabelColour = PlantTimerPlugin.DryLabelColour;
}
internal override bool ShouldBeVisible()
{
if (Object.op_Implicit((Object)(object)_plot) && _plot.isDry)
{
return _plot.HasGrowingPlants();
}
return false;
}
protected override string GetTooltip()
{
if (Object.op_Implicit((Object)(object)_plot) && _plot.isDry)
{
return "Needs Water!";
}
return null;
}
}
[DisallowMultipleComponent]
public class HarvestTooltip : TooltipBase
{
private Plant _plant;
private TimeData TimeLeftToGrow
{
get
{
//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_002c: 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_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
if (_plant.fullGrown)
{
return TimeData.zero;
}
TimeData currentTime = TimeData.currentTime;
float num = 0f;
PlantStage currentStage = _plant.currentStage;
TimeData endTime = currentStage.endTime;
if (((TimeData)(ref endTime)).timeInDays > ((TimeData)(ref currentTime)).timeInDays)
{
num += ((TimeData)(ref endTime)).timeInDays - ((TimeData)(ref currentTime)).timeInDays;
}
for (int i = _plant.stageNum + 1; i < Math.Max(0, _plant.growthStages.Length - 2); i++)
{
PlantStage val = _plant.growthStages[i];
TimeData duration = val.duration;
if (currentStage.enriched)
{
((TimeData)(ref duration))..ctor(((TimeData)(ref duration)).year / 2, ((TimeData)(ref duration)).month / 2, ((TimeData)(ref duration)).day / 2, ((TimeData)(ref duration)).hour / 2f);
}
if (currentStage.fastGrowthActive)
{
((TimeData)(ref duration)).timeInDays = ((TimeData)(ref duration)).timeInDays * val.fastGrowthTimeMultiplier;
}
num += ((TimeData)(ref duration)).timeInDays;
}
TimeData result = default(TimeData);
((TimeData)(ref result)).timeInDays = num;
return result;
}
}
public void SetPlant(Plant plant)
{
_plant = plant;
}
private void Start()
{
//IL_0001: 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_0027: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
base.LabelColour = PlantTimerPlugin.HarvestLabelColour;
Canvas.transform.localPosition = new Vector3(0f, ((int)_plant.zoneType == 1) ? 2.8f : TooltipBase.VerticalOffset, 0f);
}
internal override bool ShouldBeVisible()
{
if (!Object.op_Implicit((Object)(object)_plant))
{
return false;
}
if (_plant.farm == null)
{
return false;
}
if (_plant.farm.isDry)
{
return false;
}
return !_plant.IsGrown();
}
protected override string GetTooltip()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)_plant) || _plant.isDead || _plant.IsGrown())
{
return null;
}
return FormatTimeForTooltip(TimeLeftToGrow);
}
private static string FormatTimeForTooltip(TimeData remainingTime)
{
float num = 1440f / TimeData.DayLengthInMinutes;
TimeSpan timeSpan = TimeSpan.FromSeconds(((TimeData)(ref remainingTime)).timeInDays * 24f * 60f * 60f / num);
if (timeSpan.Hours > 0)
{
return $"{timeSpan.Hours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}";
}
if (timeSpan.Minutes > 0)
{
return $"{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}";
}
return $"{timeSpan.Seconds}s";
}
}
public abstract class TooltipBase : MonoBehaviour
{
protected GameObject Canvas;
private TextMeshPro _label;
private Camera _camera;
private Coroutine _updateLabel;
protected static float VerticalOffset => 1.5f;
public Color LabelColour
{
get
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return ((Graphic)_label).color;
}
set
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
((Graphic)_label).color = value;
}
}
private void Awake()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_004c: 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_0086: Expected O, but got Unknown
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
_camera = Camera.main;
Canvas = new GameObject("TooltipCanvas");
Canvas.transform.SetParent(((Component)this).transform, false);
Canvas.transform.localPosition = new Vector3(0f, VerticalOffset, 0f);
Canvas obj = Canvas.AddComponent<Canvas>();
obj.renderMode = (RenderMode)2;
obj.worldCamera = _camera;
obj.sortingOrder = 50;
GameObject val = new GameObject("TooltipText");
val.transform.SetParent(Canvas.transform, false);
val.transform.localPosition = Vector3.zero;
val.layer = LayerMask.NameToLayer("UI");
_label = val.AddComponent<TextMeshPro>();
((TMP_Text)_label).alignment = (TextAlignmentOptions)514;
((TMP_Text)_label).autoSizeTextContainer = false;
((TMP_Text)_label).enableWordWrapping = false;
((TMP_Text)_label).fontSize = 2f;
((Graphic)_label).color = Color.cyan;
((TMP_Text)_label).text = "";
Canvas.SetActive(false);
}
private void LateUpdate()
{
//IL_004a: 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)
if (_label != null && Object.op_Implicit((Object)(object)_camera) && Object.op_Implicit((Object)(object)Canvas) && Canvas.activeSelf)
{
_label.transform.parent.rotation = Quaternion.LookRotation(((Component)_camera).transform.forward);
}
}
protected void OnBecameVisible()
{
bool flag = ShouldBeVisible();
if (flag)
{
StartUpdateLoop();
}
Canvas.SetActive(flag);
}
protected void OnBecameInvisible()
{
Hide();
}
private void OnDestroy()
{
StopUpdateLoop();
if (Object.op_Implicit((Object)(object)Canvas))
{
Object.Destroy((Object)(object)Canvas);
Canvas = null;
}
}
private void StartUpdateLoop()
{
if (_updateLabel == null)
{
_updateLabel = ((MonoBehaviour)this).StartCoroutine(UpdateTooltipLoop());
}
}
private void StopUpdateLoop()
{
if (_updateLabel != null)
{
((MonoBehaviour)this).StopCoroutine(_updateLabel);
_updateLabel = null;
}
}
private IEnumerator UpdateTooltipLoop()
{
while (true)
{
string tooltip = GetTooltip();
if (tooltip == null)
{
break;
}
((TMP_Text)_label).text = tooltip;
yield return (object)new WaitForSecondsRealtime(1f);
}
Hide();
}
public void Show()
{
StartUpdateLoop();
Canvas.SetActive(true);
}
public void Hide()
{
StopUpdateLoop();
Canvas.SetActive(false);
}
[CanBeNull]
protected abstract string GetTooltip();
internal abstract bool ShouldBeVisible();
}
}
namespace PlantTimers.Patches
{
public static class FarmPlotPatches
{
private sealed class DryState
{
public bool WasDry;
}
private static readonly ConditionalWeakTable<FarmPlot, DryState> LastDryStates = new ConditionalWeakTable<FarmPlot, DryState>();
[HarmonyPostfix]
[HarmonyPatch(typeof(FarmPlot), "OnEnable")]
public static void OnEnablePostfix(FarmPlot __instance)
{
Renderer component = ((Component)__instance).GetComponent<Renderer>();
DryPlotTooltip dryPlotTooltip = ((Component)__instance).gameObject.GetComponent<DryPlotTooltip>() ?? ((Component)__instance).gameObject.AddComponent<DryPlotTooltip>();
dryPlotTooltip.SetFarmPlot(__instance);
if (Object.op_Implicit((Object)(object)component) && component.isVisible && dryPlotTooltip.ShouldBeVisible())
{
dryPlotTooltip.Show();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(FarmPlot), "Update")]
public static void UpdatePostfix(FarmPlot __instance)
{
if (!__instance.HasGrowingPlants())
{
DryPlotTooltip dryPlotTooltip = default(DryPlotTooltip);
if (((Component)__instance).gameObject.TryGetComponent<DryPlotTooltip>(ref dryPlotTooltip))
{
dryPlotTooltip.Hide();
}
return;
}
bool isDry = __instance.isDry;
if (!LastDryStates.TryGetValue(__instance, out var value))
{
LastDryStates.Add(__instance, new DryState
{
WasDry = !isDry
});
return;
}
DryPlotTooltip dryPlotTooltip2 = default(DryPlotTooltip);
if (!value.WasDry)
{
if (isDry)
{
if (((Component)__instance).gameObject.TryGetComponent<DryPlotTooltip>(ref dryPlotTooltip2))
{
dryPlotTooltip2.Show();
}
DisablePlantTimers(__instance);
}
}
else if (!isDry)
{
if (((Component)__instance).gameObject.TryGetComponent<DryPlotTooltip>(ref dryPlotTooltip2))
{
dryPlotTooltip2.Hide();
}
RestorePlantTimers(__instance);
}
value.WasDry = isDry;
}
private static void DisablePlantTimers(FarmPlot plot)
{
if (!Object.op_Implicit((Object)(object)plot) || plot.plantZones == null)
{
return;
}
PlantZone[] plantZones = plot.plantZones;
foreach (PlantZone val in plantZones)
{
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.plant) && !val.plant.isDead && !val.plant.IsGrown())
{
HarvestTooltip[] componentsInChildren = ((Component)val.plant).GetComponentsInChildren<HarvestTooltip>();
for (int j = 0; j < componentsInChildren.Length; j++)
{
componentsInChildren[j].Hide();
}
}
}
}
private static void RestorePlantTimers(FarmPlot plot)
{
if (!Object.op_Implicit((Object)(object)plot) || plot.plantZones == null)
{
return;
}
PlantZone[] plantZones = plot.plantZones;
foreach (PlantZone val in plantZones)
{
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.plant) && !val.plant.isDead && !val.plant.IsGrown())
{
HarvestTooltip[] componentsInChildren = ((Component)val.plant).GetComponentsInChildren<HarvestTooltip>();
for (int j = 0; j < componentsInChildren.Length; j++)
{
componentsInChildren[j].Show();
}
}
}
}
}
public static class PlantPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Plant), "OnEnable")]
public static void OnEnablePostfix(Plant __instance)
{
HarvestTooltip harvestTooltip = default(HarvestTooltip);
if (__instance.isDead)
{
PlantTimerPlugin.Logger.LogDebug((object)(((Object)__instance).name + " is dead"));
}
else if (__instance.IsGrown())
{
PlantTimerPlugin.Logger.LogDebug((object)(((Object)__instance).name + " is grown"));
}
else if (!((Component)__instance).gameObject.TryGetComponent<HarvestTooltip>(ref harvestTooltip))
{
HarvestTooltip harvestTooltip2 = ((Component)__instance).gameObject.AddComponent<HarvestTooltip>();
Renderer component = ((Component)__instance).GetComponent<Renderer>();
harvestTooltip2.SetPlant(__instance);
if (Object.op_Implicit((Object)(object)component) && component.isVisible && harvestTooltip2.ShouldBeVisible())
{
harvestTooltip2.Show();
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Plant), "SetGrowthStage")]
public static void SetGrowthStagePostfix(Plant __instance)
{
HarvestTooltip harvestTooltip = default(HarvestTooltip);
if (!__instance.isDead && Object.op_Implicit((Object)(object)__instance.currentStage.obj) && ((Object)__instance.currentStage.obj).name.Contains("Sparkle") && ((Component)__instance).TryGetComponent<HarvestTooltip>(ref harvestTooltip))
{
Object.Destroy((Object)(object)harvestTooltip);
}
}
[HarmonyPostfix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public static void SetIsDeadPostfix(Plant __instance)
{
if (__instance.isDead)
{
PlantTimerPlugin.Logger.LogDebug((object)(((Object)__instance).name + " was marked dead"));
HarvestTooltip harvestTooltip = default(HarvestTooltip);
if (((Component)__instance).TryGetComponent<HarvestTooltip>(ref harvestTooltip))
{
Object.Destroy((Object)(object)harvestTooltip);
}
}
}
}
}