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 TolerableFog v1.0.2
BepInEx/plugins/TolerableFog/bobabulkerENTERPRISE.TolerableFog.dll
Decompiled 9 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Extensions; using CSync.Lib; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using WeatherRegistry; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("bobabulkerENTERPRISE.TolerableFog")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyProduct("TolerableFog")] [assembly: AssemblyTitle("bobabulkerENTERPRISE.TolerableFog")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TolerableFog { [BepInPlugin("bobabulkerENTERPRISE.TolerableFog", "TolerableFog", "1.0.2")] [BepInDependency("com.sigurd.csync", "5.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static Plugin Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } internal static FogConfig Settings { get; private set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Settings = new FogConfig(((BaseUnityPlugin)this).Config); ModdedWeatherStrengths.Init(((BaseUnityPlugin)this).Config); Patch(); FixCameraResolutionsCompat.EnsurePatched("plugin startup"); RegisterLethalConfig(); foreach (SyncedEntry<float> allEntry in Settings.AllEntries) { allEntry.Changed += delegate { FogController.RefreshIfSettingsChanged(); }; } Settings.ModdedWeatherStrengths.Changed += delegate { FogController.RefreshIfSettingsChanged(); }; Logger.LogInfo((object)"bobabulkerENTERPRISE.TolerableFog v1.0.2 has loaded!"); } private void RegisterLethalConfig() { if (!LethalConfigCompat.IsLoaded) { return; } try { LethalConfigCompat.Register(((BaseUnityPlugin)this).Config); Logger.LogDebug((object)"Registered with LethalConfig."); } catch (Exception ex) { Logger.LogWarning((object)("LethalConfig integration failed, falling back to its auto-generated entries: " + ex.Message)); } } internal static void Patch() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("bobabulkerENTERPRISE.TolerableFog"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } internal static class FixCameraResolutionsCompat { private const string PatchesTypeName = "Rumi.FixCameraResolutions.Fogs.FCRHDRPPatches"; private static bool _patched; private static readonly string[] VolumetricsOffByDesign = new string[1] { "MapCamera" }; private const string StartupReason = "plugin startup"; private static bool IsOffByDesign(string cameraName) { return Array.IndexOf(VolumetricsOffByDesign, cameraName) >= 0; } internal static void EnsurePatched(string reason) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown if (_patched || Plugin.Harmony == null) { return; } Type type = AccessTools.TypeByName("Rumi.FixCameraResolutions.Fogs.FCRHDRPPatches"); if (type == null) { return; } _patched = true; try { MethodInfo methodInfo = AccessTools.Method(type, "UpdateVolume", new Type[1] { typeof(Volume) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "UpdateHDCameraData", new Type[1] { typeof(HDAdditionalCameraData) }, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Plugin.Logger.LogWarning((object)"Fix Camera Resolutions is installed but its fog methods were not found (different version?); its fog option may override TolerableFog."); return; } string text = AccessTools.Property(type, "fogMode")?.GetValue(null)?.ToString() ?? "unknown"; Plugin.Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(FixCameraResolutionsCompat), "SkipUpdateVolume", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(FixCameraResolutionsCompat), "RestoreVolumetrics", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); AccessTools.Method(type, "UpdateAllHDCameraData", (Type[])null, (Type[])null)?.Invoke(null, null); Plugin.Logger.LogInfo((object)("Fix Camera Resolutions detected (fog mode: " + text + "); patched during " + reason + ". TolerableFog's fog settings take precedence over its fog option.")); if (reason != "plugin startup" && (text == "Disable" || text == "ForceDisable")) { Plugin.Logger.LogWarning((object)("Patched after startup while Fix Camera Resolutions' fog mode is " + text + ": fog volumes that were enabled before this point may have been deactivated by it and stay off. This happens only if it loaded after TolerableFog.")); } } catch (Exception arg) { Plugin.Logger.LogWarning((object)$"Could not neutralise Fix Camera Resolutions' fog option: {arg}"); } } private static bool SkipUpdateVolume() { return false; } private static void RestoreVolumetrics(HDAdditionalCameraData cameraData) { bool flag = !IsOffByDesign(((Object)cameraData).name); ((BitArray128)(ref cameraData.renderingPathCustomFrameSettingsOverrideMask.mask))[28u] = !flag; ((FrameSettings)(ref cameraData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)28, flag); } internal static void VerifyVolumetrics() { try { Camera[] allCameras = Camera.allCameras; int num = 0; StringBuilder stringBuilder = new StringBuilder(); Camera[] array = allCameras; foreach (Camera val in array) { HDAdditionalCameraData component = ((Component)val).GetComponent<HDAdditionalCameraData>(); if (!((Object)(object)component == (Object)null) && !IsOffByDesign(((Object)val).name)) { bool flag = ((BitArray128)(ref component.renderingPathCustomFrameSettingsOverrideMask.mask))[28u]; bool flag2 = ((FrameSettings)(ref component.renderingPathCustomFrameSettings)).IsEnabled((FrameSettingsField)28); if (flag && !flag2) { num++; stringBuilder.Append(" '" + ((Object)val).name + "'"); } } } if (num == 0) { Plugin.Logger.LogDebug((object)$"Volumetric fog check: OK ({allCameras.Length} camera(s), none has volumetric fog switched off)."); } else { Plugin.Logger.LogWarning((object)($"Volumetric fog check: volumetric fog is switched OFF on {num} camera(s):{stringBuilder}. " + "Something other than TolerableFog is overriding it.")); } } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Volumetric fog check failed: " + ex.Message)); } } } public class FogConfig : SyncedConfig2<FogConfig> { internal const float StrengthMin = 0f; internal const float StrengthMax = 1f; internal const float MovingStrengthMin = 0f; internal const float MovingStrengthMax = 1f; internal const float ReflectionMin = 0f; internal const float ReflectionMax = 1f; internal const float SteamStrengthMin = 0f; internal const float SteamStrengthMax = 1f; internal const float SteamSizeMin = 0f; internal const float SteamSizeMax = 1f; internal static readonly ConfigDefinition MovingStrengthDefinition = new ConfigDefinition("MovingFog", "Strength"); internal static readonly ConfigDefinition ReflectionDefinition = new ConfigDefinition("Flashlight", "Reflection"); internal static readonly ConfigDefinition SteamStrengthDefinition = new ConfigDefinition("SteamLeak", "Strength"); internal static readonly ConfigDefinition SteamSizeDefinition = new ConfigDefinition("SteamLeak", "Size"); internal static readonly ConfigDefinition ModdedStrengthsDefinition = new ConfigDefinition("Internal", "ModdedWeatherStrengths"); internal static readonly ConfigDefinition NoneStrengthDefinition = new ConfigDefinition("Strength", "None"); internal static readonly ConfigDefinition RainyStrengthDefinition = new ConfigDefinition("Strength", "Rainy"); internal static readonly ConfigDefinition StormyStrengthDefinition = new ConfigDefinition("Strength", "Stormy"); internal static readonly ConfigDefinition FoggyStrengthDefinition = new ConfigDefinition("Strength", "Foggy"); internal static readonly ConfigDefinition FloodedStrengthDefinition = new ConfigDefinition("Strength", "Flooded"); internal static readonly ConfigDefinition EclipsedStrengthDefinition = new ConfigDefinition("Strength", "Eclipsed"); internal static readonly ConfigDefinition DustCloudsStrengthDefinition = new ConfigDefinition("Strength", "DustClouds"); internal static readonly ConfigDefinition[] WeatherStrengthDefinitions = (ConfigDefinition[])(object)new ConfigDefinition[7] { NoneStrengthDefinition, RainyStrengthDefinition, StormyStrengthDefinition, FoggyStrengthDefinition, FloodedStrengthDefinition, EclipsedStrengthDefinition, DustCloudsStrengthDefinition }; [field: SyncedEntryField] public SyncedEntry<float> NoneStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> RainyStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> StormyStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> FoggyStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> FloodedStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> EclipsedStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> DustCloudsStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> MovingFogStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> FlashlightReflection { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> SteamLeakStrength { get; private set; } [field: SyncedEntryField] public SyncedEntry<float> SteamLeakSize { get; private set; } [field: SyncedEntryField] public SyncedEntry<string> ModdedWeatherStrengths { get; private set; } internal IEnumerable<SyncedEntry<float>> AllEntries => new SyncedEntry<float>[11] { NoneStrength, RainyStrength, StormyStrength, FoggyStrength, FloodedStrength, EclipsedStrength, DustCloudsStrength, MovingFogStrength, FlashlightReflection, SteamLeakStrength, SteamLeakSize }; public FogConfig(ConfigFile cfg) : base("bobabulkerENTERPRISE.TolerableFog") { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown NoneStrength = Bind(cfg, NoneStrengthDefinition, 0.2f, "Fog density on clear days (weather None). 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); RainyStrength = Bind(cfg, RainyStrengthDefinition, 0.2f, "Fog density while it is Rainy. 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); StormyStrength = Bind(cfg, StormyStrengthDefinition, 0.2f, "Fog density while it is Stormy. 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); FoggyStrength = Bind(cfg, FoggyStrengthDefinition, 0.2f, "Fog density while it is Foggy. 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); FloodedStrength = Bind(cfg, FloodedStrengthDefinition, 0.2f, "Fog density while it is Flooded. 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); EclipsedStrength = Bind(cfg, EclipsedStrengthDefinition, 0.2f, "Fog density while it is Eclipsed. 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); DustCloudsStrength = Bind(cfg, DustCloudsStrengthDefinition, 0.2f, "Fog density while there are DustClouds. 1 = vanilla, 0 = no fog, above 1 = denser.", 0f, 1f); MovingFogStrength = Bind(cfg, MovingStrengthDefinition, 0.5f, "Strength of the drifting fog that moves around a moon (e.g. dust storms), in every weather. Independent of the weather strengths. 1 = vanilla, 0 = removed, above 1 = denser.", 0f, 1f); FlashlightReflection = Bind(cfg, ReflectionDefinition, 0.1f, "How strongly flashlight and helmet-light beams glow in fog. 1 = vanilla, 0 = invisible beams.", 0f, 1f); SteamLeakStrength = Bind(cfg, SteamStrengthDefinition, 0.4f, "How dense the fog from burst steam valves is. 1 = vanilla, 0 = no steam fog.", 0f, 1f); SteamLeakSize = Bind(cfg, SteamSizeDefinition, 0.6f, "How large burst steam fog can grow. 1 = vanilla (full size), 0 = it never grows.", 0f, 1f); ModdedWeatherStrengths = SyncedBindingExtensions.BindSyncedEntry<string>(CreateInMemoryConfig(), ModdedStrengthsDefinition, "", new ConfigDescription("Managed automatically from the [Strength (Modded)] settings.", (AcceptableValueBase)null, Array.Empty<object>())); ConfigManager.Register<FogConfig>((SyncedConfig2<FogConfig>)(object)this); } public SyncedEntry<float> StrengthFor(LevelWeatherType weather) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown return (SyncedEntry<float>)((int)weather switch { 1 => RainyStrength, 2 => StormyStrength, 3 => FoggyStrength, 4 => FloodedStrength, 5 => EclipsedStrength, 0 => DustCloudsStrength, _ => NoneStrength, }); } private static ConfigFile CreateInMemoryConfig() { //IL_0026: 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_0033: Expected O, but got Unknown string text = Path.Combine(Path.GetTempPath(), string.Format("{0}.{1:N}.cfg", "bobabulkerENTERPRISE.TolerableFog", Guid.NewGuid())); return new ConfigFile(text, false) { SaveOnConfigSet = false }; } private static SyncedEntry<float> Bind(ConfigFile cfg, ConfigDefinition definition, float defaultValue, string description, float min, float max) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown return SyncedBindingExtensions.BindSyncedEntry<float>(cfg, definition, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>())); } } internal static class FogController { private struct FogBaseline { public LocalVolumetricFog Fog; public float MeanFreePath; } private sealed class ManagedFogEntry { public LocalVolumetricFog Fog; public float BaseMeanFreePath; public bool IsMoving; } private sealed class GlobalFogEntry { public Fog Component; public float BaseMeanFreePath; } private sealed class FollowedFog { public LocalVolumetricFog Fog; public float Base; public float LastWritten; } private const float FogOffDistance = 1000000f; private static FollowedFog? _foggy; private static FogBaseline? _indoorFog; private static readonly List<ManagedFogEntry> ManagedFogs = new List<ManagedFogEntry>(); private static readonly List<GlobalFogEntry> GlobalFogs = new List<GlobalFogEntry>(); private static readonly HashSet<LocalVolumetricFog> SteamFogs = new HashSet<LocalVolumetricFog>(); private static readonly ConditionalWeakTable<HDAdditionalLightData, StrongBox<float>> LightBaselines = new ConditionalWeakTable<HDAdditionalLightData, StrongBox<float>>(); private static float _lastStrength = float.NaN; private static float _strengthCache; private static int _strengthFrame = -1; private static float _nextTick; private static float _lastMovingStrength = float.NaN; private static float _lastReflection = float.NaN; private static float _lastSteamStrength = float.NaN; private static float _lastSteamSize = float.NaN; internal static LevelWeatherType CurrentWeather { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) TimeOfDay instance = TimeOfDay.Instance; if (!((Object)(object)instance != (Object)null)) { return (LevelWeatherType)(-1); } return instance.currentLevelWeather; } } internal static float CurrentStrength { get { if (_strengthFrame != Time.frameCount) { _strengthCache = ComputeCurrentStrength(); _strengthFrame = Time.frameCount; } return _strengthCache; } } internal static float MovingStrength => Mathf.Clamp(Plugin.Settings.MovingFogStrength.Value, 0f, 1f); internal static float Reflection => Mathf.Clamp(Plugin.Settings.FlashlightReflection.Value, 0f, 1f); internal static float SteamStrength => Mathf.Clamp(Plugin.Settings.SteamLeakStrength.Value, 0f, 1f); internal static float SteamSize => Mathf.Clamp(Plugin.Settings.SteamLeakSize.Value, 0f, 1f); internal static float WeatherStrength(LevelWeatherType weather) { //IL_000a: 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_0017: Unknown result type (might be due to invalid IL or missing references) if (!Enum.IsDefined(typeof(LevelWeatherType), weather) && ModdedWeatherStrengths.TryGetStrength(weather, out var strength)) { return Mathf.Clamp(strength, 0f, 1f); } return Mathf.Clamp(Plugin.Settings.StrengthFor(weather).Value, 0f, 1f); } private static float ComputeCurrentStrength() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_002f: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) List<LevelWeatherType> list = WeatherRegistryCompat.ActiveEffects(); if (list != null && list.Count > 0) { float num = 1f; int num2 = 0; foreach (LevelWeatherType item in list) { if ((int)item != -1 || list.Count <= 1) { num *= WeatherStrength(item); num2++; } } if (num2 > 0) { return Mathf.Min(num, 1f); } } return WeatherStrength(CurrentWeather); } private unsafe static string WeatherLabel(LevelWeatherType type) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected I4, but got Unknown if (Enum.IsDefined(typeof(LevelWeatherType), type)) { return ((object)(*(LevelWeatherType*)(&type))/*cast due to .constrained prefix*/).ToString(); } return WeatherRegistryCompat.NameOf(type) ?? $"Modded({(int)type})"; } internal static string DescribeCurrentWeather() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //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_002a: Unknown result type (might be due to invalid IL or missing references) List<LevelWeatherType> list = WeatherRegistryCompat.ActiveEffects(); if (list != null && list.Count > 0) { List<string> list2 = new List<string>(); foreach (LevelWeatherType item in list) { list2.Add(WeatherLabel(item)); } return string.Join("+", list2); } return WeatherLabel(CurrentWeather); } internal static float ScaleByStrength(float vanilla, float strength) { if (Mathf.Approximately(strength, 1f)) { return vanilla; } float num = ((strength <= 0.0001f) ? 1000000f : (vanilla / strength)); return Mathf.Max(1f, num); } internal static float ScaleMeanFreePath(float vanilla) { return ScaleByStrength(vanilla, CurrentStrength); } private static float ScaleMovingMeanFreePath(float vanilla) { return ScaleByStrength(vanilla, MovingStrength); } private static float ScaleManaged(ManagedFogEntry entry) { if (!entry.IsMoving) { return ScaleMeanFreePath(entry.BaseMeanFreePath); } return ScaleMovingMeanFreePath(entry.BaseMeanFreePath); } private static void SetMeanFreePath(LocalVolumetricFog fog, float value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0020: Unknown result type (might be due to invalid IL or missing references) LocalVolumetricFogArtistParameters parameters = fog.parameters; if (!Mathf.Approximately(parameters.meanFreePath, value)) { parameters.meanFreePath = value; fog.parameters = parameters; } } private static void SetGlobalMeanFreePath(Fog fog, float value) { if (!Mathf.Approximately(((VolumeParameter<float>)(object)fog.meanFreePath).value, value)) { ((VolumeParameter<float>)(object)fog.meanFreePath).value = value; } } private static void Apply(in FogBaseline baseline) { SetMeanFreePath(baseline.Fog, ScaleMeanFreePath(baseline.MeanFreePath)); } private static string PathOf(Transform t) { string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } internal static void OnFoggyWeatherSet(TimeOfDay timeOfDay) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)timeOfDay.currentLevelWeather == 3 && !((Object)(object)timeOfDay.foggyWeather == (Object)null)) { LocalVolumetricFog foggyWeather = timeOfDay.foggyWeather; float meanFreePath = foggyWeather.parameters.meanFreePath; float num = ScaleMeanFreePath(meanFreePath); SetMeanFreePath(foggyWeather, num); _foggy = new FollowedFog { Fog = foggyWeather, Base = meanFreePath, LastWritten = num }; Plugin.Logger.LogDebug((object)$"Foggy weather (game set it): {meanFreePath} -> {foggyWeather.parameters.meanFreePath}"); } } internal static void OnPlayerEffectsSet(PlayerControllerB player) { PlayerControllerB spectatedPlayerScript = player.spectatedPlayerScript; AudioReverbTrigger val = (((Object)(object)spectatedPlayerScript != (Object)null) ? spectatedPlayerScript.currentAudioTrigger : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.localFog == (Object)null) && val.toggleLocalFog) { SetMeanFreePath(val.localFog, ScaleMeanFreePath(val.fogEnabledAmount)); } } internal static bool ApplyLight(Light? light) { if ((Object)(object)light == (Object)null) { return false; } HDAdditionalLightData component = ((Component)light).GetComponent<HDAdditionalLightData>(); if ((Object)(object)component == (Object)null || !component.affectsVolumetric) { return false; } StrongBox<float> value = LightBaselines.GetValue(component, (HDAdditionalLightData h) => new StrongBox<float>(h.volumetricDimmer)); component.volumetricDimmer = Mathf.Clamp(value.Value * Reflection, 0f, 16f); return true; } internal static void Refresh() { _strengthFrame = -1; float num = (_lastStrength = CurrentStrength); _lastMovingStrength = MovingStrength; _lastReflection = Reflection; _lastSteamStrength = SteamStrength; _lastSteamSize = SteamSize; bool flag = RefreshFoggyWeather(); bool flag2 = RefreshIndoorFog(); int num2 = RefreshManagedFogs(); int num3 = RefreshGlobalFogs(); int num4 = RefreshLights(); RefreshAreaFog(); int num5 = CountSteamValves(); RoundManager instance = RoundManager.Instance; bool flag3 = (Object)(object)instance != (Object)null && (Object)(object)instance.indoorFog != (Object)null && ((Component)instance.indoorFog).gameObject.activeSelf; string text = ""; if (flag && _foggy != null) { text = $" [attenuation {_foggy.Base} -> {_foggy.Fog.parameters.meanFreePath}]"; } Plugin.Logger.LogDebug((object)($"Refresh | weather={DescribeCurrentWeather()} strength={num} | movingFog={_lastMovingStrength}, " + $"reflection={_lastReflection}, steamStrength={_lastSteamStrength}, steamSize={_lastSteamSize} | " + string.Format("foggy weather fog={0}{1}, indoor fog applied={2} (active={3}), ", flag ? "found" : "missing", text, flag2, flag3) + $"scene fogs={num2}, global fog volumes={num3}, lights={num4}, steam valves={num5}")); } internal static void Tick() { if (!(Time.unscaledTime < _nextTick)) { _nextTick = Time.unscaledTime + 0.25f; ModdedWeatherStrengths.Poll(); RefreshIfSettingsChanged(); if (FoggyFogWasRewritten()) { RefreshFoggyWeather(); } } } internal static void RefreshIfSettingsChanged() { if (Plugin.Settings != null) { _strengthFrame = -1; if (CurrentStrength != _lastStrength || MovingStrength != _lastMovingStrength || Reflection != _lastReflection || SteamStrength != _lastSteamStrength || SteamSize != _lastSteamSize) { Refresh(); } } } private static bool RefreshFoggyWeather() { TimeOfDay instance = TimeOfDay.Instance; LocalVolumetricFog val = (((Object)(object)instance != (Object)null) ? instance.foggyWeather : null); if ((Object)(object)val == (Object)null) { _foggy = null; return false; } float meanFreePath = val.parameters.meanFreePath; if (_foggy == null || (Object)(object)_foggy.Fog != (Object)(object)val) { _foggy = new FollowedFog { Fog = val, Base = meanFreePath, LastWritten = meanFreePath }; Plugin.Logger.LogDebug((object)$"Foggy weather fog found (vanilla attenuation {meanFreePath})."); } else if (!Mathf.Approximately(meanFreePath, _foggy.LastWritten)) { _foggy.Base = meanFreePath; Plugin.Logger.LogDebug((object)$"Foggy weather fog was rewritten by the game (now {meanFreePath}); following it."); } float num = ScaleMeanFreePath(_foggy.Base); SetMeanFreePath(val, num); _foggy.LastWritten = num; return true; } private static bool FoggyFogWasRewritten() { if (_foggy != null && (Object)(object)_foggy.Fog != (Object)null) { return !Mathf.Approximately(_foggy.Fog.parameters.meanFreePath, _foggy.LastWritten); } return false; } private static bool RefreshIndoorFog() { RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.indoorFog == (Object)null) { return false; } LocalVolumetricFog indoorFog = instance.indoorFog; if (!_indoorFog.HasValue || (Object)(object)_indoorFog.Value.Fog != (Object)(object)indoorFog) { _indoorFog = new FogBaseline { Fog = indoorFog, MeanFreePath = indoorFog.parameters.meanFreePath }; } Apply(_indoorFog.Value); return true; } private static int RefreshManagedFogs() { ManagedFogs.RemoveAll((ManagedFogEntry e) => (Object)(object)e.Fog == (Object)null); HashSet<LocalVolumetricFog> hashSet = new HashSet<LocalVolumetricFog>(); TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.foggyWeather != (Object)null) { hashSet.Add(instance.foggyWeather); } RoundManager instance2 = RoundManager.Instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.indoorFog != (Object)null) { hashSet.Add(instance2.indoorFog); } AudioReverbTrigger[] array = Object.FindObjectsByType<AudioReverbTrigger>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (AudioReverbTrigger val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.localFog != (Object)null) { hashSet.Add(val.localFog); } } LocalVolumetricFog[] array2 = Object.FindObjectsByType<LocalVolumetricFog>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (LocalVolumetricFog fog in array2) { if (!((Object)(object)fog == (Object)null) && !hashSet.Contains(fog) && !IsExcludedByRole(fog) && !ManagedFogs.Exists((ManagedFogEntry e) => (Object)(object)e.Fog == (Object)(object)fog)) { float meanFreePath = fog.parameters.meanFreePath; bool flag = IsMovingFog(fog); ManagedFogs.Add(new ManagedFogEntry { Fog = fog, BaseMeanFreePath = meanFreePath, IsMoving = flag }); Plugin.Logger.LogDebug((object)string.Format("{0}: '{1}' (vanilla attenuation {2})", flag ? "Moving fog" : "Scene fog", PathOf(((Component)fog).transform), meanFreePath)); } } foreach (ManagedFogEntry managedFog in ManagedFogs) { SetMeanFreePath(managedFog.Fog, ScaleManaged(managedFog)); } return ManagedFogs.Count; } private static bool IsMovingFog(LocalVolumetricFog fog) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) LocalVolumetricFogArtistParameters parameters = fog.parameters; if ((Object)(object)parameters.volumeMask != (Object)null) { return ((Vector3)(ref parameters.textureScrollingSpeed)).sqrMagnitude > 0f; } return false; } private static bool IsExcludedByRole(LocalVolumetricFog fog) { if (SteamFogs.Contains(fog) || (Object)(object)((Component)fog).GetComponentInParent<SteamValveHazard>(true) != (Object)null) { return true; } return ((Object)fog).name.IndexOf("exclusion", StringComparison.OrdinalIgnoreCase) >= 0; } private static int RefreshGlobalFogs() { GlobalFogs.RemoveAll((GlobalFogEntry e) => (Object)(object)e.Component == (Object)null); Volume[] array = Object.FindObjectsByType<Volume>((FindObjectsInactive)1, (FindObjectsSortMode)0); Fog fog = default(Fog); foreach (Volume val in array) { VolumeProfile sharedProfile = val.sharedProfile; if (!((Object)(object)sharedProfile == (Object)null) && sharedProfile.TryGet<Fog>(ref fog) && ((VolumeComponent)fog).active && ((VolumeParameter)fog.meanFreePath).overrideState && !GlobalFogs.Exists((GlobalFogEntry e) => (Object)(object)e.Component == (Object)(object)fog)) { float value = ((VolumeParameter<float>)(object)fog.meanFreePath).value; GlobalFogs.Add(new GlobalFogEntry { Component = fog, BaseMeanFreePath = value }); Plugin.Logger.LogDebug((object)$"Global fog: volume '{((Object)val).name}' (vanilla attenuation {value})"); } } foreach (GlobalFogEntry globalFog in GlobalFogs) { SetGlobalMeanFreePath(globalFog.Component, ScaleMeanFreePath(globalFog.BaseMeanFreePath)); } return GlobalFogs.Count; } private static void RefreshAreaFog() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.localPlayerController != (Object)null) { OnPlayerEffectsSet(instance.localPlayerController); } } private static int RefreshLights() { int num = 0; StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.allPlayerScripts != null) { PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if ((Object)(object)val == (Object)null || val.allHelmetLights == null) { continue; } Light[] allHelmetLights = val.allHelmetLights; foreach (Light light in allHelmetLights) { if (ApplyLight(light)) { num++; } } } } FlashlightItem[] array = Object.FindObjectsByType<FlashlightItem>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (FlashlightItem val2 in array) { if (ApplyLight(val2.flashlightBulb)) { num++; } } return num; } internal static void OnSteamValveUpdated(SteamValveHazard valve) { float steamSize = SteamSize; if (!(steamSize >= 1f) && !((Object)(object)valve.fogAnimator == (Object)null) && !(valve.currentFogSize <= 0f)) { valve.fogAnimator.SetFloat("time", valve.currentFogSize * steamSize); } } private static void AddFogs(List<LocalVolumetricFog> into, LocalVolumetricFog[] found) { foreach (LocalVolumetricFog val in found) { if ((Object)(object)val != (Object)null && !into.Contains(val)) { into.Add(val); } } } internal static void OnSteamValveStart(SteamValveHazard valve) { List<LocalVolumetricFog> list = new List<LocalVolumetricFog>(); AddFogs(list, ((Component)valve).GetComponentsInChildren<LocalVolumetricFog>(true)); if ((Object)(object)valve.fogAnimator != (Object)null) { AddFogs(list, ((Component)valve.fogAnimator).GetComponentsInChildren<LocalVolumetricFog>(true)); } if (list.Count == 0) { Plugin.Logger.LogWarning((object)("Steam valve '" + ((Object)valve).name + "': no LocalVolumetricFog found under the valve or its fog animator, so SteamLeak/Strength can't affect it (SteamLeak/Size still works).")); return; } foreach (LocalVolumetricFog fog in list) { SteamFogs.Add(fog); ManagedFogEntry managedFogEntry = ManagedFogs.Find((ManagedFogEntry e) => (Object)(object)e.Fog == (Object)(object)fog); if (managedFogEntry != null) { SetMeanFreePath(fog, managedFogEntry.BaseMeanFreePath); ManagedFogs.Remove(managedFogEntry); } } SteamFogScaler steamFogScaler = ((Component)valve).GetComponent<SteamFogScaler>(); if ((Object)(object)steamFogScaler == (Object)null) { steamFogScaler = ((Component)valve).gameObject.AddComponent<SteamFogScaler>(); } steamFogScaler.Init(list.ToArray()); Plugin.Logger.LogDebug((object)($"Steam valve '{((Object)valve).name}': tracking {list.Count} fog volume(s) " + "[" + string.Join(", ", list.ConvertAll((LocalVolumetricFog f) => $"{((Object)f).name} (attenuation {f.parameters.meanFreePath})")) + "]")); } private static int CountSteamValves() { return Object.FindObjectsByType<SteamValveHazard>((FindObjectsInactive)1, (FindObjectsSortMode)0).Length; } } internal static class FogDiagnostics { private const int MaxNamedObjects = 200; internal static void LogFogObjects() { //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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) try { StringBuilder stringBuilder = new StringBuilder("Fog object dump:"); FieldInfo[] fields = typeof(LocalVolumetricFogArtistParameters).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); LocalVolumetricFog[] array = Object.FindObjectsByType<LocalVolumetricFog>((FindObjectsInactive)1, (FindObjectsSortMode)0); Scene scene; foreach (LocalVolumetricFog val in array) { string[] obj = new string[6] { "\n LocalVolumetricFog '", PathOf(((Component)val).transform), "' scene='", null, null, null }; scene = ((Component)val).gameObject.scene; obj[3] = ((Scene)(ref scene)).name; obj[4] = "' "; obj[5] = $"activeInHierarchy={((Component)val).gameObject.activeInHierarchy} enabled={((Behaviour)val).enabled}"; stringBuilder.Append(string.Concat(obj)); object boxed = val.parameters; stringBuilder.Append("\n "); stringBuilder.Append(string.Join("; ", fields.Select((FieldInfo f) => f.Name + "=" + Format(f.GetValue(boxed))))); } string[] source = new string[7] { "fog", "mist", "haze", "cloud", "smoke", "vapor", "steam" }; int num = 0; stringBuilder.Append("\n Objects with fog-like names:"); Transform[] array2 = Object.FindObjectsByType<Transform>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Transform val2 in array2) { string lower = ((Object)val2).name.ToLowerInvariant(); if (source.Any((string k) => lower.Contains(k))) { if (++num > 200) { stringBuilder.Append("\n ... (truncated)"); break; } string arg = string.Join(", ", from c in ((Component)val2).GetComponents<Component>() where (Object)(object)c != (Object)null && !(c is Transform) select ((object)c).GetType().Name); string[] obj2 = new string[6] { "\n '", PathOf(val2), "' scene='", null, null, null }; scene = ((Component)val2).gameObject.scene; obj2[3] = ((Scene)(ref scene)).name; obj2[4] = "' "; obj2[5] = $"active={((Component)val2).gameObject.activeInHierarchy} [{arg}]"; stringBuilder.Append(string.Concat(obj2)); } } Plugin.Logger.LogDebug((object)stringBuilder.ToString()); } catch (Exception arg2) { Plugin.Logger.LogWarning((object)$"Fog object dump failed: {arg2}"); } } private static string Format(object? value) { if (value != null) { Object val = (Object)((value is Object) ? value : null); if (val != null) { return (val != (Object)null) ? (((object)val).GetType().Name + ":" + val.name) : "null"; } return value.ToString(); } return "null"; } private static string PathOf(Transform t) { StringBuilder stringBuilder = new StringBuilder(((Object)t).name); Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, ((Object)parent).name + "/"); parent = parent.parent; } return stringBuilder.ToString(); } } internal static class LethalConfigBridge { internal static void RegisterSlider(ConfigEntry<float> entry) { if (!LethalConfigCompat.IsLoaded) { return; } try { LethalConfigCompat.RegisterModdedSlider(entry); } catch (Exception ex) { Plugin.Logger.LogDebug((object)("Could not add '" + ((ConfigEntryBase)entry).Definition.Key + "' to LethalConfig: " + ex.Message)); } } } internal static class LethalConfigCompat { [CompilerGenerated] private static class <>O { public static CanModifyDelegate <0>__CanModify; } internal const string PluginGuid = "ainavt.lc.lethalconfig"; internal static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"); [MethodImpl(MethodImplOptions.NoInlining)] internal static void Register(ConfigFile cfg) { ConfigDefinition[] weatherStrengthDefinitions = FogConfig.WeatherStrengthDefinitions; foreach (ConfigDefinition definition in weatherStrengthDefinitions) { AddSlider(cfg, definition, 0f, 1f); } AddSlider(cfg, FogConfig.MovingStrengthDefinition, 0f, 1f); AddSlider(cfg, FogConfig.ReflectionDefinition, 0f, 1f); AddSlider(cfg, FogConfig.SteamStrengthDefinition, 0f, 1f); AddSlider(cfg, FogConfig.SteamSizeDefinition, 0f, 1f); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void RegisterModdedSlider(ConfigEntry<float> entry) { AddSlider(entry, 0f, 1f); } private static void AddSlider(ConfigFile cfg, ConfigDefinition definition, float min, float max) { AddSlider((ConfigEntry<float>)(object)cfg[definition], min, max); } private static void AddSlider(ConfigEntry<float> entry, float min, float max) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown FloatSliderOptions val = new FloatSliderOptions(); ((BaseRangeOptions<float>)(object)val).Min = min; ((BaseRangeOptions<float>)(object)val).Max = max; ((BaseOptions)val).RequiresRestart = false; object obj = <>O.<0>__CanModify; if (obj == null) { CanModifyDelegate val2 = CanModify; <>O.<0>__CanModify = val2; obj = (object)val2; } ((BaseOptions)val).CanModifyCallback = (CanModifyDelegate)obj; LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(entry, val)); } private static CanModifyResult CanModify() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton != (Object)null) || !singleton.IsClient || singleton.IsHost) { return CanModifyResult.True(); } return CanModifyResult.False("Controlled by the host while you are in their lobby."); } } internal static class ModdedWeatherStrengths { internal const string Section = "Strength (Modded)"; private static ConfigFile? _cfg; private static readonly Dictionary<string, ConfigEntry<float>> Entries = new Dictionary<string, ConfigEntry<float>>(); private static readonly Dictionary<LevelWeatherType, string> KeyByType = new Dictionary<LevelWeatherType, string>(); private static bool _needsRebuild = true; private static int _lastCount = -1; private static string _parsedFrom = ""; private static Dictionary<string, float> _parsed = new Dictionary<string, float>(); internal static void Init(ConfigFile cfg) { _cfg = cfg; } internal static void Poll() { if (_cfg == null || !WeatherRegistryCompat.TryGetSetupState(out var finished, out var count)) { return; } if (!finished) { _needsRebuild = true; } else if (_needsRebuild || count != _lastCount) { List<KeyValuePair<LevelWeatherType, string>> list = WeatherRegistryCompat.ModdedWeathers(); if (list != null) { _needsRebuild = false; _lastCount = count; Rebuild(list); } } } private static void Rebuild(List<KeyValuePair<LevelWeatherType, string>> weathers) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected I4, but got Unknown KeyByType.Clear(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); List<string> list = new List<string>(); foreach (KeyValuePair<LevelWeatherType, string> weather in weathers) { string text = Sanitize(weather.Value, weather.Key); string text2 = text; int num = 2; while (!hashSet.Add(text2)) { text2 = $"{text} ({num})"; num++; } KeyByType[weather.Key] = text2; Bind(text2, weather.Value); list.Add($"'{text2}' = {(int)weather.Key}"); } Plugin.Logger.LogDebug((object)((weathers.Count == 0) ? "WeatherRegistry is set up; no modded weathers registered." : ("Modded weathers found: " + string.Join(", ", list)))); Pack(); } private static void Bind(string key, string displayName) { //IL_0019: 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) //IL_0051: Expected O, but got Unknown //IL_0051: Expected O, but got Unknown if (!Entries.ContainsKey(key)) { ConfigEntry<float> val = _cfg.Bind<float>(new ConfigDefinition("Strength (Modded)", key), 1f, new ConfigDescription("Fog density while the modded weather '" + displayName + "' is active. 1 = vanilla, 0 = no fog, above 1 = denser.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); Entries[key] = val; val.SettingChanged += delegate { Pack(); }; LethalConfigBridge.RegisterSlider(val); } } internal static void Pack() { NetworkManager singleton = NetworkManager.Singleton; if (Plugin.Settings == null || ((Object)(object)singleton != (Object)null && singleton.IsClient && !singleton.IsHost)) { return; } StringBuilder stringBuilder = new StringBuilder(); foreach (string value2 in KeyByType.Values) { if (Entries.TryGetValue(value2, out ConfigEntry<float> value)) { stringBuilder.Append(value2).Append('=').Append(value.Value.ToString("0.####", CultureInfo.InvariantCulture)) .Append(';'); } } string text = stringBuilder.ToString(); if (Plugin.Settings.ModdedWeatherStrengths.LocalValue != text) { Plugin.Settings.ModdedWeatherStrengths.LocalValue = text; } } internal static bool TryGetStrength(LevelWeatherType type, out float strength) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) strength = 1f; if (!KeyByType.TryGetValue(type, out string value)) { return false; } strength = (Parsed().TryGetValue(value, out var value2) ? value2 : 1f); return true; } private static Dictionary<string, float> Parsed() { string text = Plugin.Settings.ModdedWeatherStrengths.Value ?? ""; if (text == _parsedFrom) { return _parsed; } Dictionary<string, float> dictionary = new Dictionary<string, float>(StringComparer.Ordinal); string[] array = text.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { int num = text2.LastIndexOf('='); if (num > 0 && float.TryParse(text2.Substring(num + 1), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { dictionary[text2.Substring(0, num)] = Mathf.Clamp(result, 0f, 1f); } } _parsedFrom = text; _parsed = dictionary; return dictionary; } private static string Sanitize(string name, LevelWeatherType type) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected I4, but got Unknown StringBuilder stringBuilder = new StringBuilder(); foreach (char c in name) { if (c != '=' && c != ';' && c != '\n' && c != '\r' && c != '\t' && c != '"' && c != '\'' && c != '[' && c != ']') { stringBuilder.Append(c); } } string text = stringBuilder.ToString().Trim(); if (text.Length <= 0) { return $"Weather{(int)type}"; } return text; } } internal sealed class SteamFogScaler : MonoBehaviour { private LocalVolumetricFog[] _fogs = Array.Empty<LocalVolumetricFog>(); private float[] _baseline = Array.Empty<float>(); private float[] _lastWritten = Array.Empty<float>(); private bool _reportedAnimated; internal void Init(LocalVolumetricFog[] fogs) { _fogs = fogs; _baseline = new float[fogs.Length]; _lastWritten = new float[fogs.Length]; for (int i = 0; i < fogs.Length; i++) { float meanFreePath = fogs[i].parameters.meanFreePath; _baseline[i] = meanFreePath; _lastWritten[i] = meanFreePath; } } private void LateUpdate() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) float steamStrength = FogController.SteamStrength; for (int i = 0; i < _fogs.Length; i++) { LocalVolumetricFog val = _fogs[i]; if ((Object)(object)val == (Object)null) { continue; } LocalVolumetricFogArtistParameters parameters = val.parameters; float meanFreePath = parameters.meanFreePath; if (!Mathf.Approximately(meanFreePath, _lastWritten[i])) { if (!_reportedAnimated) { _reportedAnimated = true; Plugin.Logger.LogDebug((object)$"Steam fog '{((Object)val).name}': attenuation is changed by the game (now {meanFreePath}); scaling it each frame."); } _baseline[i] = meanFreePath; } float num = FogController.ScaleByStrength(_baseline[i], steamStrength); if (!Mathf.Approximately(num, meanFreePath)) { parameters.meanFreePath = num; val.parameters = parameters; } _lastWritten[i] = num; } } } internal static class WeatherRegistryCompat { private const string ManagerTypeName = "WeatherRegistry.WeatherManager"; private static bool? _available; private static bool _reportedError; internal static bool IsAvailable { get { bool valueOrDefault = _available == true; if (!_available.HasValue) { valueOrDefault = AccessTools.TypeByName("WeatherRegistry.WeatherManager") != null; _available = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } internal static List<LevelWeatherType>? ActiveEffects() { if (!IsAvailable) { return null; } try { return ReadActiveEffects(); } catch (Exception e) { ReportOnce(e); return null; } } internal static string? NameOf(LevelWeatherType type) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!IsAvailable) { return null; } try { return ReadName(type); } catch (Exception e) { ReportOnce(e); return null; } } internal static bool TryGetSetupState(out bool finished, out int count) { finished = false; count = 0; if (!IsAvailable) { return false; } try { finished = ReadSetupState(out count); return true; } catch (Exception e) { ReportOnce(e); return false; } } internal static List<KeyValuePair<LevelWeatherType, string>>? ModdedWeathers() { if (!IsAvailable) { return null; } try { return ReadModdedWeathers(); } catch (Exception e) { ReportOnce(e); return null; } } private static void ReportOnce(Exception e) { if (!_reportedError) { _reportedError = true; Plugin.Logger.LogWarning((object)("WeatherRegistry integration failed (different version?); modded weathers fall back to the None strength. " + e.Message)); } } [MethodImpl(MethodImplOptions.NoInlining)] private static List<LevelWeatherType>? ReadActiveEffects() { if (!WeatherManager.IsSetupFinished) { return null; } return WeatherManager.CurrentEffectTypes; } [MethodImpl(MethodImplOptions.NoInlining)] private static string? ReadName(LevelWeatherType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (!WeatherManager.WeathersDictionary.TryGetValue(type, out var value)) { return null; } return value.Name; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool ReadSetupState(out int count) { count = WeatherManager.WeathersDictionary.Count; return WeatherManager.IsSetupFinished; } [MethodImpl(MethodImplOptions.NoInlining)] private static List<KeyValuePair<LevelWeatherType, string>>? ReadModdedWeathers() { //IL_0030: 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) if (!WeatherManager.IsSetupFinished) { return null; } List<KeyValuePair<LevelWeatherType, string>> list = new List<KeyValuePair<LevelWeatherType, string>>(); foreach (KeyValuePair<LevelWeatherType, Weather> item in WeatherManager.WeathersDictionary) { if (!Enum.IsDefined(typeof(LevelWeatherType), item.Key) && item.Value != null) { list.Add(new KeyValuePair<LevelWeatherType, string>(item.Key, item.Value.Name ?? string.Empty)); } } list.Sort((KeyValuePair<LevelWeatherType, string> a, KeyValuePair<LevelWeatherType, string> b) => ((int)a.Key).CompareTo((int)b.Key)); return list; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "bobabulkerENTERPRISE.TolerableFog"; public const string PLUGIN_NAME = "TolerableFog"; public const string PLUGIN_VERSION = "1.0.2"; } } namespace TolerableFog.Patches { [HarmonyPatch(typeof(TimeOfDay))] internal static class TimeOfDayPatches { [HarmonyPatch("SetWeatherBasedOnVariables")] [HarmonyPostfix] private static void SetWeatherBasedOnVariablesPostfix(TimeOfDay __instance) { FogController.OnFoggyWeatherSet(__instance); } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePostfix() { FogController.Tick(); } } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] internal static class RoundManagerPatches { [HarmonyPostfix] private static void FinishGeneratingLevelPostfix() { FixCameraResolutionsCompat.EnsurePatched("level load"); FixCameraResolutionsCompat.VerifyVolumetrics(); FogController.Refresh(); } } [HarmonyPatch(typeof(PlayerControllerB))] internal static class PlayerControllerBPatches { [HarmonyPatch("SetSpectatedPlayerEffects")] [HarmonyPostfix] private static void SetSpectatedPlayerEffectsPostfix(PlayerControllerB __instance) { FogController.OnPlayerEffectsSet(__instance); } } [HarmonyPatch(typeof(FlashlightItem))] internal static class FlashlightItemPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(FlashlightItem __instance) { FogController.ApplyLight(__instance.flashlightBulb); } } [HarmonyPatch(typeof(SteamValveHazard))] internal static class SteamValveHazardPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(SteamValveHazard __instance) { FogController.OnSteamValveStart(__instance); } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePostfix(SteamValveHazard __instance) { FogController.OnSteamValveUpdated(__instance); } } [HarmonyPatch(typeof(StartOfRound), "Awake")] internal static class StartOfRoundPatches { [HarmonyPostfix] private static void AwakePostfix() { FixCameraResolutionsCompat.EnsurePatched("StartOfRound.Awake"); } } }