Please disclose if any significant portion of your mod was created 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 ObeliskValheimOptimizer v0.1.2
Obelisk.ValheimOptimizer.dll
Decompiled 6 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Obelisk.ValheimOptimizer")] [assembly: AssemblyDescription("Lightweight Valheim performance fixes with SkyAlpha caching and optional weather controls")] [assembly: AssemblyCompany("Obelisk")] [assembly: AssemblyProduct("Obelisk.ValheimOptimizer")] [assembly: AssemblyFileVersion("0.1.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.1.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Obelisk.ValheimOptimizer { [HarmonyPatch(typeof(LightFlicker), "ApplySettings")] internal static class PersistentLightFlickerPatch { private static void Postfix(LightFlicker __instance, Light ___m_light, float ___m_baseIntensity, Vector3 ___m_basePosition) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (OptimizerPlugin.DisablePersistentLightFlicker.Value && !(__instance.m_ttl > 0f) && !Settings.ReduceFlashingLights) { if ((Object)(object)___m_light != (Object)null) { ___m_light.intensity = ___m_baseIntensity; } ((Component)__instance).transform.localPosition = ___m_basePosition; LightFlicker.Instances.Remove((IMonoUpdater)(object)__instance); } } } [HarmonyPatch(typeof(LightLod), "OnEnable")] internal static class LightLodDistancePatch { private static void Prefix(LightLod __instance) { if (OptimizerPlugin.LightDistance.Value > 0f) { __instance.m_lightDistance = Math.Min(__instance.m_lightDistance, OptimizerPlugin.LightDistance.Value); } if (OptimizerPlugin.ShadowDistance.Value > 0f) { __instance.m_shadowDistance = Math.Min(__instance.m_shadowDistance, OptimizerPlugin.ShadowDistance.Value); } } } [HarmonyPatch(typeof(GraphicsSettingsManager), "ApplyLightLod")] internal static class LightLimitPatch { private static void Postfix() { LightLod.m_lightLimit = ClampVanillaLimit(LightLod.m_lightLimit, OptimizerPlugin.PointLightLimit.Value); LightLod.m_shadowLimit = ClampVanillaLimit(LightLod.m_shadowLimit, OptimizerPlugin.PointLightShadowLimit.Value); } private static int ClampVanillaLimit(int vanilla, int configured) { if (configured < 0) { return vanilla; } if (vanilla >= 0) { return Math.Min(vanilla, configured); } return configured; } } [HarmonyPatch(typeof(SmokeSpawner), "Awake")] internal static class SmokeSpawnerPatch { private static void Prefix(SmokeSpawner __instance) { float value = OptimizerPlugin.MinimumSmokeInterval.Value; if (value > 0f && __instance.m_interval < value) { __instance.m_interval = value; } } } [HarmonyPatch(typeof(Smoke), "Awake")] internal static class SmokeLifetimePatch { private static void Prefix(Smoke __instance) { float value = OptimizerPlugin.MaximumSmokeLifetime.Value; if (value > 0f && __instance.m_ttl > value) { __instance.m_ttl = value; } float value2 = OptimizerPlugin.MaximumSmokeFadeTime.Value; if (value2 > 0f && __instance.m_fadetime > value2) { __instance.m_fadetime = value2; } } } [HarmonyPatch(typeof(ItemDrop), "AutoStackItems")] internal static class GroundLootAutoStackPatch { private static readonly Collider[] NearbyItems = (Collider[])(object)new Collider[256]; private static readonly FieldRef<ItemDrop, bool> HaveAutoStacked = AccessTools.FieldRefAccess<ItemDrop, bool>("m_haveAutoStacked"); private static readonly FieldRef<ItemDrop, ZNetView> NetworkView = AccessTools.FieldRefAccess<ItemDrop, ZNetView>("m_nview"); private static readonly MethodInfo SaveMethod = AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null) ?? throw new MissingMethodException(typeof(ItemDrop).FullName, "Save"); private static readonly int ItemMask = LayerMask.GetMask(new string[1] { "item" }); private static bool Prefix(ItemDrop __instance) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!OptimizerPlugin.OptimizeGroundLootAutoStack.Value) { return true; } ItemData itemData = __instance.m_itemData; ref bool reference = ref HaveAutoStacked.Invoke(__instance); if ((itemData.m_shared.m_maxStackSize <= 1 || itemData.m_stack >= itemData.m_shared.m_maxStackSize) | reference) { return false; } reference = true; bool flag = false; int num = Physics.OverlapSphereNonAlloc(((Component)__instance).transform.position, 4f, NearbyItems, ItemMask); try { for (int i = 0; i < num; i++) { Collider val = NearbyItems[i]; Rigidbody val2 = (((Object)(object)val != (Object)null) ? val.attachedRigidbody : null); ItemDrop val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<ItemDrop>() : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)__instance) { continue; } ZNetView val4 = NetworkView.Invoke(val3); ItemData itemData2 = val3.m_itemData; if (itemData2.m_shared.m_autoStack && !((Object)(object)val4 == (Object)null) && val4.IsValid() && val4.IsOwner() && !(itemData2.m_shared.m_name != itemData.m_shared.m_name) && itemData2.m_quality == itemData.m_quality) { int num2 = itemData.m_shared.m_maxStackSize - itemData.m_stack; if (num2 == 0) { break; } if (itemData2.m_stack <= num2) { itemData.m_stack += itemData2.m_stack; val4.Destroy(); flag = true; } } } } finally { Array.Clear(NearbyItems, 0, num); } if (flag) { SaveMethod.Invoke(__instance, null); } return false; } } [BepInPlugin("obelisk.valheimoptimizer", "Obelisk Valheim Optimizer", "0.1.2")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public sealed class OptimizerPlugin : BaseUnityPlugin { public const string PluginGuid = "obelisk.valheimoptimizer"; public const string PluginName = "Obelisk Valheim Optimizer"; public const string PluginVersion = "0.1.2"; internal static ConfigEntry<bool> DisablePersistentLightFlicker; internal static ConfigEntry<float> LightDistance; internal static ConfigEntry<float> ShadowDistance; internal static ConfigEntry<int> PointLightLimit; internal static ConfigEntry<int> PointLightShadowLimit; internal static ConfigEntry<float> MinimumSmokeInterval; internal static ConfigEntry<float> MaximumSmokeLifetime; internal static ConfigEntry<float> MaximumSmokeFadeTime; internal static ConfigEntry<bool> OptimizeFireParticles; internal static ConfigEntry<float> FireParticleEmissionMultiplier; internal static ConfigEntry<int> FireParticleLimit; internal static ConfigEntry<bool> CleanupOrphanedParticleEffects; internal static ConfigEntry<bool> OptimizeGroundLootAutoStack; internal static ConfigEntry<bool> EnableSkyAlphaOptimizer; internal static ConfigEntry<bool> DisableRainWear; internal static ConfigEntry<bool> DisablePieceRoofWetChecks; internal static ManualLogSource Log; private Harmony _harmony; internal static bool IsGraphicalClient => string.Equals(Paths.ProcessName, "valheim", StringComparison.OrdinalIgnoreCase); private void Awake() { //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; DisablePersistentLightFlicker = ((BaseUnityPlugin)this).Config.Bind<bool>("Light", "DisablePersistentFlicker", true, "Stops per-frame flicker and transform motion on persistent lights. TTL-driven lights are never disabled."); LightDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Light", "MaximumLightDistance", 32f, "Maximum LightLod distance. Lower vanilla values are preserved."); ShadowDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Light", "MaximumShadowDistance", 16f, "Maximum LightLod shadow distance. Lower vanilla values are preserved."); PointLightLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Light", "MaximumPointLights", 32, "Client-side cap applied after the vanilla graphics preset. Set to -1 to keep vanilla."); PointLightShadowLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Light", "MaximumShadowedPointLights", 2, "Client-side cap applied after the vanilla graphics preset. Set to -1 to keep vanilla."); MinimumSmokeInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Smoke", "MinimumSpawnInterval", 0.75f, "Minimum interval between visual smoke balls. Ventilation/blockage checks are not bypassed."); MaximumSmokeLifetime = ((BaseUnityPlugin)this).Config.Bind<float>("Smoke", "MaximumLifetime", 8f, "Maximum active lifetime of a visual smoke Rigidbody."); MaximumSmokeFadeTime = ((BaseUnityPlugin)this).Config.Bind<float>("Smoke", "MaximumFadeTime", 2.5f, "Maximum fade time after a visual smoke Rigidbody expires."); OptimizeFireParticles = ((BaseUnityPlugin)this).Config.Bind<bool>("Particles", "OptimizeFireParticles", true, "Pauses off-screen looping fireplace particles and applies conservative emission limits."); FireParticleEmissionMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Particles", "FireEmissionMultiplier", 0.75f, "Multiplier for looping particle emission owned by fireplaces."); FireParticleLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Particles", "FireMaxParticlesPerSystem", 256, "Maximum particles in each looping particle system owned by a fireplace."); CleanupOrphanedParticleEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Particles", "CleanupOrphanedEffects", true, "Destroys local, non-looping EffectList results that have no vanilla lifetime owner."); OptimizeGroundLootAutoStack = ((BaseUnityPlugin)this).Config.Bind<bool>("Loot", "AllocationFreeAutoStack", true, "Uses a fixed non-allocating physics buffer for vanilla owner-only ground-item auto stacking."); EnableSkyAlphaOptimizer = ((BaseUnityPlugin)this).Config.Bind<bool>("Rendering", "EnableSkyAlphaOptimizer", true, "Caches the 100 m SkyAlpha mask until the player moves 10 m or relevant world geometry changes. No per-frame tracking is added."); DisableRainWear = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "DisableRainWear", false, "Disables rain-only structure wear. Requires a world restart and the same value on every potential multiplayer ZDO owner."); DisablePieceRoofWetChecks = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "DisableRoofWetChecks", false, "Skips normal rain roof casts and piece wet VFX while preserving Ashlands roof checks and underwater wetness. Requires a world restart."); EnableSkyAlphaOptimizer.SettingChanged += OnSkyAlphaSettingChanged; _harmony = new Harmony("obelisk.valheimoptimizer"); _harmony.PatchAll(typeof(OptimizerPlugin).Assembly); if (DisableRainWear.Value || DisablePieceRoofWetChecks.Value) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Weather gameplay options are enabled. Use the same values on every client/server that can own piece ZDOs."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Obelisk Valheim Optimizer 0.1.2 loaded."); } private static void OnSkyAlphaSettingChanged(object sender, EventArgs args) { SkyAlphaOptimizerPatch.MarkDirty(); } private void OnDestroy() { if (EnableSkyAlphaOptimizer != null) { EnableSkyAlphaOptimizer.SettingChanged -= OnSkyAlphaSettingChanged; } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Fireplace), "Awake")] internal static class FireplaceParticlePatch { private static void Postfix(Fireplace __instance) { if (OptimizerPlugin.OptimizeFireParticles.Value) { HashSet<int> seenRoots = new HashSet<int>(); HashSet<int> seenSystems = new HashSet<int>(); OptimizeRoot(__instance.m_enabledObject, seenRoots, seenSystems); OptimizeRoot(__instance.m_enabledObjectLow, seenRoots, seenSystems); OptimizeRoot(__instance.m_enabledObjectHigh, seenRoots, seenSystems); OptimizeRoot(__instance.m_fullObject, seenRoots, seenSystems); OptimizeRoot(__instance.m_halfObject, seenRoots, seenSystems); } } private static void OptimizeRoot(GameObject root, HashSet<int> seenRoots, HashSet<int> seenSystems) { //IL_0043: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null || !seenRoots.Add(((Object)root).GetInstanceID())) { return; } ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { if ((Object)(object)val == (Object)null || !seenSystems.Add(((Object)val).GetInstanceID())) { continue; } MainModule main = val.main; if (((MainModule)(ref main)).loop) { ((MainModule)(ref main)).cullingMode = (ParticleSystemCullingMode)2; int value = OptimizerPlugin.FireParticleLimit.Value; if (value > 0 && ((MainModule)(ref main)).maxParticles > value) { ((MainModule)(ref main)).maxParticles = value; } float num = Mathf.Clamp01(OptimizerPlugin.FireParticleEmissionMultiplier.Value); if (num < 1f) { EmissionModule emission = val.emission; ((EmissionModule)(ref emission)).rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier * num; } } } } } [HarmonyPatch(typeof(EffectList), "Create", new Type[] { typeof(Vector3), typeof(Quaternion), typeof(Transform), typeof(float), typeof(int) })] internal static class OrphanedParticleCleanupPatch { private const float CleanupPadding = 3f; private const float MaximumCleanupDelay = 60f; private static readonly HashSet<string> AuditedOrphanNames = new HashSet<string>(StringComparer.Ordinal) { "fx_Fader_Ragdoll", "vfx_charredcross_spawner_destroyed", "vfx_ashland_ruin_wall_windows_broken_4x6_destruction", "fx_altar_charred_destruction", "fx_altar_crystal_destruction", "vfx_Ash_Arch2_Broken1_destroyed", "vfx_Ash_Arch2_Broken2_destroyed", "vfx_Ashpiece_roof_destroyed", "vfx_Ashruin_steepstair_destroyed", "vfx_Ashruin_wall3_destroyed", "vfx_Ashruin_wall4_destroyed", "vfx_Ashruin_wall5_destroyed", "vfx_Ashruin_window2_destroyed", "vfx_Ashruin_window3_destroyed", "vfx_Ashruin_window4_destroyed", "vfx_Ashruin_window5_destroyed", "vfx_Ashruin_window6_destroyed", "vfx_Destroyed_AshlandsShip", "vfx_Destroyed_Karve", "vfx_Destroyed_Raft", "vfx_Destroyed_VikingShip", "vfx_CharredBanner1_destroyed", "vfx_CharredBanner2_destroyed", "vfx_CharredBanner3_destroyed", "vfx_creep_hangingdetroyed", "vfx_crypt_skeleton_chest_destroyed" }; private static void Postfix(GameObject[] __result) { if (OptimizerPlugin.CleanupOrphanedParticleEffects.Value && __result != null) { for (int i = 0; i < __result.Length; i++) { ScheduleIfOrphaned(__result[i]); } } } private static void ScheduleIfOrphaned(GameObject effect) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)effect == (Object)null || !AuditedOrphanNames.Contains(StripCloneSuffix(((Object)effect).name)) || (Object)(object)effect.GetComponentInChildren<TimedDestruction>(true) != (Object)null || (Object)(object)effect.GetComponentInChildren<ZNetView>(true) != (Object)null) { return; } ParticleSystem[] componentsInChildren = effect.GetComponentsInChildren<ParticleSystem>(true); if (componentsInChildren.Length == 0) { return; } float num = 0f; ParticleSystem[] array = componentsInChildren; foreach (ParticleSystem val in array) { if (!((Object)(object)val == (Object)null)) { MainModule main = val.main; if (((MainModule)(ref main)).loop) { return; } float val2 = num; MinMaxCurve val3 = ((MainModule)(ref main)).startDelay; float num2 = ((MinMaxCurve)(ref val3)).constantMax + ((MainModule)(ref main)).duration; val3 = ((MainModule)(ref main)).startLifetime; num = Math.Max(val2, num2 + ((MinMaxCurve)(ref val3)).constantMax); } } LightFlicker[] componentsInChildren2 = effect.GetComponentsInChildren<LightFlicker>(true); foreach (LightFlicker val4 in componentsInChildren2) { if ((Object)(object)val4 != (Object)null && val4.m_ttl > 0f) { return; } } float num3 = Mathf.Clamp(num + 3f, 3f, 60f); Object.Destroy((Object)(object)effect, num3); } private static string StripCloneSuffix(string name) { if (!name.EndsWith("(Clone)", StringComparison.Ordinal)) { return name; } return name.Substring(0, name.Length - "(Clone)".Length); } } [HarmonyPatch(typeof(DepthCamera), "RenderDepth")] internal static class SkyAlphaOptimizerPatch { private sealed class CameraState { internal bool Initialized; internal Vector3 Anchor; internal int DirtyVersion; } private struct PendingRender { internal bool Commit; internal CameraState State; internal Vector3 Anchor; internal int DirtyVersion; } private const float RecenterDistance = 10f; private const float RecenterDistanceSquared = 100f; private const float VerticalRecenterDistance = 5f; private const float MaximumMaskLodBias = 2.5f; private static readonly ConditionalWeakTable<DepthCamera, CameraState> States = new ConditionalWeakTable<DepthCamera, CameraState>(); private static readonly MethodInfo GetMaskLodBiasMethod = AccessTools.Method(typeof(SkyAlphaOptimizerPatch), "GetMaskLodBias", (Type[])null, (Type[])null) ?? throw new MissingMethodException(typeof(SkyAlphaOptimizerPatch).FullName, "GetMaskLodBias"); private static int _dirtyVersion; [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } internal static void MarkDirty() { Interlocked.Increment(ref _dirtyVersion); } private static bool Prefix(DepthCamera __instance, ref PendingRender __state) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if (!OptimizerPlugin.EnableSkyAlphaOptimizer.Value) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } if ((Object)(object)Utils.GetMainCamera() == (Object)null) { return true; } CameraState value = States.GetValue(__instance, (DepthCamera _) => new CameraState()); if (((Character)localPlayer).IsTeleporting()) { MarkDirty(); if (value.Initialized) { return false; } } Vector3 position = ((Component)localPlayer).transform.position; int num = Volatile.Read(in _dirtyVersion); Vector3 val = position - value.Anchor; bool flag = val.x * val.x + val.z * val.z >= 100f || Mathf.Abs(val.y) >= 5f; if (value.Initialized && !flag && value.DirtyVersion == num) { return false; } __state = new PendingRender { Commit = true, State = value, Anchor = position, DirtyVersion = num }; return true; } private static void Postfix(PendingRender __state) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (__state.Commit) { __state.State.Anchor = __state.Anchor; __state.State.DirtyVersion = __state.DirtyVersion; __state.State.Initialized = true; } } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); List<int> list2 = new List<int>(); for (int i = 0; i < list.Count; i++) { CodeInstruction val = list[i]; if (val.opcode == OpCodes.Ldc_R4 && val.operand is float num && num.Equals(10f)) { list2.Add(i); } } if (list2.Count != 1) { ManualLogSource log = OptimizerPlugin.Log; if (log != null) { log.LogWarning((object)$"SkyAlpha lodBias patch disabled: expected one constant in DepthCamera.RenderDepth, found {list2.Count}."); } return list; } CodeInstruction obj = list[list2[0]]; obj.opcode = OpCodes.Call; obj.operand = GetMaskLodBiasMethod; return list; } private static float GetMaskLodBias() { if (!OptimizerPlugin.EnableSkyAlphaOptimizer.Value || !((Object)(object)Player.m_localPlayer != (Object)null)) { return 10f; } return Mathf.Min(QualitySettings.lodBias, 2.5f); } } [HarmonyPatch(typeof(Piece), "Awake")] internal static class SkyAlphaPieceCreatedPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } private static void Postfix(Piece __instance) { if (!ZNetView.m_forceDisableInit) { SkyAlphaOccluderLifecycle.MarkIfRelevant(((Object)(object)__instance != (Object)null) ? ((Component)__instance).gameObject : null); } } } [HarmonyPatch(typeof(Piece), "OnDestroy")] internal static class SkyAlphaPieceDestroyedPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } private static void Prefix(Piece __instance) { SkyAlphaOccluderLifecycle.MarkIfRelevant(((Object)(object)__instance != (Object)null) ? ((Component)__instance).gameObject : null); } } [HarmonyPatch(typeof(ZNetScene), "CreateObject")] internal static class SkyAlphaNetworkObjectCreatedPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } private static void Postfix(GameObject __result) { SkyAlphaOccluderLifecycle.MarkIfRelevant(__result); } } [HarmonyPatch(typeof(ZNetView), "OnDestroy")] internal static class SkyAlphaNetworkObjectDestroyedPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } private static void Prefix(ZNetView __instance) { SkyAlphaOccluderLifecycle.MarkIfRelevant(((Object)(object)__instance != (Object)null) ? ((Component)__instance).gameObject : null); } } [HarmonyPatch(typeof(Door), "SetState")] internal static class SkyAlphaDoorStatePatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } private static void Postfix(Door __instance) { SkyAlphaOccluderLifecycle.MarkIfRelevant(((Object)(object)__instance != (Object)null) ? ((Component)__instance).gameObject : null); } } [HarmonyPatch(typeof(MineRock5), "UpdateMesh")] internal static class SkyAlphaMineRockMeshPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.IsGraphicalClient; } private static void Postfix(MineRock5 __instance) { SkyAlphaOccluderLifecycle.MarkIfRelevant(((Object)(object)__instance != (Object)null) ? ((Component)__instance).gameObject : null); } } internal static class SkyAlphaOccluderLifecycle { private static readonly int PieceLayer = LayerMask.NameToLayer("piece"); private static readonly int StaticSolidLayer = LayerMask.NameToLayer("static_solid"); internal static void MarkIfRelevant(GameObject gameObject) { if (OptimizerPlugin.EnableSkyAlphaOptimizer.Value && !((Object)(object)gameObject == (Object)null) && ContainsRelevantLayer(gameObject.transform)) { SkyAlphaOptimizerPatch.MarkDirty(); } } private static bool ContainsRelevantLayer(Transform transform) { int layer = ((Component)transform).gameObject.layer; if (layer == PieceLayer || layer == StaticSolidLayer) { return true; } for (int i = 0; i < transform.childCount; i++) { if (ContainsRelevantLayer(transform.GetChild(i))) { return true; } } return false; } } [HarmonyPatch(typeof(WearNTear), "Awake")] internal static class PieceWeatherDefaultsPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.DisableRainWear.Value; } private static void Prefix(WearNTear __instance) { __instance.m_noRoofWear = false; } } [HarmonyPatch(typeof(WearNTear), "UpdateCover")] internal static class PieceCoverUpdatePatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.DisablePieceRoofWetChecks.Value; } private static bool Prefix(WearNTear __instance, bool ___m_inAshlands, ref bool ___m_haveRoof) { ___m_haveRoof = true; if ((Object)(object)__instance.m_wet != (Object)null && __instance.m_wet.activeSelf) { __instance.m_wet.SetActive(false); } return ___m_inAshlands; } } [HarmonyPatch(typeof(WearNTear), "HaveRoof")] internal static class PieceNormalRoofCheckPatch { [HarmonyPrepare] private static bool Prepare() { return OptimizerPlugin.DisablePieceRoofWetChecks.Value; } private static bool Prefix(ref bool __result) { __result = true; return false; } } }