using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using ServerSync; using SoftReferenceableAssets; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Advize_PlantEverything")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Valheim Game Modification")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("85f3bb36-d51d-4e6c-a523-feb593b3156f")] [assembly: AssemblyFileVersion("1.21.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.21.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } internal class ConfigurationManagerAttributes { public bool? Browsable; public string? Category; public int? Order; public bool? ReadOnly; } namespace Advize_PlantEverything { public static class SeasonsCompatibility { private static bool _isInitialized; private static bool _isReady; private const string GUID = "shudnal.Seasons"; private static Assembly _assembly; private static FieldInfo _seasonState; private static MethodInfo _getSecondsToRespawnPickable; private static MethodInfo _getSecondsToGrowPlant; public static bool IsReady { get { if (!_isInitialized) { Initialize(); } return _isReady; } } public static double GetSecondsToRespawnPickable(Pickable pickable) { return (double)_getSecondsToRespawnPickable.Invoke(_seasonState.GetValue(_seasonState), new object[1] { pickable }); } public static double GetSecondsToGrowPlant(Plant plant) { return (double)_getSecondsToGrowPlant.Invoke(_seasonState.GetValue(_seasonState), new object[1] { plant }); } private static void Initialize() { _isInitialized = true; if (Chainloader.PluginInfos.TryGetValue("shudnal.Seasons", out var value)) { _assembly = Assembly.GetAssembly(((object)value.Instance).GetType()); if (_assembly != null) { _seasonState = AccessTools.Field(_assembly.GetType("Seasons.Seasons"), "seasonState"); _getSecondsToRespawnPickable = AccessTools.Method(_seasonState.FieldType, "GetSecondsToRespawnPickable", (Type[])null, (Type[])null); _getSecondsToGrowPlant = AccessTools.Method(_seasonState.FieldType, "GetSecondsToGrowPlant", (Type[])null, (Type[])null); } } _isReady = _seasonState != null && _getSecondsToRespawnPickable != null && _getSecondsToGrowPlant != null; } } internal static class ConfigEventHandlers { private static bool s_reInitQueueInProcess = false; private static bool s_isLocalConfigChange = false; private static bool s_configSettingChangedFirst = false; private static bool s_configFileChangedFirst = false; private static readonly HashSet s_reInitMethodSet = new HashSet(); private static readonly Queue s_reInitMethodQueue = new Queue(); private static readonly Dictionary s_initMethods = new Dictionary { { "Core", new Action[7] { PluginInitUtils.InitPieceRefs, PluginInitUtils.InitPieces, PluginInitUtils.InitSaplingRefs, PluginInitUtils.InitSaplings, PluginInitUtils.InitCrops, PluginInitUtils.InitVines, PluginInitUtils.InitCultivator } }, { "Piece", new Action[3] { PluginInitUtils.InitPieceRefs, PluginInitUtils.InitPieces, PluginInitUtils.InitCultivator } }, { "Sapling", new Action[3] { PluginInitUtils.InitSaplingRefs, PluginInitUtils.InitSaplings, PluginInitUtils.InitCultivator } }, { "Seed", new Action[1] { PluginInitUtils.ModifyTreeDrops } }, { "Crop", new Action[1] { PluginInitUtils.InitCrops } }, { "Vine", new Action[1] { PluginInitUtils.InitVines } } }; private static bool PerformingLocalConfigChange { get { return s_isLocalConfigChange; } set { StaticMembers.Dbgl("Config change " + (value ? "is" : "was") + " local.", forceLog: false, (LogLevel)16); s_isLocalConfigChange = value; } } private static bool ShouldQueueMethod { get { if (!StaticMembers.isDedicatedServer && !StaticMembers.config.IsSourceOfTruth) { return !PerformingLocalConfigChange; } return false; } } private static void QueueReInitMethod(Action method) { if (!s_reInitQueueInProcess) { StaticMembers.Dbgl("Beginning method queue.", forceLog: false, (LogLevel)16); s_reInitQueueInProcess = true; } if (s_reInitMethodSet.Add(method)) { StaticMembers.Dbgl("Adding method to queue.", forceLog: false, (LogLevel)16); s_reInitMethodQueue.Enqueue(method); } } internal static void ProcessReInitQueue() { StaticMembers.Dbgl("Processing ReInit queue.", forceLog: false, (LogLevel)16); if (s_reInitMethodQueue.Count == 0 && !StaticMembers.isDedicatedServer && !StaticMembers.config.IsSourceOfTruth && StaticMembers.config.InitialSyncDone) { PerformingLocalConfigChange = true; return; } while (s_reInitMethodQueue.Count > 0) { s_reInitMethodQueue.Dequeue()(); } s_reInitMethodSet.Clear(); s_reInitQueueInProcess = false; } private static void HandleSettingChange(string category) { if (ShouldQueueMethod) { Array.ForEach(s_initMethods[category], QueueReInitMethod); return; } Array.ForEach(s_initMethods[category], delegate(Action initMethod) { initMethod(); }); PerformingLocalConfigChange = false; } internal static void CoreSettingChanged(object o, EventArgs e) { StaticMembers.Dbgl("Config setting changed, scheduling re-initialization of mod", forceLog: false, (LogLevel)16); HandleSettingChange("Core"); } internal static void PieceSettingChanged(object o, EventArgs e) { StaticMembers.Dbgl("Config setting changed, scheduling re-initialization of pieces", forceLog: false, (LogLevel)16); HandleSettingChange("Piece"); } internal static void SaplingSettingChanged(object o, EventArgs e) { StaticMembers.Dbgl("Config setting changed, scheduling re-initialization of saplings", forceLog: false, (LogLevel)16); HandleSettingChange("Sapling"); } internal static void SeedSettingChanged(object o, EventArgs e) { StaticMembers.Dbgl("Config setting changed, scheduling modification of TreeBase drop tables", forceLog: false, (LogLevel)16); HandleSettingChange("Seed"); } internal static void CropSettingChanged(object o, EventArgs e) { StaticMembers.Dbgl("Config setting changed, scheduling re-initialization of crops", forceLog: false, (LogLevel)16); HandleSettingChange("Crop"); } internal static void VineSettingChanged(object o, EventArgs e) { StaticMembers.Dbgl("Config setting changed, scheduling re-initialization of vines", forceLog: false, (LogLevel)16); HandleSettingChange("Vine"); } internal static void ExtraResourcesChanged() { StaticMembers.Dbgl("ExtraResourcesChanged", forceLog: false, (LogLevel)16); StaticMembers.deserializedExtraResources.Clear(); foreach (string item2 in StaticMembers.config.SyncedExtraResources.Value) { ExtraResource item = PluginUtils.DeserializeExtraResource(item2); StaticMembers.deserializedExtraResources.Add(item); } if (Object.op_Implicit((Object)(object)ZNetScene.s_instance)) { PluginInitUtils.InitExtraResourceRefs(ZNetScene.s_instance); PieceSettingChanged(null, null); } } internal static void ExtraResourcesFileOrSettingChanged(object sender, EventArgs e) { StaticMembers.Dbgl("ExtraResources file or setting has changed", forceLog: false, (LogLevel)16); if (ConfigWatcher.ExtraResourcesWatcher == null) { ConfigWatcher.InitExtraResourcesWatcher(); } if (StaticMembers.config.IsSourceOfTruth) { if (StaticMembers.config.EnableExtraResources) { StaticMembers.Dbgl("IsSourceOfTruth: true, loading extra resources from disk", forceLog: false, (LogLevel)16); PluginUtils.LoadExtraResources(); } else { StaticMembers.config.SyncedExtraResources.AssignLocalValue(new List()); } } else { StaticMembers.Dbgl("IsSourceOfTruth: false, extra resources will not be loaded from disk", forceLog: false, (LogLevel)16); } } internal static void ConfigSettingChanged(object sender, EventArgs e) { if (!s_configFileChangedFirst && !ShouldQueueMethod) { s_configSettingChangedFirst = true; StaticMembers.Dbgl("SAVING", forceLog: false, (LogLevel)16); StaticMembers.config.Save(); } else { s_configFileChangedFirst = false; } } internal static void ConfigFileChanged(object sender, EventArgs e) { s_configFileChangedFirst = !s_configSettingChangedFirst; if (StaticMembers.isDedicatedServer || s_configFileChangedFirst) { StaticMembers.Dbgl("RELOADING", forceLog: false, (LogLevel)16); StaticMembers.config.Reload(); } s_configSettingChangedFirst = false; } internal static void ConfigManagerDisplayingWindowChanged(object sender, EventArgs e) { if (!ConfigManagerHelper.IsConfigManagerWindowActive) { StaticMembers.Dbgl("Configuration Manager Window Closed", forceLog: false, (LogLevel)16); } } } internal class ConfigManagerHelper { private static object? _configManagerInstance; private static Type? _configManagerType; private static MethodInfo? _buildSettingList; private static PropertyInfo? _displayingWindowProperty; internal static bool IsConfigManagerWindowActive { get { object obj = _displayingWindowProperty?.GetValue(_configManagerInstance); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } internal static void Initialize() { _configManagerType = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager"); _configManagerInstance = ((_configManagerType == null) ? null : Chainloader.ManagerObject.GetComponent(_configManagerType)); _buildSettingList = _configManagerType?.GetMethod("BuildSettingList"); _displayingWindowProperty = _configManagerType?.GetProperty("DisplayingWindow"); EventInfo eventInfo = _configManagerInstance?.GetType().GetEvent("DisplayingWindowChanged"); if ((object)eventInfo != null) { EventHandler eventHandler = ConfigEventHandlers.ConfigManagerDisplayingWindowChanged; Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventHandler.Target, eventHandler.Method); eventInfo.AddEventHandler(_configManagerInstance, handler); } } internal static void ReloadConfigDisplay() { _buildSettingList?.Invoke(_configManagerInstance, Array.Empty()); } } internal sealed class ConfigWatcher { internal static FileSystemWatcher ExtraResourcesWatcher; internal static void InitConfigWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "advize.PlantEverything.cfg"); fileSystemWatcher.Changed += ConfigEventHandlers.ConfigFileChanged; fileSystemWatcher.Created += ConfigEventHandlers.ConfigFileChanged; fileSystemWatcher.Renamed += ConfigEventHandlers.ConfigFileChanged; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.EnableRaisingEvents = true; } internal static void InitExtraResourcesWatcher() { ExtraResourcesWatcher = new FileSystemWatcher(StaticMembers.CustomConfigPath, "ExtraResources.json"); ExtraResourcesWatcher.Changed += ConfigEventHandlers.ExtraResourcesFileOrSettingChanged; ExtraResourcesWatcher.Created += ConfigEventHandlers.ExtraResourcesFileOrSettingChanged; ExtraResourcesWatcher.Renamed += ConfigEventHandlers.ExtraResourcesFileOrSettingChanged; ExtraResourcesWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; ExtraResourcesWatcher.IncludeSubdirectories = true; ExtraResourcesWatcher.EnableRaisingEvents = true; } } internal sealed class ModConfig { private readonly ConfigFile ConfigFile; private readonly ConfigSync ConfigSync; private ConfigEntry serverConfigLocked; internal ConfigEntry nexusID; private ConfigEntry enableDebugMessages; private ConfigEntry showPickableSpawners; private ConfigEntry enableMiscFlora; private ConfigEntry enableDebris; private ConfigEntry enableExtraResources; private ConfigEntry snappableVines; private ConfigEntry enableLocalization; private ConfigEntry language; private ConfigEntry disabledResourceNames; private ConfigEntry requireCultivation; private ConfigEntry placeAnywhere; private ConfigEntry enforceBiomes; private ConfigEntry enforceBiomesVanilla; private ConfigEntry plantsRequireShielding; private ConfigEntry canRemoveFlora; private ConfigEntry recoverResources; private ConfigEntry resourcesSpawnEmpty; private ConfigEntry enemiesTargetPieces; private ConfigEntry raspberryCost; private ConfigEntry blueberryCost; private ConfigEntry cloudberryCost; private ConfigEntry raspberryRespawnTime; private ConfigEntry blueberryRespawnTime; private ConfigEntry cloudberryRespawnTime; private ConfigEntry raspberryReturn; private ConfigEntry blueberryReturn; private ConfigEntry cloudberryReturn; private ConfigEntry enableCropOverrides; private ConfigEntry overrideModdedCrops; private ConfigEntry cropRequireCultivation; private ConfigEntry cropRequireSunlight; private ConfigEntry cropRequireGrowthSpace; private ConfigEntry enemiesTargetCrops; private ConfigEntry cropMinScale; private ConfigEntry cropMaxScale; private ConfigEntry cropGrowTimeMin; private ConfigEntry cropGrowTimeMax; private ConfigEntry cropGrowRadius; private ConfigEntry barleyCost; private ConfigEntry barleyReturn; private ConfigEntry carrotCost; private ConfigEntry carrotReturn; private ConfigEntry flaxCost; private ConfigEntry flaxReturn; private ConfigEntry onionCost; private ConfigEntry onionReturn; private ConfigEntry seedCarrotCost; private ConfigEntry seedCarrotReturn; private ConfigEntry seedOnionCost; private ConfigEntry seedOnionReturn; private ConfigEntry seedTurnipCost; private ConfigEntry seedTurnipReturn; private ConfigEntry turnipCost; private ConfigEntry turnipReturn; private ConfigEntry magecapCost; private ConfigEntry magecapReturn; private ConfigEntry jotunPuffsCost; private ConfigEntry jotunPuffsReturn; private ConfigEntry pickableBranchCost; private ConfigEntry pickableBranchReturn; private ConfigEntry pickableBranchRespawnTime; private ConfigEntry pickableStoneCost; private ConfigEntry pickableStoneReturn; private ConfigEntry pickableStoneRespawnTime; private ConfigEntry pickableFlintCost; private ConfigEntry pickableFlintReturn; private ConfigEntry pickableFlintRespawnTime; private ConfigEntry mushroomCost; private ConfigEntry yellowMushroomCost; private ConfigEntry blueMushroomCost; private ConfigEntry smokePuffCost; private ConfigEntry mushroomRespawnTime; private ConfigEntry yellowMushroomRespawnTime; private ConfigEntry blueMushroomRespawnTime; private ConfigEntry smokePuffRespawnTime; private ConfigEntry mushroomReturn; private ConfigEntry yellowMushroomReturn; private ConfigEntry blueMushroomReturn; private ConfigEntry smokePuffReturn; private ConfigEntry thistleCost; private ConfigEntry dandelionCost; private ConfigEntry fiddleheadCost; private ConfigEntry thistleRespawnTime; private ConfigEntry dandelionRespawnTime; private ConfigEntry fiddleheadRespawnTime; private ConfigEntry thistleReturn; private ConfigEntry dandelionReturn; private ConfigEntry fiddleheadReturn; private ConfigEntry overrideModdedSaplings; private ConfigEntry moddedSaplingMinScale; private ConfigEntry moddedSaplingMaxScale; private ConfigEntry moddedSaplingGrowthTime; private ConfigEntry moddedSaplingGrowRadius; private ConfigEntry birchMinScale; private ConfigEntry birchMaxScale; private ConfigEntry oakMinScale; private ConfigEntry oakMaxScale; private ConfigEntry ancientMinScale; private ConfigEntry ancientMaxScale; private ConfigEntry birchGrowthTime; private ConfigEntry oakGrowthTime; private ConfigEntry ancientGrowthTime; private ConfigEntry birchGrowRadius; private ConfigEntry oakGrowRadius; private ConfigEntry ancientGrowRadius; private ConfigEntry beechGrowthTime; private ConfigEntry pineGrowthTime; private ConfigEntry firGrowthTime; private ConfigEntry beechMinScale; private ConfigEntry beechMaxScale; private ConfigEntry pineMinScale; private ConfigEntry pineMaxScale; private ConfigEntry firMinScale; private ConfigEntry firMaxScale; private ConfigEntry beechGrowRadius; private ConfigEntry pineGrowRadius; private ConfigEntry firGrowRadius; private ConfigEntry yggaMinScale; private ConfigEntry yggaMaxScale; private ConfigEntry yggaGrowthTime; private ConfigEntry yggaGrowRadius; private ConfigEntry autumnBirchMinScale; private ConfigEntry autumnBirchMaxScale; private ConfigEntry autumnBirchGrowthTime; private ConfigEntry autumnBirchGrowRadius; private ConfigEntry ashwoodMinScale; private ConfigEntry ashwoodMaxScale; private ConfigEntry ashwoodGrowthTime; private ConfigEntry ashwoodGrowRadius; private ConfigEntry enableSeedOverrides; private ConfigEntry seedDropMin; private ConfigEntry seedDropMax; private ConfigEntry treeDropMin; private ConfigEntry treeDropMax; private ConfigEntry dropChance; private ConfigEntry oneOfEach; private ConfigEntry enablePickableTimers; private ConfigEntry enablePlantTimers; private ConfigEntry growthAsPercentage; private ConfigEntry enableVineOverrides; private ConfigEntry vineAttachDistance; private ConfigEntry vineGrowRadius; private ConfigEntry vineGrowthTime; private ConfigEntry vineBerryRespawnTime; private ConfigEntry vineBerryReturn; private CustomSyncedValue> extraResources; private readonly ConfigurationManagerAttributes seedSettingAtrributes = new ConfigurationManagerAttributes(); private readonly List cropSettingAttributes = new List(2) { new ConfigurationManagerAttributes(), new ConfigurationManagerAttributes { Order = 27 } }; internal bool EnableDebugMessages => enableDebugMessages.Value; internal bool ShowPickableSpawners => showPickableSpawners.Value; internal bool EnableMiscFlora => enableMiscFlora.Value; internal bool EnableDebris => enableDebris.Value; internal bool EnableExtraResources => enableExtraResources.Value; internal bool SnappableVines => snappableVines.Value; internal bool EnableLocalization => enableLocalization.Value; internal string Language => language.Value; internal string[] DisabledResourceNames => disabledResourceNames.Value.Split(new char[1] { ',' }); internal bool RequireCultivation => requireCultivation.Value; internal bool PlaceAnywhere => placeAnywhere.Value; internal bool EnforceBiomes => enforceBiomes.Value; internal bool EnforceBiomesVanilla => enforceBiomesVanilla.Value; internal bool PlantsRequireShielding => plantsRequireShielding.Value; internal bool CanRemoveFlora => canRemoveFlora.Value; internal bool RecoverResources => recoverResources.Value; internal bool ResourcesSpawnEmpty => resourcesSpawnEmpty.Value; internal bool EnemiesTargetPieces => enemiesTargetPieces.Value; internal int RaspberryCost => raspberryCost.Value; internal int BlueberryCost => blueberryCost.Value; internal int CloudberryCost => cloudberryCost.Value; internal int RaspberryRespawnTime => raspberryRespawnTime.Value; internal int BlueberryRespawnTime => blueberryRespawnTime.Value; internal int CloudberryRespawnTime => cloudberryRespawnTime.Value; internal int RaspberryReturn => raspberryReturn.Value; internal int BlueberryReturn => blueberryReturn.Value; internal int CloudberryReturn => cloudberryReturn.Value; internal bool EnableCropOverrides => enableCropOverrides.Value; internal bool OverrideModdedCrops => overrideModdedCrops.Value; internal float CropMinScale => cropMinScale.Value; internal float CropMaxScale => cropMaxScale.Value; internal float CropGrowTimeMin => Mathf.Max(cropGrowTimeMin.Value, 10f); internal float CropGrowTimeMax => Mathf.Max(cropGrowTimeMax.Value, 10f); internal float CropGrowRadius => cropGrowRadius.Value; internal bool CropRequireCultivation => cropRequireCultivation.Value; internal bool CropRequireSunlight => cropRequireSunlight.Value; internal bool CropRequireGrowthSpace => cropRequireGrowthSpace.Value; internal bool EnemiesTargetCrops => enemiesTargetCrops.Value; internal int BarleyCost => barleyCost.Value; internal int BarleyReturn => barleyReturn.Value; internal int CarrotCost => carrotCost.Value; internal int CarrotReturn => carrotReturn.Value; internal int FlaxCost => flaxCost.Value; internal int FlaxReturn => flaxReturn.Value; internal int OnionCost => onionCost.Value; internal int OnionReturn => onionReturn.Value; internal int SeedCarrotCost => seedCarrotCost.Value; internal int SeedCarrotReturn => seedCarrotReturn.Value; internal int SeedOnionCost => seedOnionCost.Value; internal int SeedOnionReturn => seedOnionReturn.Value; internal int SeedTurnipCost => seedTurnipCost.Value; internal int SeedTurnipReturn => seedTurnipReturn.Value; internal int TurnipCost => turnipCost.Value; internal int TurnipReturn => turnipReturn.Value; internal int MagecapCost => magecapCost.Value; internal int MagecapReturn => magecapReturn.Value; internal int JotunPuffsCost => jotunPuffsCost.Value; internal int JotunPuffsReturn => jotunPuffsReturn.Value; internal int PickableBranchCost => pickableBranchCost.Value; internal int PickableBranchReturn => pickableBranchReturn.Value; internal int PickableBranchRespawnTime => pickableBranchRespawnTime.Value; internal int PickableStoneCost => pickableStoneCost.Value; internal int PickableStoneReturn => pickableStoneReturn.Value; internal int PickableStoneRespawnTime => pickableStoneRespawnTime.Value; internal int PickableFlintCost => pickableFlintCost.Value; internal int PickableFlintReturn => pickableFlintReturn.Value; internal int PickableFlintRespawnTime => pickableFlintRespawnTime.Value; internal int MushroomCost => mushroomCost.Value; internal int YellowMushroomCost => yellowMushroomCost.Value; internal int BlueMushroomCost => blueMushroomCost.Value; internal int SmokePuffCost => smokePuffCost.Value; internal int MushroomRespawnTime => mushroomRespawnTime.Value; internal int YellowMushroomRespawnTime => yellowMushroomRespawnTime.Value; internal int BlueMushroomRespawnTime => blueMushroomRespawnTime.Value; internal int SmokePuffRespawnTime => smokePuffRespawnTime.Value; internal int MushroomReturn => mushroomReturn.Value; internal int YellowMushroomReturn => yellowMushroomReturn.Value; internal int BlueMushroomReturn => blueMushroomReturn.Value; internal int SmokePuffReturn => smokePuffReturn.Value; internal int ThistleCost => thistleCost.Value; internal int DandelionCost => dandelionCost.Value; internal int FiddleheadCost => fiddleheadCost.Value; internal int ThistleRespawnTime => thistleRespawnTime.Value; internal int DandelionRespawnTime => dandelionRespawnTime.Value; internal int FiddleheadRespawnTime => fiddleheadRespawnTime.Value; internal int ThistleReturn => thistleReturn.Value; internal int DandelionReturn => dandelionReturn.Value; internal int FiddleheadReturn => fiddleheadReturn.Value; internal bool OverrideModdedSaplings => overrideModdedSaplings.Value; internal float ModdedSaplingMinScale => moddedSaplingMinScale.Value; internal float ModdedSaplingMaxScale => moddedSaplingMaxScale.Value; internal float ModdedSaplingGrowthTime => moddedSaplingGrowthTime.Value; internal float ModdedSaplingGrowRadius => moddedSaplingGrowRadius.Value; internal float BirchMinScale => birchMinScale.Value; internal float BirchMaxScale => birchMaxScale.Value; internal float OakMinScale => oakMinScale.Value; internal float OakMaxScale => oakMaxScale.Value; internal float AncientMinScale => ancientMinScale.Value; internal float AncientMaxScale => ancientMaxScale.Value; internal float BirchGrowthTime => Mathf.Max(birchGrowthTime.Value, 10f); internal float OakGrowthTime => Mathf.Max(oakGrowthTime.Value, 10f); internal float AncientGrowthTime => Mathf.Max(ancientGrowthTime.Value, 10f); internal float BirchGrowRadius => birchGrowRadius.Value; internal float OakGrowRadius => oakGrowRadius.Value; internal float AncientGrowRadius => ancientGrowRadius.Value; internal float BeechGrowthTime => Mathf.Max(beechGrowthTime.Value, 10f); internal float PineGrowthTime => Mathf.Max(pineGrowthTime.Value, 10f); internal float FirGrowthTime => Mathf.Max(firGrowthTime.Value, 10f); internal float BeechMinScale => beechMinScale.Value; internal float BeechMaxScale => beechMaxScale.Value; internal float PineMinScale => pineMinScale.Value; internal float PineMaxScale => pineMaxScale.Value; internal float FirMinScale => firMinScale.Value; internal float FirMaxScale => firMaxScale.Value; internal float BeechGrowRadius => beechGrowRadius.Value; internal float PineGrowRadius => pineGrowRadius.Value; internal float FirGrowRadius => firGrowRadius.Value; internal float YggaMinScale => yggaMinScale.Value; internal float YggaMaxScale => yggaMaxScale.Value; internal float YggaGrowthTime => yggaGrowthTime.Value; internal float YggaGrowRadius => yggaGrowRadius.Value; internal float AutumnBirchMinScale => autumnBirchMinScale.Value; internal float AutumnBirchMaxScale => autumnBirchMaxScale.Value; internal float AutumnBirchGrowthTime => autumnBirchGrowthTime.Value; internal float AutumnBirchGrowRadius => autumnBirchGrowRadius.Value; internal float AshwoodMinScale => ashwoodMinScale.Value; internal float AshwoodMaxScale => ashwoodMaxScale.Value; internal float AshwoodGrowthTime => ashwoodGrowthTime.Value; internal float AshwoodGrowRadius => ashwoodGrowRadius.Value; internal bool EnableSeedOverrides => enableSeedOverrides.Value; internal int SeedDropMin => seedDropMin.Value; internal int SeedDropMax => seedDropMax.Value; internal int TreeDropMin => treeDropMin.Value; internal int TreeDropMax => treeDropMax.Value; internal float DropChance => dropChance.Value; internal bool OneOfEach => oneOfEach.Value; internal bool EnablePickableTimers => enablePickableTimers.Value; internal bool EnablePlantTimers => enablePlantTimers.Value; internal bool GrowthAsPercentage => growthAsPercentage.Value; internal bool EnableVineOverrides => enableVineOverrides.Value; internal float VinesAttachDistance => vineAttachDistance.Value; internal float VineGrowRadius => vineGrowRadius.Value; internal float VinesGrowthTime => vineGrowthTime.Value; internal int VineBerryRespawnTime => vineBerryRespawnTime.Value; internal int VineBerryReturn => vineBerryReturn.Value; internal CustomSyncedValue> SyncedExtraResources => extraResources; internal bool IsSourceOfTruth => ConfigSync.IsSourceOfTruth; internal bool InitialSyncDone => ConfigSync.InitialSyncDone; private ConfigEntry Config(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry val = ConfigFile.Bind(group, name, value, description); ((OwnConfigEntryBase)ConfigSync.AddConfigEntry(val)).SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry Config(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return Config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } internal ModConfig(ConfigFile configFile, ConfigSync configSync) { ConfigFile = configFile; ConfigSync = configSync; configFile.SaveOnConfigSet = false; BindConfigEntries(); configFile.Save(); SetupSettingChangedSubscriptions(); configSync.AddLockingConfigEntry(serverConfigLocked); ConfigWatcher.InitConfigWatcher(); ConfigManagerHelper.Initialize(); } private void BindConfigEntries() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Expected O, but got Unknown //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Expected O, but got Unknown //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Expected O, but got Unknown //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Expected O, but got Unknown //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Expected O, but got Unknown //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Expected O, but got Unknown //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Expected O, but got Unknown //IL_05ae: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Expected O, but got Unknown //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Expected O, but got Unknown //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Expected O, but got Unknown //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Expected O, but got Unknown //IL_068e: Unknown result type (might be due to invalid IL or missing references) //IL_0699: Expected O, but got Unknown //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06d1: Expected O, but got Unknown //IL_06fe: Unknown result type (might be due to invalid IL or missing references) //IL_0709: Expected O, but got Unknown //IL_0736: Unknown result type (might be due to invalid IL or missing references) //IL_0741: Expected O, but got Unknown //IL_076e: Unknown result type (might be due to invalid IL or missing references) //IL_0779: Expected O, but got Unknown //IL_07a6: Unknown result type (might be due to invalid IL or missing references) //IL_07b1: Expected O, but got Unknown //IL_07de: Unknown result type (might be due to invalid IL or missing references) //IL_07e9: Expected O, but got Unknown //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_0821: Expected O, but got Unknown //IL_084e: Unknown result type (might be due to invalid IL or missing references) //IL_0859: Expected O, but got Unknown //IL_0886: Unknown result type (might be due to invalid IL or missing references) //IL_0891: Expected O, but got Unknown //IL_08be: Unknown result type (might be due to invalid IL or missing references) //IL_08c9: Expected O, but got Unknown //IL_08f6: Unknown result type (might be due to invalid IL or missing references) //IL_0901: Expected O, but got Unknown //IL_092e: Unknown result type (might be due to invalid IL or missing references) //IL_0939: Expected O, but got Unknown //IL_0966: Unknown result type (might be due to invalid IL or missing references) //IL_0971: Expected O, but got Unknown //IL_099e: Unknown result type (might be due to invalid IL or missing references) //IL_09a9: Expected O, but got Unknown //IL_09d6: Unknown result type (might be due to invalid IL or missing references) //IL_09e1: Expected O, but got Unknown //IL_0a0e: Unknown result type (might be due to invalid IL or missing references) //IL_0a19: Expected O, but got Unknown //IL_0a46: Unknown result type (might be due to invalid IL or missing references) //IL_0a51: Expected O, but got Unknown //IL_0a7e: Unknown result type (might be due to invalid IL or missing references) //IL_0a89: Expected O, but got Unknown //IL_0e47: Unknown result type (might be due to invalid IL or missing references) //IL_0e52: Expected O, but got Unknown //IL_0e89: Unknown result type (might be due to invalid IL or missing references) //IL_0e94: Expected O, but got Unknown //IL_0ecb: Unknown result type (might be due to invalid IL or missing references) //IL_0ed6: Expected O, but got Unknown //IL_0f0d: Unknown result type (might be due to invalid IL or missing references) //IL_0f18: Expected O, but got Unknown //IL_0f4f: Unknown result type (might be due to invalid IL or missing references) //IL_0f5a: Expected O, but got Unknown //IL_1431: Unknown result type (might be due to invalid IL or missing references) //IL_143c: Expected O, but got Unknown //IL_1463: Unknown result type (might be due to invalid IL or missing references) //IL_146e: Expected O, but got Unknown //IL_1495: Unknown result type (might be due to invalid IL or missing references) //IL_14a0: Expected O, but got Unknown //IL_14c7: Unknown result type (might be due to invalid IL or missing references) //IL_14d2: Expected O, but got Unknown //IL_14f9: Unknown result type (might be due to invalid IL or missing references) //IL_1504: Expected O, but got Unknown //IL_152f: Unknown result type (might be due to invalid IL or missing references) //IL_153a: Expected O, but got Unknown //IL_1561: Unknown result type (might be due to invalid IL or missing references) //IL_156c: Expected O, but got Unknown //IL_15f6: Unknown result type (might be due to invalid IL or missing references) //IL_1601: Expected O, but got Unknown serverConfigLocked = Config("General", "LockConfiguration", value: true, "If on, the configuration is locked and can be changed by server admins only."); nexusID = Config("General", "NexusID", 1042, new ConfigDescription("Nexus mod ID for updates.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = "Internal", ReadOnly = true } }), synchronizedSetting: false); enableDebugMessages = Config("General", "EnableDebugMessages", value: false, "Enable mod debug messages in console.", synchronizedSetting: false); showPickableSpawners = Config("General", "ShowPickableSpawners", value: true, "Continue to show mushroom, thistle, and dandelion spawners after being picked. (Requires world reload on client to take effect.)", synchronizedSetting: false); enableMiscFlora = Config("General", "EnableMiscFlora", value: true, "Enables small trees, bushes, shrubs, vines, and large mushrooms."); enableDebris = Config("General", "EnableDebris", value: true, "Allows for the placement of debris such as branches, flint, and stone."); enableExtraResources = Config("General", "EnableExtraResources", value: false, "When set to true, the mod will attempt to make user-defined prefabs buildable with the cultivator. Prefabs are defined in PlantEverything_ExtraResources.cfg. If file is not present, an example one will be generated for you."); snappableVines = Config("General", "SnappableVines", value: true, "Enables snap points when placing vines adjacently.", synchronizedSetting: false); enableLocalization = Config("General", "EnableLocalization", value: false, "Enable this to attempt to load localized text data for the language set in the following setting.", synchronizedSetting: false); language = Config("General", "Language", "english", "Language to be used. If EnableLocalization is enabled, game will attempt to load localized text from a file named {language}_PlantEverything.json.", synchronizedSetting: false); disabledResourceNames = Config("General", "DisabledResourceNames", "", new ConfigDescription("To disable specific resources added by this mod (and not add them to the cultivator), list their prefab names here separated by a comma. Names are case-sensitive.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = -1 } })); requireCultivation = Config("Difficulty", "RequireCultivation", value: false, "Pickable resources can only be planted on cultivated ground."); placeAnywhere = Config("Difficulty", "PlaceAnywhere", value: false, "Allow resources to be placed anywhere (not just on the ground). Does not apply to mushrooms or flowers."); enforceBiomes = Config("Difficulty", "EnforceBiomes", value: false, "Restrict modded plantables (pickables and saplings) to being placed in their respective biome."); enforceBiomesVanilla = Config("Difficulty", "EnforceBiomesVanilla", value: true, "Restrict vanilla plantables (crops and saplings) to being placed in their respective biome."); plantsRequireShielding = Config("Difficulty", "PlantsRequireShielding", value: true, "Controls whether plants need shielding to survive in hostile environments."); canRemoveFlora = Config("Difficulty", "CanRemoveFlora", value: false, "Allows the cultivator to deconstruct decorative flora placed by a player. Useful for creative game types."); recoverResources = Config("Difficulty", "RecoverResources", value: false, "Recover resources when pickables are removed with the cultivator. Applies to berries, mushrooms, and flowers."); resourcesSpawnEmpty = Config("Difficulty", "ResourcesSpawnEmpty", value: false, "Specifies whether resources should spawn empty or full. Applies to berry bushes, mushrooms, flowers, and debris."); enemiesTargetPieces = Config("Difficulty", "EnemiesTargetPieces", value: true, "When enabled, enemies may target and attack player placed resources added by the mod. If this setting is changed, pre-existing placed pieces will not be affected until the world/server is reloaded."); raspberryCost = Config("Berries", "RaspberryCost", 5, "Number of raspberries required to place a raspberry bush. Set to 0 to disable the ability to plant this resource."); blueberryCost = Config("Berries", "BlueberryCost", 5, "Number of blueberries required to place a blueberry bush. Set to 0 to disable the ability to plant this resource."); cloudberryCost = Config("Berries", "CloudberryCost", 5, "Number of cloudberries required to place a cloudberry bush. Set to 0 to disable the ability to plant this resource."); raspberryRespawnTime = Config("Berries", "RaspberryRespawnTime", 300, "Number of minutes it takes for a raspberry bush to respawn berries."); blueberryRespawnTime = Config("Berries", "BlueberryRespawnTime", 300, "Number of minutes it takes for a blueberry bush to respawn berries."); cloudberryRespawnTime = Config("Berries", "CloudberryRespawnTime", 300, "Number of minutes it takes for a cloudberry bush to respawn berries."); raspberryReturn = Config("Berries", "RaspberryReturn", 1, "Number of berries a raspberry bush will spawn."); blueberryReturn = Config("Berries", "BlueberryReturn", 1, "Number of berries a blueberry bush will spawn."); cloudberryReturn = Config("Berries", "CloudberryReturn", 1, "Number of berries a cloudberry bush will spawn."); enableCropOverrides = Config("Crops", "EnableCropOverrides", value: false, new ConfigDescription("Enables the [Crops] section of this config.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 28 } })); overrideModdedCrops = Config("Crops", "OverrideModdedCrops", value: true, new ConfigDescription("Applies all [Crops] settings to 3rd party modded crops.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[1] })); cropMinScale = Config("Crops", "CropMinScale", 0.9f, new ConfigDescription("The minimum scaling factor used to scale crops upon growth.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); cropMaxScale = Config("Crops", "CropMaxScale", 1.1f, new ConfigDescription("The maximum scaling factor used to scale crops upon growth.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); cropGrowTimeMin = Config("Crops", "CropGrowTimeMin", 4000f, new ConfigDescription("Minimum number of seconds it takes for crops to grow (will take at least 10 seconds after planting to grow).", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); cropGrowTimeMax = Config("Crops", "CropGrowTimeMax", 5000f, new ConfigDescription("Maximum number of seconds it takes for crops to grow (will take at least 10 seconds after planting to grow).", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); cropGrowRadius = Config("Crops", "CropGrowRadius", 0.5f, new ConfigDescription("Radius of free space required for crops to grow.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); cropRequireCultivation = Config("Crops", "CropsRequireCultivation", value: true, new ConfigDescription("Crops can only be planted on cultivated ground.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[1] })); cropRequireSunlight = Config("Crops", "CropsRequireSunlight", value: true, new ConfigDescription("Crops can only grow under an open sky.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[1] })); cropRequireGrowthSpace = Config("Crops", "CropsRequireGrowthSpace", value: true, new ConfigDescription("Crops require space to grow. This setting overrides the CropGrowRadius setting but without altering it, allowing grid spacing mods to continue functioning.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[1] })); enemiesTargetCrops = Config("Crops", "EnemiesTargetCrops", value: true, new ConfigDescription("Determines whether enemies will target and attack crops. If this setting is changed, pre-existing placed crops will not be affected until the world/server is reloaded.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[1] })); barleyCost = Config("Crops", "BarleyCost", 1, new ConfigDescription("Resource cost of planting barley.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); barleyReturn = Config("Crops", "BarleyReturn", 2, new ConfigDescription("Resources gained upon harvesting barley (does not apply to wild barley).", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); carrotCost = Config("Crops", "CarrotCost", 1, new ConfigDescription("Resource cost of planting carrots.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); carrotReturn = Config("Crops", "CarrotReturn", 1, new ConfigDescription("Resources gained upon harvesting carrots.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); flaxCost = Config("Crops", "FlaxCost", 1, new ConfigDescription("Resource cost of planting flax.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); flaxReturn = Config("Crops", "FlaxReturn", 2, new ConfigDescription("Resources gained upon harvesting flax (does not apply to wild flax).", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); onionCost = Config("Crops", "OnionCost", 1, new ConfigDescription("Resource cost of planting onions.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); onionReturn = Config("Crops", "OnionReturn", 1, new ConfigDescription("Resources gained upon harvesting onions.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); seedCarrotCost = Config("Crops", "SeedCarrotCost", 1, new ConfigDescription("Resource cost of planting seed carrots.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); seedCarrotReturn = Config("Crops", "SeedCarrotReturn", 3, new ConfigDescription("Resources gained upon harvesting seed carrots.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); seedOnionCost = Config("Crops", "SeedOnionCost", 1, new ConfigDescription("Resource cost of planting seed onions.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); seedOnionReturn = Config("Crops", "SeedOnionReturn", 3, new ConfigDescription("Resources gained upon harvesting seed onions.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); seedTurnipCost = Config("Crops", "SeedTurnipCost", 1, new ConfigDescription("Resource cost of planting seed turnips.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); seedTurnipReturn = Config("Crops", "SeedTurnipReturn", 3, new ConfigDescription("Resources gained upon harvesting seed turnips.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); turnipCost = Config("Crops", "TurnipCost", 1, new ConfigDescription("Resource cost of planting turnips.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); turnipReturn = Config("Crops", "TurnipReturn", 1, new ConfigDescription("Resources gained upon harvesting turnips.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); magecapCost = Config("Crops", "MagecapCost", 1, new ConfigDescription("Resource cost of planting magecap.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); magecapReturn = Config("Crops", "MagecapReturn", 3, new ConfigDescription("Resources gained upon harvesting magecap.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); jotunPuffsCost = Config("Crops", "JotunPuffsCost", 1, new ConfigDescription("Resource cost of planting Jotun puffs.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); jotunPuffsReturn = Config("Crops", "JotunPuffsReturn", 3, new ConfigDescription("Resources gained upon harvesting Jotun puffs.", (AcceptableValueBase)null, new object[1] { cropSettingAttributes[0] })); pickableBranchCost = Config("Debris", "PickableBranchCost", 5, "Amount of wood required to place branch debris. Set to 0 to disable the ability to plant this resource."); pickableBranchReturn = Config("Debris", "PickableBranchReturn", 1, "Amount of wood that branch debris drops when picked."); pickableBranchRespawnTime = Config("Debris", "PickableBranchRespawnTime", 240, "Number of minutes it takes for a pickable branch to respawn."); pickableStoneCost = Config("Debris", "PickableStoneCost", 1, "Amount of stone required to place stone debris. Set to 0 to disable the ability to plant this resource."); pickableStoneReturn = Config("Debris", "PickableStoneReturn", 1, "Amount of stones that stone debris drops when picked."); pickableStoneRespawnTime = Config("Debris", "PickableStoneRespawnTime", 0, "Number of minutes it takes for a pickable Stone to respawn."); pickableFlintCost = Config("Debris", "PickableFlintCost", 5, "Amount of flint required to place flint debris. Set to 0 to disable the ability to plant this resource."); pickableFlintReturn = Config("Debris", "PickableFlintReturn", 1, "Amount of flint that flint debris drops when picked."); pickableFlintRespawnTime = Config("Debris", "PickableFlintRespawnTime", 240, "Number of minutes it takes for pickable flint to respawn."); mushroomCost = Config("Mushrooms", "MushroomCost", 5, "Number of mushrooms required to place a pickable mushroom spawner. Set to 0 to disable the ability to plant this resource."); yellowMushroomCost = Config("Mushrooms", "YellowMushroomCost", 5, "Number of yellow mushrooms required to place a pickable yellow mushroom spawner. Set to 0 to disable the ability to plant this resource."); blueMushroomCost = Config("Mushrooms", "BlueMushroomCost", 5, "Number of blue mushrooms required to place a pickable blue mushroom spawner. Set to 0 to disable the ability to plant this resource."); smokePuffCost = Config("Mushrooms", "SmokepuffCost", 5, "Number of smoke puffs required to place a pickable smoke puff spawner. Set to 0 to disable the ability to plant this resource."); mushroomRespawnTime = Config("Mushrooms", "MushroomRespawnTime", 240, "Number of minutes it takes for mushrooms to respawn."); yellowMushroomRespawnTime = Config("Mushrooms", "YellowMushroomRespawnTime", 240, "Number of minutes it takes for yellow mushrooms to respawn."); blueMushroomRespawnTime = Config("Mushrooms", "BlueMushroomRespawnTime", 240, "Number of minutes it takes for blue mushrooms to respawn."); smokePuffRespawnTime = Config("Mushrooms", "SmokepuffRespawnTime", 240, "Number of minutes it takes for smoke puffs to respawn."); mushroomReturn = Config("Mushrooms", "MushroomReturn", 1, "Number of mushrooms a pickable mushroom spawner will spawn."); yellowMushroomReturn = Config("Mushrooms", "YellowMushroomReturn", 1, "Number of yellow mushrooms a pickable yellow mushroom spawner will spawn."); blueMushroomReturn = Config("Mushrooms", "BlueMushroomReturn", 1, "Number of blue mushrooms a pickable blue mushroom spawner will spawn."); smokePuffReturn = Config("Mushrooms", "SmokepuffReturn", 1, "Number of smoke puffs a pickable smoke puff spawner will spawn."); thistleCost = Config("Flowers", "ThistleCost", 5, "Number of thistle required to place a pickable thistle spawner. Set to 0 to disable the ability to plant this resource."); dandelionCost = Config("Flowers", "DandelionCost", 5, "Number of dandelion required to place a pickable dandelion spawner. Set to 0 to disable the ability to plant this resource."); fiddleheadCost = Config("Flowers", "FiddleheadCost", 15, "Number of fiddlehead required to place a pickable fiddlehead spawner. Set to 0 to disable the ability to plant this resource."); thistleRespawnTime = Config("Flowers", "ThistleRespawnTime", 240, "Number of minutes it takes for thistle to respawn."); dandelionRespawnTime = Config("Flowers", "DandelionRespawnTime", 240, "Number of minutes it takes for dandelion to respawn."); fiddleheadRespawnTime = Config("Flowers", "FiddleheadRespawnTime", 300, "Number of minutes it takes for fiddlehead to respawn."); thistleReturn = Config("Flowers", "ThistleReturn", 1, "Number of thistle a pickable thistle spawner will spawn."); dandelionReturn = Config("Flowers", "DandelionReturn", 1, "Number of dandelion a pickable dandelion spawner will spawn."); fiddleheadReturn = Config("Flowers", "FiddleheadReturn", 3, "Number of fiddlehead a pickable fiddlehead spawner will spawn."); overrideModdedSaplings = Config("Saplings", "OverrideModdedSaplings", value: false, new ConfigDescription("Applies all [Saplings]Modded* settings to 3rd party modded saplings.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 41 } })); moddedSaplingMinScale = Config("Saplings", "ModdedSaplingMinScale", 0.5f, new ConfigDescription("The minimum scaling factor used to scale a 3rd party modded tree upon growth.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 37 } })); moddedSaplingMaxScale = Config("Saplings", "ModdedSaplingMaxScale", 2f, new ConfigDescription("The maximum scaling factor used to scale a 3rd party modded tree upon growth.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 38 } })); moddedSaplingGrowthTime = Config("Saplings", "ModdedSaplingGrowthTime", 3000f, new ConfigDescription("Number of seconds it takes for a 3rd party modded tree to grow from its modded sapling (will take at least 10 seconds after planting to grow).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 39 } })); moddedSaplingGrowRadius = Config("Saplings", "ModdedSaplingGrowRadius", 2f, new ConfigDescription("Radius of free space required for a 3rd party modded sapling to grow.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 40 } })); birchMinScale = Config("Saplings", "BirchMinScale", 0.5f, "The minimum scaling factor used to scale a birch tree upon growth."); birchMaxScale = Config("Saplings", "BirchMaxScale", 1f, "The maximum scaling factor used to scale a birch tree upon growth."); oakMinScale = Config("Saplings", "OakMinScale", 0.7f, "The minimum scaling factor used to scale an oak tree upon growth."); oakMaxScale = Config("Saplings", "OakMaxScale", 0.9f, "The maximum scaling factor used to scale an oak tree upon growth."); ancientMinScale = Config("Saplings", "AncientMinScale", 0.5f, "The minimum scaling factor used to scale an ancient tree upon growth."); ancientMaxScale = Config("Saplings", "AncientMaxScale", 2f, "The maximum scaling factor used to scale an ancient tree upon growth."); birchGrowthTime = Config("Saplings", "BirchGrowthTime", 3000f, "Number of seconds it takes for a birch tree to grow from a birch sapling (will take at least 10 seconds after planting to grow)."); oakGrowthTime = Config("Saplings", "OakGrowthTime", 3000f, "Number of seconds it takes for an oak tree to grow from an oak sapling (will take at least 10 seconds after planting to grow)."); ancientGrowthTime = Config("Saplings", "AncientGrowthTime", 3000f, "Number of seconds it takes for an ancient tree to grow from an ancient sapling (will take at least 10 seconds after planting to grow)."); birchGrowRadius = Config("Saplings", "BirchGrowRadius", 2f, "Radius of free space required for a birch sapling to grow."); oakGrowRadius = Config("Saplings", "OakGrowRadius", 3f, "Radius of free space required for an oak sapling to grow."); ancientGrowRadius = Config("Saplings", "AncientGrowRadius", 2f, "Radius of free space required for an ancient sapling to grow."); beechGrowthTime = Config("Saplings", "BeechGrowthTime", 3000f, "Number of seconds it takes for a beech tree to grow from a beech sapling (will take at least 10 seconds after planting to grow)."); pineGrowthTime = Config("Saplings", "PineGrowthTime", 3000f, "Number of seconds it takes for a pine tree to grow from a pine sapling (will take at least 10 seconds after planting to grow)."); firGrowthTime = Config("Saplings", "FirGrowthTime", 3000f, "Number of seconds it takes for a fir tree to grow from a fir sapling (will take at least 10 seconds after planting to grow)."); beechMinScale = Config("Saplings", "BeechMinScale", 0.8f, "The minimum scaling factor used to scale a beech tree upon growth."); beechMaxScale = Config("Saplings", "BeechMaxScale", 1.5f, "The maximum scaling factor used to scale a beech tree upon growth."); pineMinScale = Config("Saplings", "PineMinScale", 1.5f, "The minimum scaling factor used to scale a pine tree upon growth."); pineMaxScale = Config("Saplings", "PineMaxScale", 2.5f, "The maximum scaling factor used to scale a pine tree upon growth."); firMinScale = Config("Saplings", "FirMinScale", 1f, "The minimum scaling factor used to scale a fir tree upon growth."); firMaxScale = Config("Saplings", "FirMaxScale", 2.5f, "The maximum scaling factor used to scale a fir tree upon growth."); beechGrowRadius = Config("Saplings", "BeechGrowRadius", 2f, "Radius of free space required for a beech sapling to grow."); pineGrowRadius = Config("Saplings", "PineGrowRadius", 2f, "Radius of free space required for a pine sapling to grow."); firGrowRadius = Config("Saplings", "FirGrowRadius", 2f, "Radius of free space required for a fir sapling to grow."); yggaMinScale = Config("Saplings", "YggaMinScale", 0.5f, "The minimum scaling factor used to scale a ygga tree upon growth."); yggaMaxScale = Config("Saplings", "YggaMaxScale", 2f, "The minimum scaling factor used to scale a ygga tree upon growth."); yggaGrowthTime = Config("Saplings", "YggaGrowthTime", 3000f, "Number of seconds it takes for a ygga tree to grow from a ygga sapling (will take at least 10 seconds after planting to grow)."); yggaGrowRadius = Config("Saplings", "YggaGrowRadius", 2f, "Radius of free space required for a ygga sapling to grow."); autumnBirchMinScale = Config("Saplings", "AutumnBirchMinScale", 0.5f, "The minimum scaling factor used to scale an autumn birch tree upon growth."); autumnBirchMaxScale = Config("Saplings", "AutumnBirchMaxScale", 1f, "The minimum scaling factor used to scale an autumn birch tree upon growth."); autumnBirchGrowthTime = Config("Saplings", "AutumnBirchGrowthTime", 3000f, "Number of seconds it takes for an autumn birch tree to grow from an autumn birch sapling (will take at least 10 seconds after planting to grow)."); autumnBirchGrowRadius = Config("Saplings", "AutumnBirchGrowRadius", 2f, "Radius of free space required for an autumn birch sapling to grow."); ashwoodMinScale = Config("Saplings", "AshwoodMinScale", 0.5f, "The minimum scaling factor used to scale an ashwood tree upon growth."); ashwoodMaxScale = Config("Saplings", "AshwoodMaxScale", 2f, "The minimum scaling factor used to scale an ashwood tree upon growth."); ashwoodGrowthTime = Config("Saplings", "AshwoodGrowthTime", 3000f, "Number of seconds it takes for an ashwood tree to grow from an ashwood sapling (will take at least 10 seconds after planting to grow)."); ashwoodGrowRadius = Config("Saplings", "AshwoodGrowRadius", 2f, "Radius of free space required for an ashwood sapling to grow."); enableSeedOverrides = Config("Seeds", "EnableSeedOverrides", value: false, new ConfigDescription("Enables the [Seeds] section of this config.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); seedDropMin = Config("Seeds", "seedDropMin", 1, new ConfigDescription("Determines minimum amount of seeds that can drop when trees drop seeds.", (AcceptableValueBase)null, new object[1] { seedSettingAtrributes })); seedDropMax = Config("Seeds", "seedDropMax", 2, new ConfigDescription("Determines maximum amount of seeds that can drop when trees drop seeds.", (AcceptableValueBase)null, new object[1] { seedSettingAtrributes })); treeDropMin = Config("Seeds", "treeDropMin", 1, new ConfigDescription("Determines minimum amount of times a destroyed tree will attempt to select a drop from its drop table.", (AcceptableValueBase)null, new object[1] { seedSettingAtrributes })); treeDropMax = Config("Seeds", "treeDropMax", 3, new ConfigDescription("Determines (maximum amount of times - 1) a destroyed tree will attempt to select a drop from its drop table.", (AcceptableValueBase)null, new object[1] { seedSettingAtrributes })); dropChance = Config("Seeds", "dropChance", 0.5f, new ConfigDescription("Chance that items will drop from trees when destroyed. Default value 0.5f (50%). Set between 0 and 1f.", (AcceptableValueBase)null, new object[1] { seedSettingAtrributes })); oneOfEach = Config("Seeds", "oneOfEach", value: false, new ConfigDescription("When enabled, destroyed trees will not drop the same item from its drop table more than once.", (AcceptableValueBase)null, new object[1] { seedSettingAtrributes })); enablePickableTimers = Config("UI", "EnablePickableTimers", value: true, "Enables display of growth time remaining on pickable resources.", synchronizedSetting: false); enablePlantTimers = Config("UI", "EnablePlantTimers", value: true, "Enables display of growth time remaining on planted resources, such as crops and saplings.", synchronizedSetting: false); growthAsPercentage = Config("UI", "GrowthAsPercentage", value: false, "Enables display of growth time as a percentage instead of time remaining.", synchronizedSetting: false); enableVineOverrides = Config("Vines", "EnableVineOverrides", value: false, new ConfigDescription("Enables/Disables the [Vines] section of this config with the exception of color related settings.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 12 } })); vineAttachDistance = Config("Vines", "VineAttachDistance", 1.8f, "Distance at which vine saplings can attach to walls."); vineGrowRadius = Config("Vines", "VineGrowRadius", 1.8f, "Distance from existing wall-attached vines required for an ashvine sapling to mature and attach to a wall."); vineGrowthTime = Config("Vines", "VineGrowthTime", 200f, "Length of time (in seconds) that it takes for a vine ash sapling to mature."); vineBerryRespawnTime = Config("Vines", "VineBerryRespawnTime", 200, "Length of time (in minutes) that it takes for vine berries to regrow"); vineBerryReturn = Config("Vines", "VineBerryReturn", 3, "Resources gained upon harvesting vine berries."); } private void SetupSettingChangedSubscriptions() { ConfigFile.SettingChanged += ConfigEventHandlers.ConfigSettingChanged; showPickableSpawners.SettingChanged += ConfigEventHandlers.CoreSettingChanged; enableMiscFlora.SettingChanged += ConfigEventHandlers.PieceSettingChanged; enableDebris.SettingChanged += ConfigEventHandlers.PieceSettingChanged; snappableVines.SettingChanged += ConfigEventHandlers.CoreSettingChanged; enableExtraResources.SettingChanged += ConfigEventHandlers.ExtraResourcesFileOrSettingChanged; disabledResourceNames.SettingChanged += ConfigEventHandlers.CoreSettingChanged; requireCultivation.SettingChanged += ConfigEventHandlers.CoreSettingChanged; placeAnywhere.SettingChanged += ConfigEventHandlers.CoreSettingChanged; enforceBiomes.SettingChanged += ConfigEventHandlers.CoreSettingChanged; enforceBiomesVanilla.SettingChanged += ConfigEventHandlers.CoreSettingChanged; plantsRequireShielding.SettingChanged += ConfigEventHandlers.CoreSettingChanged; recoverResources.SettingChanged += ConfigEventHandlers.CoreSettingChanged; enemiesTargetPieces.SettingChanged += ConfigEventHandlers.PieceSettingChanged; raspberryCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; blueberryCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; cloudberryCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; raspberryRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; blueberryRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; cloudberryRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; raspberryReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; blueberryReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; cloudberryReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; enableCropOverrides.SettingChanged += ConfigEventHandlers.CropSettingChanged; overrideModdedCrops.SettingChanged += ConfigEventHandlers.CropSettingChanged; cropMinScale.SettingChanged += ConfigEventHandlers.CropSettingChanged; cropMaxScale.SettingChanged += ConfigEventHandlers.CropSettingChanged; cropGrowTimeMin.SettingChanged += ConfigEventHandlers.CropSettingChanged; cropGrowTimeMax.SettingChanged += ConfigEventHandlers.CropSettingChanged; cropGrowRadius.SettingChanged += ConfigEventHandlers.CropSettingChanged; cropRequireCultivation.SettingChanged += ConfigEventHandlers.CropSettingChanged; enemiesTargetCrops.SettingChanged += ConfigEventHandlers.CropSettingChanged; barleyCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; barleyReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; carrotCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; carrotReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; flaxCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; flaxReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; onionCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; onionReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; seedCarrotCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; seedCarrotReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; seedOnionCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; seedOnionReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; seedTurnipCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; seedTurnipReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; turnipCost.SettingChanged += ConfigEventHandlers.CropSettingChanged; turnipReturn.SettingChanged += ConfigEventHandlers.CropSettingChanged; pickableBranchCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableBranchReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableBranchRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableStoneCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableStoneReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableStoneRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableFlintCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableFlintReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; pickableFlintRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; mushroomCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; yellowMushroomCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; blueMushroomCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; smokePuffCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; mushroomRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; yellowMushroomRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; blueMushroomRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; smokePuffRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; mushroomReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; yellowMushroomReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; blueMushroomReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; smokePuffReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; thistleCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; dandelionCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; fiddleheadCost.SettingChanged += ConfigEventHandlers.PieceSettingChanged; thistleRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; dandelionRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; fiddleheadRespawnTime.SettingChanged += ConfigEventHandlers.PieceSettingChanged; thistleReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; dandelionReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; fiddleheadReturn.SettingChanged += ConfigEventHandlers.PieceSettingChanged; overrideModdedSaplings.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; moddedSaplingMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; moddedSaplingMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; moddedSaplingGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; moddedSaplingGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ancientGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ancientGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ancientMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ancientMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; beechGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; beechGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; beechMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; beechMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; pineGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; pineGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; pineMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; pineMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; firGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; firGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; firMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; firMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; birchGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; birchGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; birchMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; birchMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; oakGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; oakGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; oakMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; oakMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; yggaGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; yggaGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; yggaMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; yggaMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; autumnBirchGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; autumnBirchGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; autumnBirchMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; autumnBirchMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ashwoodGrowRadius.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ashwoodGrowthTime.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ashwoodMinScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; ashwoodMaxScale.SettingChanged += ConfigEventHandlers.SaplingSettingChanged; enableSeedOverrides.SettingChanged += ConfigEventHandlers.SeedSettingChanged; seedDropMin.SettingChanged += ConfigEventHandlers.SeedSettingChanged; seedDropMax.SettingChanged += ConfigEventHandlers.SeedSettingChanged; treeDropMin.SettingChanged += ConfigEventHandlers.SeedSettingChanged; treeDropMax.SettingChanged += ConfigEventHandlers.SeedSettingChanged; dropChance.SettingChanged += ConfigEventHandlers.SeedSettingChanged; oneOfEach.SettingChanged += ConfigEventHandlers.SeedSettingChanged; enableVineOverrides.SettingChanged += ConfigEventHandlers.VineSettingChanged; vineAttachDistance.SettingChanged += ConfigEventHandlers.VineSettingChanged; vineGrowRadius.SettingChanged += ConfigEventHandlers.VineSettingChanged; vineGrowthTime.SettingChanged += ConfigEventHandlers.VineSettingChanged; vineBerryRespawnTime.SettingChanged += ConfigEventHandlers.VineSettingChanged; vineBerryReturn.SettingChanged += ConfigEventHandlers.VineSettingChanged; extraResources = new CustomSyncedValue>(ConfigSync, "PE_ExtraResources", new List(), 0); ((CustomSyncedValueBase)extraResources).ValueChanged += ConfigEventHandlers.ExtraResourcesChanged; cropSettingAttributes.ForEach(delegate(ConfigurationManagerAttributes attributes) { attributes.Browsable = enableCropOverrides.Value; }); seedSettingAtrributes.Browsable = enableSeedOverrides.Value; enableCropOverrides.SettingChanged += delegate { cropSettingAttributes.ForEach(delegate(ConfigurationManagerAttributes attributes) { attributes.Browsable = enableCropOverrides.Value; }); ConfigManagerHelper.ReloadConfigDisplay(); }; enableSeedOverrides.SettingChanged += delegate { seedSettingAtrributes.Browsable = enableSeedOverrides.Value; ConfigManagerHelper.ReloadConfigDisplay(); }; } internal void Save() { ConfigFile.Save(); } internal void Reload() { ConfigFile.Reload(); } } internal struct ExtraResource { public string prefabName; public string resourceName; public int resourceCost; public bool groundOnly; public string pieceName; public string pieceDescription; internal readonly bool IsValid() { if (prefabName != null && !prefabName.StartsWith("PE_Fake") && resourceName != null) { return resourceCost != 0; } return false; } } internal static class PluginInitUtils { internal static void InitPrefabRefs() { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Expected O, but got Unknown StaticMembers.Dbgl("InitPrefabRefs", forceLog: false, (LogLevel)16); if (StaticMembers.prefabRefs.Count > 0) { return; } Dictionary allAssetPathsInBundleMappedToAssetID = Runtime.GetAllAssetPathsInBundleMappedToAssetID(); bool flag = false; StaticContent.VanillaPrefabRefs.ForEach(delegate(string s) { StaticMembers.prefabRefs.Add(s, null); }); StaticContent.VanillaPrefabRefs.Clear(); StaticMembers.deserializedExtraResources.ForEach(delegate(ExtraResource er) { StaticMembers.prefabRefs[er.prefabName] = null; }); SoftReference val = default(SoftReference); foreach (string key2 in allAssetPathsInBundleMappedToAssetID.Keys) { if (!key2.EndsWith(".prefab", StringComparison.Ordinal)) { continue; } string key = key2.Split(new char[1] { '/' }).Last().Replace(".prefab", ""); if (StaticMembers.prefabRefs.ContainsKey(key)) { val..ctor(allAssetPathsInBundleMappedToAssetID[key2]); val.Load(); StaticMembers.prefabRefs[key] = val.Asset; if (!StaticMembers.prefabRefs.Any((KeyValuePair keyValuePair) => !Object.op_Implicit((Object)(object)keyValuePair.Value))) { StaticMembers.Dbgl("Found all prefab references.", forceLog: false, (LogLevel)16); flag = true; break; } } } if (!flag) { StaticMembers.Dbgl("Could not find all prefab references, attempting alternate prefab detection method.", forceLog: false, (LogLevel)16); List list = (from kvp in StaticMembers.prefabRefs where !Object.op_Implicit((Object)(object)kvp.Value) select kvp.Key).ToList(); Object[] array = Resources.FindObjectsOfTypeAll(typeof(GameObject)); for (int num = 0; num < array.Length; num++) { GameObject val2 = (GameObject)array[num]; if (list.Contains(((Object)val2).name)) { StaticMembers.prefabRefs[((Object)val2).name] = val2; list.Remove(((Object)val2).name); if (!list.Any()) { StaticMembers.Dbgl("Found all prefab references on second attempt.", forceLog: false, (LogLevel)16); break; } } } foreach (string item in list) { StaticMembers.Dbgl("prefabRefs[" + item + "] value is null, removing key and value pair.", forceLog: false, (LogLevel)16); StaticMembers.prefabRefs.Remove(item); } } StaticContent.CustomPrefabRefs.ForEach(delegate(string s) { StaticMembers.prefabRefs.Add(s, PluginUtils.CreatePrefab(s)); }); StaticContent.CustomPrefabRefs.Clear(); } internal static bool InitExtraResourceRefs(ZNetScene instance, bool logErrors = false) { StaticMembers.Dbgl("InitExtraResourceRefs", forceLog: false, (LogLevel)16); bool result = false; foreach (ExtraResource deserializedExtraResource in StaticMembers.deserializedExtraResources) { if (!StaticMembers.prefabRefs.TryGetValue(deserializedExtraResource.prefabName, out var value)) { value = instance.GetPrefab(deserializedExtraResource.prefabName); if (Object.op_Implicit((Object)(object)value)) { StaticMembers.prefabRefs[deserializedExtraResource.prefabName] = value; StaticMembers.Dbgl("Added " + deserializedExtraResource.prefabName + " to prefabRefs", forceLog: false, (LogLevel)16); result = true; } else { StaticMembers.Dbgl("Could not find prefab reference for " + deserializedExtraResource.prefabName + ", skipping entry.", logErrors || StaticMembers.config.EnableDebugMessages, (LogLevel)4); } } } return result; } internal static void InitPieceRefs() { StaticMembers.Dbgl("InitPieceRefs", forceLog: false, (LogLevel)16); if (StaticMembers.pieceRefs.Count > 0) { PluginUtils.RemoveFromCultivator(StaticMembers.pieceRefs.ConvertAll((Converter)((PieceDB x) => x))); StaticMembers.pieceRefs.Clear(); } StaticMembers.pieceRefs = StaticContent.GeneratePieceRefs(); } internal static void InitPieces() { //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Expected O, but got Unknown //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) StaticMembers.Dbgl("InitPieces", forceLog: false, (LogLevel)16); foreach (PieceDB pdb in StaticMembers.pieceRefs) { if (StaticMembers.config.DisabledResourceNames.Contains(pdb.key)) { StaticMembers.Dbgl("Resource disabled: " + pdb.key + ", skipping.", forceLog: false, (LogLevel)16); pdb.enabled = false; } ItemDrop component = ObjectDB.instance.GetItemPrefab(pdb.Resource.Key).GetComponent(); if (pdb.Resources.Count > 0) { List list = new List(); foreach (string key in pdb.Resources.Keys) { list.Add(new Requirement { m_resItem = ObjectDB.instance.GetItemPrefab(key).GetComponent(), m_amount = pdb.Resources[key], m_recover = pdb.recover }); } pdb.Piece.m_resources = list.ToArray(); } else { pdb.Piece.m_resources = (Requirement[])(object)new Requirement[1] { new Requirement { m_resItem = component, m_amount = pdb.ResourceCost, m_recover = pdb.recover } }; } pdb.Piece.m_icon = (pdb.icon ? PluginUtils.CreateSprite(pdb.key + "PieceIcon.png", new Rect(0f, 0f, 64f, 64f)) : component.m_itemData.GetIcon()); pdb.Piece.m_placeEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[2] { new EffectData { m_prefab = StaticMembers.prefabRefs["vfx_Place_wood_pole"], m_enabled = true }, new EffectData { m_prefab = StaticMembers.prefabRefs["sfx_build_cultivator"], m_enabled = true } }; if (pdb.snapPoints != null) { Transform val = pdb.Prefab.transform.Find("_snappoint"); if (StaticMembers.config.SnappableVines) { if (!Object.op_Implicit((Object)(object)val)) { foreach (Vector3 snapPoint in pdb.snapPoints) { GameObject val2 = new GameObject("_snappoint") { tag = "snappoint" }; val2.transform.position = snapPoint; val2.transform.SetParent(pdb.Prefab.transform); val2.SetActive(false); } } } else { while (Object.op_Implicit((Object)(object)val)) { Object.DestroyImmediate((Object)(object)((Component)val).gameObject); val = pdb.Prefab.transform.Find("_snappoint"); } } } Pickable component2 = pdb.Prefab.GetComponent(); if (!Object.op_Implicit((Object)(object)component2) || StaticMembers.deserializedExtraResources.Any((ExtraResource x) => x.prefabName == pdb.key)) { continue; } component2.m_respawnTimeMinutes = pdb.respawnTime; component2.m_amount = pdb.resourceReturn; pdb.Piece.m_onlyInBiome = pdb.biome; if (pdb.hideWhenPicked) { component2.m_hideWhenPicked = ((pdb.respawnTime > 0) ? ((Component)component2).gameObject : null); } Transform val3 = pdb.Prefab.transform.Find("visual"); if (!Object.op_Implicit((Object)(object)val3)) { continue; } Transform val4 = StaticMembers.prefabRefs[pdb.key + "_Picked"].transform.Find("PE_Picked"); if (Object.op_Implicit((Object)(object)val4)) { if (StaticMembers.config.ShowPickableSpawners) { val4.SetParent(pdb.Prefab.transform); } if (!StaticMembers.piecesInitialized) { MeshRenderer component3 = ((Component)val4).GetComponent(); MeshRenderer component4 = ((Component)val3).GetComponent(); ((Renderer)component3).sharedMaterials = ((pdb.key == "Pickable_Thistle") ? ((Renderer)((Component)val3.Find("default")).GetComponent()).sharedMaterials : ((Renderer)component4).sharedMaterials); if (pdb.key.Contains("Dandelion")) { Material val5 = ((Renderer)component4).sharedMaterials[0]; ((Renderer)component3).sharedMaterials = (Material[])(object)new Material[2] { val5, val5 }; } } } else { Transform val6 = StaticMembers.prefabRefs[pdb.key].transform.Find("PE_Picked"); if (!StaticMembers.config.ShowPickableSpawners && Object.op_Implicit((Object)(object)val6)) { val6.SetParent(StaticMembers.prefabRefs[pdb.key + "_Picked"].transform); } } if (pdb.extraDrops) { component2.m_extraDrops.m_drops.Clear(); } } StaticMembers.piecesInitialized = true; } internal static void InitSaplingRefs() { StaticMembers.Dbgl("InitSaplingRefs", forceLog: false, (LogLevel)16); if (StaticMembers.saplingRefs.Count > 0) { PluginUtils.RemoveFromCultivator(StaticMembers.saplingRefs.ConvertAll((Converter)((SaplingDB x) => x))); StaticMembers.saplingRefs.Clear(); } StaticMembers.saplingRefs = StaticContent.GenerateCustomSaplingRefs(); } internal static void InitSaplings() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_094c: Unknown result type (might be due to invalid IL or missing references) //IL_0958: Unknown result type (might be due to invalid IL or missing references) //IL_0959: Unknown result type (might be due to invalid IL or missing references) //IL_095b: Unknown result type (might be due to invalid IL or missing references) //IL_0960: Unknown result type (might be due to invalid IL or missing references) //IL_0962: Unknown result type (might be due to invalid IL or missing references) //IL_0953: Unknown result type (might be due to invalid IL or missing references) //IL_078a: Unknown result type (might be due to invalid IL or missing references) StaticMembers.Dbgl("InitSaplings", forceLog: false, (LogLevel)16); ModifyTreeDrops(); AssetID val2 = default(AssetID); SoftReference val3 = default(SoftReference); foreach (SaplingDB item in StaticContent.GenerateVanillaSaplingRefs().Concat(StaticMembers.saplingRefs)) { Plant component = item.Prefab.GetComponent(); Piece component2 = item.Prefab.GetComponent(); component.m_growTime = (component.m_growTimeMax = item.growTime); component.m_growRadius = item.growRadius; component.m_minScale = item.minScale; component.m_maxScale = item.maxScale; component2.m_onlyInBiome = (component.m_biome = item.biome); component.m_tolerateCold = item.tolerateCold || !StaticMembers.config.PlantsRequireShielding; component.m_tolerateHeat = item.tolerateHeat || !StaticMembers.config.PlantsRequireShielding; component.m_destroyIfCantGrow = (component2.m_groundOnly = !StaticMembers.config.PlaceAnywhere); if (!StaticMembers.saplingRefs.Contains(item)) { continue; } component.m_grownPrefabs = item.grownPrefabs; List list = new List(); foreach (string key in item.Resources.Keys) { list.Add(new Requirement { m_resItem = ObjectDB.instance.GetItemPrefab(key).GetComponent(), m_amount = item.Resources[key], m_recover = false }); } component2.m_resources = list.ToArray(); if (StaticMembers.config.DisabledResourceNames.Contains(item.key)) { StaticMembers.Dbgl("Resource disabled: " + item.key, forceLog: false, (LogLevel)16); item.enabled = false; } if (StaticMembers.saplingsInitialized) { continue; } string[] array = new string[2] { "healthy", "unhealthy" }; Transform val = StaticMembers.prefabRefs["Birch_Sapling"].transform.Find(array[0]); Shader shader; if (!StaticMembers.isDedicatedServer) { AssetID.TryParse("f6de4704e075b4095ae641aed283b641", ref val2); val3..ctor(val2); val3.Load(); shader = val3.Asset; } else { shader = Shader.Find("Custom/Piece"); } if (item.source != "AshlandsTree3") { string[] array2 = array; foreach (string text in array2) { ((Component)item.Prefab.transform.Find(text)).GetComponent().mesh = ((Component)val.Find("Birch_Sapling")).GetComponent().mesh; } } switch (item.source) { case "YggaShoot_small1": { string[] array7 = new string[6] { "birchleafs002", "birchleafs003", "birchleafs008", "birchleafs009", "birchleafs010", "birchleafs011" }; Material[] sharedMaterials3 = (Material[])(object)new Material[1] { ((Renderer)((Component)StaticMembers.prefabRefs[item.source].transform.Find("beech")).GetComponent()).sharedMaterials[0] }; Material[] sharedMaterials4 = (Material[])(object)new Material[1] { ((Renderer)((Component)StaticMembers.prefabRefs[item.source].transform.Find("beech")).GetComponent()).sharedMaterials[1] }; string[] array2 = array; foreach (string text7 in array2) { ((Renderer)((Component)item.Prefab.transform.Find(text7)).GetComponent()).sharedMaterials = sharedMaterials4; } array2 = array7; foreach (string text8 in array2) { string[] array6 = array; foreach (string text9 in array6) { ((Component)item.Prefab.transform.Find(text9).Find(text8)).GetComponent().mesh = ((Component)val.Find(text8)).GetComponent().mesh; ((Renderer)((Component)item.Prefab.transform.Find(text9).Find(text8)).GetComponent()).sharedMaterials = sharedMaterials3; } } break; } case "SwampTree1": { Material[] array4 = (Material[])(object)new Material[1] { ((Renderer)((Component)StaticMembers.prefabRefs[item.source].transform.Find("swamptree1")).GetComponent()).sharedMaterials[0] }; array4[0].shader = shader; string[] array2 = array; foreach (string text3 in array2) { ((Renderer)((Component)item.Prefab.transform.Find(text3)).GetComponent()).sharedMaterials = array4; } break; } case "Birch1_aut": { string[] array5 = new string[6] { "birchleafs002", "birchleafs003", "birchleafs008", "birchleafs009", "birchleafs010", "birchleafs011" }; Material[] sharedMaterials = (Material[])(object)new Material[1] { ((Renderer)((Component)StaticMembers.prefabRefs[item.source].transform.Find("Lod0")).GetComponent()).sharedMaterials[0] }; Material[] sharedMaterials2 = (Material[])(object)new Material[1] { ((Renderer)((Component)val.Find("Birch_Sapling")).GetComponent()).sharedMaterials[0] }; string[] array2 = array; foreach (string text4 in array2) { ((Renderer)((Component)item.Prefab.transform.Find(text4)).GetComponent()).sharedMaterials = sharedMaterials2; } array2 = array5; foreach (string text5 in array2) { string[] array6 = array; foreach (string text6 in array6) { ((Component)item.Prefab.transform.Find(text6).Find(text5)).GetComponent().mesh = ((Component)val.Find(text5)).GetComponent().mesh; ((Renderer)((Component)item.Prefab.transform.Find(text6).Find(text5)).GetComponent()).sharedMaterials = sharedMaterials; } } break; } case "AshlandsTree3": { Transform val4 = StaticMembers.prefabRefs[item.source].transform.Find("default"); MeshRenderer component3 = ((Component)val4).GetComponent(); Material[] array3 = (Material[])(object)new Material[1] { ((Renderer)component3).sharedMaterials[0] }; array3[0].shader = shader; array3[0].SetTexture("_EmissionMap", ((Renderer)component3).sharedMaterials[0].GetTexture("_EmissiveTex")); string[] array2 = array; foreach (string text2 in array2) { ((Component)item.Prefab.transform.Find(text2)).GetComponent().mesh = ((Component)val4).GetComponent().mesh; ((Renderer)((Component)item.Prefab.transform.Find(text2)).GetComponent()).sharedMaterials = array3; } break; } } component2.m_icon = (item.icon ? PluginUtils.CreateSprite(item.key + "PieceIcon.png", new Rect(0f, 0f, 64f, 64f)) : component2.m_resources[0].m_resItem.m_itemData.GetIcon()); component2.m_placeEffect.m_effectPrefabs[0].m_prefab = StaticMembers.prefabRefs["vfx_Place_wood_pole"]; component2.m_placeEffect.m_effectPrefabs[1].m_prefab = StaticMembers.prefabRefs["sfx_build_cultivator"]; item.Prefab.GetComponent().m_hitEffect.m_effectPrefabs = StaticMembers.prefabRefs["Birch_Sapling"].GetComponent().m_hitEffect.m_effectPrefabs; } StaticMembers.saplingsInitialized = true; if (StaticMembers.moddedSaplingRefs.Count == 0) { return; } bool overrideModdedSaplings = StaticMembers.config.OverrideModdedSaplings; foreach (ModdedPlantDB moddedSaplingRef in StaticMembers.moddedSaplingRefs) { if (!Object.op_Implicit((Object)(object)moddedSaplingRef.Prefab)) { StaticMembers.Dbgl(moddedSaplingRef.key + " reference is null, skipping application of modded sapling override settings", forceLog: true, (LogLevel)4); continue; } Piece component4 = moddedSaplingRef.Prefab.GetComponent(); Plant component5 = moddedSaplingRef.Prefab.GetComponent(); component5.m_growTime = (overrideModdedSaplings ? StaticMembers.config.ModdedSaplingGrowthTime : moddedSaplingRef.growTime); component5.m_growTimeMax = (overrideModdedSaplings ? StaticMembers.config.ModdedSaplingGrowthTime : moddedSaplingRef.growTimeMax); component5.m_growRadius = (overrideModdedSaplings ? StaticMembers.config.ModdedSaplingGrowRadius : moddedSaplingRef.growRadius); component5.m_minScale = (overrideModdedSaplings ? StaticMembers.config.ModdedSaplingMinScale : moddedSaplingRef.minScale); component5.m_maxScale = (overrideModdedSaplings ? StaticMembers.config.ModdedSaplingMaxScale : moddedSaplingRef.maxScale); component4.m_onlyInBiome = (component5.m_biome = ((overrideModdedSaplings && !StaticMembers.config.EnforceBiomes) ? StaticMembers.AllBiomes : moddedSaplingRef.biome)); component5.m_tolerateCold = moddedSaplingRef.tolerateCold || !StaticMembers.config.PlantsRequireShielding; component5.m_tolerateHeat = moddedSaplingRef.tolerateHeat || !StaticMembers.config.PlantsRequireShielding; component5.m_destroyIfCantGrow = (component4.m_groundOnly = !StaticMembers.config.PlaceAnywhere); } } internal static void ModifyTreeDrops() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!StaticMembers.config.EnableSeedOverrides) { return; } foreach (KeyValuePair treesToSeed in StaticContent.TreesToSeeds) { TreeBase component = treesToSeed.Key.GetComponent(); DropData item = default(DropData); bool flag = false; foreach (DropData drop in component.m_dropWhenDestroyed.m_drops) { if (((object)drop.m_item).Equals((object?)treesToSeed.Value)) { flag = true; item = drop; break; } } if (flag) { component.m_dropWhenDestroyed.m_drops.Remove(item); } item.m_item = treesToSeed.Value; item.m_stackMin = StaticMembers.config.SeedDropMin; item.m_stackMax = StaticMembers.config.SeedDropMax; item.m_weight = 1f; component.m_dropWhenDestroyed.m_dropMin = StaticMembers.config.TreeDropMin; component.m_dropWhenDestroyed.m_dropMax = StaticMembers.config.TreeDropMax; component.m_dropWhenDestroyed.m_drops.Add(item); component.m_dropWhenDestroyed.m_dropChance = Mathf.Clamp(StaticMembers.config.DropChance, 0f, 1f); component.m_dropWhenDestroyed.m_oneOfEach = StaticMembers.config.OneOfEach; } } internal static void InitCrops() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) StaticMembers.Dbgl("InitCrops", forceLog: false, (LogLevel)16); bool enableCropOverrides = StaticMembers.config.EnableCropOverrides; foreach (PrefabDB item in StaticContent.GenerateCropRefs()) { Piece component = item.Prefab.GetComponent(); Plant component2 = item.Prefab.GetComponent(); Pickable component3 = component2.m_grownPrefabs[0].GetComponent(); component.m_resources[0].m_amount = item.resourceCost; ((StaticTarget)component).m_primaryTarget = (((StaticTarget)component).m_randomTarget = StaticMembers.config.EnemiesTargetCrops); component2.m_biome = item.biome; component2.m_tolerateCold = item.tolerateCold || !StaticMembers.config.PlantsRequireShielding; component2.m_tolerateHeat = item.tolerateHeat || !StaticMembers.config.PlantsRequireShielding; component2.m_minScale = (enableCropOverrides ? StaticMembers.config.CropMinScale : 0.9f); component2.m_maxScale = (enableCropOverrides ? StaticMembers.config.CropMaxScale : 1.1f); component2.m_growTime = (enableCropOverrides ? StaticMembers.config.CropGrowTimeMin : 4000f); component2.m_growTimeMax = (enableCropOverrides ? StaticMembers.config.CropGrowTimeMax : 5000f); component2.m_growRadius = (enableCropOverrides ? StaticMembers.config.CropGrowRadius : 0.5f); component2.m_needCultivatedGround = (component.m_cultivatedGroundOnly = !enableCropOverrides || StaticMembers.config.CropRequireCultivation); component3.m_amount = item.resourceReturn; component3.m_extraDrops.m_drops.Clear(); if (item.extraDrops && !enableCropOverrides) { component3.m_extraDrops.m_drops.Add(new DropData { m_item = component3.m_itemPrefab, m_stackMin = 1, m_stackMax = 1, m_weight = 0f }); } } if (StaticMembers.moddedCropRefs.Count == 0) { return; } enableCropOverrides = enableCropOverrides && StaticMembers.config.OverrideModdedCrops; foreach (ModdedPlantDB moddedCropRef in StaticMembers.moddedCropRefs) { if (!Object.op_Implicit((Object)(object)moddedCropRef.Prefab)) { StaticMembers.Dbgl(moddedCropRef.key + " reference is null, skipping application of crop override settings", forceLog: true, (LogLevel)4); continue; } Piece component4 = moddedCropRef.Prefab.GetComponent(); Plant component5 = moddedCropRef.Prefab.GetComponent(); ((StaticTarget)component4).m_primaryTarget = (((StaticTarget)component4).m_randomTarget = StaticMembers.config.EnemiesTargetCrops); component5.m_biome = ((enableCropOverrides && !StaticMembers.config.EnforceBiomesVanilla) ? StaticMembers.AllBiomes : moddedCropRef.biome); component5.m_tolerateCold = moddedCropRef.tolerateCold || !StaticMembers.config.PlantsRequireShielding; component5.m_tolerateHeat = moddedCropRef.tolerateHeat || !StaticMembers.config.PlantsRequireShielding; component5.m_minScale = (enableCropOverrides ? StaticMembers.config.CropMinScale : moddedCropRef.minScale); component5.m_maxScale = (enableCropOverrides ? StaticMembers.config.CropMaxScale : moddedCropRef.maxScale); component5.m_growTime = (enableCropOverrides ? StaticMembers.config.CropGrowTimeMin : moddedCropRef.growTime); component5.m_growTimeMax = (enableCropOverrides ? StaticMembers.config.CropGrowTimeMax : moddedCropRef.growTimeMax); component5.m_growRadius = (enableCropOverrides ? StaticMembers.config.CropGrowRadius : moddedCropRef.growRadius); component5.m_needCultivatedGround = (component4.m_cultivatedGroundOnly = !enableCropOverrides || StaticMembers.config.CropRequireCultivation); } } internal static void InitVines() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) StaticMembers.Dbgl("InitVines", forceLog: false, (LogLevel)16); Plant component = StaticMembers.prefabRefs["VineAsh_sapling"].GetComponent(); Pickable component2 = StaticMembers.prefabRefs["VineAsh"].GetComponent(); component.m_biome = (Biome)(StaticMembers.config.EnforceBiomesVanilla ? 827 : 895); component.m_needCultivatedGround = (StaticMembers.prefabRefs["VineAsh_sapling"].GetComponent().m_cultivatedGroundOnly = !StaticMembers.config.EnableCropOverrides || StaticMembers.config.CropRequireCultivation); component.m_growTime = (StaticMembers.config.EnableVineOverrides ? StaticMembers.config.VinesGrowthTime : 200f); component.m_growTimeMax = (StaticMembers.config.EnableVineOverrides ? StaticMembers.config.VinesGrowthTime : 300f); component.m_attachDistance = (StaticMembers.config.EnableVineOverrides ? StaticMembers.config.VinesAttachDistance : 1.8f); component.m_growRadiusVines = (StaticMembers.config.EnableVineOverrides ? StaticMembers.config.VineGrowRadius : 1.8f); component.m_tolerateCold = !StaticMembers.config.PlantsRequireShielding; component2.m_amount = (StaticMembers.config.EnableVineOverrides ? StaticMembers.config.VineBerryReturn : 3); component2.m_respawnTimeInitMax = ((!StaticMembers.config.EnableVineOverrides) ? 150 : 0); component2.m_respawnTimeMinutes = (StaticMembers.config.EnableVineOverrides ? StaticMembers.config.VineBerryRespawnTime : 200); } internal static void InitCultivator() { StaticMembers.Dbgl("InitCultivator", forceLog: false, (LogLevel)16); PieceTable buildPieces = StaticMembers.prefabRefs["Cultivator"].GetComponent().m_itemData.m_shared.m_buildPieces; for (int i = 0; i < StaticMembers.saplingRefs.Count; i++) { if (StaticMembers.saplingRefs[i].enabled && !buildPieces.m_pieces.Contains(StaticMembers.saplingRefs[i].Prefab)) { buildPieces.m_pieces.Insert(16, StaticMembers.saplingRefs[i].Prefab); } } for (int j = 0; j < StaticMembers.pieceRefs.Count; j++) { if (StaticMembers.pieceRefs[j].enabled && !buildPieces.m_pieces.Contains(StaticMembers.pieceRefs[j].Prefab)) { buildPieces.m_pieces.Add(StaticMembers.pieceRefs[j].Prefab); } } buildPieces.m_canRemovePieces = true; } public static void InitLocalization() { StaticMembers.Dbgl("InitLocalization", forceLog: false, (LogLevel)16); foreach (KeyValuePair defaultLocalizedString in StaticContent.DefaultLocalizedStrings) { Localization.instance.AddWord("pe" + defaultLocalizedString.Key, defaultLocalizedString.Value); } StaticContent.DefaultLocalizedStrings.Clear(); } internal static void FullInit(ZNetScene instance) { StaticMembers.Dbgl("Performing full mod initialization", forceLog: false, (LogLevel)16); InitExtraResourceRefs(instance); InitPieceRefs(); InitPieces(); InitSaplingRefs(); InitSaplings(); InitCrops(); InitVines(); InitCultivator(); if (StaticContent.DefaultLocalizedStrings.Count > 0) { InitLocalization(); } for (int i = 0; i < StaticMembers.saplingRefs.Count; i++) { GameObject prefab = StaticMembers.saplingRefs[i].Prefab; if (!instance.m_prefabs.Contains(prefab)) { instance.m_prefabs.Add(prefab); instance.m_namedPrefabs.Add(instance.GetPrefabHash(prefab), prefab); } } } } internal static class PluginUtils { internal static bool HoldingCultivator { get { Player localPlayer = Player.m_localPlayer; return ((localPlayer == null) ? null : ((Humanoid)localPlayer).GetRightItem()?.m_shared.m_name) == "$item_cultivator"; } } internal static AssetBundle LoadAssetBundle(string fileName) { return AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("Advize_PlantEverything.Assets." + fileName)); } internal static GameObject CreatePrefab(string name) { GameObject obj = StaticMembers.assetBundle.LoadAsset(name); obj.SetActive(true); return obj; } internal static Piece GetOrAddPieceComponent(GameObject go) { return go.GetComponent() ?? go.AddComponent(); } internal static string GetPrefabName(Component c) { return ((Object)c.transform.root).name.Replace("(Clone)", ""); } internal static bool IsModdedPrefab(Component c) { if (Object.op_Implicit((Object)(object)c)) { return StaticMembers.prefabRefs.ContainsKey(GetPrefabName(c)); } return false; } internal static bool IsModdedPrefabOrSapling(string s) { if (!s.StartsWith("$pe")) { return s.EndsWith("_sapling"); } return true; } internal static void RemoveFromCultivator(List prefabs) { if (HoldingCultivator) { SheatheCultivator(); } PieceTable pieceTable = StaticMembers.prefabRefs["Cultivator"].GetComponent().m_itemData.m_shared.m_buildPieces; prefabs.ForEach(delegate(PrefabDB x) { pieceTable.m_pieces.Remove(x.Prefab); }); } internal static void SheatheCultivator() { StaticMembers.Dbgl("Cultivator updated through config change, unequipping cultivator.", forceLog: true, (LogLevel)16); if (!ZNet.instance.HaveStopped) { ((Humanoid)Player.m_localPlayer).HideHandItems(false, true); } } internal static Piece CreatePiece(PieceDB pdb) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) Piece orAddPieceComponent = GetOrAddPieceComponent(StaticMembers.prefabRefs[pdb.key]); orAddPieceComponent.m_name = (pdb.extraResource ? pdb.pieceName : ("$pe" + pdb.Name + "Name")); orAddPieceComponent.m_description = (pdb.extraResource ? pdb.pieceDescription : ("$pe" + pdb.Name + "Description")); orAddPieceComponent.m_category = (PieceCategory)0; orAddPieceComponent.m_cultivatedGroundOnly = (pdb.key.Contains("berryBush") || pdb.key.Contains("Pickable")) && StaticMembers.config.RequireCultivation; bool num = pdb.isGrounded ?? (!StaticMembers.config.PlaceAnywhere); bool groundOnly = num; orAddPieceComponent.m_groundPiece = num; orAddPieceComponent.m_groundOnly = groundOnly; orAddPieceComponent.m_canBeRemoved = pdb.canBeRemoved ?? true; orAddPieceComponent.m_targetNonPlayerBuilt = false; ((StaticTarget)orAddPieceComponent).m_randomTarget = StaticMembers.config.EnemiesTargetPieces; return orAddPieceComponent; } internal static Sprite CreateSprite(string fileName, Rect spriteSection) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) try { Texture2D val = LoadTexture(fileName); Sprite val2; if (StaticMembers.cachedSprites.ContainsKey(val)) { val2 = StaticMembers.cachedSprites[val]; } else { val2 = Sprite.Create(val, spriteSection, Vector2.zero); StaticMembers.cachedSprites.Add(val, val2); } return val2; } catch { StaticMembers.Dbgl("Unable to load texture", forceLog: true, (LogLevel)2); } return null; } private static Texture2D LoadTexture(string fileName) { Texture2D val; if (StaticMembers.cachedTextures.ContainsKey(fileName)) { val = StaticMembers.cachedTextures[fileName]; } else { val = StaticMembers.assetBundle.LoadAsset(fileName); StaticMembers.cachedTextures.Add(fileName, val); } return val; } private static string SerializeExtraResource(ExtraResource extraResource, bool prettyPrint = true) { return JsonUtility.ToJson((object)extraResource, prettyPrint); } internal static ExtraResource DeserializeExtraResource(string extraResource) { return JsonUtility.FromJson(extraResource); } private static void SaveExtraResources() { string text = Path.Combine(StaticMembers.CustomConfigPath, "ExtraResources.json"); StaticMembers.Dbgl($"deserializedExtraResources.Count is {StaticMembers.deserializedExtraResources.Count}", forceLog: false, (LogLevel)16); string text2 = ""; text2 = text2 + SerializeExtraResource(StaticMembers.deserializedExtraResources[0]) + ";\n\n"; text2 = text2 + SerializeExtraResource(StaticMembers.deserializedExtraResources[1], prettyPrint: false) + ";\n"; File.WriteAllText(text, text2); StaticMembers.Dbgl("Serialized extraResources to " + text, forceLog: true, (LogLevel)16); } internal static void LoadExtraResources() { StaticMembers.Dbgl("LoadExtraResources", forceLog: false, (LogLevel)16); StaticMembers.deserializedExtraResources.Clear(); string text = "ExtraResources.json"; string text2 = Path.Combine(StaticMembers.CustomConfigPath, text); try { string[] array = File.ReadAllText(text2).Split(new char[1] { ';' }); foreach (string text3 in array) { if (!Utility.IsNullOrWhiteSpace(text3)) { ExtraResource item = DeserializeExtraResource(text3); if (item.IsValid()) { StaticMembers.deserializedExtraResources.Add(item); } else if (!item.prefabName.StartsWith("PE_Fake")) { StaticMembers.Dbgl("Invalid resource, " + item.prefabName + ", configured in " + text + ", skipping entry", forceLog: true, (LogLevel)4); } } } StaticMembers.Dbgl("Loaded extra resources from " + text2, forceLog: true, (LogLevel)16); StaticMembers.Dbgl("Assigning local value from deserializedExtraResources", forceLog: false, (LogLevel)16); List resourcesToSync = new List(); StaticMembers.deserializedExtraResources.ForEach(delegate(ExtraResource er) { resourcesToSync.Add(SerializeExtraResource(er)); }); StaticMembers.config.SyncedExtraResources.AssignLocalValue(resourcesToSync); } catch (Exception ex) { if (ex is FileNotFoundException) { StaticMembers.Dbgl("Error loading data from " + text + ". Generating new file with example values", forceLog: true, (LogLevel)4); StaticMembers.deserializedExtraResources = StaticContent.GenerateExampleResources(); SaveExtraResources(); } else { StaticMembers.Dbgl("Error loading data from " + text + ". Additional resources have not been added", forceLog: false, (LogLevel)4); StaticMembers.deserializedExtraResources.Clear(); } } } internal static void LoadLocalizedStrings() { string path = StaticMembers.config.Language + "_PlantEverything.json"; string text = Path.Combine(StaticMembers.CustomConfigPath, path); try { foreach (string localizedString in JsonUtility.FromJson(File.ReadAllText(text)).LocalizedStrings) { string[] array = localizedString.Split(new char[1] { ':' }); StaticContent.DefaultLocalizedStrings.Remove(array[0]); StaticContent.DefaultLocalizedStrings.Add(array[0], array[1]); } StaticMembers.Dbgl("Loaded localized strings from " + text, forceLog: false, (LogLevel)16); return; } catch { StaticMembers.Dbgl("EnableLocalization is true but unable to load localized text file, generating new one from default English values", forceLog: true, (LogLevel)16); } SerializeDict(); } private static void SerializeDict() { string text = Path.Combine(StaticMembers.CustomConfigPath, "english_PlantEverything.json"); ModLocalization modLocalization = new ModLocalization(); foreach (KeyValuePair defaultLocalizedString in StaticContent.DefaultLocalizedStrings) { modLocalization.LocalizedStrings.Add(defaultLocalizedString.Key + ":" + defaultLocalizedString.Value); } File.WriteAllText(text, JsonUtility.ToJson((object)modLocalization, true)); StaticMembers.Dbgl("Saved english localized strings to " + text, forceLog: false, (LogLevel)16); } internal static Biome GetBiomeMask(Biome[] biomes) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Biome val = (Biome)0; foreach (Biome val2 in biomes) { val |= val2; } return val; } internal static string SetupConfigDirectory() { string text = Path.Combine(Paths.ConfigPath, "PlantEverything"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } return text; } } internal class PrefabDB { internal string key; internal Biome biome; protected Dictionary resources; internal int resourceCost; internal int resourceReturn; internal bool extraDrops; internal bool tolerateCold; internal bool tolerateHeat; internal bool icon; internal bool enabled = true; internal GameObject Prefab => StaticMembers.prefabRefs[key]; internal KeyValuePair Resource { get { if (Resources.Count <= 0) { return new KeyValuePair(((Object)Prefab.GetComponent().m_itemPrefab).name, resourceCost); } return Resources.First(); } set { if (resources == null) { resources = new Dictionary(); } resources.Add(value.Key, value.Value); } } internal Dictionary Resources { get { return resources ?? new Dictionary(); } set { resources = value; } } } internal sealed class PieceDB : PrefabDB { internal int respawnTime; internal bool recover; private Piece piece; internal List snapPoints; private string name; internal string pieceName; internal string pieceDescription; internal bool? isGrounded; internal bool? canBeRemoved; internal bool extraResource; internal bool hideWhenPicked; internal Piece Piece => piece ?? (piece = PluginUtils.CreatePiece(this)); internal string Name { get { return name ?? key; } set { name = value; } } internal int ResourceCost { get { return resourceCost; } set { resourceCost = value; enabled = value != 0; } } } internal sealed class SaplingDB : PrefabDB { internal string source; internal float growTime; internal float growRadius; internal float minScale; internal float maxScale; internal GameObject[] grownPrefabs; } internal sealed class ModdedPlantDB : PrefabDB { internal float minScale; internal float maxScale; internal float growTime; internal float growTimeMax; internal float growRadius; } internal static class StaticContent { internal static Dictionary DefaultLocalizedStrings = new Dictionary { { "AncientSaplingName", "Ancient Sapling" }, { "AncientSaplingDescription", "" }, { "YggaSaplingName", "Ygga Sapling" }, { "YggaSaplingDescription", "" }, { "AutumnBirchSaplingName", "Autumn Birch Sapling" }, { "AutumnBirchSaplingDescription", "Plains Variant" }, { "AshwoodSaplingName", "Ashwood Sapling" }, { "AshwoodSaplingDescription", "" }, { "VineAshSaplingName", "Custom Ashvine" }, { "VineAshSaplingDescription", "Plants an Ashvine sapling with the colours defined in the mod config." }, { "RaspberryBushName", "Raspberry Bush" }, { "RaspberryBushDescription", "Plant raspberries to grow raspberry bushes." }, { "BlueberryBushName", "Blueberry Bush" }, { "BlueberryBushDescription", "Plant blueberries to grow blueberry bushes." }, { "CloudberryBushName", "Cloudberry Bush" }, { "CloudberryBushDescription", "Plant cloudberries to grow cloudberry bushes." }, { "PickableMushroomName", "Pickable Mushrooms" }, { "PickableMushroomDescription", "Plant mushrooms to grow more pickable mushrooms." }, { "PickableYellowMushroomName", "Pickable Yellow Mushrooms" }, { "PickableYellowMushroomDescription", "Plant yellow mushrooms to grow more pickable yellow mushrooms." }, { "PickableBlueMushroomName", "Pickable Blue Mushrooms" }, { "PickableBlueMushroomDescription", "Plant blue mushrooms to grow more pickable blue mushrooms." }, { "PickableThistleName", "Pickable Thistle" }, { "PickableThistleDescription", "Plant thistle to grow more pickable thistle." }, { "PickableDandelionName", "Pickable Dandelion" }, { "PickableDandelionDescription", "Plant dandelion to grow more pickable dandelion." }, { "BeechSmallName", "Small Beech Tree" }, { "BeechSmallDescription", "Plant a small beech tree." }, { "FirSmallName", "Small Fir Tree" }, { "FirSmallDescription", "Plant a small fir tree." }, { "FirSmallDeadName", "Small Dead Fir Tree" }, { "FirSmallDeadDescription", "Plant a small dead fir tree." }, { "Bush01Name", "Small Bush 1" }, { "Bush01Description", "Plant a small bush." }, { "Bush02Name", "Small Bush 2" }, { "Bush02Description", "Plant a small bush." }, { "PlainsBushName", "Small Plains Bush" }, { "PlainsBushDescription", "Plant a bush native to the plains." }, { "Shrub01Name", "Small Shrub 1" }, { "Shrub01Description", "Plant a small shrub." }, { "Shrub02Name", "Small Shrub 2" }, { "Shrub02Description", "Plant a small shrub." }, { "YggaShootName", "Small Ygga Shoot" }, { "YggaShootDescription", "Plant a small ygga shoot." }, { "VinesName", "Vines" }, { "VinesDescription", "Plant vines." }, { "AshlandsFernName", "Ashlands Fern" }, { "AshlandsFernDescription", "Plant a fern native to the ashlands." }, { "PickableBranchName", "Pickable Branch" }, { "PickableBranchDescription", "Plant respawning pickable branches." }, { "PickableStoneName", "Pickable Stone" }, { "PickableStoneDescription", "Plant pickable stone." }, { "PickableFlintName", "Pickable Flint" }, { "PickableFlintDescription", "Plant respawning pickable flint." }, { "PickableSmokePuffName", "Pickable Smoke Puff" }, { "PickableSmokePuffDescription", "Plant smoke puffs to grow more pickable smoke puffs." }, { "PickableFiddleheadName", "Pickable Fiddlehead" }, { "PickableFiddleheadDescription", "Plant fiddlehead to grow more pickable fiddlehead." }, { "GrowthTimeHoverPrefix", "Ready in" } }; internal static readonly List VanillaPrefabRefs = new List { "Acorn", "AncientSeed", "BeechSeeds", "BirchSeeds", "FirCone", "PineCone", "Sap", "Pickable_Branch", "Pickable_Dandelion", "Pickable_Fiddlehead", "Pickable_Flint", "Pickable_Mushroom", "Pickable_Mushroom_blue", "Pickable_Mushroom_yellow", "Pickable_SmokePuff", "Pickable_Stone", "Pickable_Thistle", "Cultivator", "sfx_build_cultivator", "vfx_Place_wood_pole", "sapling_barley", "sapling_carrot", "sapling_flax", "sapling_jotunpuffs", "sapling_magecap", "sapling_onion", "sapling_seedcarrot", "sapling_seedonion", "sapling_seedturnip", "sapling_turnip", "FernAshlands", "AshlandsTree3", "AshlandsTree4", "AshlandsTree5", "AshlandsTree6_big", "Beech1", "Beech_Sapling", "Beech_small1", "Birch1", "Birch1_aut", "Birch2", "Birch2_aut", "Birch_Sapling", "BlueberryBush", "Bush01", "Bush01_heath", "Bush02_en", "RaspberryBush", "CloudberryBush", "FirTree", "FirTree_Sapling", "FirTree_small", "FirTree_small_dead", "PineTree_Sapling", "Pinetree_01", "YggaShoot1", "YggaShoot2", "YggaShoot3", "YggaShoot_small1", "shrub_2", "shrub_2_heath", "SwampTree1", "vines", "VineAsh", "VineAsh_sapling", "Oak1", "Oak_Sapling" }; internal static readonly List CustomPrefabRefs = new List { "Ancient_Sapling", "Ygga_Sapling", "Autumn_Birch_Sapling", "Ashwood_Sapling", "Pickable_Dandelion_Picked", "Pickable_Thistle_Picked", "Pickable_Mushroom_Picked", "Pickable_Mushroom_yellow_Picked", "Pickable_Mushroom_blue_Picked", "Pickable_SmokePuff_Picked", "Pickable_Fiddlehead_Picked" }; private static Dictionary treesToSeeds; internal static Dictionary TreesToSeeds { get { object obj = treesToSeeds; if (obj == null) { obj = new Dictionary { { StaticMembers.prefabRefs["Birch1"], StaticMembers.prefabRefs["BirchSeeds"] }, { StaticMembers.prefabRefs["Birch2"], StaticMembers.prefabRefs["BirchSeeds"] }, { StaticMembers.prefabRefs["Birch2_aut"], StaticMembers.prefabRefs["BirchSeeds"] }, { StaticMembers.prefabRefs["Birch1_aut"], StaticMembers.prefabRefs["BirchSeeds"] }, { StaticMembers.prefabRefs["Oak1"], StaticMembers.prefabRefs["Acorn"] }, { StaticMembers.prefabRefs["SwampTree1"], StaticMembers.prefabRefs["AncientSeed"] }, { StaticMembers.prefabRefs["Beech1"], StaticMembers.prefabRefs["BeechSeeds"] }, { StaticMembers.prefabRefs["Pinetree_01"], StaticMembers.prefabRefs["PineCone"] }, { StaticMembers.prefabRefs["FirTree"], StaticMembers.prefabRefs["FirCone"] } }; treesToSeeds = (Dictionary)obj; } return (Dictionary)obj; } } internal static List GenerateExampleResources() { return new List(2) { new ExtraResource { prefabName = "PE_FakePrefab1", resourceName = "PretendSeeds1", resourceCost = 1, groundOnly = true, pieceName = "PickableMushrooms", pieceDescription = "Plant this to grow more pickable mushrooms." }, new ExtraResource { prefabName = "PE_FakePrefab2", resourceName = "PretendSeeds2", resourceCost = 2, groundOnly = false } }; } internal static List GeneratePieceRefs() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0784: Unknown result type (might be due to invalid IL or missing references) //IL_079e: Unknown result type (might be due to invalid IL or missing references) //IL_07b8: Unknown result type (might be due to invalid IL or missing references) //IL_07d2: Unknown result type (might be due to invalid IL or missing references) bool enforceBiomes = StaticMembers.config.EnforceBiomes; List list = new List(10) { new PieceDB { key = "RaspberryBush", ResourceCost = StaticMembers.config.RaspberryCost, resourceReturn = StaticMembers.config.RaspberryReturn, respawnTime = StaticMembers.config.RaspberryRespawnTime, biome = (Biome)(enforceBiomes ? 1 : 0), icon = true, isGrounded = true, recover = StaticMembers.config.RecoverResources }, new PieceDB { key = "BlueberryBush", ResourceCost = StaticMembers.config.BlueberryCost, resourceReturn = StaticMembers.config.BlueberryReturn, respawnTime = StaticMembers.config.BlueberryRespawnTime, biome = (Biome)(enforceBiomes ? 8 : 0), icon = true, isGrounded = true, recover = StaticMembers.config.RecoverResources }, new PieceDB { key = "CloudberryBush", ResourceCost = StaticMembers.config.CloudberryCost, resourceReturn = StaticMembers.config.CloudberryReturn, respawnTime = StaticMembers.config.CloudberryRespawnTime, biome = (Biome)(enforceBiomes ? 16 : 0), icon = true, isGrounded = true, recover = StaticMembers.config.RecoverResources }, new PieceDB { key = "Pickable_Mushroom", ResourceCost = StaticMembers.config.MushroomCost, resourceReturn = StaticMembers.config.MushroomReturn, respawnTime = StaticMembers.config.MushroomRespawnTime, recover = StaticMembers.config.RecoverResources, Name = "PickableMushroom", isGrounded = true }, new PieceDB { key = "Pickable_Mushroom_yellow", ResourceCost = StaticMembers.config.YellowMushroomCost, resourceReturn = StaticMembers.config.YellowMushroomReturn, respawnTime = StaticMembers.config.YellowMushroomRespawnTime, recover = StaticMembers.config.RecoverResources, Name = "PickableYellowMushroom", isGrounded = true }, new PieceDB { key = "Pickable_Mushroom_blue", ResourceCost = StaticMembers.config.BlueMushroomCost, resourceReturn = StaticMembers.config.BlueMushroomReturn, respawnTime = StaticMembers.config.BlueMushroomRespawnTime, recover = StaticMembers.config.RecoverResources, Name = "PickableBlueMushroom", isGrounded = true }, new PieceDB { key = "Pickable_Thistle", ResourceCost = StaticMembers.config.ThistleCost, resourceReturn = StaticMembers.config.ThistleReturn, respawnTime = StaticMembers.config.ThistleRespawnTime, biome = (Biome)(enforceBiomes ? 8 : 0), recover = StaticMembers.config.RecoverResources, Name = "PickableThistle", isGrounded = true }, new PieceDB { key = "Pickable_Dandelion", ResourceCost = StaticMembers.config.DandelionCost, resourceReturn = StaticMembers.config.DandelionReturn, respawnTime = StaticMembers.config.DandelionRespawnTime, biome = (Biome)(enforceBiomes ? 1 : 0), recover = StaticMembers.config.RecoverResources, Name = "PickableDandelion", isGrounded = true }, new PieceDB { key = "Pickable_SmokePuff", ResourceCost = StaticMembers.config.SmokePuffCost, resourceReturn = StaticMembers.config.SmokePuffReturn, respawnTime = StaticMembers.config.SmokePuffRespawnTime, biome = (Biome)(enforceBiomes ? 32 : 0), recover = StaticMembers.config.RecoverResources, Name = "PickableSmokePuff", isGrounded = true }, new PieceDB { key = "Pickable_Fiddlehead", ResourceCost = StaticMembers.config.FiddleheadCost, resourceReturn = StaticMembers.config.FiddleheadReturn, respawnTime = StaticMembers.config.FiddleheadRespawnTime, biome = (Biome)(enforceBiomes ? 32 : 0), icon = true, recover = StaticMembers.config.RecoverResources, Name = "PickableFiddlehead", isGrounded = true, extraDrops = true } }; if (StaticMembers.config.EnableMiscFlora) { list.AddRange(new <>z__ReadOnlyArray(new PieceDB[11] { new PieceDB { key = "Beech_small1", Resource = new KeyValuePair("BeechSeeds", 1), icon = true, Name = "BeechSmall", canBeRemoved = false }, new PieceDB { key = "FirTree_small", Resource = new KeyValuePair("FirCone", 1), icon = true, Name = "FirSmall", canBeRemoved = false }, new PieceDB { key = "FirTree_small_dead", Resource = new KeyValuePair("FirCone", 1), icon = true, Name = "FirSmallDead", canBeRemoved = false }, new PieceDB { key = "Bush01", Resource = new KeyValuePair("Wood", 2), icon = true, canBeRemoved = false }, new PieceDB { key = "Bush01_heath", Resource = new KeyValuePair("Wood", 2), icon = true, Name = "Bush02", canBeRemoved = false }, new PieceDB { key = "Bush02_en", Resource = new KeyValuePair("Wood", 3), icon = true, Name = "PlainsBush", canBeRemoved = false }, new PieceDB { key = "shrub_2", Resource = new KeyValuePair("Wood", 2), icon = true, Name = "Shrub01", canBeRemoved = false }, new PieceDB { key = "shrub_2_heath", Resource = new KeyValuePair("Wood", 2), icon = true, Name = "Shrub02", canBeRemoved = false }, new PieceDB { key = "YggaShoot_small1", Resources = new Dictionary { { "YggdrasilWood", 1 }, { "Wood", 2 } }, icon = true, Name = "YggaShoot", canBeRemoved = false }, new PieceDB { key = "vines", Resource = new KeyValuePair("Wood", 2), icon = true, recover = true, Name = "Vines", isGrounded = false, snapPoints = new List { new Vector3(1f, 0.5f, 0f), new Vector3(-1f, 0.5f, 0f), new Vector3(1f, -1f, 0f), new Vector3(-1f, -1f, 0f) } }, new PieceDB { key = "FernAshlands", Resource = new KeyValuePair("Wood", 2), icon = true, Name = "AshlandsFern", isGrounded = true, canBeRemoved = false } })); } if (StaticMembers.config.EnableDebris) { list.AddRange(new <>z__ReadOnlyArray(new PieceDB[3] { new PieceDB { key = "Pickable_Branch", ResourceCost = StaticMembers.config.PickableBranchCost, resourceReturn = StaticMembers.config.PickableBranchReturn, respawnTime = StaticMembers.config.PickableBranchRespawnTime, recover = StaticMembers.config.RecoverResources, Name = "PickableBranch", isGrounded = true }, new PieceDB { key = "Pickable_Stone", ResourceCost = StaticMembers.config.PickableStoneCost, resourceReturn = StaticMembers.config.PickableStoneReturn, respawnTime = StaticMembers.config.PickableStoneRespawnTime, recover = StaticMembers.config.RecoverResources, Name = "PickableStone", isGrounded = true, hideWhenPicked = true }, new PieceDB { key = "Pickable_Flint", ResourceCost = StaticMembers.config.PickableFlintCost, resourceReturn = StaticMembers.config.PickableFlintReturn, respawnTime = StaticMembers.config.PickableFlintRespawnTime, recover = StaticMembers.config.RecoverResources, Name = "PickableFlint", isGrounded = true } })); } if (StaticMembers.config.EnableExtraResources) { string[] layersForPieceRemoval = StaticMembers.layersForPieceRemoval; List list2 = new List(layersForPieceRemoval.Length); list2.AddRange(layersForPieceRemoval); List list3 = list2; bool resolveMissingReferences = false; foreach (ExtraResource deserializedExtraResource in StaticMembers.deserializedExtraResources) { if (!StaticMembers.prefabRefs.ContainsKey(deserializedExtraResource.prefabName) || !Object.op_Implicit((Object)(object)StaticMembers.prefabRefs[deserializedExtraResource.prefabName])) { StaticMembers.Dbgl(deserializedExtraResource.prefabName + " is not in dictionary of prefab references or has a null value", forceLog: false, (LogLevel)4); resolveMissingReferences = true; continue; } ObjectDB instance = ObjectDB.instance; object obj; if (instance == null) { obj = null; } else { GameObject itemPrefab = instance.GetItemPrefab(deserializedExtraResource.resourceName); obj = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); } if (!Object.op_Implicit((Object)obj)) { StaticMembers.Dbgl(deserializedExtraResource.prefabName + "'s required resource " + deserializedExtraResource.resourceName + " not found", forceLog: false, (LogLevel)4); resolveMissingReferences = true; continue; } list.Add(new PieceDB { key = deserializedExtraResource.prefabName, Resource = new KeyValuePair(deserializedExtraResource.resourceName, deserializedExtraResource.resourceCost), isGrounded = deserializedExtraResource.groundOnly, extraResource = true, pieceName = ((deserializedExtraResource.pieceName == "") ? deserializedExtraResource.prefabName : deserializedExtraResource.pieceName), pieceDescription = deserializedExtraResource.pieceDescription }); Collider[] componentsInChildren = StaticMembers.prefabRefs[deserializedExtraResource.prefabName].GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { string item = LayerMask.LayerToName(((Component)componentsInChildren[i]).gameObject.layer); list3.Add(item); } } StaticMembers.layersForPieceRemoval = list3.Distinct().ToArray(); StaticMembers.resolveMissingReferences = resolveMissingReferences; } return list; } internal static List GenerateCustomSaplingRefs() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) List list = new List(4); list.Add(new SaplingDB { key = "Ashwood_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomes ? 57 : ((int)StaticMembers.AllBiomes)), source = "AshlandsTree3", Resources = new Dictionary { { "BeechSeeds", 1 }, { "SulfurStone", 1 } }, icon = true, growTime = StaticMembers.config.AshwoodGrowthTime, growRadius = StaticMembers.config.AshwoodGrowRadius, minScale = StaticMembers.config.AshwoodMinScale, maxScale = StaticMembers.config.AshwoodMaxScale, grownPrefabs = (GameObject[])(object)new GameObject[4] { StaticMembers.prefabRefs["AshlandsTree3"], StaticMembers.prefabRefs["AshlandsTree4"], StaticMembers.prefabRefs["AshlandsTree5"], StaticMembers.prefabRefs["AshlandsTree6_big"] }, tolerateHeat = true }); list.Add(new SaplingDB { key = "Ygga_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomes ? 537 : ((int)StaticMembers.AllBiomes)), source = "YggaShoot_small1", Resource = new KeyValuePair("Sap", 1), icon = true, growTime = StaticMembers.config.YggaGrowthTime, growRadius = StaticMembers.config.YggaGrowRadius, minScale = StaticMembers.config.YggaMinScale, maxScale = StaticMembers.config.YggaMaxScale, grownPrefabs = (GameObject[])(object)new GameObject[3] { StaticMembers.prefabRefs["YggaShoot1"], StaticMembers.prefabRefs["YggaShoot2"], StaticMembers.prefabRefs["YggaShoot3"] } }); list.Add(new SaplingDB { key = "Ancient_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomes ? 27 : ((int)StaticMembers.AllBiomes)), source = "SwampTree1", Resource = new KeyValuePair("AncientSeed", 1), icon = true, growTime = StaticMembers.config.AncientGrowthTime, growRadius = StaticMembers.config.AncientGrowRadius, minScale = StaticMembers.config.AncientMinScale, maxScale = StaticMembers.config.AncientMaxScale, grownPrefabs = (GameObject[])(object)new GameObject[1] { StaticMembers.prefabRefs["SwampTree1"] } }); list.Add(new SaplingDB { key = "Autumn_Birch_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomes ? 25 : ((int)StaticMembers.AllBiomes)), source = "Birch1_aut", Resource = new KeyValuePair("BirchSeeds", 1), icon = true, growTime = StaticMembers.config.AutumnBirchGrowthTime, growRadius = StaticMembers.config.AutumnBirchGrowRadius, minScale = StaticMembers.config.AutumnBirchMinScale, maxScale = StaticMembers.config.AutumnBirchMaxScale, grownPrefabs = (GameObject[])(object)new GameObject[2] { StaticMembers.prefabRefs["Birch1_aut"], StaticMembers.prefabRefs["Birch2_aut"] } }); return list; } internal static List GenerateVanillaSaplingRefs() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) return new List(5) { new SaplingDB { key = "Beech_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), growTime = StaticMembers.config.BeechGrowthTime, growRadius = StaticMembers.config.BeechGrowRadius, minScale = StaticMembers.config.BeechMinScale, maxScale = StaticMembers.config.BeechMaxScale }, new SaplingDB { key = "PineTree_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), growTime = StaticMembers.config.PineGrowthTime, growRadius = StaticMembers.config.PineGrowRadius, minScale = StaticMembers.config.PineMinScale, maxScale = StaticMembers.config.PineMaxScale }, new SaplingDB { key = "FirTree_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomesVanilla ? 29 : ((int)StaticMembers.AllBiomes)), growTime = StaticMembers.config.FirGrowthTime, growRadius = StaticMembers.config.FirGrowRadius, minScale = StaticMembers.config.FirMinScale, maxScale = StaticMembers.config.FirMaxScale, tolerateCold = true }, new SaplingDB { key = "Birch_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), growTime = StaticMembers.config.BirchGrowthTime, growRadius = StaticMembers.config.BirchGrowRadius, minScale = StaticMembers.config.BirchMinScale, maxScale = StaticMembers.config.BirchMaxScale }, new SaplingDB { key = "Oak_Sapling", biome = (Biome)(StaticMembers.config.EnforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), growTime = StaticMembers.config.OakGrowthTime, growRadius = StaticMembers.config.OakGrowRadius, minScale = StaticMembers.config.OakMinScale, maxScale = StaticMembers.config.OakMaxScale } }; } internal static List GenerateCropRefs() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) bool enableCropOverrides = StaticMembers.config.EnableCropOverrides; bool enforceBiomesVanilla = StaticMembers.config.EnforceBiomesVanilla; return new List(10) { new PrefabDB { key = "sapling_barley", biome = (Biome)(enforceBiomesVanilla ? 16 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.BarleyCost), resourceReturn = (enableCropOverrides ? StaticMembers.config.BarleyReturn : 2) }, new PrefabDB { key = "sapling_carrot", biome = (Biome)(enforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.CarrotCost), resourceReturn = ((!enableCropOverrides) ? 1 : StaticMembers.config.CarrotReturn) }, new PrefabDB { key = "sapling_flax", biome = (Biome)(enforceBiomesVanilla ? 16 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.FlaxCost), resourceReturn = (enableCropOverrides ? StaticMembers.config.FlaxReturn : 2) }, new PrefabDB { key = "sapling_onion", biome = (Biome)(enforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.OnionCost), resourceReturn = ((!enableCropOverrides) ? 1 : StaticMembers.config.OnionReturn) }, new PrefabDB { key = "sapling_seedcarrot", biome = (Biome)(enforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.SeedCarrotCost), resourceReturn = (enableCropOverrides ? StaticMembers.config.SeedCarrotReturn : 3) }, new PrefabDB { key = "sapling_seedonion", biome = (Biome)(enforceBiomesVanilla ? 25 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.SeedOnionCost), resourceReturn = (enableCropOverrides ? StaticMembers.config.SeedOnionReturn : 3) }, new PrefabDB { key = "sapling_seedturnip", biome = (Biome)(enforceBiomesVanilla ? 539 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.SeedTurnipCost), resourceReturn = (enableCropOverrides ? StaticMembers.config.SeedTurnipReturn : 3) }, new PrefabDB { key = "sapling_turnip", biome = (Biome)(enforceBiomesVanilla ? 539 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.TurnipCost), resourceReturn = ((!enableCropOverrides) ? 1 : StaticMembers.config.TurnipReturn) }, new PrefabDB { key = "sapling_magecap", biome = (Biome)(enforceBiomesVanilla ? 512 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.MagecapCost), resourceReturn = ((!enableCropOverrides) ? 1 : StaticMembers.config.MagecapReturn), extraDrops = true }, new PrefabDB { key = "sapling_jotunpuffs", biome = (Biome)(enforceBiomesVanilla ? 512 : ((int)StaticMembers.AllBiomes)), resourceCost = ((!enableCropOverrides) ? 1 : StaticMembers.config.JotunPuffsCost), resourceReturn = ((!enableCropOverrides) ? 1 : StaticMembers.config.JotunPuffsReturn), extraDrops = true } }; } internal static List GenerateCustomPlantRefs(List customPlants) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (GameObject customPlant in customPlants) { Plant component = customPlant.GetComponent(); list.Add(new ModdedPlantDB { key = ((Object)customPlant).name, biome = component.m_biome, tolerateCold = component.m_tolerateCold, tolerateHeat = component.m_tolerateHeat, minScale = component.m_minScale, maxScale = component.m_maxScale, growTime = component.m_growTime, growTimeMax = component.m_growTimeMax, growRadius = component.m_growRadius }); StaticMembers.prefabRefs[((Object)customPlant).name] = customPlant; } return list; } } internal static class StaticMembers { internal static ManualLogSource ModLogger = new ManualLogSource(" PlantEverything"); internal static ModConfig config; private static string customConfigPath; internal static readonly Dictionary> logActions = new Dictionary> { { (LogLevel)1, (Action)ModLogger.LogFatal }, { (LogLevel)2, (Action)ModLogger.LogError }, { (LogLevel)4, (Action)ModLogger.LogWarning }, { (LogLevel)8, (Action)ModLogger.LogMessage }, { (LogLevel)16, (Action)ModLogger.LogInfo }, { (LogLevel)32, (Action)ModLogger.LogDebug } }; internal static readonly Dictionary prefabRefs = new Dictionary(); internal static List pieceRefs = new List(); internal static List saplingRefs = new List(); internal static List moddedCropRefs = new List(); internal static List moddedSaplingRefs = new List(); internal static List deserializedExtraResources = new List(); internal static bool piecesInitialized = false; internal static bool saplingsInitialized = false; internal static bool resolveMissingReferences = false; internal static bool isDedicatedServer = false; internal static AssetBundle assetBundle; internal static readonly Dictionary cachedTextures = new Dictionary(); internal static readonly Dictionary cachedSprites = new Dictionary(); internal const Biome TemperateBiomes = (Biome)25; internal static Biome AllBiomes = PluginUtils.GetBiomeMask((Biome[])Enum.GetValues(typeof(Biome))); internal static readonly int PlaceAnywhereHash = StringExtensionMethods.GetStableHashCode("pe_placeAnywhere"); internal static string[] layersForPieceRemoval = new string[4] { "item", "piece_nonsolid", "Default_small", "Default" }; internal static string CustomConfigPath => customConfigPath ?? (customConfigPath = PluginUtils.SetupConfigDirectory()); internal static void Dbgl(string message, bool forceLog = false, LogLevel level = (LogLevel)16) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (forceLog || config.EnableDebugMessages) { logActions[level](message); } } } internal sealed class ModLocalization { public List LocalizedStrings = new List(); } [HarmonyPatch] internal static class ApplyZDOPatches { private static readonly MethodInfo ModifyPlantGrowMethod = AccessTools.Method(typeof(ApplyZDOPatches), "ModifyPlantGrow", (Type[])null, (Type[])null); private static void ModifyPlantGrow(Plant plant, GameObject grownTree) { TreeBase val = default(TreeBase); StaticPhysics val2 = default(StaticPhysics); if (plant.m_nview.GetZDO().GetBool(StaticMembers.PlaceAnywhereHash, false) && grownTree.TryGetComponent(ref val) && ((Component)val).TryGetComponent(ref val2)) { val2.m_fall = false; val.m_nview.GetZDO().Set(StaticMembers.PlaceAnywhereHash, true); } } [HarmonyPatch(typeof(Plant), "Grow")] [HarmonyTranspiler] private static IEnumerable PlantTranspiler(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(TreeBase), "Grow", (Type[])null, (Type[])null), (string)null) }).ThrowIfInvalid("Could not patch Plant.Grow() ([Difficulty]PlaceAnywhere)").Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Call, (object)ModifyPlantGrowMethod) }) .InstructionEnumeration(); } } [HarmonyPatch] internal static class CheckZDOPatches { [HarmonyPatch(typeof(Piece), "Awake")] [HarmonyPatch(typeof(TreeBase), "Awake")] private static void Postfix(ZNetView ___m_nview) { ZDO val = ((___m_nview != null) ? ___m_nview.GetZDO() : null); if (val != null && val.GetBool(StaticMembers.PlaceAnywhereHash, false)) { ((Component)___m_nview).GetComponent().m_fall = false; } } } [HarmonyPatch] internal static class HoverTextPatches { private static Gradient _hoverGradient; private static Gradient HoverGradient => _hoverGradient ?? InitializeGradient(); private static Gradient InitializeGradient() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) _hoverGradient = new Gradient(); _hoverGradient.SetKeys((GradientColorKey[])(object)new GradientColorKey[5] { new GradientColorKey(Color.red, 0f), new GradientColorKey(new Color(1f, 0.6470588f, 0f), 0.3f), new GradientColorKey(Color.yellow, 0.6f), new GradientColorKey(Color.green, 0.9f), new GradientColorKey(Color.cyan, 1f) }, Array.Empty()); return _hoverGradient; } [HarmonyPatch(typeof(Pickable), "GetHoverText")] private static void Postfix(Pickable __instance, ref string __result) { if (StaticMembers.config.EnablePlantTimers && __instance.m_picked && !(__instance.m_respawnTimeMinutes <= 0f)) { ZNetView nview = __instance.m_nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val != null) { long ticks = val.GetLong(ZDOVars.s_pickedTime, 0L); TimeSpan timeSpan = ZNet.instance.GetTime() - new DateTime(ticks); double secondsToRespawnPickable = GetSecondsToRespawnPickable(__instance); string text = FormatTime(timeSpan.TotalSeconds / secondsToRespawnPickable, secondsToRespawnPickable - timeSpan.TotalSeconds); __result = Localization.instance.Localize(__instance.GetHoverName()) + "\n" + text; } } } [HarmonyPatch(typeof(Plant), "GetHoverText")] private static void Postfix(Plant __instance, ref string __result) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (StaticMembers.config.EnablePlantTimers && (int)__instance.m_status == 0) { ZNetView nview = __instance.m_nview; if (((nview != null) ? nview.GetZDO() : null) != null) { double secondsToGrowPlant = GetSecondsToGrowPlant(__instance); string text = FormatTime(__instance.TimeSincePlanted() / (double)__instance.GetGrowTime(), secondsToGrowPlant); __result = __result + "\n" + text; } } } private static double GetSecondsToRespawnPickable(Pickable pickable) { if (SeasonsCompatibility.IsReady) { return SeasonsCompatibility.GetSecondsToRespawnPickable(pickable); } return pickable.m_respawnTimeMinutes * 60f; } private static double GetSecondsToGrowPlant(Plant plant) { if (SeasonsCompatibility.IsReady) { return SeasonsCompatibility.GetSecondsToGrowPlant(plant); } return (double)plant.GetGrowTime() - plant.TimeSincePlanted(); } private static string FormatTime(double percent, double secondsToGrow) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01((float)percent); string text = ColorUtility.ToHtmlStringRGB(HoverGradient.Evaluate(num)); if (StaticMembers.config.GrowthAsPercentage) { return $"({num:P0})"; } if (secondsToGrow <= 0.0) { return Localization.instance.Localize("$hud_ready"); } TimeSpan timeSpan = TimeSpan.FromSeconds(secondsToGrow); string text2 = ((timeSpan.Hours > 0) ? $"{timeSpan.Hours:D2}h {timeSpan.Minutes:D2}m {timeSpan.Seconds:D2}s" : ((timeSpan.Minutes <= 0) ? $"{timeSpan.Seconds:D2}s" : $"{timeSpan.Minutes:D2}m {timeSpan.Seconds:D2}s")); return "(" + Localization.instance.Localize("$peGrowthTimeHoverPrefix") + " " + text2 + ")"; } } [HarmonyPatch] internal static class ModInitPatches { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScenePatches { private static List unfilteredPrefabs; [HarmonyPriority(800)] private static void Prefix(ZNetScene __instance) { unfilteredPrefabs = ((StaticMembers.moddedCropRefs.Count == 0 && StaticMembers.moddedSaplingRefs.Count == 0) ? new List(__instance.m_prefabs) : null); } private static void Postfix(ZNetScene __instance) { if (StaticMembers.isDedicatedServer) { PluginInitUtils.InitPrefabRefs(); } PluginInitUtils.FullInit(__instance); } [HarmonyPostfix] [HarmonyPriority(0)] private static void LastPostfix(ZNetScene __instance) { if (unfilteredPrefabs != null) { List list = __instance.m_prefabs.Except(unfilteredPrefabs).ToList(); list.RemoveAll((GameObject x) => !Object.op_Implicit((Object)(object)x.GetComponent())); list.RemoveAll(StaticMembers.saplingRefs.Select((SaplingDB x) => x.Prefab).ToList().Contains); foreach (ModdedPlantDB item in StaticContent.GenerateCustomPlantRefs(list)) { if (item.Prefab.GetComponent().m_grownPrefabs.Any((GameObject x) => Object.op_Implicit((Object)(object)x.GetComponent()))) { StaticMembers.Dbgl("Adding modded sapling reference " + item.key, forceLog: false, (LogLevel)16); StaticMembers.moddedSaplingRefs.Add(item); } else { StaticMembers.Dbgl("Adding modded crop reference " + item.key, forceLog: false, (LogLevel)16); StaticMembers.moddedCropRefs.Add(item); } } if (StaticMembers.moddedCropRefs.Count > 0) { StaticMembers.Dbgl($"Added {StaticMembers.moddedCropRefs.Count} modded crop references", forceLog: false, (LogLevel)16); ConfigEventHandlers.CropSettingChanged(null, null); } if (StaticMembers.moddedSaplingRefs.Count > 0) { StaticMembers.Dbgl($"Added {StaticMembers.moddedSaplingRefs.Count} modded sapling references", forceLog: false, (LogLevel)16); ConfigEventHandlers.SaplingSettingChanged(null, null); } unfilteredPrefabs.Clear(); } if (StaticMembers.resolveMissingReferences) { StaticMembers.Dbgl("Performing final attempt to resolve missing references for configured ExtraResources", forceLog: true, (LogLevel)16); StaticMembers.resolveMissingReferences = false; if (PluginInitUtils.InitExtraResourceRefs(__instance, logErrors: true)) { StaticMembers.Dbgl("One or more missing references for configured ExtraResources were successfully resolved", forceLog: true, (LogLevel)16); ConfigEventHandlers.PieceSettingChanged(null, null); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static void Postfix() { if (!StaticMembers.isDedicatedServer) { PluginInitUtils.InitPrefabRefs(); } } } [HarmonyPatch(typeof(Piece), "SetCreator")] internal static class PieceCreationPatches { private static void Postfix(Piece __instance) { if (PluginUtils.IsModdedPrefabOrSapling(__instance.m_name)) { if (StaticMembers.config.ResourcesSpawnEmpty && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent()) && __instance.m_name != "Pickable_Stone") { __instance.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetPicked", new object[1] { true }); } StaticPhysics val = default(StaticPhysics); if (StaticMembers.config.PlaceAnywhere && ((Component)__instance).TryGetComponent(ref val)) { val.m_fall = false; __instance.m_nview.GetZDO().Set(StaticMembers.PlaceAnywhereHash, true); } } } } [HarmonyPatch] internal static class PieceRemovalPatches { [HarmonyPatch(typeof(Player), "RemovePiece")] private static class PlayerRemovePiece { private static bool Prefix(Player __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (((Humanoid)__instance).GetRightItem().m_shared.m_name == "$item_cultivator") { Transform transform = ((Component)GameCamera.instance).transform; RaycastHit val = default(RaycastHit); if (Physics.Raycast(transform.position, transform.forward, ref val, 50f, LayerMask.GetMask(StaticMembers.layersForPieceRemoval)) && Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)__instance).m_eye.position) < __instance.m_maxPlaceDistance) { Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent(); if (PluginUtils.IsModdedPrefab((Component)(object)componentInParent)) { if (!CanRemove(componentInParent, __instance)) { return false; } RemoveObject(componentInParent, __instance); } } return false; } return true; } private static bool CanRemove(Piece piece, Player instance) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) bool flag = piece.m_canBeRemoved || (StaticMembers.config.CanRemoveFlora && piece.IsPlacedByPlayer() && !piece.m_name.Contains("sapling")); if (flag && !PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false)) { ((Character)instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false); flag = false; } return flag; } private static void RemoveObject(Piece piece, Player player) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) ZNetView nview = piece.m_nview; WearNTear component = ((Component)piece).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { player.m_removeEffects.Create(((Component)piece).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); component.Remove(false); } else { nview.ClaimOwnership(); piece.DropResources((HitData)null); piece.m_placeEffect.Create(((Component)piece).transform.position, ((Component)piece).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); Pickable val = default(Pickable); if (((Component)piece).TryGetComponent(ref val)) { int num = 0; if (!val.m_picked && (int)val.m_pickRaiseSkill != 0) { ((Character)player).RaiseSkill(val.m_pickRaiseSkill, 1f); if ((double)Random.value < (double)((Character)player).GetSkillFactor(val.m_pickRaiseSkill) * (double)val.m_maxLevelBonusChance) { num = val.m_bonusYieldAmount; DamageText.instance.ShowText((TextType)7, ((Component)val).transform.position + Vector3.up * val.m_spawnOffset, $"+{num}", true); val.m_bonusEffect.Create(((Component)val).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } } val.m_nview.InvokeRPC("RPC_Pick", new object[1] { num }); } ZNetScene.instance.Destroy(((Component)piece).gameObject); } player.FaceLookDirection(); ((Character)player).m_zanim.SetTrigger(((Humanoid)player).GetRightItem().m_shared.m_attack.m_attackAnimation); } } [HarmonyPatch(typeof(Piece), "DropResources")] private static class PieceDropResources { private static void Prefix(Piece __instance, ref Requirement[] __state) { Pickable pickable = default(Pickable); if (StaticMembers.config.RecoverResources && PluginUtils.IsModdedPrefab((Component)(object)__instance) && ((Component)__instance).TryGetComponent(ref pickable)) { __state = __instance.m_resources; __instance.m_resources = RemovePickableDropFromRequirements(__instance.m_resources, pickable); } } private static void Postfix(Piece __instance, Requirement[] __state) { if (__state != null) { __instance.m_resources = __state; } } private static Requirement[] RemovePickableDropFromRequirements(Requirement[] requirements, Pickable pickable) { ItemData itemData = pickable.m_itemPrefab.GetComponent().m_itemData; for (int i = 0; i < requirements.Length; i++) { Requirement val = requirements[i]; if (val.m_resItem.m_itemData.m_shared.m_name == itemData.m_shared.m_name) { Requirement[] array = (Requirement[])(object)new Requirement[requirements.Length]; requirements.CopyTo(array, 0); int scaledPickableDropAmount = GetScaledPickableDropAmount(pickable); array[i].m_amount = Mathf.Clamp(val.m_amount - scaledPickableDropAmount, 0, val.m_amount); return array; } } return requirements; } private static int GetScaledPickableDropAmount(Pickable pickable) { if (!pickable.m_dontScale) { return Mathf.Max(pickable.m_minAmountScaled, Game.instance.ScaleDrops(pickable.m_itemPrefab, pickable.m_amount)); } return pickable.m_amount; } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] private static bool Prefix(Piece piece, ref bool __result) { if (PluginUtils.IsModdedPrefab((Component)(object)piece)) { return __result = false; } return true; } } [HarmonyPatch] internal static class PlantPatches { [HarmonyPatch(typeof(Plant), "HaveRoof")] private static class PlantHaveRoof { private static bool Prefix(Plant __instance, ref bool __result) { if ((!StaticMembers.config.CropRequireSunlight && __instance.m_name.StartsWith("$piece_sapling")) || (StaticMembers.config.PlaceAnywhere && PluginUtils.IsModdedPrefabOrSapling(__instance.m_name))) { return __result = false; } return true; } } [HarmonyPatch(typeof(Plant), "HaveGrowSpace")] private static class PlantHaveGrowSpace { private static bool Prefix(Plant __instance, ref bool __result) { if ((!StaticMembers.config.CropRequireGrowthSpace && __instance.m_name.StartsWith("$piece_sapling")) || (StaticMembers.config.PlaceAnywhere && PluginUtils.IsModdedPrefabOrSapling(__instance.m_name))) { __result = true; return false; } return true; } } } [HarmonyPatch(typeof(ConfigSync))] internal static class ServerSyncPatches { [HarmonyPatch("RPC_FromServerConfigSync")] [HarmonyPatch("RPC_FromOtherClientConfigSync")] [HarmonyPatch("resetConfigsFromServer")] internal static void Postfix() { StaticMembers.Dbgl("ServerSync event: Processing re-initialization queue.", forceLog: false, (LogLevel)16); ConfigEventHandlers.ProcessReInitQueue(); } } [HarmonyPatch(typeof(Pickable))] internal static class ShowPickableSpawnerPatches { [HarmonyPatch("Awake")] private static void Postfix(Pickable __instance) { TogglePickedMesh(__instance, __instance.m_picked); } [HarmonyPatch("SetPicked")] private static void Postfix(Pickable __instance, bool picked) { TogglePickedMesh(__instance, picked); } private static void TogglePickedMesh(Pickable instance, bool picked) { Transform obj = ((Component)instance).transform.root.Find("PE_Picked"); if (obj != null) { ((Component)obj).gameObject.SetActive(picked); } } } [BepInPlugin("advize.PlantEverything", "PlantEverything", "1.21.1")] public sealed class PlantEverything : BaseUnityPlugin { public const string PluginID = "advize.PlantEverything"; public const string PluginName = "PlantEverything"; public const string Version = "1.21.1"; public void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) Runtime.MakeAllAssetsLoadable(); Logger.Sources.Add((ILogSource)(object)StaticMembers.ModLogger); StaticMembers.assetBundle = PluginUtils.LoadAssetBundle("planteverything"); StaticMembers.config = new ModConfig(((BaseUnityPlugin)this).Config, new ConfigSync("advize.PlantEverything") { DisplayName = "PlantEverything", CurrentVersion = "1.21.1", MinimumRequiredVersion = "1.21.0" }); if ((int)SystemInfo.graphicsDeviceType == 4) { StaticMembers.Dbgl("Dedicated Server Detected", forceLog: false, (LogLevel)16); StaticMembers.isDedicatedServer = true; } if (StaticMembers.config.EnableExtraResources) { ConfigEventHandlers.ExtraResourcesFileOrSettingChanged(null, null); } if (StaticMembers.config.EnableLocalization) { PluginUtils.LoadLocalizedStrings(); } new Harmony("advize.PlantEverything").PatchAll(); StaticMembers.Dbgl("PlantEverything has loaded. Set [General]EnableDebugMessages to false to disable these messages.", forceLog: false, (LogLevel)8); } } } internal sealed class <>z__ReadOnlyArray : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } }