

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerTasks;
using Il2CppScheduleOne.PlayerTasks.Tasks;
using Il2CppScheduleOne.StationFramework;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.Trash;
using Il2CppScheduleOne.UI.Stations;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SuperGrow;
using SuperGrow.Features;
using SuperGrow.Patches;
using SuperGrow.Utils;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "SuperGrow", "1.3.3", "HazDS", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SuperGrow_Il2Cpp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3299f0b98073429beb1d9d070075813648d324d0")]
[assembly: AssemblyProduct("SuperGrow_Il2Cpp")]
[assembly: AssemblyTitle("SuperGrow_Il2Cpp")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.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]
[Microsoft.CodeAnalysis.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]
[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 SuperGrow
{
internal static class SuperGrowSettings
{
private static bool _initialized;
private static MelonPreferences_Category? _prefsCategory;
public static MelonPreferences_Entry<int> PgrRequired { get; private set; }
public static MelonPreferences_Entry<int> SpeedGrowRequired { get; private set; }
public static MelonPreferences_Entry<int> FertilizerRequired { get; private set; }
public static MelonPreferences_Entry<int> OutputQuantity { get; private set; }
public static MelonPreferences_Entry<int> CookTimeMinutes { get; private set; }
public static MelonPreferences_Entry<float> YieldMultiplier { get; private set; }
public static MelonPreferences_Entry<float> InstantGrowth { get; private set; }
public static MelonPreferences_Entry<float> QualityChange { get; private set; }
public static void Initialize()
{
if (!_initialized)
{
_prefsCategory = MelonPreferences.CreateCategory("SuperGrow", "SuperGrow Settings");
PgrRequired = _prefsCategory.CreateEntry<int>("PgrRequired", 1, "PGR Required", "Amount of PGR needed per craft", false, false, (ValueValidator)null, (string)null);
SpeedGrowRequired = _prefsCategory.CreateEntry<int>("SpeedGrowRequired", 1, "Speed Grow Required", "Amount of Speed Grow needed per craft", false, false, (ValueValidator)null, (string)null);
FertilizerRequired = _prefsCategory.CreateEntry<int>("FertilizerRequired", 1, "Fertilizer Required", "Amount of Fertilizer needed per craft", false, false, (ValueValidator)null, (string)null);
OutputQuantity = _prefsCategory.CreateEntry<int>("OutputQuantity", 3, "Output Quantity", "Amount of SuperGrow produced per craft", false, false, (ValueValidator)null, (string)null);
CookTimeMinutes = _prefsCategory.CreateEntry<int>("CookTimeMinutes", 30, "Cook Time (Minutes)", "Chemistry Station cook time in in-game minutes", false, false, (ValueValidator)null, (string)null);
YieldMultiplier = _prefsCategory.CreateEntry<float>("YieldMultiplier", 1.5f, "Yield Multiplier", "Yield multiplier applied to plants (1.5 = 50% more yield)", false, false, (ValueValidator)null, (string)null);
InstantGrowth = _prefsCategory.CreateEntry<float>("InstantGrowth", 0.5f, "Instant Growth", "Instant growth progress (0.5 = 50% instant growth)", false, false, (ValueValidator)null, (string)null);
QualityChange = _prefsCategory.CreateEntry<float>("QualityChange", 1f, "Quality Change", "Quality modifier applied to plants", false, false, (ValueValidator)null, (string)null);
Clamp(PgrRequired, 1, 10);
Clamp(SpeedGrowRequired, 1, 10);
Clamp(FertilizerRequired, 1, 10);
Clamp(OutputQuantity, 1, 10);
Clamp(CookTimeMinutes, 1, 240);
Clamp(YieldMultiplier, 0.1f, 10f);
Clamp(InstantGrowth, 0f, 1f);
Clamp(QualityChange, -1f, 1f);
_initialized = true;
}
}
private static void Clamp(MelonPreferences_Entry<int> entry, int min, int max)
{
if (entry.Value < min)
{
entry.Value = min;
}
if (entry.Value > max)
{
entry.Value = max;
}
}
private static void Clamp(MelonPreferences_Entry<float> entry, float min, float max)
{
if (entry.Value < min)
{
entry.Value = min;
}
if (entry.Value > max)
{
entry.Value = max;
}
}
}
public class Core : MelonMod
{
private bool _itemsInitialized;
private int _nextInitAttemptTick;
private const int InitAttemptIntervalMs = 250;
public static Core Instance { get; private set; }
public override void OnInitializeMelon()
{
Instance = this;
SuperGrowSettings.Initialize();
MelonLogger.Msg("[SuperGrow v1.3.3] Initialized.");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
if (sceneName == "Menu")
{
_itemsInitialized = false;
_nextInitAttemptTick = 0;
ChemistryStationPatches.Reset();
}
}
public override void OnUpdate()
{
if (_itemsInitialized && (Object)(object)Registry.GetItem("supergrow") != (Object)null)
{
return;
}
if ((Object)(object)Registry.GetItem("supergrow") != (Object)null)
{
ChemistryStationPatches.EnsureAdditiveStationItemPrefabs();
_itemsInitialized = true;
}
else if (ShouldAttemptInitNow())
{
_itemsInitialized = false;
if (SuperGrowWorldState.IsRegistryReady())
{
SuperGrowCreator.CreateSuperGrowItem();
ChemistryStationPatches.EnsureAdditiveStationItemPrefabs();
_itemsInitialized = (Object)(object)Registry.GetItem("supergrow") != (Object)null;
}
}
}
private bool ShouldAttemptInitNow()
{
int tickCount = Environment.TickCount;
if (tickCount - _nextInitAttemptTick < 0)
{
return false;
}
_nextInitAttemptTick = tickCount + 250;
return true;
}
}
internal static class SuperGrowAssets
{
private const string IconResourceName = "SuperGrow.Assets.SuperGrow_Icon.png";
private const string LabelResourceName = "SuperGrow.Assets.SuperGrow_Label.png";
private static Sprite? _icon;
private static Texture2D? _labelTexture;
private static bool _loggedIconLoadException;
private static bool _loggedLabelLoadException;
private static bool _loggedImageLoadException;
public static Sprite? GetIconSprite()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_0071: 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)
if ((Object)(object)_icon != (Object)null)
{
return _icon;
}
try
{
byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Icon.png");
if (array == null)
{
return null;
}
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!TryLoadImage(val, array))
{
MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Icon.png");
return null;
}
((Object)val).name = "SuperGrow_Icon";
_icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
return _icon;
}
catch (Exception ex)
{
if (!_loggedIconLoadException)
{
_loggedIconLoadException = true;
MelonLogger.Warning("Failed to load icon: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
return null;
}
}
public static Texture2D? GetLabelTexture()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
if ((Object)(object)_labelTexture != (Object)null)
{
return _labelTexture;
}
try
{
byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Label.png");
if (array == null)
{
return null;
}
_labelTexture = new Texture2D(2, 2, (TextureFormat)4, false);
if (!TryLoadImage(_labelTexture, array))
{
MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Label.png");
_labelTexture = null;
return null;
}
((Object)_labelTexture).name = "SuperGrow_Label";
return _labelTexture;
}
catch (Exception ex)
{
if (!_loggedLabelLoadException)
{
_loggedLabelLoadException = true;
MelonLogger.Error("Failed to load SuperGrow label texture: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
_labelTexture = null;
return null;
}
}
private static byte[]? LoadEmbeddedResourceBytes(string resourceName)
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
if (stream == null)
{
MelonLogger.Warning("Could not find embedded resource: " + resourceName);
return null;
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
private static bool TryLoadImage(Texture2D texture, byte[] bytes)
{
try
{
Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule") ?? typeof(Texture2D).Assembly.GetType("UnityEngine.ImageConversion");
if (type == null)
{
return false;
}
MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
bool flag = default(bool);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.Name != "LoadImage")
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if ((parameters.Length != 2 && parameters.Length != 3) || parameters[0].ParameterType != typeof(Texture2D))
{
continue;
}
Type parameterType = parameters[1].ParameterType;
object obj;
if (parameterType == typeof(byte[]))
{
obj = bytes;
}
else
{
if (!parameterType.IsGenericType || !(parameterType.GetGenericTypeDefinition() == typeof(Il2CppStructArray<>)))
{
continue;
}
Il2CppStructArray<byte> val = new Il2CppStructArray<byte>((long)bytes.Length);
for (int j = 0; j < bytes.Length; j++)
{
((Il2CppArrayBase<byte>)(object)val)[j] = bytes[j];
}
obj = val;
}
object obj2 = ((parameters.Length != 3) ? methodInfo.Invoke(null, new object[2] { texture, obj }) : methodInfo.Invoke(null, new object[3] { texture, obj, false }));
int num;
if (obj2 is bool)
{
flag = (bool)obj2;
num = 1;
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
return false;
}
catch (Exception ex)
{
if (!_loggedImageLoadException)
{
_loggedImageLoadException = true;
MelonLogger.Warning("Failed to decode embedded image bytes via ImageConversion.LoadImage: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
return false;
}
}
}
internal static class SuperGrowWorldState
{
private static bool _loggedReady;
private static bool _ready;
private static bool _loggedRegistryReadyException;
public static bool IsRegistryReady()
{
try
{
if (_ready)
{
return true;
}
ItemDefinition item = Registry.GetItem("pgr");
AdditiveDefinition obj = ((item != null) ? ((Il2CppObjectBase)item).TryCast<AdditiveDefinition>() : null);
ItemDefinition item2 = Registry.GetItem("speedgrow");
AdditiveDefinition val = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<AdditiveDefinition>() : null);
ItemDefinition item3 = Registry.GetItem("fertilizer");
AdditiveDefinition val2 = ((item3 != null) ? ((Il2CppObjectBase)item3).TryCast<AdditiveDefinition>() : null);
if ((Object)(object)obj == (Object)null && (Object)(object)val == (Object)null && (Object)(object)val2 == (Object)null)
{
return false;
}
_ready = true;
if (!_loggedReady)
{
_loggedReady = true;
}
return true;
}
catch (Exception ex)
{
if (!_loggedRegistryReadyException)
{
_loggedRegistryReadyException = true;
MelonLogger.Warning("Registry readiness check failed: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
return false;
}
}
}
}
namespace SuperGrow.Utils
{
public static class Constants
{
public static class Game
{
public const string GAME_STUDIO = "TVGS";
public const string GAME_NAME = "Schedule I";
}
public static class Additives
{
public const string PGR = "pgr";
public const string SPEED_GROW = "speedgrow";
public const string FERTILIZER = "fertilizer";
}
public static class ItemIds
{
public const string SUPER_GROW = "supergrow";
}
public static class DefaultEffects
{
public const float YIELD_MULTIPLIER = 1.5f;
public const float INSTANT_GROWTH = 0.5f;
public const float QUALITY_CHANGE = 1f;
}
public const string MOD_NAME = "SuperGrow";
public const string MOD_VERSION = "1.3.3";
public const string MOD_AUTHOR = "HazDS";
public const string PREFERENCES_CATEGORY = "SuperGrow";
}
internal static class SuperGrowVisuals
{
internal static readonly Color PourColor = new Color(0.4f, 0.2f, 0.6f, 1f);
internal static readonly Color LidTint = new Color(0.6f, 0.4f, 0.8f, 1f);
internal static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
{
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
if (renderers == null)
{
return;
}
Texture2D labelTexture = SuperGrowAssets.GetLabelTexture();
if ((Object)(object)labelTexture == (Object)null)
{
MelonLogger.Warning("SuperGrow label texture is null, cannot apply");
return;
}
try
{
foreach (Renderer val in renderers)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
string text = ((Object)val).name.ToLowerInvariant();
bool flag = text.Contains("label");
if (!flag)
{
foreach (Material item in (Il2CppArrayBase<Material>)(object)val.sharedMaterials)
{
if ((Object)(object)item != (Object)null && ((Object)item).name.ToLowerInvariant().Contains("label"))
{
flag = true;
break;
}
}
}
bool flag2 = text.Contains("lid");
if (!flag2)
{
foreach (Material item2 in (Il2CppArrayBase<Material>)(object)val.sharedMaterials)
{
if ((Object)(object)item2 != (Object)null && ((Object)item2).name.ToLowerInvariant().Contains("lid"))
{
flag2 = true;
break;
}
}
}
if (flag)
{
Il2CppReferenceArray<Material> materials = val.materials;
for (int j = 0; j < ((Il2CppArrayBase<Material>)(object)materials).Length; j++)
{
Material val2 = ((Il2CppArrayBase<Material>)(object)materials)[j];
if (!((Object)(object)val2 == (Object)null))
{
val2.mainTexture = (Texture)(object)labelTexture;
if (val2.HasProperty("_BaseMap"))
{
val2.SetTexture("_BaseMap", (Texture)(object)labelTexture);
}
if (val2.HasProperty("_MainTex"))
{
val2.SetTexture("_MainTex", (Texture)(object)labelTexture);
}
}
}
val.materials = materials;
}
else
{
if (!flag2)
{
continue;
}
Il2CppReferenceArray<Material> materials2 = val.materials;
for (int k = 0; k < ((Il2CppArrayBase<Material>)(object)materials2).Length; k++)
{
Material val3 = ((Il2CppArrayBase<Material>)(object)materials2)[k];
if (!((Object)(object)val3 == (Object)null))
{
val3.color = LidTint;
if (val3.HasProperty("_BaseColor"))
{
val3.SetColor("_BaseColor", LidTint);
}
if (val3.HasProperty("_Color"))
{
val3.SetColor("_Color", LidTint);
}
}
}
val.materials = materials2;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow materials: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
}
}
namespace SuperGrow.Patches
{
[HarmonyPatch]
internal static class ChemistryStationPatches
{
private readonly struct PendingTrashReskin
{
public string TrashId { get; }
public string AdditiveId { get; }
public PendingTrashReskin(string trashId, string additiveId)
{
TrashId = trashId;
AdditiveId = additiveId;
}
}
[CompilerGenerated]
private sealed class <DelayedChemistryIngredientAudit>d__42 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedChemistryIngredientAudit>d__42(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.4f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static StationRecipe? _superGrowRecipe;
private static bool _additivesPatched;
private static bool _loggedMissingStationItemTemplate;
private static bool _loggedRegistryStart;
private static bool _loggedRecipeNotReady;
private static int _superGrowBeginAuditUntilTick;
private static int _superGrowBeginAuditSeq;
private static ChemistryStation? _superGrowBeginStation;
private static int _superGrowBeginStationSeq;
private static string? _lastSelectedRecipeProductId;
private static string? _lastSelectedRecipeTitle;
private static string? _lastSelectedRecipeId;
private static int _lastSelectedAtTick;
private const string PgrBottleTrashId = "supergrow_pgr_bottle";
private const string SpeedGrowBottleTrashId = "supergrow_speedgrow_bottle";
private const string FertilizerBottleTrashId = "supergrow_fertilizer_bottle";
private const string SuperGrowBottleTrashId = "supergrow_bottle";
private static GameObject? _prefabCacheRoot;
private static bool _baseStationItemPrefabsEnsured;
private static readonly Dictionary<string, StationItem> _stationItemPrefabByAdditiveId = new Dictionary<string, StationItem>();
private static int _il2cppTrashPrefabsEnsuredForManagerId;
private static readonly Dictionary<string, TrashItem> _il2cppBottleTrashPrefabByAdditiveId = new Dictionary<string, TrashItem>(StringComparer.OrdinalIgnoreCase);
private static bool _loggedIl2CppTrashPrefabInjectionException;
private static bool _loggedIl2CppTrashPrefabEnsureException;
private static int _pendingStationTrashReskinExpireTick;
private static readonly List<PendingTrashReskin> _pendingStationTrashReskins = new List<PendingTrashReskin>();
private static readonly Dictionary<string, GameObject> _pourablePrefabs = new Dictionary<string, GameObject>();
private static readonly Dictionary<string, Color> _additiveColors = new Dictionary<string, Color>
{
{
"pgr",
new Color(1f, 0.506f, 0.506f, 1f)
},
{
"speedgrow",
new Color(0.506f, 0.812f, 1f, 1f)
},
{
"fertilizer",
new Color(0.639f, 1f, 0.506f, 1f)
},
{
"supergrow",
SuperGrowVisuals.PourColor
}
};
private const float LiquidScale = 0.65f;
public static void Reset()
{
_superGrowRecipe = null;
_additivesPatched = false;
_loggedMissingStationItemTemplate = false;
_loggedRegistryStart = false;
_loggedRecipeNotReady = false;
_baseStationItemPrefabsEnsured = false;
_il2cppTrashPrefabsEnsuredForManagerId = 0;
}
private static Transform GetOrCreatePrefabCacheRoot()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
if ((Object)(object)_prefabCacheRoot != (Object)null)
{
return _prefabCacheRoot.transform;
}
_prefabCacheRoot = new GameObject("SuperGrow_PrefabCache");
Object.DontDestroyOnLoad((Object)(object)_prefabCacheRoot);
_prefabCacheRoot.SetActive(false);
return _prefabCacheRoot.transform;
}
private static bool TryGetBottleTrashId(string additiveId, out string trashId)
{
trashId = null;
if (string.Equals(additiveId, "pgr", StringComparison.OrdinalIgnoreCase))
{
trashId = "supergrow_pgr_bottle";
return true;
}
if (string.Equals(additiveId, "speedgrow", StringComparison.OrdinalIgnoreCase))
{
trashId = "supergrow_speedgrow_bottle";
return true;
}
if (string.Equals(additiveId, "fertilizer", StringComparison.OrdinalIgnoreCase))
{
trashId = "supergrow_fertilizer_bottle";
return true;
}
return false;
}
private static void EnsureIl2CppBottleTrashPrefabsInjected(TrashManager manager)
{
TrashManager manager2 = manager;
if ((Object)(object)manager2 == (Object)null)
{
return;
}
int instanceID = ((Object)manager2).GetInstanceID();
if (instanceID != 0 && instanceID == _il2cppTrashPrefabsEnsuredForManagerId)
{
return;
}
try
{
CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
TrashItem baseTrash = manager2.GetTrashPrefab("acid");
TrashItem pgrTrash = manager2.GetTrashPrefab("pgr");
if ((Object)(object)baseTrash == (Object)null || (Object)(object)((Component)baseTrash).gameObject == (Object)null)
{
return;
}
List<TrashItem> additions = new List<TrashItem>();
Ensure("pgr", "supergrow_pgr_bottle");
Ensure("speedgrow", "supergrow_speedgrow_bottle");
Ensure("fertilizer", "supergrow_fertilizer_bottle");
Ensure("supergrow", "supergrow_bottle");
if (additions.Count == 0)
{
_il2cppTrashPrefabsEnsuredForManagerId = instanceID;
return;
}
Il2CppReferenceArray<TrashItem> trashPrefabs = manager2.TrashPrefabs;
int num = ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs)?.Length ?? 0;
TrashItem[] array = (TrashItem[])(object)new TrashItem[num + additions.Count];
for (int i = 0; i < num; i++)
{
array[i] = ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs)[i];
}
for (int j = 0; j < additions.Count; j++)
{
array[num + j] = additions[j];
}
manager2.TrashPrefabs = new Il2CppReferenceArray<TrashItem>(array);
_il2cppTrashPrefabsEnsuredForManagerId = instanceID;
void Ensure(string additiveId, string newId)
{
try
{
if (!((Object)(object)manager2.GetTrashPrefab(newId) != (Object)null))
{
if (_il2cppBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out TrashItem value) && (Object)(object)value != (Object)null)
{
value.ID = newId;
additions.Add(value);
}
else
{
Transform orCreatePrefabCacheRoot = GetOrCreatePrefabCacheRoot();
GameObject val = ((string.Equals(additiveId, "supergrow", StringComparison.OrdinalIgnoreCase) && (Object)(object)pgrTrash != (Object)null && (Object)(object)((Component)pgrTrash).gameObject != (Object)null) ? ((Component)pgrTrash).gameObject : ((Component)baseTrash).gameObject);
GameObject val2 = Object.Instantiate<GameObject>(val);
((Object)val2).name = "SuperGrow_" + additiveId + "_TrashPrefab";
val2.SetActive(val.activeSelf);
val2.transform.SetParent(orCreatePrefabCacheRoot, false);
Object.DontDestroyOnLoad((Object)(object)val2);
TrashItem component = val2.GetComponent<TrashItem>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val2);
}
else
{
component.ID = newId;
SwapTrashItemVisualsById(additiveId, component);
_il2cppBottleTrashPrefabByAdditiveId[additiveId] = component;
additions.Add(component);
}
}
}
}
catch (Exception ex2)
{
if (!_loggedIl2CppTrashPrefabEnsureException)
{
_loggedIl2CppTrashPrefabEnsureException = true;
MelonLogger.Warning("Failed to create SuperGrow trash prefab for '" + additiveId + "' (IL2CPP): " + ex2.Message);
MelonLogger.Warning(ex2.StackTrace ?? "<no stack trace>");
}
}
}
}
catch (Exception ex)
{
if (!_loggedIl2CppTrashPrefabInjectionException)
{
_loggedIl2CppTrashPrefabInjectionException = true;
MelonLogger.Warning("Failed to inject SuperGrow trash prefabs (IL2CPP): " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
}
}
private static void TryAssignIl2CppBottleTrashPrefab(string additiveId, StationItem stationItem)
{
if ((Object)(object)stationItem == (Object)null || !TryGetBottleTrashId(additiveId, out string trashId))
{
return;
}
try
{
TrashManager val = Object.FindObjectOfType<TrashManager>();
if ((Object)(object)val == (Object)null)
{
return;
}
EnsureIl2CppBottleTrashPrefabsInjected(val);
if (_il2cppBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out TrashItem value) && (Object)(object)value != (Object)null)
{
stationItem.TrashPrefab = value;
return;
}
TrashItem trashPrefab = val.GetTrashPrefab(trashId);
if ((Object)(object)trashPrefab != (Object)null)
{
stationItem.TrashPrefab = trashPrefab;
}
}
catch
{
}
}
private static void ApplyIl2CppBottleTrashPrefabsToCachedStationItems(TrashManager manager)
{
if ((Object)(object)manager == (Object)null)
{
return;
}
try
{
EnsureIl2CppBottleTrashPrefabsInjected(manager);
string[] array = new string[3] { "pgr", "speedgrow", "fertilizer" };
foreach (string text in array)
{
if (_stationItemPrefabByAdditiveId.TryGetValue(text, out StationItem value) && (Object)(object)value != (Object)null)
{
TryAssignIl2CppBottleTrashPrefab(text, value);
}
}
}
catch
{
}
}
public static bool EnsureAdditiveStationItemPrefabs()
{
if (!TryGetStationItemTemplate(out StationItem templateStationItem))
{
return false;
}
CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
TrashManager val = Object.FindObjectOfType<TrashManager>();
if ((Object)(object)val != (Object)null)
{
EnsureIl2CppBottleTrashPrefabsInjected(val);
}
if (!_baseStationItemPrefabsEnsured)
{
_baseStationItemPrefabsEnsured = true;
EnsureStationItemPrefabForAdditive("pgr", templateStationItem, overrideIfPresent: true);
EnsureStationItemPrefabForAdditive("speedgrow", templateStationItem, overrideIfPresent: true);
EnsureStationItemPrefabForAdditive("fertilizer", templateStationItem, overrideIfPresent: true);
}
EnsureStationItemPrefabForAdditive("supergrow", templateStationItem, overrideIfPresent: true);
return true;
}
private static void EnsureStationItemPrefabForAdditive(string additiveId, StationItem templateStationItem, bool overrideIfPresent)
{
ItemDefinition item = Registry.GetItem(additiveId);
StorableItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<StorableItemDefinition>() : null);
if ((Object)(object)val == (Object)null || (!overrideIfPresent && (Object)(object)val.StationItem != (Object)null))
{
return;
}
if (_stationItemPrefabByAdditiveId.TryGetValue(additiveId, out StationItem value) && (Object)(object)value != (Object)null)
{
val.StationItem = value;
TryAssignIl2CppBottleTrashPrefab(additiveId, value);
return;
}
Transform orCreatePrefabCacheRoot = GetOrCreatePrefabCacheRoot();
GameObject val2 = Object.Instantiate<GameObject>(((Component)templateStationItem).gameObject);
((Object)val2).name = "SuperGrow_StationItemPrefab_" + additiveId;
val2.SetActive(true);
val2.transform.SetParent(orCreatePrefabCacheRoot, false);
Object.DontDestroyOnLoad((Object)(object)val2);
StationItem component = val2.GetComponent<StationItem>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val2);
return;
}
TryAssignIl2CppBottleTrashPrefab(additiveId, component);
_stationItemPrefabByAdditiveId[additiveId] = component;
val.StationItem = component;
SwapStationItemVisualsById(additiveId, component);
}
[HarmonyPatch(typeof(TrashManager), "Start")]
[HarmonyPostfix]
private static void TrashManager_Start_Postfix_Il2Cpp(TrashManager __instance)
{
EnsureIl2CppBottleTrashPrefabsInjected(__instance);
ApplyIl2CppBottleTrashPrefabsToCachedStationItems(__instance);
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Awake")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_Awake_Prefix(ChemistryStationCanvas __instance)
{
try
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
SuperGrowCreator.CreateSuperGrowItem();
if ((Object)(object)_superGrowRecipe == (Object)null)
{
CreateSuperGrowRecipe();
}
if ((Object)(object)_superGrowRecipe == (Object)null)
{
if (!_loggedRecipeNotReady)
{
_loggedRecipeNotReady = true;
MelonLogger.Warning("SuperGrow recipe is null; cannot add to chemistry station yet");
}
return;
}
List<StationRecipe> recipes = __instance.Recipes;
if (recipes == null)
{
if (!_loggedRecipeNotReady)
{
_loggedRecipeNotReady = true;
MelonLogger.Warning("ChemistryStationCanvas.Recipes is null; cannot add SuperGrow recipe");
}
}
else if (!recipes.Contains(_superGrowRecipe))
{
recipes.Add(_superGrowRecipe);
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to add SuperGrow recipe: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Awake")]
[HarmonyPostfix]
private static void ChemistryStationCanvas_Awake_Postfix(ChemistryStationCanvas __instance)
{
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Start")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_Start_Prefix(ChemistryStationCanvas __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null))
{
SetupAdditiveStationItems();
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to add SuperGrow recipe: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Start")]
[HarmonyPostfix]
private static void ChemistryStationCanvas_Start_Postfix(ChemistryStationCanvas __instance)
{
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Open")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_Open_PrefixAudit(ChemistryStationCanvas __instance, ChemistryStation station)
{
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "SetSelectedRecipe")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_SetSelectedRecipe_Prefix(ChemistryStationCanvas __instance, StationRecipeEntry entry)
{
try
{
StationRecipe val = ((entry != null) ? entry.Recipe : null);
string text = SafeGetProductId(val);
if (!(text == "<null>") && !(text == "<error>"))
{
_lastSelectedRecipeProductId = text;
_lastSelectedRecipeTitle = SafeGetRecipeEntryTitle(entry);
_lastSelectedRecipeId = (((Object)(object)val == (Object)null) ? "<null>" : SafeGetStationRecipeId(val));
_lastSelectedAtTick = Environment.TickCount;
}
}
catch
{
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "BeginButtonPressed")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_BeginButtonPressed_Prefix(ChemistryStationCanvas __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null))
{
StationRecipeEntry? obj = TryGetSelectedRecipeEntry(__instance);
string text = SafeGetProductId((obj != null) ? obj.Recipe : null);
if (text == "<null>" || text == "<error>")
{
text = _lastSelectedRecipeProductId ?? text;
}
if (!(text != "supergrow"))
{
_superGrowBeginAuditSeq++;
_superGrowBeginAuditUntilTick = Environment.TickCount + 10000;
_superGrowBeginStation = __instance.ChemistryStation;
_superGrowBeginStationSeq = _superGrowBeginAuditSeq;
_ = _superGrowBeginAuditSeq;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("SuperGrow Begin audit failed (Prefix): " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "BeginButtonPressed")]
[HarmonyPostfix]
private static void ChemistryStationCanvas_BeginButtonPressed_Postfix(ChemistryStationCanvas __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null) && !TickExpired(_superGrowBeginAuditUntilTick))
{
int superGrowBeginAuditSeq = _superGrowBeginAuditSeq;
ChemistryStation val = __instance.ChemistryStation;
if ((Object)(object)val == (Object)null && _superGrowBeginStationSeq == superGrowBeginAuditSeq)
{
val = _superGrowBeginStation;
}
_ = (Object)(object)val != (Object)null;
}
}
catch (Exception ex)
{
MelonLogger.Error("SuperGrow Begin audit failed (Postfix): " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
private static bool TickExpired(int untilTick)
{
return Environment.TickCount - untilTick >= 0;
}
[IteratorStateMachine(typeof(<DelayedChemistryIngredientAudit>d__42))]
private static IEnumerator DelayedChemistryIngredientAudit(int seq, ChemistryStation station)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedChemistryIngredientAudit>d__42(0);
}
private static StationRecipeEntry? TryGetSelectedRecipeEntry(ChemistryStationCanvas canvas)
{
try
{
Type typeFromHandle = typeof(ChemistryStationCanvas);
FieldInfo field = typeFromHandle.GetField("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object? value = field.GetValue(canvas);
return (StationRecipeEntry?)((value is StationRecipeEntry) ? value : null);
}
PropertyInfo property = typeFromHandle.GetProperty("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null)
{
object? value2 = property.GetValue(canvas);
return (StationRecipeEntry?)((value2 is StationRecipeEntry) ? value2 : null);
}
FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (!(fieldInfo.FieldType != typeof(StationRecipeEntry)) && !(fieldInfo.Name == "RecipeEntryPrefab") && !(fieldInfo.Name == "InProgressRecipeEntry"))
{
object? value3 = fieldInfo.GetValue(canvas);
StationRecipeEntry val = (StationRecipeEntry)((value3 is StationRecipeEntry) ? value3 : null);
if ((Object)(object)((val != null) ? val.Recipe : null) != (Object)null)
{
return val;
}
}
}
}
catch
{
}
return null;
}
private static string SafeGetRecipeEntryTitle(StationRecipeEntry? entry)
{
try
{
return ((Object)(object)((entry != null) ? entry.TitleLabel : null) == (Object)null) ? "<null>" : (((TMP_Text)entry.TitleLabel).text ?? "<null>");
}
catch
{
return "<error>";
}
}
private static bool SafeGetBeginInteractable(ChemistryStationCanvas canvas)
{
try
{
return (Object)(object)canvas.BeginButton != (Object)null && ((Selectable)canvas.BeginButton).interactable;
}
catch
{
return false;
}
}
private static string SafeGetProductId(StationRecipe? recipe)
{
try
{
object obj;
if (recipe == null)
{
obj = null;
}
else
{
ItemQuantity product = recipe.Product;
if (product == null)
{
obj = null;
}
else
{
ItemDefinition item = product.Item;
obj = ((item != null) ? ((BaseItemDefinition)item).ID : null);
}
}
if (obj == null)
{
obj = "<null>";
}
return (string)obj;
}
catch
{
return "<error>";
}
}
private static string SafeGetStationRecipeId(StationRecipe recipe)
{
try
{
return recipe.RecipeID ?? "<null>";
}
catch
{
return "<error>";
}
}
private static void CreateSuperGrowRecipe()
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Expected O, but got Unknown
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Expected O, but got Unknown
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Expected O, but got Unknown
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
ItemDefinition item = Registry.GetItem("pgr");
ItemDefinition item2 = Registry.GetItem("speedgrow");
ItemDefinition item3 = Registry.GetItem("fertilizer");
ItemDefinition item4 = Registry.GetItem("supergrow");
if ((Object)(object)item == (Object)null || (Object)(object)item2 == (Object)null || (Object)(object)item3 == (Object)null)
{
MelonLogger.Error("Could not find one or more base additive definitions");
return;
}
if ((Object)(object)item4 == (Object)null)
{
SuperGrowCreator.CreateSuperGrowItem();
item4 = Registry.GetItem("supergrow");
if ((Object)(object)item4 == (Object)null)
{
MelonLogger.Warning("Could not find SuperGrow definition; will retry when registry is ready");
return;
}
}
_superGrowRecipe = ScriptableObject.CreateInstance<StationRecipe>();
_superGrowRecipe.IsDiscovered = true;
_superGrowRecipe.RecipeTitle = "SuperGrow";
_superGrowRecipe.CookTime_Mins = SuperGrowSettings.CookTimeMinutes.Value;
_superGrowRecipe.Unlocked = true;
List<IngredientQuantity> val = new List<IngredientQuantity>();
IngredientQuantity val2 = new IngredientQuantity();
List<ItemDefinition> val3 = new List<ItemDefinition>();
val3.Add(item);
val2.Items = val3;
val2.Quantity = SuperGrowSettings.PgrRequired.Value;
val.Add(val2);
IngredientQuantity val4 = new IngredientQuantity();
List<ItemDefinition> val5 = new List<ItemDefinition>();
val5.Add(item2);
val4.Items = val5;
val4.Quantity = SuperGrowSettings.SpeedGrowRequired.Value;
val.Add(val4);
IngredientQuantity val6 = new IngredientQuantity();
List<ItemDefinition> val7 = new List<ItemDefinition>();
val7.Add(item3);
val6.Items = val7;
val6.Quantity = SuperGrowSettings.FertilizerRequired.Value;
val.Add(val6);
_superGrowRecipe.Ingredients = val;
_superGrowRecipe.Product = new ItemQuantity
{
Item = item4,
Quantity = SuperGrowSettings.OutputQuantity.Value
};
_superGrowRecipe.FinalLiquidColor = SuperGrowVisuals.PourColor;
}
private static bool TryGetStationItemTemplate(out StationItem templateStationItem)
{
templateStationItem = null;
string[] array = new string[4] { "acid", "pgr", "speedgrow", "fertilizer" };
string[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
ItemDefinition item = Registry.GetItem(array2[i]);
StorableItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<StorableItemDefinition>() : null);
if ((Object)(object)((val != null) ? val.StationItem : null) != (Object)null)
{
templateStationItem = val.StationItem;
return true;
}
}
if (!_loggedMissingStationItemTemplate)
{
_loggedMissingStationItemTemplate = true;
MelonLogger.Warning("Could not find any StationItem template (acid/pgr/speedgrow/fertilizer)");
array2 = array;
foreach (string text in array2)
{
ItemDefinition item2 = Registry.GetItem(text);
StorableItemDefinition val2 = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<StorableItemDefinition>() : null);
MelonLogger.Warning($"{text}: def={(((Object)(object)val2 == (Object)null) ? "<null>" : ((object)val2).GetType().FullName)} stationItem={(((Object)(object)((val2 != null) ? val2.StationItem : null) == (Object)null) ? "<null>" : ((object)val2.StationItem).GetType().FullName)}");
}
}
return false;
}
[HarmonyPatch(typeof(Registry), "Start")]
[HarmonyPostfix]
private static void Registry_Start_Postfix()
{
if (_loggedRegistryStart)
{
return;
}
_loggedRegistryStart = true;
try
{
SuperGrowCreator.CreateSuperGrowItem();
EnsureAdditiveStationItemPrefabs();
}
catch (Exception ex)
{
MelonLogger.Error("Registry.Start hook failed: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
public static void SetupAdditiveStationItems()
{
if (_additivesPatched)
{
return;
}
try
{
CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
if (EnsureAdditiveStationItemPrefabs())
{
_additivesPatched = true;
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to set up additive StationItems: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
[HarmonyPatch(typeof(StoredItem), "InitializeStoredItem")]
[HarmonyPostfix]
private static void StoredItem_InitializeStoredItem_Postfix(StoredItem __instance, StorableItemInstance _item)
{
try
{
object obj;
if (_item == null)
{
obj = null;
}
else
{
ItemDefinition definition = ((ItemInstance)_item).Definition;
obj = ((definition != null) ? ((BaseItemDefinition)definition).ID : null);
}
if (!((string?)obj != "supergrow"))
{
ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)__instance).GetComponentsInChildren<Renderer>(true)));
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow visuals to stored item: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
private static void SetPendingStationTrashReskins(List<PendingTrashReskin> reskins)
{
_pendingStationTrashReskins.Clear();
if (reskins.Count > 0)
{
_pendingStationTrashReskins.AddRange(reskins);
_pendingStationTrashReskinExpireTick = Environment.TickCount + 5000;
}
else
{
_pendingStationTrashReskinExpireTick = 0;
}
}
[HarmonyPatch(typeof(ChemistryStation), "CreateTrash")]
[HarmonyPrefix]
private static void ChemistryStation_CreateTrash_Prefix(ChemistryStation __instance, List<StationItem> mixerItems)
{
try
{
if (mixerItems == null)
{
return;
}
List<PendingTrashReskin> list = new List<PendingTrashReskin>();
for (int i = 0; i < mixerItems.Count; i++)
{
StationItem val = mixerItems[i];
if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
{
continue;
}
string text = TryParseAdditiveIdFromStationItemName(((Object)((Component)val).gameObject).name);
if (text != null)
{
string text2 = (((Object)(object)val.TrashPrefab != (Object)null) ? val.TrashPrefab.ID : null);
if (!string.IsNullOrEmpty(text2))
{
list.Add(new PendingTrashReskin(text2, text));
}
}
}
SetPendingStationTrashReskins(list);
}
catch
{
}
}
private static string? TryParseAdditiveIdFromStationItemName(string? stationItemName)
{
if (string.IsNullOrEmpty(stationItemName))
{
return null;
}
int num = stationItemName.IndexOf("SuperGrow_StationItemPrefab_", StringComparison.OrdinalIgnoreCase);
if (num < 0)
{
return null;
}
num += "SuperGrow_StationItemPrefab_".Length;
if (num >= stationItemName.Length)
{
return null;
}
int num2 = stationItemName.IndexOf('(', num);
if (num2 < 0)
{
num2 = stationItemName.Length;
}
string text = stationItemName.Substring(num, num2 - num).Trim();
if (text.Length == 0)
{
return null;
}
text = text.ToLowerInvariant();
switch (text)
{
default:
return null;
case "pgr":
case "speedgrow":
case "fertilizer":
case "supergrow":
return text;
}
}
[HarmonyPatch(typeof(TrashItem), "Start")]
[HarmonyPostfix]
private static void TrashItem_Start_Postfix(TrashItem __instance)
{
try
{
if (_pendingStationTrashReskins.Count == 0)
{
return;
}
if (_pendingStationTrashReskinExpireTick != 0 && Environment.TickCount - _pendingStationTrashReskinExpireTick >= 0)
{
_pendingStationTrashReskins.Clear();
_pendingStationTrashReskinExpireTick = 0;
return;
}
string iD = __instance.ID;
if (string.IsNullOrEmpty(iD))
{
return;
}
for (int i = 0; i < _pendingStationTrashReskins.Count; i++)
{
PendingTrashReskin pendingTrashReskin = _pendingStationTrashReskins[i];
if (!(pendingTrashReskin.TrashId != iD))
{
_pendingStationTrashReskins.RemoveAt(i);
SwapTrashItemVisualsById(pendingTrashReskin.AdditiveId, __instance);
break;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow visuals to trash item: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
private static bool IsChemistryBeakerFillable(Fillable fillable)
{
if ((Object)(object)fillable == (Object)null)
{
return false;
}
LiquidContainer liquidContainer = fillable.LiquidContainer;
if ((Object)(object)liquidContainer == (Object)null || (Object)(object)((Component)liquidContainer).transform == (Object)null)
{
return false;
}
Transform transform = ((Component)liquidContainer).transform;
if (!string.Equals(((Object)transform).name, "Liquid", StringComparison.OrdinalIgnoreCase))
{
return false;
}
Transform parent = transform.parent;
if ((Object)(object)parent == (Object)null || !string.Equals(((Object)parent).name, "Beaker", StringComparison.OrdinalIgnoreCase))
{
return false;
}
Transform parent2 = parent.parent;
if ((Object)(object)parent2 == (Object)null || !((Object)parent2).name.StartsWith("Beaker", StringComparison.OrdinalIgnoreCase))
{
return false;
}
Transform val = parent2;
while ((Object)(object)val != (Object)null)
{
if (((Object)val).name != null && ((Object)val).name.IndexOf("ChemistryStation", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
val = val.parent;
}
return false;
}
private static void CachePourablePrefab(string additiveId, string pourablePath)
{
if (!_pourablePrefabs.ContainsKey(additiveId))
{
GameObject val = Resources.Load<GameObject>(pourablePath);
if ((Object)(object)val != (Object)null)
{
_pourablePrefabs[additiveId] = val;
}
else
{
MelonLogger.Warning("Could not load pourable prefab for " + additiveId + " at " + pourablePath);
}
}
}
private static Transform? FindStationItemBottleContainer(StationItem stationItem)
{
Transform val = ((Component)stationItem).transform.Find("Pourable");
if ((Object)(object)val == (Object)null)
{
return null;
}
Transform result = null;
int childCount = val.childCount;
for (int i = 0; i < childCount; i++)
{
Transform child = val.GetChild(i);
if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Bottle", StringComparison.OrdinalIgnoreCase) >= 0)
{
result = child;
break;
}
}
return result;
}
private static void SwapBottleMeshesAndMaterials(GameObject templatePrefab, Transform targetRoot)
{
Il2CppArrayBase<MeshFilter> componentsInChildren = templatePrefab.GetComponentsInChildren<MeshFilter>(true);
foreach (MeshFilter componentsInChild in ((Component)targetRoot).GetComponentsInChildren<MeshFilter>(true))
{
if ((Object)(object)componentsInChild == (Object)null)
{
continue;
}
string text = ((Object)componentsInChild).name.ToLowerInvariant();
foreach (MeshFilter item in componentsInChildren)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
string text2 = ((Object)item).name.ToLowerInvariant();
if ((text.Contains("body") && text2.Contains("body")) || (text.Contains("label") && text2.Contains("label")) || (text.Contains("lid") && text2.Contains("lid")))
{
componentsInChild.sharedMesh = item.sharedMesh;
MeshRenderer component = ((Component)componentsInChild).GetComponent<MeshRenderer>();
MeshRenderer component2 = ((Component)item).GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
{
((Renderer)component).sharedMaterials = ((Renderer)component2).sharedMaterials;
}
break;
}
}
}
}
private static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
{
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(renderers);
}
private static void SetupAdditiveStationItem(string additiveId, StationItem templateStationItem)
{
ItemDefinition item = Registry.GetItem(additiveId);
StorableItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<StorableItemDefinition>() : null);
if ((Object)(object)val == (Object)null)
{
MelonLogger.Warning("Could not find additive: " + additiveId);
}
else if (!((Object)(object)val.StationItem != (Object)null))
{
val.StationItem = templateStationItem;
}
}
private static void SwapTrashItemVisualsById(string id, TrashItem trashItem)
{
if ((Object)(object)trashItem == (Object)null || string.IsNullOrEmpty(id))
{
return;
}
bool flag = id == "supergrow";
if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
{
return;
}
GameObject value = null;
if (flag)
{
_pourablePrefabs.TryGetValue("pgr", out value);
}
else
{
_pourablePrefabs.TryGetValue(id, out value);
}
if ((Object)(object)value == (Object)null)
{
return;
}
try
{
if (!((Object)(object)((Component)trashItem).transform == (Object)null))
{
SwapBottleMeshesAndMaterials(value, ((Component)trashItem).transform);
if (flag)
{
ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)trashItem).GetComponentsInChildren<Renderer>(true)));
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to swap trash visuals for " + id + ": " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
private static void SwapStationItemVisualsById(string id, StationItem stationItem)
{
//IL_0115: 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_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)stationItem == (Object)null || string.IsNullOrEmpty(id))
{
return;
}
bool flag = id == "supergrow";
if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
{
return;
}
GameObject value = null;
if (flag)
{
_pourablePrefabs.TryGetValue("pgr", out value);
}
else
{
_pourablePrefabs.TryGetValue(id, out value);
}
if ((Object)(object)value == (Object)null)
{
return;
}
try
{
Transform val = FindStationItemBottleContainer(stationItem);
if ((Object)(object)val == (Object)null)
{
return;
}
SwapBottleMeshesAndMaterials(value, val);
if (flag)
{
ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)val).GetComponentsInChildren<Renderer>(true)));
}
object obj;
if (!((Object)(object)((Component)stationItem).transform != (Object)null))
{
obj = null;
}
else
{
Transform obj2 = ((Component)stationItem).transform.Find("Pourable");
obj = ((obj2 != null) ? ((Component)obj2).GetComponent<PourableModule>() : null);
}
PourableModule val2 = (PourableModule)obj;
if ((Object)(object)val2 != (Object)null && (Object)(object)val2.LiquidContainer != (Object)null)
{
LiquidContainer liquidContainer = val2.LiquidContainer;
if ((Object)(object)liquidContainer.LiquidVolume != (Object)null)
{
Transform transform = ((Component)liquidContainer.LiquidVolume).transform;
transform.localScale *= 0.65f;
}
liquidContainer.MaxLevel *= 0.65f;
if (_additiveColors.TryGetValue(id, out var value2))
{
val2.LiquidType = id;
val2.LiquidColor = value2;
val2.PourParticlesColor = value2;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to swap station item visuals for " + id + ": " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
private static void SwapStationItemVisualsById(string id, StationItem stationItem, StorableItemDefinition itemDef)
{
if (!((Object)(object)stationItem == (Object)null) && !((Object)(object)itemDef == (Object)null))
{
SwapStationItemVisualsById(id, stationItem);
}
}
}
[HarmonyPatch]
internal static class GrowContainerPatches
{
private const string SuperGrowBottleTrashId = "supergrow_bottle";
private static bool _loggedGrowContainerTrashPrefabAssignException;
private static readonly Vector3 HiddenPrefabPosition = new Vector3(100000f, 100000f, 100000f);
private static Pourable? _superGrowPourablePrefab;
private static int _removeItemDepth;
private static bool _shouldReskinNextTrashSpawn;
private static readonly HashSet<string> _loggedReskinnedTrashIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private static void InjectSuperGrowIntoAllowedAdditives(GrowContainer container)
{
try
{
ItemDefinition item = Registry.GetItem("supergrow");
AdditiveDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<AdditiveDefinition>() : null);
if ((Object)(object)val == (Object)null)
{
return;
}
Il2CppReferenceArray<AdditiveDefinition> allowedAdditives = container.AllowedAdditives;
int num = ((Il2CppArrayBase<AdditiveDefinition>)(object)allowedAdditives)?.Length ?? 0;
for (int i = 0; i < num; i++)
{
AdditiveDefinition val2 = ((Il2CppArrayBase<AdditiveDefinition>)(object)allowedAdditives)[i];
if ((Object)(object)val2 != (Object)null && ((BaseItemDefinition)val2).ID == "supergrow")
{
return;
}
}
AdditiveDefinition[] array = (AdditiveDefinition[])(object)new AdditiveDefinition[num + 1];
for (int j = 0; j < num; j++)
{
array[j] = ((Il2CppArrayBase<AdditiveDefinition>)(object)allowedAdditives)[j];
}
array[num] = val;
container.AllowedAdditives = new Il2CppReferenceArray<AdditiveDefinition>(array);
}
catch (Exception ex)
{
MelonLogger.Error("Failed to inject SuperGrow into AllowedAdditives: " + ex.Message);
}
}
[HarmonyPatch(typeof(GrowContainer), "InitializeGridItem")]
[HarmonyPrefix]
private static void GrowContainer_InitializeGridItem_Prefix(GrowContainer __instance)
{
InjectSuperGrowIntoAllowedAdditives(__instance);
}
private static Pourable? GetOrCreateSuperGrowPourablePrefab(Pourable basePrefab)
{
//IL_006a: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_superGrowPourablePrefab != (Object)null && (Object)(object)((Component)_superGrowPourablePrefab).gameObject != (Object)null)
{
return _superGrowPourablePrefab;
}
if ((Object)(object)basePrefab == (Object)null || (Object)(object)((Component)basePrefab).gameObject == (Object)null)
{
return null;
}
try
{
GameObject val = Object.Instantiate<GameObject>(((Component)basePrefab).gameObject);
((Object)val).name = "SuperGrow_PourablePrefab";
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)val);
val.transform.position = HiddenPrefabPosition;
if (!val.activeSelf)
{
val.SetActive(true);
}
Pourable component = val.GetComponent<Pourable>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val);
return null;
}
PourableAdditive component2 = val.GetComponent<PourableAdditive>();
if ((Object)(object)component2 != (Object)null)
{
component2.LiquidColor = SuperGrowVisuals.PourColor;
}
foreach (ParticleSystem componentsInChild in val.GetComponentsInChildren<ParticleSystem>(true))
{
if (!((Object)(object)componentsInChild == (Object)null))
{
componentsInChild.main.startColor = MinMaxGradient.op_Implicit(SuperGrowVisuals.PourColor);
}
}
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(val.GetComponentsInChildren<Renderer>(true)));
try
{
TrashManager val2 = Object.FindObjectOfType<TrashManager>();
if ((Object)(object)val2 != (Object)null)
{
TrashItem trashPrefab = val2.GetTrashPrefab("supergrow_bottle");
if ((Object)(object)trashPrefab != (Object)null)
{
component.TrashItem = trashPrefab;
}
}
}
catch (Exception ex)
{
if (!_loggedGrowContainerTrashPrefabAssignException)
{
_loggedGrowContainerTrashPrefabAssignException = true;
MelonLogger.Warning("Failed to assign SuperGrow trash prefab to grow-container pourable: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
}
_superGrowPourablePrefab = component;
return _superGrowPourablePrefab;
}
catch (Exception ex2)
{
MelonLogger.Error("Failed to create SuperGrow pourable prefab: " + ex2.Message);
MelonLogger.Error(ex2.StackTrace);
return null;
}
}
[HarmonyPatch(typeof(Equippable_Additive), "Equip")]
[HarmonyPostfix]
private static void Equippable_Additive_Equip_Postfix(Equippable_Additive __instance, ItemInstance item)
{
try
{
object obj;
if (item == null)
{
obj = null;
}
else
{
ItemDefinition definition = item.Definition;
obj = ((definition != null) ? ((BaseItemDefinition)definition).ID : null);
}
if ((string?)obj != "supergrow")
{
return;
}
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)__instance).GetComponentsInChildren<Renderer>(true)));
Pourable pourablePrefab = ((Equippable_Pourable)__instance).PourablePrefab;
if (!((Object)(object)pourablePrefab == (Object)null))
{
Pourable orCreateSuperGrowPourablePrefab = GetOrCreateSuperGrowPourablePrefab(pourablePrefab);
if ((Object)(object)orCreateSuperGrowPourablePrefab != (Object)null)
{
((Equippable_Pourable)__instance).PourablePrefab = orCreateSuperGrowPourablePrefab;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow grow-container pour visuals: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
[HarmonyPatch(typeof(GrowContainerPourTask), "RemoveItem")]
[HarmonyPrefix]
private static void GrowContainerPourTask_RemoveItem_Prefix()
{
_removeItemDepth++;
}
[HarmonyPatch(typeof(GrowContainerPourTask), "RemoveItem")]
[HarmonyFinalizer]
private static void GrowContainerPourTask_RemoveItem_Finalizer(Exception __exception)
{
_removeItemDepth = Math.Max(0, _removeItemDepth - 1);
_shouldReskinNextTrashSpawn = false;
}
[HarmonyPatch(typeof(PlayerInventory), "RemoveAmountOfItem")]
[HarmonyPrefix]
private static void PlayerInventory_RemoveAmountOfItem_Prefix(string ID)
{
if (_removeItemDepth > 0 && string.Equals(ID, "supergrow", StringComparison.OrdinalIgnoreCase))
{
_shouldReskinNextTrashSpawn = true;
}
}
[HarmonyPatch(typeof(TrashManager), "CreateAndReturnTrashItem")]
[HarmonyPostfix]
private static void TrashManager_CreateAndReturnTrashItem_Postfix_GrowContainerReskin(string id, object __result)
{
if (!_shouldReskinNextTrashSpawn)
{
return;
}
_shouldReskinNextTrashSpawn = false;
try
{
if (__result != null)
{
object? obj = AccessTools.Property(__result.GetType(), "gameObject")?.GetValue(__result);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(val.GetComponentsInChildren<Renderer>(true)));
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to reskin grow-container trash for SuperGrow: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
}
}
namespace SuperGrow.Features
{
internal static class SuperGrowCreator
{
private static AdditiveDefinition? _superGrowDefinition;
private static bool _loggedMissingAdditiveTemplate;
private static bool _loggedRegistryUnavailable;
public static void CreateSuperGrowItem()
{
try
{
if (!((Object)(object)Registry.GetItem("supergrow") != (Object)null))
{
CreateAdditiveDefinition();
_ = (Object)(object)Registry.GetItem("supergrow") != (Object)null;
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to create SuperGrow item: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
private static void CreateAdditiveDefinition()
{
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
//IL_02cf: Expected O, but got Unknown
if (!Singleton<Registry>.InstanceExists && !_loggedRegistryUnavailable)
{
_loggedRegistryUnavailable = true;
MelonLogger.Warning("Registry singleton is not available yet; will retry");
}
Registry val = Singleton<Registry>.Instance;
if ((Object)(object)val == (Object)null)
{
val = Object.FindObjectOfType<Registry>();
}
if ((Object)(object)val == (Object)null)
{
if (!_loggedRegistryUnavailable)
{
_loggedRegistryUnavailable = true;
MelonLogger.Warning("Registry instance is not available; cannot add SuperGrow definition yet.");
}
return;
}
ItemDefinition item = Registry.GetItem("pgr");
object obj = ((item != null) ? ((Il2CppObjectBase)item).TryCast<AdditiveDefinition>() : null);
if (obj == null)
{
ItemDefinition item2 = Registry.GetItem("speedgrow");
obj = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<AdditiveDefinition>() : null);
if (obj == null)
{
ItemDefinition item3 = Registry.GetItem("fertilizer");
obj = ((item3 != null) ? ((Il2CppObjectBase)item3).TryCast<AdditiveDefinition>() : null);
}
}
AdditiveDefinition val2 = (AdditiveDefinition)obj;
if ((Object)(object)val2 == (Object)null)
{
if (!_loggedMissingAdditiveTemplate)
{
_loggedMissingAdditiveTemplate = true;
ItemDefinition item4 = Registry.GetItem("pgr");
ItemDefinition item5 = Registry.GetItem("speedgrow");
ItemDefinition item6 = Registry.GetItem("fertilizer");
MelonLogger.Error("Could not find any existing additive to clone from!");
MelonLogger.Error("pgr=" + (((Object)(object)item4 == (Object)null) ? "<null>" : ((object)item4).GetType().FullName));
MelonLogger.Error("speedgrow=" + (((Object)(object)item5 == (Object)null) ? "<null>" : ((object)item5).GetType().FullName));
MelonLogger.Error("fertilizer=" + (((Object)(object)item6 == (Object)null) ? "<null>" : ((object)item6).GetType().FullName));
}
return;
}
if ((Object)(object)_superGrowDefinition != (Object)null)
{
val.AddToRegistry((ItemDefinition)(object)_superGrowDefinition);
return;
}
_superGrowDefinition = ScriptableObject.CreateInstance<AdditiveDefinition>();
((BaseItemDefinition)_superGrowDefinition).Category = ((BaseItemDefinition)val2).Category;
((BaseItemDefinition)_superGrowDefinition).StackLimit = ((BaseItemDefinition)val2).StackLimit;
((ItemDefinition)_superGrowDefinition).AvailableInDemo = ((ItemDefinition)val2).AvailableInDemo;
((BaseItemDefinition)_superGrowDefinition).UsableInFilters = ((BaseItemDefinition)val2).UsableInFilters;
((StorableItemDefinition)_superGrowDefinition).ResellMultiplier = ((StorableItemDefinition)val2).ResellMultiplier;
((StorableItemDefinition)_superGrowDefinition).ShopCategories = ((StorableItemDefinition)val2).ShopCategories;
((BaseItemDefinition)_superGrowDefinition).legalStatus = ((BaseItemDefinition)val2).legalStatus;
((ItemDefinition)_superGrowDefinition).Equippable = ((ItemDefinition)val2).Equippable;
((StorableItemDefinition)_superGrowDefinition).StoredItem = ((StorableItemDefinition)val2).StoredItem;
((StorableItemDefinition)_superGrowDefinition).StationItem = ((StorableItemDefinition)val2).StationItem;
((StorableItemDefinition)_superGrowDefinition).BasePurchasePrice = ((StorableItemDefinition)val2).BasePurchasePrice;
((BaseItemDefinition)_superGrowDefinition).ID = "supergrow";
((BaseItemDefinition)_superGrowDefinition).Name = "SuperGrow";
((BaseItemDefinition)_superGrowDefinition).Description = "A powerful growth enhancer combining the effects of PGR, Speed Grow, and Fertilizer. Apply to plants for increased yield, faster growth, and improved quality.";
((Object)_superGrowDefinition).name = "SuperGrow";
Sprite iconSprite = SuperGrowAssets.GetIconSprite();
((BaseItemDefinition)_superGrowDefinition).Icon = iconSprite ?? ((BaseItemDefinition)val2).Icon;
if ((Object)(object)val2.DisplayMaterial != (Object)null)
{
Material displayMaterial = new Material(val2.DisplayMaterial)
{
color = new Color(0.3f, 0.9f, 0.3f, 1f)
};
_superGrowDefinition.DisplayMaterial = displayMaterial;
}
_superGrowDefinition.QualityChange = SuperGrowSettings.QualityChange.Value;
_superGrowDefinition.YieldMultiplier = SuperGrowSettings.YieldMultiplier.Value;
_superGrowDefinition.InstantGrowth = SuperGrowSettings.InstantGrowth.Value;
val.AddToRegistry((ItemDefinition)(object)_superGrowDefinition);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using ScheduleOne;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.DevUtilities;
using ScheduleOne.Equipping;
using ScheduleOne.Growing;
using ScheduleOne.ItemFramework;
using ScheduleOne.ObjectScripts;
using ScheduleOne.PlayerScripts;
using ScheduleOne.PlayerTasks;
using ScheduleOne.PlayerTasks.Tasks;
using ScheduleOne.StationFramework;
using ScheduleOne.Storage;
using ScheduleOne.Trash;
using ScheduleOne.UI.Stations;
using SuperGrow;
using SuperGrow.Features;
using SuperGrow.Patches;
using SuperGrow.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "SuperGrow", "1.3.3", "HazDS", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SuperGrow")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3299f0b98073429beb1d9d070075813648d324d0")]
[assembly: AssemblyProduct("SuperGrow")]
[assembly: AssemblyTitle("SuperGrow")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.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]
[Microsoft.CodeAnalysis.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]
[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 SuperGrow
{
internal static class SuperGrowSettings
{
private static bool _initialized;
private static MelonPreferences_Category? _prefsCategory;
public static MelonPreferences_Entry<int> PgrRequired { get; private set; }
public static MelonPreferences_Entry<int> SpeedGrowRequired { get; private set; }
public static MelonPreferences_Entry<int> FertilizerRequired { get; private set; }
public static MelonPreferences_Entry<int> OutputQuantity { get; private set; }
public static MelonPreferences_Entry<int> CookTimeMinutes { get; private set; }
public static MelonPreferences_Entry<float> YieldMultiplier { get; private set; }
public static MelonPreferences_Entry<float> InstantGrowth { get; private set; }
public static MelonPreferences_Entry<float> QualityChange { get; private set; }
public static void Initialize()
{
if (!_initialized)
{
_prefsCategory = MelonPreferences.CreateCategory("SuperGrow", "SuperGrow Settings");
PgrRequired = _prefsCategory.CreateEntry<int>("PgrRequired", 1, "PGR Required", "Amount of PGR needed per craft", false, false, (ValueValidator)null, (string)null);
SpeedGrowRequired = _prefsCategory.CreateEntry<int>("SpeedGrowRequired", 1, "Speed Grow Required", "Amount of Speed Grow needed per craft", false, false, (ValueValidator)null, (string)null);
FertilizerRequired = _prefsCategory.CreateEntry<int>("FertilizerRequired", 1, "Fertilizer Required", "Amount of Fertilizer needed per craft", false, false, (ValueValidator)null, (string)null);
OutputQuantity = _prefsCategory.CreateEntry<int>("OutputQuantity", 3, "Output Quantity", "Amount of SuperGrow produced per craft", false, false, (ValueValidator)null, (string)null);
CookTimeMinutes = _prefsCategory.CreateEntry<int>("CookTimeMinutes", 30, "Cook Time (Minutes)", "Chemistry Station cook time in in-game minutes", false, false, (ValueValidator)null, (string)null);
YieldMultiplier = _prefsCategory.CreateEntry<float>("YieldMultiplier", 1.5f, "Yield Multiplier", "Yield multiplier applied to plants (1.5 = 50% more yield)", false, false, (ValueValidator)null, (string)null);
InstantGrowth = _prefsCategory.CreateEntry<float>("InstantGrowth", 0.5f, "Instant Growth", "Instant growth progress (0.5 = 50% instant growth)", false, false, (ValueValidator)null, (string)null);
QualityChange = _prefsCategory.CreateEntry<float>("QualityChange", 1f, "Quality Change", "Quality modifier applied to plants", false, false, (ValueValidator)null, (string)null);
Clamp(PgrRequired, 1, 10);
Clamp(SpeedGrowRequired, 1, 10);
Clamp(FertilizerRequired, 1, 10);
Clamp(OutputQuantity, 1, 10);
Clamp(CookTimeMinutes, 1, 240);
Clamp(YieldMultiplier, 0.1f, 10f);
Clamp(InstantGrowth, 0f, 1f);
Clamp(QualityChange, -1f, 1f);
_initialized = true;
}
}
private static void Clamp(MelonPreferences_Entry<int> entry, int min, int max)
{
if (entry.Value < min)
{
entry.Value = min;
}
if (entry.Value > max)
{
entry.Value = max;
}
}
private static void Clamp(MelonPreferences_Entry<float> entry, float min, float max)
{
if (entry.Value < min)
{
entry.Value = min;
}
if (entry.Value > max)
{
entry.Value = max;
}
}
}
public class Core : MelonMod
{
private bool _itemsInitialized;
private int _nextInitAttemptTick;
private const int InitAttemptIntervalMs = 250;
public static Core Instance { get; private set; }
public override void OnInitializeMelon()
{
Instance = this;
SuperGrowSettings.Initialize();
MelonLogger.Msg("[SuperGrow v1.3.3] Initialized.");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
if (sceneName == "Menu")
{
_itemsInitialized = false;
_nextInitAttemptTick = 0;
ChemistryStationPatches.Reset();
}
}
public override void OnUpdate()
{
if (_itemsInitialized && (Object)(object)Registry.GetItem("supergrow") != (Object)null)
{
return;
}
if ((Object)(object)Registry.GetItem("supergrow") != (Object)null)
{
_itemsInitialized = true;
}
else if (ShouldAttemptInitNow())
{
_itemsInitialized = false;
if (SuperGrowWorldState.IsRegistryReady())
{
SuperGrowCreator.CreateSuperGrowItem();
_itemsInitialized = (Object)(object)Registry.GetItem("supergrow") != (Object)null;
}
}
}
private bool ShouldAttemptInitNow()
{
int tickCount = Environment.TickCount;
if (tickCount - _nextInitAttemptTick < 0)
{
return false;
}
_nextInitAttemptTick = tickCount + 250;
return true;
}
}
internal static class SuperGrowAssets
{
private const string IconResourceName = "SuperGrow.Assets.SuperGrow_Icon.png";
private const string LabelResourceName = "SuperGrow.Assets.SuperGrow_Label.png";
private static Sprite? _icon;
private static Texture2D? _labelTexture;
private static bool _loggedIconLoadException;
private static bool _loggedLabelLoadException;
private static bool _loggedImageLoadException;
public static Sprite? GetIconSprite()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_0071: 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)
if ((Object)(object)_icon != (Object)null)
{
return _icon;
}
try
{
byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Icon.png");
if (array == null)
{
return null;
}
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!TryLoadImage(val, array))
{
MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Icon.png");
return null;
}
((Object)val).name = "SuperGrow_Icon";
_icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
return _icon;
}
catch (Exception ex)
{
if (!_loggedIconLoadException)
{
_loggedIconLoadException = true;
MelonLogger.Warning("Failed to load icon: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
return null;
}
}
public static Texture2D? GetLabelTexture()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
if ((Object)(object)_labelTexture != (Object)null)
{
return _labelTexture;
}
try
{
byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Label.png");
if (array == null)
{
return null;
}
_labelTexture = new Texture2D(2, 2, (TextureFormat)4, false);
if (!TryLoadImage(_labelTexture, array))
{
MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Label.png");
_labelTexture = null;
return null;
}
((Object)_labelTexture).name = "SuperGrow_Label";
return _labelTexture;
}
catch (Exception ex)
{
if (!_loggedLabelLoadException)
{
_loggedLabelLoadException = true;
MelonLogger.Error("Failed to load SuperGrow label texture: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
_labelTexture = null;
return null;
}
}
private static byte[]? LoadEmbeddedResourceBytes(string resourceName)
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
if (stream == null)
{
MelonLogger.Warning("Could not find embedded resource: " + resourceName);
return null;
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
private static bool TryLoadImage(Texture2D texture, byte[] bytes)
{
try
{
Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule") ?? typeof(Texture2D).Assembly.GetType("UnityEngine.ImageConversion");
if (type == null)
{
return false;
}
MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
bool flag = default(bool);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.Name != "LoadImage")
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if ((parameters.Length == 2 || parameters.Length == 3) && !(parameters[0].ParameterType != typeof(Texture2D)) && parameters[1].ParameterType == typeof(byte[]))
{
object obj = ((parameters.Length != 3) ? methodInfo.Invoke(null, new object[2] { texture, bytes }) : methodInfo.Invoke(null, new object[3] { texture, bytes, false }));
int num;
if (obj is bool)
{
flag = (bool)obj;
num = 1;
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
}
return false;
}
catch (Exception ex)
{
if (!_loggedImageLoadException)
{
_loggedImageLoadException = true;
MelonLogger.Warning("Failed to decode embedded image bytes via ImageConversion.LoadImage: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
return false;
}
}
}
internal static class SuperGrowWorldState
{
private static bool _loggedReady;
private static bool _ready;
private static bool _loggedRegistryReadyException;
public static bool IsRegistryReady()
{
try
{
if (_ready)
{
return true;
}
ItemDefinition item = Registry.GetItem("pgr");
ItemDefinition obj = ((item is AdditiveDefinition) ? item : null);
ItemDefinition item2 = Registry.GetItem("speedgrow");
AdditiveDefinition val = (AdditiveDefinition)(object)((item2 is AdditiveDefinition) ? item2 : null);
ItemDefinition item3 = Registry.GetItem("fertilizer");
AdditiveDefinition val2 = (AdditiveDefinition)(object)((item3 is AdditiveDefinition) ? item3 : null);
if ((Object)(object)obj == (Object)null && (Object)(object)val == (Object)null && (Object)(object)val2 == (Object)null)
{
return false;
}
_ready = true;
if (!_loggedReady)
{
_loggedReady = true;
}
return true;
}
catch (Exception ex)
{
if (!_loggedRegistryReadyException)
{
_loggedRegistryReadyException = true;
MelonLogger.Warning("Registry readiness check failed: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
return false;
}
}
}
}
namespace SuperGrow.Utils
{
public static class Constants
{
public static class Game
{
public const string GAME_STUDIO = "TVGS";
public const string GAME_NAME = "Schedule I";
}
public static class Additives
{
public const string PGR = "pgr";
public const string SPEED_GROW = "speedgrow";
public const string FERTILIZER = "fertilizer";
}
public static class ItemIds
{
public const string SUPER_GROW = "supergrow";
}
public static class DefaultEffects
{
public const float YIELD_MULTIPLIER = 1.5f;
public const float INSTANT_GROWTH = 0.5f;
public const float QUALITY_CHANGE = 1f;
}
public const string MOD_NAME = "SuperGrow";
public const string MOD_VERSION = "1.3.3";
public const string MOD_AUTHOR = "HazDS";
public const string PREFERENCES_CATEGORY = "SuperGrow";
}
internal static class SuperGrowVisuals
{
internal static readonly Color PourColor = new Color(0.4f, 0.2f, 0.6f, 1f);
internal static readonly Color LidTint = new Color(0.6f, 0.4f, 0.8f, 1f);
internal static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
{
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
if (renderers == null)
{
return;
}
Texture2D labelTexture = SuperGrowAssets.GetLabelTexture();
if ((Object)(object)labelTexture == (Object)null)
{
MelonLogger.Warning("SuperGrow label texture is null, cannot apply");
return;
}
try
{
foreach (Renderer val in renderers)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
string text = ((Object)val).name.ToLowerInvariant();
bool flag = text.Contains("label");
if (!flag)
{
Material[] sharedMaterials = val.sharedMaterials;
foreach (Material val2 in sharedMaterials)
{
if ((Object)(object)val2 != (Object)null && ((Object)val2).name.ToLowerInvariant().Contains("label"))
{
flag = true;
break;
}
}
}
bool flag2 = text.Contains("lid");
if (!flag2)
{
Material[] sharedMaterials = val.sharedMaterials;
foreach (Material val3 in sharedMaterials)
{
if ((Object)(object)val3 != (Object)null && ((Object)val3).name.ToLowerInvariant().Contains("lid"))
{
flag2 = true;
break;
}
}
}
if (flag)
{
Material[] materials = val.materials;
foreach (Material val4 in materials)
{
if (!((Object)(object)val4 == (Object)null))
{
val4.mainTexture = (Texture)(object)labelTexture;
if (val4.HasProperty("_BaseMap"))
{
val4.SetTexture("_BaseMap", (Texture)(object)labelTexture);
}
if (val4.HasProperty("_MainTex"))
{
val4.SetTexture("_MainTex", (Texture)(object)labelTexture);
}
}
}
val.materials = materials;
}
else
{
if (!flag2)
{
continue;
}
Material[] materials2 = val.materials;
foreach (Material val5 in materials2)
{
if (!((Object)(object)val5 == (Object)null))
{
val5.color = LidTint;
if (val5.HasProperty("_BaseColor"))
{
val5.SetColor("_BaseColor", LidTint);
}
if (val5.HasProperty("_Color"))
{
val5.SetColor("_Color", LidTint);
}
}
}
val.materials = materials2;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow materials: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
}
}
namespace SuperGrow.Patches
{
[HarmonyPatch]
internal static class ChemistryStationPatches
{
private readonly struct PendingTrashReskin
{
public string TrashId { get; }
public string AdditiveId { get; }
public PendingTrashReskin(string trashId, string additiveId)
{
TrashId = trashId;
AdditiveId = additiveId;
}
}
[CompilerGenerated]
private sealed class <DelayedChemistryIngredientAudit>d__23 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedChemistryIngredientAudit>d__23(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.4f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static StationRecipe? _superGrowRecipe;
private static bool _additivesPatched;
private static bool _loggedMissingStationItemTemplate;
private static bool _loggedRegistryStart;
private static bool _loggedRecipeNotReady;
private static int _superGrowBeginAuditUntilTick;
private static int _superGrowBeginAuditSeq;
private static ChemistryStation? _superGrowBeginStation;
private static int _superGrowBeginStationSeq;
private static string? _lastSelectedRecipeProductId;
private static string? _lastSelectedRecipeTitle;
private static string? _lastSelectedRecipeId;
private static int _lastSelectedAtTick;
private const string PgrBottleTrashId = "supergrow_pgr_bottle";
private const string SpeedGrowBottleTrashId = "supergrow_speedgrow_bottle";
private const string FertilizerBottleTrashId = "supergrow_fertilizer_bottle";
private const string SuperGrowBottleTrashId = "supergrow_bottle";
private static bool _monoTrashPrefabsInjected;
private static readonly Dictionary<string, TrashItem> _monoBottleTrashPrefabByAdditiveId = new Dictionary<string, TrashItem>();
private static bool _loggedMonoTrashPrefabInjectionException;
private static int _pendingStationTrashReskinExpireTick;
private static readonly List<PendingTrashReskin> _pendingStationTrashReskins = new List<PendingTrashReskin>();
private static readonly Dictionary<string, GameObject> _pourablePrefabs = new Dictionary<string, GameObject>();
private static readonly Dictionary<string, Color> _additiveColors = new Dictionary<string, Color>
{
{
"pgr",
new Color(1f, 0.506f, 0.506f, 1f)
},
{
"speedgrow",
new Color(0.506f, 0.812f, 1f, 1f)
},
{
"fertilizer",
new Color(0.639f, 1f, 0.506f, 1f)
},
{
"supergrow",
SuperGrowVisuals.PourColor
}
};
private const float LiquidScale = 0.65f;
public static void Reset()
{
_superGrowRecipe = null;
_additivesPatched = false;
_loggedMissingStationItemTemplate = false;
_loggedRegistryStart = false;
_loggedRecipeNotReady = false;
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Awake")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_Awake_Prefix(ChemistryStationCanvas __instance)
{
try
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
SuperGrowCreator.CreateSuperGrowItem();
if ((Object)(object)_superGrowRecipe == (Object)null)
{
CreateSuperGrowRecipe();
}
if ((Object)(object)_superGrowRecipe == (Object)null)
{
if (!_loggedRecipeNotReady)
{
_loggedRecipeNotReady = true;
MelonLogger.Warning("SuperGrow recipe is null; cannot add to chemistry station yet");
}
return;
}
List<StationRecipe> recipes = __instance.Recipes;
if (recipes == null)
{
if (!_loggedRecipeNotReady)
{
_loggedRecipeNotReady = true;
MelonLogger.Warning("ChemistryStationCanvas.Recipes is null; cannot add SuperGrow recipe");
}
}
else if (!recipes.Contains(_superGrowRecipe))
{
recipes.Add(_superGrowRecipe);
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to add SuperGrow recipe: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Awake")]
[HarmonyPostfix]
private static void ChemistryStationCanvas_Awake_Postfix(ChemistryStationCanvas __instance)
{
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Start")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_Start_Prefix(ChemistryStationCanvas __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null))
{
SetupAdditiveStationItems();
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to add SuperGrow recipe: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Start")]
[HarmonyPostfix]
private static void ChemistryStationCanvas_Start_Postfix(ChemistryStationCanvas __instance)
{
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "Open")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_Open_PrefixAudit(ChemistryStationCanvas __instance, ChemistryStation station)
{
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "SetSelectedRecipe")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_SetSelectedRecipe_Prefix(ChemistryStationCanvas __instance, StationRecipeEntry entry)
{
try
{
StationRecipe val = ((entry != null) ? entry.Recipe : null);
string text = SafeGetProductId(val);
if (!(text == "<null>") && !(text == "<error>"))
{
_lastSelectedRecipeProductId = text;
_lastSelectedRecipeTitle = SafeGetRecipeEntryTitle(entry);
_lastSelectedRecipeId = (((Object)(object)val == (Object)null) ? "<null>" : SafeGetStationRecipeId(val));
_lastSelectedAtTick = Environment.TickCount;
}
}
catch
{
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "BeginButtonPressed")]
[HarmonyPrefix]
private static void ChemistryStationCanvas_BeginButtonPressed_Prefix(ChemistryStationCanvas __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null))
{
StationRecipeEntry? obj = TryGetSelectedRecipeEntry(__instance);
string text = SafeGetProductId((obj != null) ? obj.Recipe : null);
if (text == "<null>" || text == "<error>")
{
text = _lastSelectedRecipeProductId ?? text;
}
if (!(text != "supergrow"))
{
_superGrowBeginAuditSeq++;
_superGrowBeginAuditUntilTick = Environment.TickCount + 10000;
_superGrowBeginStation = __instance.ChemistryStation;
_superGrowBeginStationSeq = _superGrowBeginAuditSeq;
_ = _superGrowBeginAuditSeq;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("SuperGrow Begin audit failed (Prefix): " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
[HarmonyPatch(typeof(ChemistryStationCanvas), "BeginButtonPressed")]
[HarmonyPostfix]
private static void ChemistryStationCanvas_BeginButtonPressed_Postfix(ChemistryStationCanvas __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null) && !TickExpired(_superGrowBeginAuditUntilTick))
{
int superGrowBeginAuditSeq = _superGrowBeginAuditSeq;
ChemistryStation val = __instance.ChemistryStation;
if ((Object)(object)val == (Object)null && _superGrowBeginStationSeq == superGrowBeginAuditSeq)
{
val = _superGrowBeginStation;
}
_ = (Object)(object)val != (Object)null;
}
}
catch (Exception ex)
{
MelonLogger.Error("SuperGrow Begin audit failed (Postfix): " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
private static bool TickExpired(int untilTick)
{
return Environment.TickCount - untilTick >= 0;
}
[IteratorStateMachine(typeof(<DelayedChemistryIngredientAudit>d__23))]
private static IEnumerator DelayedChemistryIngredientAudit(int seq, ChemistryStation station)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedChemistryIngredientAudit>d__23(0);
}
private static StationRecipeEntry? TryGetSelectedRecipeEntry(ChemistryStationCanvas canvas)
{
try
{
Type typeFromHandle = typeof(ChemistryStationCanvas);
FieldInfo field = typeFromHandle.GetField("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object? value = field.GetValue(canvas);
return (StationRecipeEntry?)((value is StationRecipeEntry) ? value : null);
}
PropertyInfo property = typeFromHandle.GetProperty("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null)
{
object? value2 = property.GetValue(canvas);
return (StationRecipeEntry?)((value2 is StationRecipeEntry) ? value2 : null);
}
FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (!(fieldInfo.FieldType != typeof(StationRecipeEntry)) && !(fieldInfo.Name == "RecipeEntryPrefab") && !(fieldInfo.Name == "InProgressRecipeEntry"))
{
object? value3 = fieldInfo.GetValue(canvas);
StationRecipeEntry val = (StationRecipeEntry)((value3 is StationRecipeEntry) ? value3 : null);
if ((Object)(object)((val != null) ? val.Recipe : null) != (Object)null)
{
return val;
}
}
}
}
catch
{
}
return null;
}
private static string SafeGetRecipeEntryTitle(StationRecipeEntry? entry)
{
try
{
return ((Object)(object)entry?.TitleLabel == (Object)null) ? "<null>" : (((TMP_Text)entry.TitleLabel).text ?? "<null>");
}
catch
{
return "<error>";
}
}
private static bool SafeGetBeginInteractable(ChemistryStationCanvas canvas)
{
try
{
return (Object)(object)canvas.BeginButton != (Object)null && ((Selectable)canvas.BeginButton).interactable;
}
catch
{
return false;
}
}
private static string SafeGetProductId(StationRecipe? recipe)
{
try
{
return ((BaseItemDefinition)(recipe?.Product?.Item?)).ID ?? "<null>";
}
catch
{
return "<error>";
}
}
private static string SafeGetStationRecipeId(StationRecipe recipe)
{
try
{
return recipe.RecipeID ?? "<null>";
}
catch
{
return "<error>";
}
}
private static void CreateSuperGrowRecipe()
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Expected O, but got Unknown
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Expected O, but got Unknown
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Expected O, but got Unknown
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
ItemDefinition item = Registry.GetItem("pgr");
ItemDefinition item2 = Registry.GetItem("speedgrow");
ItemDefinition item3 = Registry.GetItem("fertilizer");
ItemDefinition item4 = Registry.GetItem("supergrow");
if ((Object)(object)item == (Object)null || (Object)(object)item2 == (Object)null || (Object)(object)item3 == (Object)null)
{
MelonLogger.Error("Could not find one or more base additive definitions");
return;
}
if ((Object)(object)item4 == (Object)null)
{
SuperGrowCreator.CreateSuperGrowItem();
item4 = Registry.GetItem("supergrow");
if ((Object)(object)item4 == (Object)null)
{
MelonLogger.Warning("Could not find SuperGrow definition; will retry when registry is ready");
return;
}
}
_superGrowRecipe = ScriptableObject.CreateInstance<StationRecipe>();
_superGrowRecipe.IsDiscovered = true;
_superGrowRecipe.RecipeTitle = "SuperGrow";
_superGrowRecipe.CookTime_Mins = SuperGrowSettings.CookTimeMinutes.Value;
_superGrowRecipe.Unlocked = true;
List<IngredientQuantity> list = new List<IngredientQuantity>();
IngredientQuantity val = new IngredientQuantity();
List<ItemDefinition> list2 = new List<ItemDefinition>();
list2.Add(item);
val.Items = list2;
val.Quantity = SuperGrowSettings.PgrRequired.Value;
list.Add(val);
IngredientQuantity val2 = new IngredientQuantity();
List<ItemDefinition> list3 = new List<ItemDefinition>();
list3.Add(item2);
val2.Items = list3;
val2.Quantity = SuperGrowSettings.SpeedGrowRequired.Value;
list.Add(val2);
IngredientQuantity val3 = new IngredientQuantity();
List<ItemDefinition> list4 = new List<ItemDefinition>();
list4.Add(item3);
val3.Items = list4;
val3.Quantity = SuperGrowSettings.FertilizerRequired.Value;
list.Add(val3);
_superGrowRecipe.Ingredients = list;
_superGrowRecipe.Product = new ItemQuantity
{
Item = item4,
Quantity = SuperGrowSettings.OutputQuantity.Value
};
_superGrowRecipe.FinalLiquidColor = SuperGrowVisuals.PourColor;
}
private static bool TryGetStationItemTemplate(out StationItem templateStationItem)
{
templateStationItem = null;
string[] array = new string[4] { "acid", "pgr", "speedgrow", "fertilizer" };
string[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
ItemDefinition item = Registry.GetItem(array2[i]);
StorableItemDefinition val = (StorableItemDefinition)(object)((item is StorableItemDefinition) ? item : null);
if ((Object)(object)val?.StationItem != (Object)null)
{
templateStationItem = val.StationItem;
return true;
}
}
if (!_loggedMissingStationItemTemplate)
{
_loggedMissingStationItemTemplate = true;
MelonLogger.Warning("Could not find any StationItem template (acid/pgr/speedgrow/fertilizer)");
array2 = array;
foreach (string text in array2)
{
ItemDefinition item2 = Registry.GetItem(text);
StorableItemDefinition val2 = (StorableItemDefinition)(object)((item2 is StorableItemDefinition) ? item2 : null);
MelonLogger.Warning(text + ": def=" + (((Object)(object)val2 == (Object)null) ? "<null>" : ((object)val2).GetType().FullName) + " stationItem=" + (((Object)(object)val2?.StationItem == (Object)null) ? "<null>" : ((object)val2.StationItem).GetType().FullName));
}
}
return false;
}
[HarmonyPatch(typeof(Registry), "Start")]
[HarmonyPostfix]
private static void Registry_Start_Postfix()
{
if (_loggedRegistryStart)
{
return;
}
_loggedRegistryStart = true;
try
{
SuperGrowCreator.CreateSuperGrowItem();
}
catch (Exception ex)
{
MelonLogger.Error("Registry.Start hook failed: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
public static void SetupAdditiveStationItems()
{
if (_additivesPatched)
{
return;
}
try
{
CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
if (TryGetStationItemTemplate(out StationItem templateStationItem))
{
SetupAdditiveStationItem("pgr", templateStationItem);
SetupAdditiveStationItem("speedgrow", templateStationItem);
SetupAdditiveStationItem("fertilizer", templateStationItem);
_additivesPatched = true;
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to set up additive StationItems: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
[HarmonyPatch(typeof(StoredItem), "InitializeStoredItem")]
[HarmonyPostfix]
private static void StoredItem_InitializeStoredItem_Postfix(StoredItem __instance, StorableItemInstance _item)
{
try
{
if (!(((_item == null) ? null : ((BaseItemDefinition)(((ItemInstance)_item).Definition?)).ID) != "supergrow"))
{
ApplySuperGrowMaterialsToRenderers(((Component)__instance).GetComponentsInChildren<Renderer>(true));
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow visuals to stored item: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
private static bool TrashPrefabsContainsId(TrashItem[]? prefabs, string id)
{
if (prefabs == null)
{
return false;
}
foreach (TrashItem val in prefabs)
{
if ((Object)(object)val != (Object)null && val.ID == id)
{
return true;
}
}
return false;
}
private static bool TryGetMonoBottleTrashPrefab(string additiveId, out TrashItem prefab)
{
prefab = null;
if (_monoBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out TrashItem value) && (Object)(object)value != (Object)null)
{
prefab = value;
return true;
}
TrashManager val = Object.FindObjectOfType<TrashManager>();
if ((Object)(object)val == (Object)null)
{
return false;
}
EnsureMonoBottleTrashPrefabsInjected(val);
if (_monoBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out value) && (Object)(object)value != (Object)null)
{
prefab = value;
return true;
}
return false;
}
private static void EnsureMonoBottleTrashPrefabsInjected(TrashManager manager)
{
if (_monoTrashPrefabsInjected || (Object)(object)manager == (Object)null)
{
return;
}
try
{
CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
TrashItem baseTrash = manager.GetTrashPrefab("acid");
TrashItem pgrTrash = manager.GetTrashPrefab("pgr");
if ((Object)(object)baseTrash == (Object)null || (Object)(object)((Component)baseTrash).gameObject == (Object)null)
{
return;
}
TrashItem[] prefabs = manager.TrashPrefabs ?? Array.Empty<TrashItem>();
List<TrashItem> additions = new List<TrashItem>();
Ensure("pgr", "supergrow_pgr_bottle");
Ensure("speedgrow", "supergrow_speedgrow_bottle");
Ensure("fertilizer", "supergrow_fertilizer_bottle");
Ensure("supergrow", "supergrow_bottle");
if (additions.Count > 0)
{
TrashItem[] array = (TrashItem[])(object)new TrashItem[prefabs.Length + additions.Count];
Array.Copy(prefabs, array, prefabs.Length);
for (int i = 0; i < additions.Count; i++)
{
array[prefabs.Length + i] = additions[i];
}
manager.TrashPrefabs = array;
}
_monoTrashPrefabsInjected = true;
void Ensure(string additiveId, string newId)
{
if (!TrashPrefabsContainsId(prefabs, newId))
{
GameObject val = ((string.Equals(additiveId, "supergrow", StringComparison.OrdinalIgnoreCase) && (Object)(object)pgrTrash != (Object)null && (Object)(object)((Component)pgrTrash).gameObject != (Object)null) ? ((Component)pgrTrash).gameObject : ((Component)baseTrash).gameObject);
GameObject val2 = Object.Instantiate<GameObject>(val);
((Object)val2).name = "SuperGrow_" + additiveId + "_TrashPrefab";
val2.SetActive(val.activeSelf);
Object.DontDestroyOnLoad((Object)(object)val2);
TrashItem component = val2.GetComponent<TrashItem>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val2);
}
else
{
component.ID = newId;
SwapTrashItemVisualsById(additiveId, component);
_monoBottleTrashPrefabByAdditiveId[additiveId] = component;
additions.Add(component);
}
}
}
}
catch (Exception ex)
{
if (!_loggedMonoTrashPrefabInjectionException)
{
_loggedMonoTrashPrefabInjectionException = true;
MelonLogger.Warning("Failed to inject SuperGrow trash prefabs (Mono): " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
}
}
[HarmonyPatch(typeof(TrashManager), "Start")]
[HarmonyPostfix]
private static void TrashManager_Start_Postfix_Mono(TrashManager __instance)
{
EnsureMonoBottleTrashPrefabsInjected(__instance);
}
private static void SetPendingStationTrashReskins(List<PendingTrashReskin> reskins)
{
_pendingStationTrashReskins.Clear();
if (reskins.Count > 0)
{
_pendingStationTrashReskins.AddRange(reskins);
_pendingStationTrashReskinExpireTick = Environment.TickCount + 5000;
}
else
{
_pendingStationTrashReskinExpireTick = 0;
}
}
[HarmonyPatch(typeof(TrashItem), "Start")]
[HarmonyPostfix]
private static void TrashItem_Start_Postfix(TrashItem __instance)
{
try
{
if (_pendingStationTrashReskins.Count == 0)
{
return;
}
if (_pendingStationTrashReskinExpireTick != 0 && Environment.TickCount - _pendingStationTrashReskinExpireTick >= 0)
{
_pendingStationTrashReskins.Clear();
_pendingStationTrashReskinExpireTick = 0;
return;
}
string iD = __instance.ID;
if (string.IsNullOrEmpty(iD))
{
return;
}
for (int i = 0; i < _pendingStationTrashReskins.Count; i++)
{
PendingTrashReskin pendingTrashReskin = _pendingStationTrashReskins[i];
if (!(pendingTrashReskin.TrashId != iD))
{
_pendingStationTrashReskins.RemoveAt(i);
SwapTrashItemVisualsById(pendingTrashReskin.AdditiveId, __instance);
break;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow visuals to trash item: " + ex.Message);
MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
}
}
private static bool IsChemistryBeakerFillable(Fillable fillable)
{
if ((Object)(object)fillable == (Object)null)
{
return false;
}
LiquidContainer liquidContainer = fillable.LiquidContainer;
if ((Object)(object)liquidContainer == (Object)null || (Object)(object)((Component)liquidContainer).transform == (Object)null)
{
return false;
}
Transform transform = ((Component)liquidContainer).transform;
if (!string.Equals(((Object)transform).name, "Liquid", StringComparison.OrdinalIgnoreCase))
{
return false;
}
Transform parent = transform.parent;
if ((Object)(object)parent == (Object)null || !string.Equals(((Object)parent).name, "Beaker", StringComparison.OrdinalIgnoreCase))
{
return false;
}
Transform parent2 = parent.parent;
if ((Object)(object)parent2 == (Object)null || !((Object)parent2).name.StartsWith("Beaker", StringComparison.OrdinalIgnoreCase))
{
return false;
}
Transform val = parent2;
while ((Object)(object)val != (Object)null)
{
if (((Object)val).name != null && ((Object)val).name.IndexOf("ChemistryStation", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
val = val.parent;
}
return false;
}
private static void CachePourablePrefab(string additiveId, string pourablePath)
{
if (!_pourablePrefabs.ContainsKey(additiveId))
{
GameObject val = Resources.Load<GameObject>(pourablePath);
if ((Object)(object)val != (Object)null)
{
_pourablePrefabs[additiveId] = val;
}
else
{
MelonLogger.Warning("Could not load pourable prefab for " + additiveId + " at " + pourablePath);
}
}
}
private static Transform? FindStationItemBottleContainer(StationItem stationItem)
{
Transform val = ((Component)stationItem).transform.Find("Pourable");
if ((Object)(object)val == (Object)null)
{
return null;
}
Transform result = null;
int childCount = val.childCount;
for (int i = 0; i < childCount; i++)
{
Transform child = val.GetChild(i);
if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Bottle", StringComparison.OrdinalIgnoreCase) >= 0)
{
result = child;
break;
}
}
return result;
}
private static void SwapBottleMeshesAndMaterials(GameObject templatePrefab, Transform targetRoot)
{
MeshFilter[] componentsInChildren = templatePrefab.GetComponentsInChildren<MeshFilter>(true);
MeshFilter[] componentsInChildren2 = ((Component)targetRoot).GetComponentsInChildren<MeshFilter>(true);
foreach (MeshFilter val in componentsInChildren2)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
string text = ((Object)val).name.ToLowerInvariant();
MeshFilter[] array = componentsInChildren;
foreach (MeshFilter val2 in array)
{
if ((Object)(object)val2 == (Object)null)
{
continue;
}
string text2 = ((Object)val2).name.ToLowerInvariant();
if ((text.Contains("body") && text2.Contains("body")) || (text.Contains("label") && text2.Contains("label")) || (text.Contains("lid") && text2.Contains("lid")))
{
val.sharedMesh = val2.sharedMesh;
MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
MeshRenderer component2 = ((Component)val2).GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
{
((Renderer)component).sharedMaterials = ((Renderer)component2).sharedMaterials;
}
break;
}
}
}
}
private static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
{
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(renderers);
}
private static void SetupAdditiveStationItem(string additiveId, StationItem templateStationItem)
{
ItemDefinition item = Registry.GetItem(additiveId);
StorableItemDefinition val = (StorableItemDefinition)(object)((item is StorableItemDefinition) ? item : null);
if ((Object)(object)val == (Object)null)
{
MelonLogger.Warning("Could not find additive: " + additiveId);
}
else if (!((Object)(object)val.StationItem != (Object)null))
{
val.StationItem = templateStationItem;
}
}
private static void SwapTrashItemVisualsById(string id, TrashItem trashItem)
{
if ((Object)(object)trashItem == (Object)null || string.IsNullOrEmpty(id))
{
return;
}
bool flag = id == "supergrow";
if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
{
return;
}
GameObject value = null;
if (flag)
{
_pourablePrefabs.TryGetValue("pgr", out value);
}
else
{
_pourablePrefabs.TryGetValue(id, out value);
}
if ((Object)(object)value == (Object)null)
{
return;
}
try
{
if (!((Object)(object)((Component)trashItem).transform == (Object)null))
{
SwapBottleMeshesAndMaterials(value, ((Component)trashItem).transform);
if (flag)
{
ApplySuperGrowMaterialsToRenderers(((Component)trashItem).GetComponentsInChildren<Renderer>(true));
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to swap trash visuals for " + id + ": " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
private static void SwapStationItemVisualsById(string id, StationItem stationItem)
{
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: 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_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)stationItem == (Object)null || string.IsNullOrEmpty(id))
{
return;
}
bool flag = id == "supergrow";
if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
{
return;
}
GameObject value = null;
if (flag)
{
_pourablePrefabs.TryGetValue("pgr", out value);
}
else
{
_pourablePrefabs.TryGetValue(id, out value);
}
if ((Object)(object)value == (Object)null)
{
return;
}
try
{
Transform val = FindStationItemBottleContainer(stationItem);
if ((Object)(object)val == (Object)null)
{
return;
}
SwapBottleMeshesAndMaterials(value, val);
if (flag)
{
ApplySuperGrowMaterialsToRenderers(((Component)val).GetComponentsInChildren<Renderer>(true));
}
object obj;
if (!((Object)(object)((Component)stationItem).transform != (Object)null))
{
obj = null;
}
else
{
Transform obj2 = ((Component)stationItem).transform.Find("Pourable");
obj = ((obj2 != null) ? ((Component)obj2).GetComponent<PourableModule>() : null);
}
PourableModule val2 = (PourableModule)obj;
if ((Object)(object)val2 != (Object)null && (Object)(object)val2.LiquidContainer != (Object)null)
{
LiquidContainer liquidContainer = val2.LiquidContainer;
if ((Object)(object)liquidContainer.LiquidVolume != (Object)null)
{
Transform transform = ((Component)liquidContainer.LiquidVolume).transform;
transform.localScale *= 0.65f;
}
liquidContainer.MaxLevel *= 0.65f;
if (_additiveColors.TryGetValue(id, out var value2))
{
val2.LiquidType = id;
val2.LiquidColor = value2;
val2.PourParticlesColor = value2;
liquidContainer.SetLiquidColor(value2, true, true);
}
}
if (flag)
{
return;
}
switch (id)
{
case "pgr":
case "speedgrow":
case "fertilizer":
{
if (TryGetMonoBottleTrashPrefab(id, out TrashItem prefab))
{
stationItem.TrashPrefab = prefab;
}
break;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to swap station item visuals for " + id + ": " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
private static void SwapStationItemVisualsById(string id, StationItem stationItem, StorableItemDefinition itemDef)
{
if (!((Object)(object)stationItem == (Object)null) && !((Object)(object)itemDef == (Object)null))
{
SwapStationItemVisualsById(id, stationItem);
}
}
private static void SwapStationItemVisuals(StationItem stationItem, StorableItemDefinition itemDef)
{
SwapStationItemVisualsById(((BaseItemDefinition)itemDef).ID, stationItem, itemDef);
}
[HarmonyPatch(typeof(StationItem), "Initialize")]
[HarmonyPostfix]
private static void StationItem_Initialize_Postfix(StationItem __instance, StorableItemDefinition itemDefinition)
{
SwapStationItemVisuals(__instance, itemDefinition);
}
}
[HarmonyPatch]
internal static class GrowContainerPatches
{
private const string SuperGrowBottleTrashId = "supergrow_bottle";
private static bool _loggedGrowContainerTrashPrefabAssignException;
private static readonly Vector3 HiddenPrefabPosition = new Vector3(100000f, 100000f, 100000f);
private static Pourable? _superGrowPourablePrefab;
private static int _removeItemDepth;
private static bool _shouldReskinNextTrashSpawn;
private static readonly HashSet<string> _loggedReskinnedTrashIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private static void InjectSuperGrowIntoAllowedAdditives(GrowContainer container)
{
try
{
ItemDefinition item = Registry.GetItem("supergrow");
AdditiveDefinition val = (AdditiveDefinition)(object)((item is AdditiveDefinition) ? item : null);
if ((Object)(object)val == (Object)null)
{
return;
}
if (container.AllowedAdditives != null)
{
AdditiveDefinition[] allowedAdditives = container.AllowedAdditives;
foreach (AdditiveDefinition val2 in allowedAdditives)
{
if ((Object)(object)val2 != (Object)null && ((BaseItemDefinition)val2).ID == "supergrow")
{
return;
}
}
}
AdditiveDefinition[] obj = container.AllowedAdditives ?? Array.Empty<AdditiveDefinition>();
AdditiveDefinition[] array = (AdditiveDefinition[])(object)new AdditiveDefinition[obj.Length + 1];
obj.CopyTo(array, 0);
array[^1] = val;
container.AllowedAdditives = array;
}
catch (Exception ex)
{
MelonLogger.Error("Failed to inject SuperGrow into AllowedAdditives: " + ex.Message);
}
}
[HarmonyPatch(typeof(GrowContainer), "InitializeGridItem")]
[HarmonyPrefix]
private static void GrowContainer_InitializeGridItem_Prefix(GrowContainer __instance)
{
InjectSuperGrowIntoAllowedAdditives(__instance);
}
private static Pourable? GetOrCreateSuperGrowPourablePrefab(Pourable basePrefab)
{
//IL_006a: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_superGrowPourablePrefab != (Object)null && (Object)(object)((Component)_superGrowPourablePrefab).gameObject != (Object)null)
{
return _superGrowPourablePrefab;
}
if ((Object)(object)basePrefab == (Object)null || (Object)(object)((Component)basePrefab).gameObject == (Object)null)
{
return null;
}
try
{
GameObject val = Object.Instantiate<GameObject>(((Component)basePrefab).gameObject);
((Object)val).name = "SuperGrow_PourablePrefab";
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)val);
val.transform.position = HiddenPrefabPosition;
if (!val.activeSelf)
{
val.SetActive(true);
}
Pourable component = val.GetComponent<Pourable>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val);
return null;
}
PourableAdditive component2 = val.GetComponent<PourableAdditive>();
if ((Object)(object)component2 != (Object)null)
{
component2.LiquidColor = SuperGrowVisuals.PourColor;
}
ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true);
foreach (ParticleSystem val2 in componentsInChildren)
{
if (!((Object)(object)val2 == (Object)null))
{
MainModule main = val2.main;
((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(SuperGrowVisuals.PourColor);
}
}
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(val.GetComponentsInChildren<Renderer>(true));
try
{
TrashManager val3 = Object.FindObjectOfType<TrashManager>();
if ((Object)(object)val3 != (Object)null)
{
TrashItem trashPrefab = val3.GetTrashPrefab("supergrow_bottle");
if ((Object)(object)trashPrefab != (Object)null)
{
component.TrashItem = trashPrefab;
}
}
}
catch (Exception ex)
{
if (!_loggedGrowContainerTrashPrefabAssignException)
{
_loggedGrowContainerTrashPrefabAssignException = true;
MelonLogger.Warning("Failed to assign SuperGrow trash prefab to grow-container pourable: " + ex.Message);
MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
}
}
_superGrowPourablePrefab = component;
return _superGrowPourablePrefab;
}
catch (Exception ex2)
{
MelonLogger.Error("Failed to create SuperGrow pourable prefab: " + ex2.Message);
MelonLogger.Error(ex2.StackTrace);
return null;
}
}
[HarmonyPatch(typeof(Equippable_Additive), "Equip")]
[HarmonyPostfix]
private static void Equippable_Additive_Equip_Postfix(Equippable_Additive __instance, ItemInstance item)
{
try
{
if (((item == null) ? null : ((BaseItemDefinition)(item.Definition?)).ID) != "supergrow")
{
return;
}
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(((Component)__instance).GetComponentsInChildren<Renderer>(true));
Pourable pourablePrefab = ((Equippable_Pourable)__instance).PourablePrefab;
if (!((Object)(object)pourablePrefab == (Object)null))
{
Pourable orCreateSuperGrowPourablePrefab = GetOrCreateSuperGrowPourablePrefab(pourablePrefab);
if ((Object)(object)orCreateSuperGrowPourablePrefab != (Object)null)
{
((Equippable_Pourable)__instance).PourablePrefab = orCreateSuperGrowPourablePrefab;
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to apply SuperGrow grow-container pour visuals: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
[HarmonyPatch(typeof(GrowContainerPourTask), "RemoveItem")]
[HarmonyPrefix]
private static void GrowContainerPourTask_RemoveItem_Prefix()
{
_removeItemDepth++;
}
[HarmonyPatch(typeof(GrowContainerPourTask), "RemoveItem")]
[HarmonyFinalizer]
private static void GrowContainerPourTask_RemoveItem_Finalizer(Exception __exception)
{
_removeItemDepth = Math.Max(0, _removeItemDepth - 1);
_shouldReskinNextTrashSpawn = false;
}
[HarmonyPatch(typeof(PlayerInventory), "RemoveAmountOfItem")]
[HarmonyPrefix]
private static void PlayerInventory_RemoveAmountOfItem_Prefix(string ID)
{
if (_removeItemDepth > 0 && string.Equals(ID, "supergrow", StringComparison.OrdinalIgnoreCase))
{
_shouldReskinNextTrashSpawn = true;
}
}
[HarmonyPatch(typeof(TrashManager), "CreateAndReturnTrashItem")]
[HarmonyPostfix]
private static void TrashManager_CreateAndReturnTrashItem_Postfix_GrowContainerReskin(string id, object __result)
{
if (!_shouldReskinNextTrashSpawn)
{
return;
}
_shouldReskinNextTrashSpawn = false;
try
{
if (__result != null)
{
object? obj = AccessTools.Property(__result.GetType(), "gameObject")?.GetValue(__result);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(val.GetComponentsInChildren<Renderer>(true));
}
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to reskin grow-container trash for SuperGrow: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
}
}
namespace SuperGrow.Features
{
internal static class SuperGrowCreator
{
private static AdditiveDefinition? _superGrowDefinition;
private static bool _loggedMissingAdditiveTemplate;
private static bool _loggedRegistryUnavailable;
public static void CreateSuperGrowItem()
{
try
{
if (!((Object)(object)Registry.GetItem("supergrow") != (Object)null))
{
CreateAdditiveDefinition();
_ = (Object)(object)Registry.GetItem("supergrow") != (Object)null;
}
}
catch (Exception ex)
{
MelonLogger.Error("Failed to create SuperGrow item: " + ex.Message);
MelonLogger.Error(ex.StackTrace);
}
}
private static void CreateAdditiveDefinition()
{
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_0294: Unknown result type (might be due to invalid IL or missing references)
//IL_0299: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Expected O, but got Unknown
if (!Singleton<Registry>.InstanceExists && !_loggedRegistryUnavailable)
{
_loggedRegistryUnavailable = true;
MelonLogger.Warning("Registry singleton is not available yet; will retry");
}
Registry val = Singleton<Registry>.Instance;
if ((Object)(object)val == (Object)null)
{
val = Object.FindObjectOfType<Registry>();
}
if ((Object)(object)val == (Object)null)
{
if (!_loggedRegistryUnavailable)
{
_loggedRegistryUnavailable = true;
MelonLogger.Warning("Registry instance is not available; cannot add SuperGrow definition yet.");
}
return;
}
ItemDefinition item = Registry.GetItem("pgr");
AdditiveDefinition val2 = (AdditiveDefinition)(((object)((item is AdditiveDefinition) ? item : null)) ?? ((object)(/*isinst with value type is only supported in some contexts*/ ?? /*isinst with value type is only supported in some contexts*/)));
if ((Object)(object)val2 == (Object)null)
{
if (!_loggedMissingAdditiveTemplate)
{
_loggedMissingAdditiveTemplate = true;
ItemDefinition item2 = Registry.GetItem("pgr");
ItemDefinition item3 = Registry.GetItem("speedgrow");
ItemDefinition item4 = Registry.GetItem("fertilizer");
MelonLogger.Error("Could not find any existing additive to clone from!");
MelonLogger.Error("pgr=" + (((Object)(object)item2 == (Object)null) ? "<null>" : ((object)item2).GetType().FullName));
MelonLogger.Error("speedgrow=" + (((Object)(object)item3 == (Object)null) ? "<null>" : ((object)item3).GetType().FullName));
MelonLogger.Error("fertilizer=" + (((Object)(object)item4 == (Object)null) ? "<null>" : ((object)item4).GetType().FullName));
}
return;
}
if ((Object)(object)_superGrowDefinition != (Object)null)
{
val.AddToRegistry((ItemDefinition)(object)_superGrowDefinition);
return;
}
_superGrowDefinition = ScriptableObject.CreateInstance<AdditiveDefinition>();
((BaseItemDefinition)_superGrowDefinition).Category = ((BaseItemDefinition)val2).Category;
((BaseItemDefinition)_superGrowDefinition).StackLimit = ((BaseItemDefinition)val2).StackLimit;
((ItemDefinition)_superGrowDefinition).AvailableInDemo = ((ItemDefinition)val2).AvailableInDemo;
((BaseItemDefinition)_superGrowDefinition).UsableInFilters = ((BaseItemDefinition)val2).UsableInFilters;
((StorableItemDefinition)_superGrowDefinition).ResellMultiplier = ((StorableItemDefinition)val2).ResellMultiplier;
((StorableItemDefinition)_superGrowDefinition).ShopCategories = ((StorableItemDefinition)val2).ShopCategories;
((BaseItemDefinition)_superGrowDefinition).legalStatus = ((BaseItemDefinition)val2).legalStatus;
((ItemDefinition)_superGrowDefinition).Equippable = ((ItemDefinition)val2).Equippable;
((StorableItemDefinition)_superGrowDefinition).StoredItem = ((StorableItemDefinition)val2).StoredItem;
((StorableItemDefinition)_superGrowDefinition).StationItem = ((StorableItemDefinition)val2).StationItem;
((StorableItemDefinition)_superGrowDefinition).BasePurchasePrice = ((StorableItemDefinition)val2).BasePurchasePrice;
((BaseItemDefinition)_superGrowDefinition).ID = "supergrow";
((BaseItemDefinition)_superGrowDefinition).Name = "SuperGrow";
((BaseItemDefinition)_superGrowDefinition).Description = "A powerful growth enhancer combining the effects of PGR, Speed Grow, and Fertilizer. Apply to plants for increased yield, faster growth, and improved quality.";
((Object)_superGrowDefinition).name = "SuperGrow";
Sprite iconSprite = SuperGrowAssets.GetIconSprite();
((BaseItemDefinition)_superGrowDefinition).Icon = iconSprite ?? ((BaseItemDefinition)val2).Icon;
if ((Object)(object)val2.DisplayMaterial != (Object)null)
{
Material value = new Material(val2.DisplayMaterial)
{
color = new Color(0.3f, 0.9f, 0.3f, 1f)
};
SetPrivateProperty(_superGrowDefinition, "DisplayMaterial", value);
}
SetPrivateProperty(_superGrowDefinition, "QualityChange", SuperGrowSettings.QualityChange.Value);
SetPrivateProperty(_superGrowDefinition, "YieldMultiplier", SuperGrowSettings.YieldMultiplier.Value);
SetPrivateProperty(_superGrowDefinition, "InstantGrowth", SuperGrowSettings.InstantGrowth.Value);
val.AddToRegistry((ItemDefinition)(object)_superGrowDefinition);
}
private static void SetPrivateProperty(object obj, string propertyName, object value)
{
Type type = obj.GetType();
FieldInfo field = type.GetField("<" + propertyName + ">k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(obj, value);
return;
}
PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.CanWrite)
{
property.SetValue(obj, value);
}
else
{
MelonLogger.Warning("Could not set property " + propertyName + " on " + type.Name);
}
}
}
}