Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Seasons v1.7.9
Seasons.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Seasons; using Seasons.Compatibility; using Seasons.Controllers; using ServerSync; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Networking; using UnityEngine.UI; [assembly: AssemblyFileVersion("1.7.9")] [assembly: Guid("076e7e5f-9182-41e5-a76b-5c051d6b3957")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyProduct("Seasons")] [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("Seasons")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.7.9.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<a40d0a45-5d61-41e7-b9d4-c55d7532be3b>Embedded] internal sealed class <a40d0a45-5d61-41e7-b9d4-c55d7532be3b>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<a40d0a45-5d61-41e7-b9d4-c55d7532be3b>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <a6703e1b-2956-47c6-9727-c45071d1fcd5>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <a6703e1b-2956-47c6-9727-c45071d1fcd5>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <a6703e1b-2956-47c6-9727-c45071d1fcd5>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [<a40d0a45-5d61-41e7-b9d4-c55d7532be3b>Embedded] [CompilerGenerated] internal sealed class <8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContextAttribute : Attribute { public readonly byte Flag; public <8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContextAttribute(byte P_0) { Flag = P_0; } } } public struct HSLColor { public float h; public float s; public float l; public float a; public HSLColor(float h, float s, float l, float a) { this.h = h; this.s = s; this.l = l; this.a = a; } public HSLColor(float h, float s, float l) { this.h = h; this.s = s; this.l = l; a = 1f; } public HSLColor(Color c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HSLColor hSLColor = FromRGBA(c); h = hSLColor.h; s = hSLColor.s; l = hSLColor.l; a = hSLColor.a; } public static HSLColor FromRGBA(Color c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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) float num = c.a; float num2 = Mathf.Min(Mathf.Min(c.r, c.g), c.b); float num3 = Mathf.Max(Mathf.Max(c.r, c.g), c.b); float num4 = (num2 + num3) / 2f; float num5; float num6; if (num2 == num3) { num5 = 0f; num6 = 0f; } else { float num7 = num3 - num2; num5 = ((num4 <= 0.5f) ? (num7 / (num3 + num2)) : (num7 / (2f - (num3 + num2)))); num6 = 0f; if (c.r == num3) { num6 = (c.g - c.b) / num7; } else if (c.g == num3) { num6 = 2f + (c.b - c.r) / num7; } else if (c.b == num3) { num6 = 4f + (c.r - c.g) / num7; } num6 = Mathf.Repeat(num6 * 60f, 360f); } return new HSLColor(num6, num5, num4, num); } public Color ToRGBA() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) float num = a; float num2 = ((l <= 0.5f) ? (l * (1f + s)) : (l + s - l * s)); float n = 2f * l - num2; float num5; float num4; float num3; if (s == 0f) { num5 = (num4 = (num3 = l)); } else { num5 = Value(n, num2, h + 120f); num4 = Value(n, num2, h); num3 = Value(n, num2, h - 120f); } return new Color(num5, num4, num3, num); } private static float Value(float n1, float n2, float hue) { hue = Mathf.Repeat(hue, 360f); if (hue < 60f) { return n1 + (n2 - n1) * hue / 60f; } if (hue < 180f) { return n2; } if (hue < 240f) { return n1 + (n2 - n1) * (240f - hue) / 60f; } return n1; } public static implicit operator HSLColor(Color src) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return FromRGBA(src); } public static implicit operator Color(HSLColor src) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) return src.ToRGBA(); } } namespace LocalizationManager { [PublicAPI] [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(0)] [<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(1)] public class Localizer { [CompilerGenerated] private sealed class <Load>d__12 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(0)] private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] [return: <a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(0)] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <Load>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized)); <>1__state = 1; return true; case 1: <>1__state = -1; if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", ""))) { PlatformPrefs.SetString("language", "English"); } LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string defaultLanguage = "English"; private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(2)] private static BaseUnityPlugin _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin Plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, [<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null) { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += [<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (object _, EventArgs _) => { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } [IteratorStateMachine(typeof(<Load>d__12))] public static IEnumerator Load() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Load>d__12(0); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> localizationFiles = new Dictionary<string, string>(); string[] prefixes = new string[2] { Plugin.Info.Metadata.Name + ".", Plugin.Info.Metadata.Name.Replace(" ", "") + "." }; Scan(Paths.ConfigPath, warn: true); Scan(Paths.PluginPath, warn: false); byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml."); } Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(Encoding.UTF8.GetString(array)) ?? throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty."); string text = null; if (language != "English") { if (localizationFiles.ContainsKey(language)) { text = File.ReadAllText(localizationFiles[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text = Encoding.UTF8.GetString(array2); } } } if (text == null && localizationFiles.ContainsKey("English")) { text = File.ReadAllText(localizationFiles["English"]); } if (text != null) { foreach (KeyValuePair<string, string> item in JsonConvert.DeserializeObject<Dictionary<string, string>>(text) ?? new Dictionary<string, string>()) { dictionary[item.Key] = item.Value; } } loadedTexts[language] = dictionary; foreach (KeyValuePair<string, string> item2 in dictionary) { UpdatePlaceholderText(__instance, item2.Key); } void Scan(string root, bool warn) { foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories) where fileExtensions.Contains(Path.GetExtension(f)) select f) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3); string[] array3 = prefixes; foreach (string text2 in array3) { if (fileNameWithoutExtension.StartsWith(text2)) { string text3 = fileNameWithoutExtension.Substring(text2.Length); if (!string.IsNullOrWhiteSpace(text3)) { if (localizationFiles.ContainsKey(text3)) { if (warn) { global::Seasons.Seasons.LogWarning("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3); } } else { localizationFiles[text3] = item3; } } break; } } } } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string> { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [return: <a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(2)] private static byte[] LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("Translations." + language + fileExtension); if (array != null) { return array; } } return null; } [<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(2)] public static byte[] ReadEmbeddedFileBytes([<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(1)] string resourceFileName, Assembly containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Seasons { public static class LoadingTips { [HarmonyPatch(typeof(Hud), "Awake")] public static class Hud_Awake_LoadingTips { private static void Postfix() { UpdateLoadingTips(); } } public static void UpdateLoadingTips() { if (!((Object)(object)Hud.instance == (Object)null)) { UpdateTipBasedOnValue("$seasons_loadscreen_tip_ice", Seasons.enableFrozenWater.Value); UpdateTipBasedOnValue("$seasons_loadscreen_tip_torch", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Winter).m_torchAsFiresource); UpdateTipBasedOnValue("$seasons_loadscreen_tip_harvests", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Spring).m_plantsGrowthMultiplier != 1f || Seasons.seasonState.GetSeasonSettings(Seasons.Season.Summer).m_plantsGrowthMultiplier != 1f); UpdateTipBasedOnValue("$seasons_loadscreen_tip_nights", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Winter).m_nightLength > 30 || Seasons.controlLightings.Value); UpdateTipBasedOnValue("$seasons_loadscreen_tip_overheat", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Summer).m_overheatIn2WarmClothes); UpdateTipBasedOnValue("$seasons_loadscreen_tip_firewood", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Winter).m_fireplaceDrainMultiplier > 1f); UpdateTipBasedOnValue("$seasons_loadscreen_tip_perish", Seasons.cropsDiesAfterSetDayInWinter.Value != 0); UpdateTipBasedOnValue("$seasons_loadscreen_tip_traders", Seasons.controlTraders.Value); UpdateTipBasedOnValue("$seasons_loadscreen_tip_stats", Seasons.controlStats.Value); UpdateTipBasedOnValue("$seasons_loadscreen_tip_wolves", Seasons.controlRandomEvents.Value); UpdateTipBasedOnValue("$seasons_loadscreen_tip_swimming", Seasons.freezingSwimmingInWinter.Value); UpdateTipBasedOnValue("$seasons_loadscreen_tip_clutter", Seasons.controlGrass.Value); Hud.instance.m_haveSetupLoadScreen = false; Seasons.LogInfo("Loading tips updated."); } } private static void UpdateTipBasedOnValue(string tip, bool value) { if (Seasons.enableLoadingTips.Value && value && !Hud.instance.m_loadingTips.Contains(tip)) { Hud.instance.m_loadingTips.Add(tip); } else if ((!Seasons.enableLoadingTips.Value || !value) && Hud.instance.m_loadingTips.Contains(tip)) { Hud.instance.m_loadingTips.Remove(tip); } } } public static class ControlledComponentsExtentions { public static string Localize(this string text) { return Localization.instance.Localize(text); } public static bool ShouldBePickedInWinter(this Pickable pickable) { return pickable.CanBePicked() && !pickable.GetPicked() && pickable.IsVulnerableToWinter() && Seasons.seasonState.GetCurrentDay() >= Seasons.cropsDiesAfterSetDayInWinter.Value && !((MonoBehaviour)(object)pickable).IsProtectedPosition() && !((MonoBehaviour)(object)pickable).ProtectedWithHeat(); } public static bool IsVulnerableToWinter(this Pickable pickable) { return Seasons.seasonState.GetPlantsGrowthMultiplier() == 0f && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && !((MonoBehaviour)(object)pickable).ShouldSurviveWinter() && !pickable.SurvivedCurrentWinter(); } public static bool SurvivedCurrentWinter(this Pickable pickable) { return Object.op_Implicit((Object)(object)pickable.m_nview) && pickable.m_nview.IsValid() && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && Mathf.Abs(pickable.m_nview.GetZDO().GetInt(SeasonsVars.s_cropSurvivedWinterDayHash, 0) - Seasons.seasonState.GetCurrentWorldDay()) <= Seasons.seasonState.GetDaysInSeason(); } public static bool IsFreezingToDeath(this Pickable pickable) { return Object.op_Implicit((Object)(object)pickable.m_nview) && pickable.m_nview.IsValid() && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && pickable.GetSecondsToFreeze() > 0.0; } public static double GetSecondsToFreeze(this Pickable pickable) { if (Object.op_Implicit((Object)(object)pickable.m_nview) && pickable.m_nview.IsValid() && Object.op_Implicit((Object)(object)ZNet.instance)) { long @long = pickable.m_nview.GetZDO().GetLong(SeasonsVars.s_cropStartedFreezingHash, 0L); if (@long <= 0) { return 0.0; } float num = Seasons.secondsToFreezeForCropInWinter.Value; if (num % 60f == 0f) { num -= 2f; } return (new DateTime(@long).AddSeconds(num) - ZNet.instance.GetTime()).TotalSeconds; } return 0.0; } public static bool CheckForPerishInWinter(this Pickable pickable) { if (!pickable.ShouldBePickedInWinter()) { pickable.SetFreezing(freezing: false); return false; } if (Seasons.secondsToFreezeForCropInWinter.Value > 0f) { pickable.SetFreezing(freezing: true); } if (pickable.IsFreezingToDeath()) { return false; } ((MonoBehaviour)pickable).StartCoroutine(Seasons.PickableSetPickedInWinter(pickable)); return true; } public static void SetFreezing(this Pickable pickable, bool freezing) { if (!Object.op_Implicit((Object)(object)pickable.m_nview) || !pickable.m_nview.IsValid() || !Object.op_Implicit((Object)(object)ZNet.instance)) { return; } ZDO zDO = pickable.m_nview.GetZDO(); if (zDO != null) { if (freezing && zDO.GetLong(SeasonsVars.s_cropStartedFreezingHash, 0L) == 0L && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && Seasons.seasonState.GetCurrentDay() >= Seasons.cropsDiesAfterSetDayInWinter.Value) { zDO.Set(SeasonsVars.s_cropStartedFreezingHash, ZNet.instance.GetTime().Ticks); } else if (!freezing) { zDO.Set(SeasonsVars.s_cropStartedFreezingHash, 0L); } } } public static bool IsIgnored(this Pickable pickable) { return (Object)(object)pickable.m_nview == (Object)null || !pickable.m_nview.IsValid() || (pickable.m_nview.HasOwner() && !pickable.m_nview.IsOwner()) || !((MonoBehaviour)(object)pickable).ControlPlantGrowth() || ((MonoBehaviour)(object)pickable).IsIgnoredPosition(); } public static string GetColdStatus(this Pickable pickable) { if (((MonoBehaviour)(object)pickable).ShouldSurviveWinter()) { return "$seasons_plant_frost_resistant"; } if (((MonoBehaviour)(object)pickable).ProtectedWithHeat()) { return "$seasons_plant_heat_protected"; } if (pickable.SurvivedCurrentWinter()) { return "$seasons_plant_survived_winter"; } double secondsToFreeze = pickable.GetSecondsToFreeze(); if (secondsToFreeze != 0.0 && Seasons.secondsToFreezeForCropInWinter.Value > 0f) { if (secondsToFreeze > 0.0) { return "$seasons_plant_is_freezing\n" + Seasons.FromPercent(secondsToFreeze / (double)Seasons.secondsToFreezeForCropInWinter.Value); } return "$seasons_plant_is_frozen"; } if (Seasons.seasonState.GetCurrentDay() > Seasons.cropsDiesAfterSetDayInWinter.Value) { return "$seasons_plant_will_perish"; } return "$seasons_plant_is_exposed"; } public static bool ControlPlantGrowth(this MonoBehaviour behaviour) { return Seasons.ControlPlantGrowth(((Component)behaviour).gameObject); } public static bool ShouldSurviveWinter(this MonoBehaviour behaviour) { return Seasons.PlantWillSurviveWinter(((Component)behaviour).gameObject); } public static bool IsIgnoredPosition(this MonoBehaviour behaviour) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Seasons.IsIgnoredPosition(((Component)behaviour).transform.position); } public static bool IsProtectedPosition(this MonoBehaviour behaviour) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Seasons.IsProtectedPosition(((Component)behaviour).transform.position); } public static bool ProtectedWithHeat(this MonoBehaviour behaviour) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Seasons.ProtectedWithHeat(((Component)behaviour).transform.position); } } public static class TerrainDecultivation { public static int terrainCompVersion; public static int m_operations; public static Vector3 m_lastOpPoint; public static float m_lastOpRadius; public static bool[] m_modifiedHeight; public static float[] m_levelDelta; public static float[] m_smoothDelta; public static bool[] m_modifiedPaint; public static Color[] m_paintMask; public static bool DecultivateGround(ZDO zdo) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0209: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) byte[] byteArray = zdo.GetByteArray(ZDOVars.s_TCData, (byte[])null); if (byteArray == null) { return false; } ZPackage val = new ZPackage(Utils.Decompress(byteArray)); terrainCompVersion = val.ReadInt(); if (terrainCompVersion != 1) { Seasons.LogWarning("Season can not decultivate ground due to changes in terrain compiler data"); return false; } bool flag = false; m_operations = val.ReadInt(); m_lastOpPoint = val.ReadVector3(); m_lastOpRadius = val.ReadSingle(); m_modifiedHeight = new bool[val.ReadInt()]; m_levelDelta = new float[m_modifiedHeight.Length]; m_smoothDelta = new float[m_modifiedHeight.Length]; for (int i = 0; i < m_modifiedHeight.Length; i++) { m_modifiedHeight[i] = val.ReadBool(); if (m_modifiedHeight[i]) { m_levelDelta[i] = val.ReadSingle(); m_smoothDelta[i] = val.ReadSingle(); } else { m_levelDelta[i] = 0f; m_smoothDelta[i] = 0f; } } m_modifiedPaint = new bool[val.ReadInt()]; m_paintMask = (Color[])(object)new Color[m_modifiedPaint.Length]; for (int j = 0; j < m_modifiedPaint.Length; j++) { m_modifiedPaint[j] = val.ReadBool(); if (m_modifiedPaint[j]) { Color val2 = default(Color); val2.r = val.ReadSingle(); val2.g = val.ReadSingle(); val2.b = val.ReadSingle(); val2.a = val.ReadSingle(); if (val2.g > 0f) { val2.r = Mathf.Max(val2.r, val2.g); val2.g = 0f; flag = true; } m_paintMask[j] = val2; } else { m_paintMask[j] = Color.black; } } if (!flag) { return false; } ZPackage val3 = new ZPackage(); val3.Write(terrainCompVersion); val3.Write(m_operations); val3.Write(m_lastOpPoint); val3.Write(m_lastOpRadius); val3.Write(m_modifiedHeight.Length); for (int k = 0; k < m_modifiedHeight.Length; k++) { val3.Write(m_modifiedHeight[k]); if (m_modifiedHeight[k]) { val3.Write(m_levelDelta[k]); val3.Write(m_smoothDelta[k]); } } val3.Write(m_modifiedPaint.Length); for (int l = 0; l < m_modifiedPaint.Length; l++) { val3.Write(m_modifiedPaint[l]); if (m_modifiedPaint[l]) { val3.Write(m_paintMask[l].r); val3.Write(m_paintMask[l].g); val3.Write(m_paintMask[l].b); val3.Write(m_paintMask[l].a); } } byte[] array = Utils.Compress(val3.GetArray()); zdo.Set(ZDOVars.s_TCData, array); return true; } } [Serializable] public class CachedData { [Serializable] public class TextureData { public string name; public byte[] originalPNG; public TextureProperties properties; public Dictionary<Seasons.Season, Dictionary<int, byte[]>> variants = new Dictionary<Seasons.Season, Dictionary<int, byte[]>>(); public bool Initialized() { return variants.Any((KeyValuePair<Seasons.Season, Dictionary<int, byte[]>> variant) => variant.Value.Count > 0); } public TextureData(TextureVariants textureVariants) { if (textureVariants == null) { return; } originalPNG = textureVariants.originalPNG; name = textureVariants.originalName; properties = textureVariants.properties; foreach (KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> season in textureVariants.seasons) { variants.Add(season.Key, new Dictionary<int, byte[]>()); foreach (KeyValuePair<int, Texture2D> item in season.Value) { variants[season.Key].Add(item.Key, ImageConversion.EncodeToPNG(item.Value)); } } } public TextureData(DirectoryInfo texDirectory) { FileInfo[] files = texDirectory.GetFiles("properties.json"); if (files.Length != 0) { properties = JsonUtility.FromJson<TextureProperties>(File.ReadAllText(files[0].FullName)); } foreach (Seasons.Season value in Enum.GetValues(typeof(Seasons.Season))) { variants.Add(value, new Dictionary<int, byte[]>()); for (int i = 0; i < 4; i++) { FileInfo[] files2 = texDirectory.GetFiles(SeasonFileName(value, i)); if (files2.Length != 0) { variants[value].Add(i, File.ReadAllBytes(files2[0].FullName)); } } } } } internal const string cacheSubdirectory = "Cache"; internal const string prefabCacheCommonFile = "cache.bin"; internal const string prefabCacheFileName = "cache.json"; internal const string texturesDirectory = "textures"; internal const string originalPostfix = ".orig.png"; internal const string texturePropertiesFileName = "properties.json"; public Dictionary<string, PrefabController> controllers = new Dictionary<string, PrefabController>(); public Dictionary<int, TextureData> textures = new Dictionary<int, TextureData>(); public uint revision = 0u; public CachedData(uint revision) { this.revision = revision; } public bool Initialized() { return controllers.Count > 0 && textures.Count > 0; } public void SaveOnDisk() { if (Initialized()) { if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Binary) { SaveToBinary(); return; } if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Json) { SaveToJSON(); return; } SaveToJSON(); SaveToBinary(); } } public void LoadFromDisk() { if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Json) { LoadFromJSON(); } else { LoadFromBinary(); } } private void SaveToJSON() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown string text = CacheDirectory(); Directory.CreateDirectory(text); string text2 = Path.Combine(text, "cache.json"); File.WriteAllText(text2, JsonConvert.SerializeObject((object)controllers, (Formatting)1, new JsonSerializerSettings { NullValueHandling = (NullValueHandling)1, DefaultValueHandling = (DefaultValueHandling)1 })); string text3 = Path.Combine(text, "textures"); Seasons.LogInfo("Saved cache file " + text2); foreach (KeyValuePair<int, TextureData> texture in textures) { string text4 = Path.Combine(text3, texture.Key.ToString()); Directory.CreateDirectory(text4); File.WriteAllBytes(Path.Combine(text4, texture.Value.name + ".orig.png"), texture.Value.originalPNG); File.WriteAllText(Path.Combine(text4, "properties.json"), JsonUtility.ToJson((object)texture.Value.properties, true)); foreach (KeyValuePair<Seasons.Season, Dictionary<int, byte[]>> variant in texture.Value.variants) { foreach (KeyValuePair<int, byte[]> item in variant.Value) { File.WriteAllBytes(Path.Combine(text4, SeasonFileName(variant.Key, item.Key)), item.Value); } } } Seasons.LogInfo($"Saved {textures.Count} textures at {text3}"); } private void LoadFromJSON() { string text = CacheDirectory(); DirectoryInfo directoryInfo = new DirectoryInfo(text); if (!directoryInfo.Exists) { return; } FileInfo[] files = directoryInfo.GetFiles("cache.json"); if (files.Length == 0) { Seasons.LogInfo("File not found: " + Path.Combine(text, "cache.json")); return; } try { controllers = JsonConvert.DeserializeObject<Dictionary<string, PrefabController>>(File.ReadAllText(files[0].FullName)); } catch (Exception arg) { Seasons.LogWarning($"Error loading JSON cache data from {files[0].FullName}\n{arg}"); return; } DirectoryInfo[] directories = directoryInfo.GetDirectories("textures"); if (directories.Length == 0) { return; } DirectoryInfo[] directories2 = directories[0].GetDirectories(); foreach (DirectoryInfo directoryInfo2 in directories2) { int key = int.Parse(directoryInfo2.Name); if (!textures.ContainsKey(key)) { TextureData textureData = new TextureData(directoryInfo2); if (textureData.Initialized()) { textures.Add(key, textureData); } } } } private void SaveToBinary() { string text = CacheDirectory(); Directory.CreateDirectory(text); using (FileStream fileStream = new FileStream(Path.Combine(text, "cache.bin"), FileMode.Create)) { BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(fileStream, this); fileStream.Dispose(); } Seasons.LogInfo("Saved cache file " + Path.Combine(text, "cache.bin")); } private void LoadFromBinary() { string path = CacheDirectory(); string text = Path.Combine(path, "cache.bin"); if (!File.Exists(text)) { Seasons.LogInfo("File not found: " + text); return; } try { using FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryFormatter binaryFormatter = new BinaryFormatter(); CachedData cachedData = (CachedData)binaryFormatter.Deserialize(fileStream); fileStream.Dispose(); DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers); DictionaryExt.Copy<int, TextureData>(textures, cachedData.textures); cachedData = null; } catch (Exception arg) { Seasons.LogWarning($"Error loading binary cache data from {text}:\n {arg}"); } } public string CacheDirectory() { return Path.Combine(Seasons.cacheDirectory, revision.ToString()); } public static string SeasonFileName(Seasons.Season season, int variant) { return $"{season}_{variant + 1}.png"; } } [Serializable] public class PrefabController { [Serializable] public class CachedMaterial { public string name = string.Empty; public string shaderName = string.Empty; public Dictionary<string, int> textureProperties = new Dictionary<string, int>(); public Dictionary<string, string[]> colorVariants = new Dictionary<string, string[]>(); public CachedMaterial() { } public CachedMaterial(string materialName, string shader, string propertyName, int textureID) { name = materialName; shaderName = shader; AddTexture(propertyName, textureID); } public CachedMaterial(string materialName, string shader, string propertyName, Color[] colors) { name = materialName; shaderName = shader; AddColors(propertyName, colors); } public void AddTexture(string propertyName, int textureID) { if (!textureProperties.ContainsKey(propertyName)) { textureProperties.Add(propertyName, textureID); } } public void AddColors(string propertyName, Color[] colors) { List<string> vec = new List<string>(); CollectionExtensions.Do<Color>((IEnumerable<Color>)colors, (Action<Color>)delegate(Color x) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) vec.Add("#" + ColorUtility.ToHtmlStringRGBA(x)); }); if (!colorVariants.ContainsKey(propertyName)) { colorVariants.Add(propertyName, vec.ToArray()); } } } [Serializable] public class CachedRenderer { public string name = string.Empty; public string type = string.Empty; public Dictionary<string, CachedMaterial> materials = new Dictionary<string, CachedMaterial>(); public CachedRenderer() { } public CachedRenderer(string rendererName, string rendererType) { name = rendererName; type = rendererType; } public bool Initialized() { return materials.Any((KeyValuePair<string, CachedMaterial> m) => m.Value.textureProperties.Count > 0 || m.Value.colorVariants.Count > 0); } public void AddMaterialTexture(Material material, string propertyName, int textureID) { if (!materials.TryGetValue(((Object)material).name, out var value)) { materials.Add(((Object)material).name, new CachedMaterial(((Object)material).name, ((Object)material.shader).name, propertyName, textureID)); } else { value.AddTexture(propertyName, textureID); } } public void AddMaterialColors(Material material, string propertyName, Color[] colors) { if (!materials.TryGetValue(((Object)material).name, out var value)) { materials.Add(((Object)material).name, new CachedMaterial(((Object)material).name, ((Object)material.shader).name, propertyName, colors)); } else { value.AddColors(propertyName, colors); } } } public Dictionary<string, Dictionary<int, List<CachedRenderer>>> lodsInHierarchy = new Dictionary<string, Dictionary<int, List<CachedRenderer>>>(); public Dictionary<int, List<CachedRenderer>> lodLevelMaterials = new Dictionary<int, List<CachedRenderer>>(); public Dictionary<string, CachedRenderer> renderersInHierarchy = new Dictionary<string, CachedRenderer>(); public CachedRenderer cachedRenderer; public Dictionary<string, string[]> particleSystemStartColors; [NonSerialized] public long elapsedTicks = 0L; public bool Initialized() { return lodsInHierarchy.Count > 0 || lodLevelMaterials.Count > 0 || renderersInHierarchy.Count > 0 || cachedRenderer != null || particleSystemStartColors != null; } public override string ToString() { return ((cachedRenderer == null) ? "" : " 1 main renderer") + ((particleSystemStartColors == null) ? "" : " 1 particles start color") + " " + ((lodsInHierarchy.Count > 0) ? $" {lodsInHierarchy.Count} LOD groups" : "") + ((lodLevelMaterials.Count > 0) ? $" {lodLevelMaterials.Count} LODs" : "") + ((renderersInHierarchy.Count > 0) ? $" {renderersInHierarchy.Count} renderersInHierarchy" : "") + ((elapsedTicks > 0) ? $" in {(double)elapsedTicks / (double)Stopwatch.Frequency * 1000.0:F2} ms" : ""); } } public class SeasonalTextureVariants { [CompilerGenerated] private sealed class <>c__DisplayClass4_0 { public CachedData cachedData; public SeasonalTextureVariants <>4__this; internal void <SaveCacheOnDisk>b__0() { DictionaryExt.Copy<string, PrefabController>(cachedData.controllers, <>4__this.controllers); if (Directory.Exists(cachedData.CacheDirectory())) { Directory.Delete(cachedData.CacheDirectory(), recursive: true); } cachedData.SaveOnDisk(); } } [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public CachedData cachedData; public SeasonalTextureVariants <>4__this; internal void <ReloadCache>b__0() { cachedData.LoadFromDisk(); } internal void <ReloadCache>b__1() { DictionaryExt.Copy<string, PrefabController>(<>4__this.controllers, cachedData.controllers); } } [CompilerGenerated] private sealed class <>c__DisplayClass8_0 { public SeasonalTextureVariants <>4__this; public SeasonalTextureVariants newTexturesVariants; internal void <RebuildCache>b__0() { DictionaryExt.Copy<string, PrefabController>(<>4__this.controllers, newTexturesVariants.controllers); DictionaryExt.Copy<int, TextureVariants>(<>4__this.textures, newTexturesVariants.textures); } } [CompilerGenerated] private sealed class <RebuildCache>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SeasonalTextureVariants <>4__this; private <>c__DisplayClass8_0 <>8__1; private Stopwatch <stopwatch>5__2; private Thread <internalThread>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RebuildCache>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <stopwatch>5__2 = null; <internalThread>5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass8_0(); <>8__1.<>4__this = <>4__this; <>8__1.newTexturesVariants = new SeasonalTextureVariants(); SeasonalTexturePrefabCache.SetCurrentTextureVariants(<>8__1.newTexturesVariants); PrefabVariantController.instance?.RevertPrefabsState(); ClutterVariantController.Instance?.RevertColors(); <>2__current = Seasons.waitForFixedUpdate; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = SeasonalTexturePrefabCache.FillWithGameData(); <>1__state = 2; return true; case 2: <>1__state = -1; if (<>8__1.newTexturesVariants.Initialized()) { <stopwatch>5__2 = Stopwatch.StartNew(); <>4__this.controllers.Clear(); <>4__this.textures.Clear(); <>4__this.revision = <>8__1.newTexturesVariants.revision; <internalThread>5__3 = new Thread((ThreadStart)delegate { DictionaryExt.Copy<string, PrefabController>(<>8__1.<>4__this.controllers, <>8__1.newTexturesVariants.controllers); DictionaryExt.Copy<int, TextureVariants>(<>8__1.<>4__this.textures, <>8__1.newTexturesVariants.textures); }); <internalThread>5__3.Start(); goto IL_0191; } goto IL_022b; case 3: <>1__state = -1; goto IL_0191; case 4: <>1__state = -1; SeasonalTexturePrefabCache.SetCurrentTextureVariants(<>4__this); ClutterVariantController.Reinitialize(); PrefabVariantController.ReinitializePrefabVariants(); <>2__current = Seasons.waitForFixedUpdate; <>1__state = 5; return true; case 5: <>1__state = -1; Seasons.LogInfo($"Colors reinitialized in {<stopwatch>5__2.Elapsed.TotalSeconds,-4:F2} seconds"); <stopwatch>5__2 = null; <internalThread>5__3 = null; goto IL_022b; case 6: { <>1__state = -1; SeasonalTexturePrefabCache.SetCurrentTextureVariants(<>4__this); PrefabVariantController.UpdatePrefabColors(); ClutterVariantController.Instance?.UpdateColors(); Seasons.LogInfo("Cache rebuild ended"); return false; } IL_022b: <>2__current = Seasons.waitForFixedUpdate; <>1__state = 6; return true; IL_0191: if (<internalThread>5__3.IsAlive) { <>2__current = Seasons.waitForFixedUpdate; <>1__state = 3; return true; } <>2__current = <>4__this.SaveCacheOnDisk(); <>1__state = 4; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ReloadCache>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SeasonalTextureVariants <>4__this; private <>c__DisplayClass7_0 <>8__1; private Stopwatch <stopwatch>5__2; private Thread <internalThread>5__3; private Dictionary<int, CachedData.TextureData>.Enumerator <>s__4; private KeyValuePair<int, CachedData.TextureData> <texData>5__5; private TextureVariants <texVariants>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ReloadCache>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <stopwatch>5__2 = null; <internalThread>5__3 = null; <>s__4 = default(Dictionary<int, CachedData.TextureData>.Enumerator); <texData>5__5 = default(KeyValuePair<int, CachedData.TextureData>); <texVariants>5__6 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass7_0(); <>8__1.<>4__this = <>4__this; <stopwatch>5__2 = Stopwatch.StartNew(); <>8__1.cachedData = new CachedData(SeasonalTexturePrefabCache.GetRevision()); <internalThread>5__3 = new Thread((ThreadStart)delegate { <>8__1.cachedData.LoadFromDisk(); }); <internalThread>5__3.Start(); goto IL_00c6; case 1: <>1__state = -1; goto IL_00c6; case 2: <>1__state = -1; goto IL_0236; case 3: <>1__state = -1; PrefabVariantController.UpdatePrefabColors(); ClutterVariantController.Instance.UpdateColors(); Seasons.LogInfo($"Colors reinitialized in {<stopwatch>5__2.Elapsed.TotalSeconds,-4:F2} seconds"); break; case 4: { <>1__state = -1; break; } IL_00c6: if (<internalThread>5__3.IsAlive) { <>2__current = Seasons.waitForFixedUpdate; <>1__state = 1; return true; } if (<>8__1.cachedData.Initialized()) { <>4__this.revision = <>8__1.cachedData.revision; <>s__4 = <>8__1.cachedData.textures.GetEnumerator(); try { while (<>s__4.MoveNext()) { <texData>5__5 = <>s__4.Current; if (!<>4__this.textures.ContainsKey(<texData>5__5.Key)) { <texVariants>5__6 = new TextureVariants(<texData>5__5.Value); if (<texVariants>5__6.Initialized()) { <>4__this.textures.Add(<texData>5__5.Key, <texVariants>5__6); <texVariants>5__6 = null; <texData>5__5 = default(KeyValuePair<int, CachedData.TextureData>); } } } } finally { ((IDisposable)<>s__4).Dispose(); } <>s__4 = default(Dictionary<int, CachedData.TextureData>.Enumerator); <internalThread>5__3 = new Thread((ThreadStart)delegate { DictionaryExt.Copy<string, PrefabController>(<>8__1.<>4__this.controllers, <>8__1.cachedData.controllers); }); <internalThread>5__3.Start(); goto IL_0236; } <>2__current = <>4__this.RebuildCache(); <>1__state = 4; return true; IL_0236: if (<internalThread>5__3.IsAlive) { <>2__current = Seasons.waitForFixedUpdate; <>1__state = 2; return true; } Seasons.LogInfo($"Loaded from cache revision:{<>4__this.revision} controllers:{<>4__this.controllers.Count} textures:{<>4__this.textures.Count} in {<stopwatch>5__2.Elapsed.TotalSeconds,-4:F2} seconds"); <stopwatch>5__2.Restart(); ClutterVariantController.Reinitialize(); PrefabVariantController.ReinitializePrefabVariants(); <>2__current = Seasons.waitForFixedUpdate; <>1__state = 3; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SaveCacheOnDisk>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SeasonalTextureVariants <>4__this; private <>c__DisplayClass4_0 <>8__1; private Thread <internalThread>5__2; private Dictionary<int, TextureVariants>.Enumerator <>s__3; private KeyValuePair<int, TextureVariants> <texVariants>5__4; private CachedData.TextureData <texData>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SaveCacheOnDisk>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <internalThread>5__2 = null; <>s__3 = default(Dictionary<int, TextureVariants>.Enumerator); <texVariants>5__4 = default(KeyValuePair<int, TextureVariants>); <texData>5__5 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; if (!<>4__this.Initialized()) { goto IL_01ad; } <>8__1 = new <>c__DisplayClass4_0(); <>8__1.<>4__this = <>4__this; <>8__1.cachedData = new CachedData(<>4__this.revision); <>8__1.cachedData.textures.Clear(); <>s__3 = <>4__this.textures.GetEnumerator(); try { while (<>s__3.MoveNext()) { <texVariants>5__4 = <>s__3.Current; <texData>5__5 = new CachedData.TextureData(<texVariants>5__4.Value); if (<texData>5__5.Initialized()) { <>8__1.cachedData.textures.Add(<texVariants>5__4.Key, <texData>5__5); } <texData>5__5 = null; <texVariants>5__4 = default(KeyValuePair<int, TextureVariants>); } } finally { ((IDisposable)<>s__3).Dispose(); } <>s__3 = default(Dictionary<int, TextureVariants>.Enumerator); <internalThread>5__2 = new Thread((ThreadStart)delegate { DictionaryExt.Copy<string, PrefabController>(<>8__1.cachedData.controllers, <>8__1.<>4__this.controllers); if (Directory.Exists(<>8__1.cachedData.CacheDirectory())) { Directory.Delete(<>8__1.cachedData.CacheDirectory(), recursive: true); } <>8__1.cachedData.SaveOnDisk(); }); <internalThread>5__2.Start(); } if (<internalThread>5__2.IsAlive) { <>2__current = Seasons.waitForFixedUpdate; <>1__state = 1; return true; } <>4__this.ApplyTexturesToGPU(); <>8__1 = null; <internalThread>5__2 = null; goto IL_01ad; IL_01ad: return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public Dictionary<string, PrefabController> controllers = new Dictionary<string, PrefabController>(); public Dictionary<int, TextureVariants> textures = new Dictionary<int, TextureVariants>(); public uint revision = 0u; public bool Initialize(bool force = false) { if (!force && Initialized()) { return true; } controllers.Clear(); textures.Clear(); revision = SeasonalTexturePrefabCache.GetRevision(); CachedData cachedData = new CachedData(revision); if (force && Directory.Exists(cachedData.CacheDirectory())) { Directory.Delete(cachedData.CacheDirectory(), recursive: true); } cachedData.LoadFromDisk(); if (cachedData.Initialized()) { DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers); foreach (KeyValuePair<int, CachedData.TextureData> texture in cachedData.textures) { if (!textures.ContainsKey(texture.Key)) { TextureVariants textureVariants = new TextureVariants(texture.Value); if (textureVariants.Initialized()) { textures.Add(texture.Key, textureVariants); } } } Seasons.LogInfo($"Loaded from cache revision:{revision} controllers:{controllers.Count} textures:{textures.Count}"); } else if (!Seasons.runTextureCachingSync.Value) { TextureCachingController.StartCaching(this); } else { SeasonalTexturePrefabCache.SetCurrentTextureVariants(this); Seasons.StartCoroutineSync(SeasonalTexturePrefabCache.FillWithGameData()); Seasons.StartCoroutineSync(SaveCacheOnDisk()); } return Initialized(); } [IteratorStateMachine(typeof(<SaveCacheOnDisk>d__4))] public IEnumerator SaveCacheOnDisk() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SaveCacheOnDisk>d__4(0) { <>4__this = this }; } public bool Initialized() { return controllers.Count > 0 && textures.Count > 0; } public void ApplyTexturesToGPU() { foreach (KeyValuePair<int, TextureVariants> texture in textures) { texture.Value.ApplyTextures(); } } [IteratorStateMachine(typeof(<ReloadCache>d__7))] public IEnumerator ReloadCache() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ReloadCache>d__7(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<RebuildCache>d__8))] public IEnumerator RebuildCache() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RebuildCache>d__8(0) { <>4__this = this }; } } public class TextureVariants { public Texture2D original; public string originalName; public byte[] originalPNG; public TextureProperties properties; public Dictionary<Seasons.Season, Dictionary<int, Texture2D>> seasons = new Dictionary<Seasons.Season, Dictionary<int, Texture2D>>(); public TextureVariants(CachedData.TextureData texData) { if (texData == null) { return; } properties = texData.properties; foreach (Seasons.Season value3 in Enum.GetValues(typeof(Seasons.Season))) { if (!texData.variants.TryGetValue(value3, out var value)) { continue; } for (int i = 0; i < 4; i++) { if (value.TryGetValue(i, out var value2)) { Texture2D val = properties.CreateTexture(); if (ImageConversion.LoadImage(val, value2, true)) { AddVariant(value3, i, val); } else { Object.Destroy((Object)(object)val); } } } } } public TextureVariants(Texture texture) { SetOriginalTexture(texture); } public void SetOriginalTexture(Texture texture) { original = (Texture2D)(object)((texture is Texture2D) ? texture : null); properties = new TextureProperties((Texture2D)(object)((texture is Texture2D) ? texture : null)); originalName = ((Object)original).name; } public bool Initialized() { return seasons.Any((KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> season) => season.Value.Count > 0); } public bool HaveOriginalTexture() { return Object.op_Implicit((Object)(object)original); } public void ApplyTextures() { foreach (KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> season in seasons) { foreach (KeyValuePair<int, Texture2D> item in season.Value) { item.Value.Apply(true, true); } } } public void AddVariant(Seasons.Season season, int variant, Texture2D tex) { if (!seasons.TryGetValue(season, out var value)) { value = new Dictionary<int, Texture2D>(); seasons.Add(season, value); } if (!value.ContainsKey(variant)) { value.Add(variant, tex); } } public Texture2D GetSeasonalVariant(Seasons.Season season, int variant) { if (CustomTextures.HaveCustomTexture(originalName, season, variant, properties, out var texture)) { return texture; } if (seasons.TryGetValue(season, out var value) && value.TryGetValue(variant, out var value2)) { return value2; } return original; } } [Serializable] public class TextureProperties { public TextureFormat format = (TextureFormat)5; public int mipmapCount = 1; public TextureWrapMode wrapMode = (TextureWrapMode)0; public FilterMode filterMode = (FilterMode)0; public int anisoLevel = 1; public float mipMapBias = 0f; public int width = 2; public int height = 2; public TextureProperties(Texture2D tex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) mipmapCount = ((Texture)tex).mipmapCount; wrapMode = ((Texture)tex).wrapMode; filterMode = ((Texture)tex).filterMode; anisoLevel = ((Texture)tex).anisoLevel; mipMapBias = ((Texture)tex).mipMapBias; width = ((Texture)tex).width; height = ((Texture)tex).height; } public Texture2D CreateTexture() { //IL_000e: 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) //IL_001f: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown return new Texture2D(width, height, format, mipmapCount, false) { filterMode = filterMode, anisoLevel = anisoLevel, mipMapBias = mipMapBias, wrapMode = wrapMode }; } } [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(0)] [<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(1)] internal class CustomConfigs { [<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] internal class ConfigurationManagerAttributes { [UsedImplicitly] [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(new byte[] { 2, 1 })] public Action<ConfigEntryBase> CustomDrawer; [UsedImplicitly] public bool? ShowRangeAsPercent = false; } [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(2)] internal static object configManager; [<a6703e1b-2956-47c6-9727-c45071d1fcd5>Nullable(2)] internal static Type configManagerStyles; internal static GUIStyle GetStyle(GUIStyle other) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown if (configManagerStyles == null) { return other; } FieldInfo fieldInfo = AccessTools.Field(configManagerStyles, "fontSize"); if (fieldInfo == null) { return other; } return new GUIStyle(other) { fontSize = (int)fieldInfo.GetValue(configManagerStyles) }; } internal static void Awake() { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager"); Type type = assembly?.GetType("ConfigurationManager.ConfigurationManager"); configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type)); configManagerStyles = assembly?.GetType("ConfigurationManager.ConfigurationManagerStyles"); } internal static Action<ConfigEntryBase> DrawSeparatedStrings(string splitString) { return delegate(ConfigEntryBase cfg) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); bool flag = false; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); List<string> list = new List<string>(); List<string> list2 = ((string)cfg.BoxedValue).Split(new string[1] { splitString }, StringSplitOptions.None).ToList(); for (int i = 0; i < list2.Count; i++) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); string text = list2[i]; string text2 = GUILayout.TextField(text, GetStyle(GUI.skin.textArea), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (text2 != text && !valueOrDefault) { flag = true; } if (GUILayout.Button("x", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault) { flag = true; } else { list.Add(text2); } if (GUILayout.Button("+", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault) { flag = true; list.Add(""); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = string.Join(splitString, list); } }; } internal static Action<ConfigEntryBase> DrawOrderedFixedStrings(string splitString) { return delegate(ConfigEntryBase cfg) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([<8397e53d-0b0b-45b5-92b7-eef54cf6c573>NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); bool flag = false; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); string[] array = ((string)cfg.BoxedValue).Split(new string[1] { splitString }, StringSplitOptions.None).ToArray(); for (int i = 0; i < array.Length; i++) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); string text = array[i]; GUILayout.Label(text, GetStyle(GUI.skin.textArea), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("ʌ", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault && (flag = i > 0)) { ref string reference = ref array[i]; ref string reference2 = ref array[i - 1]; string text2 = array[i - 1]; string text3 = array[i]; reference = text2; reference2 = text3; } if (GUILayout.Button("v", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault && (flag = i < array.Length - 1)) { ref string reference = ref array[i]; ref string reference3 = ref array[i + 1]; string text3 = array[i + 1]; string text2 = array[i]; reference = text3; reference3 = text2; } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = string.Join(splitString, array); } }; } } internal static class CustomMusic { internal class MusicSettings { public float m_volume = 1f; public float m_fadeInTime = 3f; public bool m_alwaysFadeout = false; public bool m_loop = true; public bool m_resume = true; public bool m_enabled = true; public bool m_ambientMusic = true; } public const string subdirectory = "Custom music"; public static readonly Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>(); public static readonly Dictionary<string, MusicSettings> clipSettings = new Dictionary<string, MusicSettings>(); internal static void SetupConfigWatcher() { string filter = "*.*"; FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(GetSubdirectory(), filter); fileSystemWatcher.Changed += UpdateClipOnChange; fileSystemWatcher.Created += UpdateClipOnChange; fileSystemWatcher.Renamed += UpdateClipOnChange; fileSystemWatcher.Deleted += UpdateClipOnChange; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; UpdateCustomMusic(); CheckMusicList(); SeasonEnvironment.ClearCachedObjects(); } internal static void CheckMusicList() { if (!Object.op_Implicit((Object)(object)MusicMan.instance)) { return; } foreach (KeyValuePair<string, AudioClip> clip in audioClips) { (MusicMan.instance.m_music.Find((NamedMusic music) => music.m_name == clip.Key) ?? GetNewMusic(clip.Key)).m_clips = (AudioClip[])(object)new AudioClip[1] { clip.Value }; } MusicMan.instance.m_musicHashes.Clear(); foreach (NamedMusic item in MusicMan.instance.m_music) { if (clipSettings.TryGetValue(item.m_name, out var value)) { item.m_ambientMusic = value.m_ambientMusic; item.m_resume = value.m_resume; item.m_alwaysFadeout = value.m_alwaysFadeout; item.m_enabled = value.m_enabled; item.m_fadeInTime = value.m_fadeInTime; item.m_loop = value.m_loop; item.m_volume = value.m_volume; } if (item.m_enabled && item.m_clips.Length != 0 && (Object)(object)item.m_clips[0] != (Object)null) { MusicMan.instance.m_musicHashes[StringExtensionMethods.GetStableHashCode(item.m_name)] = item; } } } private static NamedMusic GetNewMusic(string name) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_003a: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown MusicSettings musicSettings = GeneralExtensions.GetValueSafe<string, MusicSettings>(clipSettings, name) ?? new MusicSettings(); NamedMusic val = new NamedMusic { m_name = name, m_ambientMusic = musicSettings.m_ambientMusic, m_resume = musicSettings.m_resume, m_alwaysFadeout = musicSettings.m_alwaysFadeout, m_enabled = musicSettings.m_enabled, m_fadeInTime = musicSettings.m_fadeInTime, m_loop = musicSettings.m_loop, m_volume = musicSettings.m_volume }; MusicMan.instance.m_music.Add(val); return val; } private static string GetSubdirectory() { string text = Path.Combine(Seasons.configDirectory, "Custom music"); Directory.CreateDirectory(text); return text; } private static void UpdateCustomMusic() { string path = GetSubdirectory(); if (!Directory.Exists(path)) { return; } foreach (FileInfo item in from file in new DirectoryInfo(path).EnumerateFiles("*.*", SearchOption.AllDirectories) orderby file.Extension.ToLower() != ".json" select file) { UpdateFile(item.Name, item.FullName); } } private static void UpdateClipOnChange(object sender, FileSystemEventArgs eargs) { UpdateFile(eargs.Name, eargs.FullPath); if (eargs is RenamedEventArgs) { audioClips.Remove(Path.GetFileNameWithoutExtension((eargs as RenamedEventArgs).OldName)); } CheckMusicList(); SeasonEnvironment.ClearCachedObjects(); } private static void UpdateFile(string fileName, string filePath) { if (Path.GetExtension(fileName).Equals(".json", StringComparison.OrdinalIgnoreCase)) { UpdateSettings(Path.GetFileNameWithoutExtension(fileName), filePath); } else { UpdateClip(Path.GetFileNameWithoutExtension(fileName), filePath); } } private static void UpdateClip(string clipName, string fileName) { bool flag = audioClips.Remove(clipName); if (TryGetAudioClip(fileName, out var audioClip)) { audioClips.Add(clipName, audioClip); Seasons.LogInfo("Custom music " + (flag ? "updated" : "added") + ": " + clipName); } } private static void UpdateSettings(string clipName, string fileName) { bool flag = clipSettings.Remove(clipName); if (TryGetMusicSettings(fileName, out var musicSettings)) { clipSettings.Add(clipName, musicSettings); Seasons.LogInfo("Custom music settings " + (flag ? "updated" : "added") + ": " + clipName); } } internal static bool TryGetAudioClip(string path, out AudioClip audioClip) { audioClip = null; string text = "file:///" + path.Replace("\\", "/"); UnityWebRequest audioClip2 = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)0); if (audioClip2 == null) { return false; } audioClip2.SendWebRequest(); while (!audioClip2.isDone) { } if (audioClip2.error != null) { Seasons.LogWarning("Failed to load audio from " + path + ": " + audioClip2.error); return false; } DownloadHandler downloadHandler = audioClip2.downloadHandler; DownloadHandler obj = ((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); audioClip = ((obj != null) ? ((DownloadHandlerAudioClip)obj).audioClip : null); if (Object.op_Implicit((Object)(object)audioClip)) { ((Object)audioClip).name = Path.GetFileNameWithoutExtension(path); return true; } return false; } internal static bool TryGetMusicSettings(string path, out MusicSettings musicSettings) { musicSettings = null; if (!File.Exists(path)) { return false; } try { musicSettings = JsonUtility.FromJson<MusicSettings>(File.ReadAllText(path)); } catch (Exception ex) { Seasons.LogWarning("Error reading file (" + path + ")! Error: " + ex.Message); return false; } return true; } } internal class CustomPrefabs { [HarmonyPatch(typeof(ZNetView), "Awake")] public static class ZNetView_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ZSyncTransform), "Awake")] public static class ZSyncTransform_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ZSyncTransform), "OnEnable")] public static class ZSyncTransform_OnEnable_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ItemDrop), "Awake")] public static class ItemDrop_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ItemDrop), "Start")] public static class ItemDrop_Start_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } private const string c_rootObjectName = "_shudnalRoot"; private const string c_rootPrefabsName = "Prefabs"; private static GameObject rootObject; private static GameObject rootPrefabs; public static bool prefabInit; private static void InitRootObject() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if ((Object)(object)rootObject == (Object)null) { rootObject = (GameObject)(((object)GameObject.Find("_shudnalRoot")) ?? ((object)new GameObject("_shudnalRoot"))); } Object.DontDestroyOnLoad((Object)(object)rootObject); if ((Object)(object)rootPrefabs == (Object)null) { Transform obj = rootObject.transform.Find("Prefabs"); rootPrefabs = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)rootPrefabs == (Object)null) { rootPrefabs = new GameObject("Prefabs"); rootPrefabs.transform.SetParent(rootObject.transform, false); rootPrefabs.SetActive(false); } } } internal static GameObject InitPrefabClone(GameObject prefabToClone, string prefabName) { InitRootObject(); prefabInit = true; GameObject val = Object.Instantiate<GameObject>(prefabToClone, rootPrefabs.transform, false); prefabInit = false; ((Object)val).name = prefabName; return val; } } internal class CustomTextures { public const string texturesSubdirectory = "Custom textures"; public const string defaultsSubdirectory = "Defaults"; public const string versionFileName = "version"; public static readonly Dictionary<string, Dictionary<Seasons.Season, Dictionary<int, Texture2D>>> textures = new Dictionary<string, Dictionary<Seasons.Season, Dictionary<int, Texture2D>>>(); public static Dictionary<string, Tuple<Seasons.Season, int>> seasonVariantsFileNames; public static void SetupConfigWatcher() { string filter = "*.png"; FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(GetSubdirectory(), filter); fileSystemWatcher.Changed += UpdateTexturesOnChange; fileSystemWatcher.Created += UpdateTexturesOnChange; fileSystemWatcher.Renamed += UpdateTexturesOnChange; fileSystemWatcher.Deleted += UpdateTexturesOnChange; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; UpdateTexturesOnChange(); } public static void UpdateTexturesOnChange(object sender = null, FileSystemEventArgs eargs = null) { UpdateTextures(); PrefabVariantController.MaterialVariants.UpdateSeasonalMaterials(); PrefabVariantController.UpdatePrefabColors(); ClutterVariantController.Instance?.UpdateColors(); } public static void UpdateTextures() { foreach (KeyValuePair<string, Dictionary<Seasons.Season, Dictionary<int, Texture2D>>> texture in textures) { foreach (KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> item in texture.Value) { foreach (KeyValuePair<int, Texture2D> item2 in item.Value) { Object.Destroy((Object)(object)item2.Value); } } } textures.Clear(); if (Seasons.customTextures.Value) { LoadCustomTextures(GetDefaultsSubdirectory()); LoadCustomTextures(GetSubdirectory()); if (textures.Count > 0) { Seasons.LogInfo($"Loaded {textures.Count} custom textures."); } } } public static bool HaveCustomTexture(string textureName, Seasons.Season season, int variant, TextureProperties properties, out Texture2D texture) { texture = null; if (textureName == null) { return false; } Dictionary<Seasons.Season, Dictionary<int, Texture2D>> value; Dictionary<int, Texture2D> value2; bool flag = textures.TryGetValue(textureName, out value) && value.TryGetValue(season, out value2) && value2.TryGetValue(variant, out texture) && (Object)(object)texture != (Object)null; if (flag && ((Texture)texture).isReadable) { Color32[] pixels = texture.GetPixels32(); if (pixels.Length != properties.width * properties.height) { properties.width = ((Texture)texture).width; properties.height = ((Texture)texture).height; properties.mipmapCount = Math.Min(Mathf.FloorToInt(Mathf.Log((float)Math.Min(properties.width, properties.height), 2f)), properties.mipmapCount); } Object.Destroy((Object)(object)texture); texture = properties.CreateTexture(); texture.SetPixels32(pixels); texture.Apply(true, true); textures[textureName][season][variant] = texture; } return flag; } public static void LoadCustomTextures(string path) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown if (!Directory.Exists(path)) { return; } DirectoryInfo[] directories = new DirectoryInfo(path).GetDirectories(); foreach (DirectoryInfo directoryInfo in directories) { if (directoryInfo.Name == "version" || directoryInfo.Name == "Defaults") { continue; } string name = directoryInfo.Name; textures.Remove(name); FileInfo[] files = directoryInfo.GetFiles(); foreach (FileInfo fileInfo in files) { if (!TryGetSeasonVariant(fileInfo.Name, out var season, out var variant)) { continue; } Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(fileInfo.FullName))) { Object.Destroy((Object)(object)val); continue; } ((Object)val).name = name; if (!textures.ContainsKey(name)) { textures.Add(name, new Dictionary<Seasons.Season, Dictionary<int, Texture2D>>()); } if (!textures[name].ContainsKey(season)) { textures[name].Add(season, new Dictionary<int, Texture2D>()); } textures[name][season][variant] = val; } } } public static void SaveDefaults() { string text = GetDefaultsSubdirectory(); if (Directory.Exists(text)) { string text2 = Directory.GetFiles(text, "version").FirstOrDefault(); if (text2 != null && File.ReadAllText(text2) == "1.7.9") { return; } Directory.Delete(text, recursive: true); } Directory.CreateDirectory(text); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string separator = ".Textures."; foreach (string item in from str in executingAssembly.GetManifestResourceNames() where str.IndexOf(separator) != -1 select str) { string text3 = item.Substring(item.IndexOf(separator) + separator.Length); int num = text3.IndexOf('.'); if (num != -1) { string path = text3.Substring(0, num); string text4 = text3.Substring(num + 1); if (TryGetSeasonVariant(text4, out var _, out var _)) { Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(item); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); File.WriteAllBytes(Path.Combine(Directory.CreateDirectory(Path.Combine(text, path)).FullName, text4), array); } } } File.WriteAllText(Path.Combine(text, "version"), "1.7.9"); } public static string GetSubdirectory() { string text = Path.Combine(Seasons.configDirectory, "Custom textures"); Directory.CreateDirectory(text); return text; } public static string GetDefaultsSubdirectory() { return Path.Combine(GetSubdirectory(), "Defaults"); } public static bool TryGetSeasonVariant(string filename, out Seasons.Season season, out int variant) { if (seasonVariantsFileNames == null) { seasonVariantsFileNames = new Dictionary<string, Tuple<Seasons.Season, int>>(); foreach (Seasons.Season value in Enum.GetValues(typeof(Seasons.Season))) { for (int i = 0; i < 4; i++) { seasonVariantsFileNames[CachedData.SeasonFileName(value, i)] = Tuple.Create(value, i); } } } season = Seasons.Season.Spring; variant = 0; if (!seasonVariantsFileNames.ContainsKey(filename)) { return false; } season = seasonVariantsFileNames[filename].Item1; variant = seasonVariantsFileNames[filename].Item2; return true; } } internal static class CustomSyncedValuesSynchronizer { private sealed class QueuedAssignment { public object Target; public IEnumerator Coroutine; } [CompilerGenerated] private sealed class <AssignAfterServerUpdate>d__8<T> : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomSyncedValue<T> syncedValue; public Func<T> function; public bool assignIfChanged; private T <value>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AssignAfterServerUpdate>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <value>5__1 = default(T); <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = waitForServerUpdate; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = waitForTextureCaching; <>1__state = 2; return true; case 2: <>1__state = -1; <value>5__1 = function(); if (assignIfChanged && syncedValue.Value.Equals(<value>5__1)) { return false; } syncedValue.AssignLocalValue(<value>5__1); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <AssignAfterServerUpdate>d__9<T> : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomSyncedValue<T> syncedValue; public T value; public bool assignIfChanged; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AssignAfterServerUpdate>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = waitForServerUpdate; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = waitForTextureCaching; <>1__state = 2; return true; case 2: <>1__state = -1; if (assignIfChanged && syncedValue.Value.Equals(value)) { return false; } syncedValue.AssignLocalValue(value); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <CoroutineCoordinator>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private QueuedAssignment <item>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CoroutineCoordinator>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <item>5__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; <item>5__1 = null; break; } if (coroutines.Count > 0) { <item>5__1 = coroutines.Dequeue(); <>2__current = ((MonoBehaviour)Seasons.instance).StartCoroutine(<item>5__1.Coroutine); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Queue<QueuedAssignment> coroutines = new Queue<QueuedAssignment>(); private static readonly WaitWhile waitForServerUpdate = new WaitWhile((Func<bool>)(() => ConfigSync.ProcessingServerUpdate)); private static readonly WaitWhile waitForTextureCaching = new WaitWhile((Func<bool>)(() => TextureCachingController.InProcess)); public static void AssignValueSafe<T>(this CustomSyncedValue<T> syncedValue, T value) { AddToQueue(syncedValue, AssignAfterServerUpdate(syncedValue, value, assignIfChanged: false)); } public static void AssignValueSafe<T>(this CustomSyncedValue<T> syncedValue, Func<T> function) { AddToQueue(syncedValue, AssignAfterServerUpdate(syncedValue, function, assignIfChanged: false)); } public static void AssignValueIfChanged<T>(this CustomSyncedValue<T> syncedValue, T value) { AddToQueue(syncedValue, AssignAfterServerUpdate(syncedValue, value, assignIfChanged: true)); } public static void AssignValueIfChanged<T>(this CustomSyncedValue<T> syncedValue, Func<T> function) { AddToQueue(syncedValue, AssignAfterServerUpdate(syncedValue, function, assignIfChanged: true)); } [IteratorStateMachine(typeof(<AssignAfterServerUpdate>d__8<>))] private static IEnumerator AssignAfterServerUpdate<T>(CustomSyncedValue<T> syncedValue, Func<T> function, bool assignIfChanged) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AssignAfterServerUpdate>d__8<T>(0) { syncedValue = syncedValue, function = function, assignIfChanged = assignIfChanged }; } [IteratorStateMachine(typeof(<AssignAfterServerUpdate>d__9<>))] private static IEnumerator AssignAfterServerUpdate<T>(CustomSyncedValue<T> syncedValue, T value, bool assignIfChanged) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AssignAfterServerUpdate>d__9<T>(0) { syncedValue = syncedValue, value = value, assignIfChanged = assignIfChanged }; } private static void AddToQueue<T>(CustomSyncedValue<T> syncedValue, IEnumerator coroutine) { QueuedAssignment queuedAssignment = null; int count = coroutines.Count; for (int i = 0; i < count; i++) { QueuedAssignment queuedAssignment2 = coroutines.Dequeue(); if (queuedAssignment2.Target == Seasons.currentSeasonDay) { queuedAssignment = queuedAssignment2; } else if (queuedAssignment2.Target != syncedValue) { coroutines.Enqueue(queuedAssignment2); } } coroutines.Enqueue(new QueuedAssignment { Target = syncedValue, Coroutine = coroutine }); if (queuedAssignment != null && queuedAssignment.Target != syncedValue) { coroutines.Enqueue(queuedAssignment); } if (coroutines.Count == 1) { ((MonoBehaviour)Seasons.instance).StartCoroutine(CoroutineCoordinator()); } } [IteratorStateMachine(typeof(<CoroutineCoordinator>d__11))] private static IEnumerator CoroutineCoordinator() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CoroutineCoordinator>d__11(0); } } public class IceFloeClimb : MonoBehaviour, Hoverable, Interactable { public float m_useDistance = 3f; public float m_radius = 4f; public void Start() { ZNetView component = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_body != (Object)null) { float @float = component.GetZDO().GetFloat(SeasonsVars.s_iceFloeMass, 0f); if (@float != 0f) { component.m_body.mass = @float; } } } public bool Interact(Humanoid character, bool hold, bool alt) { //IL_0028: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (hold) { return false; } if (!InUseDistance(character)) { return false; } ((Component)character).transform.position = Vector3.Lerp(((Component)character).transform.position, ((Component)this).transform.position, 0.35f) + Vector3.up; Physics.SyncTransforms(); return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { if (!InUseDistance((Humanoid)(object)Player.m_localPlayer)) { return ""; } return "[<color=yellow><b>$KEY_Use</b></color>] $seasons_ice_floe_climb".Localize(); } public string GetHoverName() { return ""; } public bool InUseDistance(Humanoid human) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (((Component)this).transform.position.y - ((Component)human).transform.position.y < 0.5f) { return false; } Vector3 val = ((Component)human).transform.position - ((Component)this).transform.position; val.y = 0f; float num = Mathf.Max(0.0001f, ((Component)this).transform.lossyScale.x); float num2 = Mathf.Max(0.0001f, ((Component)this).transform.lossyScale.z); float num3 = Mathf.Sqrt(val.x * val.x / (num * num) + val.z * val.z / (num2 * num2)); return m_radius < num3 && num3 < m_radius + m_useDistance; } } public class MinimapVariantController : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass16_0 { public int num; public MinimapVariantController <>4__this; public float num2; public Thread internalThread; internal void <GenerateWinterWorldMap>b__1() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < <>4__this.m_minimap.m_textureSize; i++) { for (int j = 0; j < <>4__this.m_minimap.m_textureSize; j++) { float num = (float)(j - this.num) * <>4__this.m_minimap.m_pixelSize + this.num2; float num2 = (float)(i - this.num) * <>4__this.m_minimap.m_pixelSize + this.num2; Biome biome = WorldGenerator.instance.GetBiome(num, num2, 0.02f, false); <>4__this.m_mapWinterTexture[i * <>4__this.m_minimap.m_textureSize + j] = Color32.op_Implicit(GetWinterPixelColor(biome)); <>4__this.m_mapTexture[i * <>4__this.m_minimap.m_textureSize + j] = Color32.op_Implicit(Minimap.instance.GetPixelColor(biome)); } } } internal bool <GenerateWinterWorldMap>b__2() { return internalThread.IsAlive; } } [CompilerGenerated] private sealed class <GenerateWinterWorldMap>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public MinimapVariantController <>4__this; private <>c__DisplayClass16_0 <>8__1; private Stopwatch <stopwatch>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GenerateWinterWorldMap>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <stopwatch>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass16_0(); <>8__1.<>4__this = <>4__this; <>8__1.num = <>4__this.m_minimap.m_textureSize / 2; <>8__1.num2 = <>4__this.m_minimap.m_pixelSize / 2f; <>4__this.m_mapWinterTexture = (Color32[])(object)new Color32[<>4__this.m_minimap.m_textureSize * <>4__this.m_minimap.m_textureSize]; <>4__this.m_mapTexture = (Color32[])(object)new Color32[<>4__this.m_minimap.m_textureSize * <>4__this.m_minimap.m_textureSize]; <>2__current = (object)new WaitUntil((Func<bool>)(() => WorldGenerator.instance != null)); <>1__state = 1; return true; case 1: <>1__state = -1; <stopwatch>5__2 = Stopwatch.StartNew(); <>8__1.internalThread = new Thread((ThreadStart)delegate { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < <>8__1.<>4__this.m_minimap.m_textureSize; i++) { for (int j = 0; j < <>8__1.<>4__this.m_minimap.m_textureSize; j++) { float num = (float)(j - <>8__1.num) * <>8__1.<>4__this.m_minimap.m_pixelSize + <>8__1.num2; float num2 = (float)(i - <>8__1.num) * <>8__1.<>4__this.m_minimap.m_pixelSize + <>8__1.num2; Biome biome = WorldGenerator.instance.GetBiome(num, num2, 0.02f, false); <>8__1.<>4__this.m_mapWinterTexture[i * <>8__1.<>4__this.m_minimap.m_textureSize + j] = Color32.op_Implicit(GetWinterPixelColor(biome)); <>8__1.<>4__this.m_mapTexture[i * <>8__1.<>4__this.m_minimap.m_textureSize + j] = Color32.op_Implicit(Minimap.instance.GetPixelColor(biome)); } } }); <>8__1.internalThread.Start(); <>2__current = (object)new WaitWhile((Func<bool>)(() => <>8__1.internalThread.IsAlive)); <>1__state = 2; return true; case 2: <>1__state = -1; <>4__this.m_initialized = true; Seasons.LogInfo($"Minimap variant controller initialized in {<stopwatch>5__2.Elapsed.TotalSeconds,-4:F2} seconds"); <>4__this.UpdateColors(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Minimap m_minimap; private static MinimapVariantController m_instance; private bool m_initialized = false; private Color32[] m_mapTexture; private Color32[] m_mapWinterTexture; private Texture2D m_forestTex; private bool m_isWinter = false; public static MinimapVariantController instance => m_instance; private void Awake() { m_instance = this; m_minimap = Minimap.instance; } private void Start() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown Texture texture = m_minimap.m_mapLargeShader.GetTexture("_ForestTex"); m_forestTex = new Texture2D(texture.width, texture.height, texture.graphicsFormat, (TextureCreationFlags)0); Graphics.CopyTexture(texture, (Texture)(object)m_forestTex); ((MonoBehaviour)this).StartCoroutine(GenerateWinterWorldMap()); } private void OnDestroy() { RevertTextures(); m_instance = null; } public void RevertTextures() { if (m_initia