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 ImmersiveCameraEnhanced v1.0.0
BepInEx/plugins/ImmersiveCameraEnhanced/ImmersiveCameraEnhanced.dll
Decompiled a day 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.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Profiling; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [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("ImmersiveCameraEnhanced")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ImmersiveCameraEnhanced")] [assembly: AssemblyTitle("ImmersiveCameraEnhanced")] [assembly: AssemblyVersion("1.0.0.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 CameraCull { internal sealed class ConfigurationManagerAttributes { public string Category; public string DispName; public int? Order; public bool? Browsable; } [BepInPlugin("com.kimbauer.valheim.cameracull", "Immersive Camera Enhanced", "1.0.0")] [BepInProcess("valheim.exe")] public sealed class Plugin : BaseUnityPlugin { public const string Id = "com.kimbauer.valheim.cameracull"; public const string Version = "1.0.0"; internal static Plugin Instance; internal static CameraCullController Controller; internal static ConfigEntry<int> CameraCollisionMask; internal static ConfigEntry<bool> EnableMod; internal static ConfigEntry<bool> EnableCylinderOcclusion; internal static ConfigEntry<float> CylinderCameraWidthPercent; internal static ConfigEntry<float> ConeCharacterDistance; internal static ConfigEntry<bool> CullHousePillars; internal static ConfigEntry<bool> LeavesOnly; internal static ConfigEntry<bool> MovementLeavesOnly; internal static ConfigEntry<float> MovementLeavesOnlyActivationDelay; internal static ConfigEntry<bool> EnableFirstPersonCamera; internal static ConfigEntry<bool> EnableFirstPersonCameraSway; internal static ConfigEntry<bool> EnableFirstPersonCameraAnimations; internal static ConfigEntry<float> FirstPersonCameraFov; internal static ConfigEntry<bool> EnableCameraZoom; internal static ConfigEntry<KeyboardShortcut> CameraZoomKey; internal static ConfigEntry<float> CameraZoomDefaultMagnification; internal static ConfigEntry<float> CameraZoomMagnificationStep; internal static ConfigEntry<float> CameraZoomMaxMagnification; internal static ConfigEntry<float> CameraZoomSmoothSpeed; internal static ConfigEntry<float> CameraZoomMouseSensitivityFactor; internal static ConfigEntry<float> CameraDistanceSmoothSpeed; internal static ConfigEntry<bool> EnableFirstPersonFreeLook; internal static ConfigEntry<KeyboardShortcut> FirstPersonFreeLookKey; internal static ConfigEntry<bool> EnableAdvancedCamera; internal static ConfigEntry<float> AdvancedCameraCeilingCheckInterval; internal static ConfigEntry<bool> EnableAdvancedCameraHeightClearance; internal static ConfigEntry<float> AdvancedCameraClearance; internal static ConfigEntry<float> ThirdPersonCameraDistance; internal static ConfigEntry<float> BoatCameraDistance; internal static ConfigEntry<bool> IgnoreVegetationCollision; internal static ConfigEntry<bool> IgnoreHousePillarCollision; internal static ConfigEntry<bool> IgnoreHouseLightCollision; internal static ConfigEntry<bool> IgnoreEntityCollision; internal static ConfigEntry<bool> KeepFoundationFloorRoofCollision; internal static ConfigEntry<float> BackCylinderLength; internal static ConfigEntry<float> ConeGrowthExponent; internal static ConfigEntry<float> ConeRearRadiusMultiplier; internal static ConfigEntry<float> CylinderVerticalFlattenPercent; internal static ConfigEntry<bool> CylinderFlattenBottom; internal static ConfigEntry<float> CylinderHorizontalFlattenPercent; internal static ConfigEntry<float> CylinderTopFlattenPercent; internal static ConfigEntry<float> CylinderSlicesPerMeter; internal static ConfigEntry<float> CylinderExponentInfluencePercent; internal static ConfigEntry<float> CylinderCheckInterval; internal static ConfigEntry<float> CylinderRestoreDelay; internal static ConfigEntry<bool> PreserveVegetationShadows; internal static ConfigEntry<bool> EnableBrightnessAdjustment; internal static ConfigEntry<float> DayBrightnessPercent; internal static ConfigEntry<float> NightBrightnessPercent; internal static ConfigEntry<float> FogCaveBrightnessPercent; internal static ConfigEntry<string> VegetationNameTokens; internal static ConfigEntry<string> ProtectedNameTokens; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<bool> ShowOcclusionCylinder; internal static ConfigEntry<float> CylinderDebugOpacity; private Harmony harmony; internal static bool ModEnabled { get { if (EnableMod != null) { return EnableMod.Value; } return false; } } private static ConfigDescription UiDescription(string description, string category, int order, string displayName = null, AcceptableValueBase acceptableValues = null) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown return new ConfigDescription(description, acceptableValues, new object[1] { new ConfigurationManagerAttributes { Category = category, Order = order, DispName = displayName } }); } private void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Invalid comparison between Unknown and I4 //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_07a9: Unknown result type (might be due to invalid IL or missing references) //IL_07b3: Expected O, but got Unknown //IL_0a4f: Unknown result type (might be due to invalid IL or missing references) //IL_0a59: Expected O, but got Unknown //IL_0cac: Unknown result type (might be due to invalid IL or missing references) //IL_0cb6: Expected O, but got Unknown //IL_0ec1: Unknown result type (might be due to invalid IL or missing references) //IL_0ec6: Unknown result type (might be due to invalid IL or missing references) //IL_0ecc: Expected O, but got Unknown //IL_0edc: Unknown result type (might be due to invalid IL or missing references) //IL_0ee6: Expected O, but got Unknown //IL_0374: Unknown result type (might be due to invalid IL or missing references) Instance = this; ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "Enabled", true, new ConfigDescription("Legacy key retained for migration.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = "99 - Legacy", Order = -100, Browsable = false } })); EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "EnableMod", val.Value, UiDescription("Master switch. When disabled, the cylinder, visual culling, and camera collision filtering are inactive.", "00 - Camera Cull", 110, "Enable Immersive Camera Enhanced")); EnableCylinderOcclusion = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "EnableCameraCull", val.Value, UiDescription("Enable or disable V1 cylinder visual culling. The global Enable Mod switch controls the whole mod.", "00 - Camera Cull", 100, "Enable Cylinder Occlusion")); LeavesOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "LeavesOnly", false, UiDescription("V1 only: hides identified leaves on large trees; trunks and branches remain visible.", "00 - Camera Cull", 90, "Leaves Only")); MovementLeavesOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "MovementLeavesOnly", true, UiDescription("Temporarily uses Leaves Only while the character walks toward the camera. Direction detection is local and does not scan the scene.", "00 - Camera Cull", 80, "Leaves Only While Moving Toward Camera")); ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "MovementLeavesOnlyDuration", 1.5f, new ConfigDescription("Legacy value retained for compatibility; it is not used as the activation delay.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = "99 - Legacy", Order = -70, Browsable = false } })); MovementLeavesOnlyActivationDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "MovementLeavesOnlyActivationDelay", 0.5f, UiDescription("Continuous movement time toward the camera before Leaves Only becomes active.", "00 - Camera Cull / Adjustments", 120, "Movement Leaves Only Activation Delay", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f))); EnableFirstPersonCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableFirstPersonCamera", true, UiDescription("Enables vanilla first person when the scroll reaches the minimum zoom. Scroll away from the minimum to return to third person. This client setting does not change the vanilla first-person camera.", "20 - Camera Improvements", 100, "Enable Vanilla First Person")); EnableFirstPersonCameraSway = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableFirstPersonCameraSway", true, UiDescription("Adds a lightweight first-person movement sway by rotating the camera only. It never repositions the camera.", "20 - Camera Improvements", 90, "Enable First Person Camera Sway")); EnableFirstPersonCameraAnimations = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableFirstPersonCameraAnimations", true, UiDescription("Enables first-person character camera animation. Crouching smoothly lowers the camera by 30% of the character height.", "20 - Camera Improvements", 80, "Enable First Person Camera Animations")); FirstPersonCameraFov = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "FirstPersonCameraFov", 65f, UiDescription("Local field of view used only while vanilla first person is active. This client value overrides server and external camera settings.", "20 - Camera Improvements / Adjustments", 70, "First Person Camera FOV", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 120f))); EnableCameraZoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableCameraZoom", true, UiDescription("Hold the configured key to magnify the view toward the crosshair in third or first person. The wheel adjusts magnification while held; releasing the key restores the normal view.", "20 - Camera Improvements", 60, "Enable Hold-to-Zoom")); CameraZoomKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Camera", "CameraZoomKey", new KeyboardShortcut((KeyCode)326, Array.Empty<KeyCode>()), UiDescription("Key held for temporary camera zoom. The default is Mouse4 (Unity Mouse3).", "20 - Camera Improvements", 50, "Zoom Hold Key")); KeyboardShortcut value = CameraZoomKey.Value; bool flag = false; using (IEnumerator<KeyCode> enumerator = ((KeyboardShortcut)(ref value)).Modifiers.GetEnumerator()) { if (enumerator.MoveNext()) { _ = enumerator.Current; flag = true; } } if ((int)((KeyboardShortcut)(ref value)).MainKey == 325 && !flag) { CameraZoomKey.Value = new KeyboardShortcut((KeyCode)326, Array.Empty<KeyCode>()); } CameraZoomDefaultMagnification = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraZoomDefaultMagnification", 2f, UiDescription("Initial optical magnification when the zoom key is held.", "20 - Camera Improvements / Adjustments", 70, "Default Zoom Magnification", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f))); CameraZoomMagnificationStep = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraZoomMagnificationStep", 0.5f, UiDescription("Change in optical magnification per scroll notch while the zoom key is held.", "20 - Camera Improvements / Adjustments", 60, "Zoom Magnification per Scroll", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f))); CameraZoomMaxMagnification = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraZoomMaxMagnification", 20f, UiDescription("Maximum optical magnification while zooming. Values up to 40 are supported.", "20 - Camera Improvements / Adjustments", 50, "Maximum Zoom Magnification", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 40f))); CameraZoomSmoothSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraZoomSmoothSpeed", 14f, UiDescription("Speed used to smooth optical zoom changes while the zoom key is held.", "20 - Camera Improvements / Adjustments", 45, "Zoom Smooth Speed", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f))); CameraZoomMouseSensitivityFactor = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraZoomMouseSensitivityFactor", 0.2f, UiDescription("Multiplier applied to mouse sensitivity while zooming. Lower values slow the view more; 0.20 is five times slower than the unscaled response.", "20 - Camera Improvements / Adjustments", 42, "Zoom Mouse Sensitivity Factor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f))); CameraDistanceSmoothSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraDistanceSmoothSpeed", 12f, UiDescription("Speed used to smooth normal third-person distance changes from the scroll wheel.", "20 - Camera Improvements / Adjustments", 40, "Camera Distance Smooth Speed", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f))); EnableFirstPersonFreeLook = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableFirstPersonFreeLook", true, UiDescription("Allows looking around freely while the configured Alt key is held without changing the character's movement direction.", "20 - Camera Improvements", 40, "Enable Alt Free Look")); FirstPersonFreeLookKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Camera", "FirstPersonFreeLookKey", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), UiDescription("Key held for free look. The default is Left Alt.", "20 - Camera Improvements", 30, "Free Look Hold Key")); EnableAdvancedCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableAdvancedCamera", true, UiDescription("Keeps third-person camera height within the clear space between ground and ceiling while vertical look rotates toward the crosshair.", "20 - Camera Improvements", 20, "Enable Advanced Camera")); AdvancedCameraCeilingCheckInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "AdvancedCameraCeilingCheckInterval", 2f, UiDescription("How often the client checks for a player-built ceiling above the current camera position.", "20 - Camera Improvements / Adjustments", 35, "Advanced Camera Ceiling Check Interval", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f))); EnableAdvancedCameraHeightClearance = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableAdvancedCameraHeightClearance", true, UiDescription("Allows Advanced Camera to move vertically inside the available floor-to-ceiling space while preserving clearance.", "20 - Camera Improvements", 15, "Enable Advanced Camera Height Clearance")); AdvancedCameraClearance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "AdvancedCameraClearance", 6f, UiDescription("Minimum clearance in metres from the floor and ceiling while height clearance is active.", "20 - Camera Improvements / Adjustments", 30, "Advanced Camera Clearance", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 10f))); ThirdPersonCameraDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "ThirdPersonCameraDistance", 6f, UiDescription("Maximum local third-person distance for the character. This client value overrides server-side camera distance settings.", "20 - Camera Improvements / Adjustments", 80, "Third Person Camera Distance", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 35f))); BoatCameraDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "BoatCameraDistance", 6f, UiDescription("Maximum local camera distance while controlling a boat. This client value overrides server-side camera distance settings.", "20 - Camera Improvements / Adjustments", 70, "Boat Camera Distance", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 35f))); CullHousePillars = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "CullHousePillars", true, UiDescription("Also hides player-built support pillars and stone arches that intersect the cylinder.", "00 - Camera Cull", 70, "Cull Supports & Stone Arches")); IgnoreVegetationCollision = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "IgnoreVegetationCollision", true, UiDescription("Prevents camera collision from stopping on recognized vegetation.", "10 - Camera Collision", 100, "Ignore Vegetation Collision")); ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "IgnoreRockCollision", false, new ConfigDescription("Legacy key retained for migration. Terrain, rocks, ores, and boulders always stop the camera.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = "99 - Legacy", Order = -90, Browsable = false } })); IgnoreHousePillarCollision = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "IgnoreHousePillarCollision", true, UiDescription("Allows the camera to pass through player-built support pillars and stone arches. Walls, foundations, floors, and roofs remain solid.", "10 - Camera Collision", 90, "Ignore Support & Arch Collision")); IgnoreHouseLightCollision = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "IgnoreHouseLightCollision", true, UiDescription("Allows the camera to pass through wall sconces, all torches, light fixtures, and tables.", "10 - Camera Collision", 80, "Ignore Props & Lights Collision")); IgnoreEntityCollision = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "IgnoreEntityCollision", true, UiDescription("Allows the camera to pass through players, animals, enemies, and other entities.", "10 - Camera Collision", 70, "Ignore Entity Collision")); KeepFoundationFloorRoofCollision = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "KeepFoundationFloorRoofCollision", true, UiDescription("Keeps structural walls, foundations, floors, ceilings, and roofs solid, with clearance below horizontal surfaces based on their thickness.", "10 - Camera Collision", 60, "Structural Surface Collision")); PreserveVegetationShadows = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "PreserveVegetationShadows", true, UiDescription("Hides vegetation color while keeping shadows.", "00 - Camera Cull", 60, "Preserve Vegetation Shadows")); CylinderCameraWidthPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderCameraWidthPercent", 25f, UiDescription("Camera-side width as a screen percentage; the apex closes to zero.", "00 - Camera Cull / Adjustments", 100, "Cylinder Camera Width", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); ConeCharacterDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "ConeCharacterDistance", 0.5f, UiDescription("Distance from the character center to the cylinder apex; the apex points toward the camera.", "00 - Camera Cull / Adjustments", 110, "Cylinder Character Distance", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f))); BackCylinderLength = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "BackCylinderLength", 10f, UiDescription("Additional cylinder length in metres beyond the camera.", "00 - Camera Cull / Adjustments", 90, "Cylinder Length Behind Camera", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f))); ConeGrowthExponent = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "ConeGrowthExponent", 2.4f, UiDescription("Cylinder radius curvature; values above 1 keep the start narrow and expand near the camera.", "00 - Camera Cull / Adjustments", 80, "Cylinder Growth Exponent", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f))); ConeRearRadiusMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "ConeRearRadiusMultiplier", 1.75f, UiDescription("Radius multiplier at the rear tip beyond the camera.", "00 - Camera Cull / Adjustments", 60, "Cylinder Rear Radius Multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f))); CylinderTopFlattenPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderTopFlattenPercent", 30f, new ConfigDescription("Legacy value migrated to CylinderVerticalFlattenPercent.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = "99 - Legacy", Order = -100, Browsable = false } })); CylinderVerticalFlattenPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderVerticalFlattenPercent", CylinderTopFlattenPercent.Value, UiDescription("Flattens the upper vertical side of the cylinder after applying the growth exponent.", "00 - Camera Cull / Adjustments", 40, "Cylinder Vertical Flatten", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); CylinderFlattenBottom = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera occlusion", "CylinderFlattenBottom", false, UiDescription("Also applies the vertical flattening limit to the lower side of the cylinder.", "00 - Camera Cull / Adjustments", 30, "Flatten Bottom")); CylinderHorizontalFlattenPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderHorizontalFlattenPercent", 0f, UiDescription("Flattens the horizontal width of the cylinder after applying the growth exponent.", "00 - Camera Cull / Adjustments", 20, "Cylinder Horizontal Flatten", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); CylinderSlicesPerMeter = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderSlicesPerMeter", 2f, UiDescription("Curved-cylinder profile cuts per metre. Higher values make the stepped profile denser.", "00 - Camera Cull / Adjustments", 50, "Cylinder Cuts Per Metre", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 12f))); CylinderExponentInfluencePercent = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderExponentInfluencePercent", 100f, UiDescription("Percentage of the growth exponent applied at each profile cut.", "00 - Camera Cull / Adjustments", 70, "Growth Exponent Influence", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); CylinderCheckInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderCheckInterval", 0.6f, UiDescription("Seconds between cylinder contact checks. The cylinder transform still follows the camera every frame.", "90 - Performance", 100, "Cylinder Check Interval", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f))); CylinderRestoreDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Camera occlusion", "CylinderRestoreDelay", 0.6f, UiDescription("Seconds an object must remain outside the cylinder before it is restored. Set to 0 for immediate restoration.", "90 - Performance", 90, "Cylinder Restore Delay", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f))); EnableBrightnessAdjustment = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "EnableBrightnessAdjustment", true, UiDescription("Enables the local darkness, cave, and fog brightness adjustment.", "30 - Visual", 100, "Enable Brightness Adjustment")); ConfigEntry<float> val2 = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "BrightnessBoostPercent", 25f, new ConfigDescription("Legacy value retained to migrate the separate night and fog/cave controls.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = "99 - Legacy", Order = -80, Browsable = false } })); DayBrightnessPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "DayBrightnessPercent", 0f, UiDescription("Signed daylight brightness. Negative values darken, zero keeps vanilla daylight, and values above 100 apply stronger HDR light.", "30 - Visual", 90, "Day Brightness", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 300f))); NightBrightnessPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "NightBrightnessPercent", val2.Value, UiDescription("Signed brightness used at night and by always-dark environments. Negative values darken; values above 100 apply stronger HDR light.", "30 - Visual", 80, "Night Brightness", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 300f))); FogCaveBrightnessPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "FogCaveBrightnessPercent", val2.Value, UiDescription("Signed brightness for dense fog, mist, caves, crypts, and dungeons. Negative values darken; values above 100 apply stronger HDR light.", "30 - Visual", 70, "Fog & Cave Brightness", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 300f))); DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, UiDescription("Writes diagnostic information to the BepInEx log.", "99 - Debug", 0)); ShowOcclusionCylinder = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ShowOcclusionCylinder", false, UiDescription("Draws the curved cylinder in green for calibration.", "99 - Debug", 1)); CylinderDebugOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Debug", "CylinderOpacity", 0.2f, UiDescription("Diagnostic outline opacity; 0 is invisible and 1 is fully opaque.", "99 - Debug", 2, "Cylinder Outline Opacity", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f))); CameraCollisionMask = ((BaseUnityPlugin)this).Config.Bind<int>("Detection", "CollisionLayerMask", -1, UiDescription("Unity layer mask used by physical queries; -1 includes every layer.", "40 - Detection / Adjustments", 0, "Collision Layer Mask", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 31))); VegetationNameTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Detection", "VegetationNameTokens", "tree,beech,birch,oak,pine,fir,ash,juniper,yggdrasil,stubbe,stump,treestump,tree_stump,ashlandstump,swamptree,sapling,bush,shrub,berry,raspberry,blueberry,cloudberry,mushroom,thistle,dandelion,grass,plant,fern,reed,vine,root,trunk,branch,treelog,treebase,foliage,leaf,leaves,flax,barley,carrot,turnip,onion", UiDescription("Comma-separated name fragments considered vegetation.", "40 - Detection / Adjustments", 1)); ProtectedNameTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Detection", "ProtectedNameTokens", "terrain,water,ocean,seafloor,sky,sun,moon,fog,minimap,map,loading,menu,ui,hud,player,character,creature,enemy,boss,vfx,particle,smoke,projectile,itemdrop,pickup,portal,rock,stone,boulder,ore,oredeposit,flint", UiDescription("Comma-separated name fragments excluded from camera occlusion detection.", "40 - Detection / Adjustments", 2)); GameObject val3 = new GameObject("ImmersiveCameraEnhancedController"); Object.DontDestroyOnLoad((Object)val3); Controller = val3.AddComponent<CameraCullController>(); harmony = new Harmony("com.kimbauer.valheim.cameracull"); PatchGameCamera(); PatchEnvironmentManager(); ((BaseUnityPlugin)this).Logger.LogInfo((object)(ModEnabled ? "Immersive Camera Enhanced 1.0.0 loaded and active." : "Immersive Camera Enhanced 1.0.0 loaded, but disabled by Camera occlusion/EnableMod=false.")); } private void PatchGameCamera() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0139: Expected O, but got Unknown //IL_0139: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_021a: Expected O, but got Unknown //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Expected O, but got Unknown //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Expected O, but got Unknown //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("GameCamera"); if (type == null) { Debug("GameCamera was not found; using only the render callback."); return; } MethodInfo methodInfo = AccessTools.Method(type, "LateUpdate", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "Update", (Type[])null, (Type[])null); if (methodInfo == null) { Debug("No GameCamera update method was found."); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(GameCameraPatch), "Postfix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug("GameCamera patched at " + methodInfo.Name + "."); MethodInfo method = type.GetMethod("UpdateCamera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null); if (method != null) { MethodInfo methodInfo3 = AccessTools.Method(typeof(GameCameraPatch), "PrefixUpdateCamera", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(GameCameraPatch), "PostfixUpdateCamera", (Type[])null, (Type[])null); MethodInfo methodInfo5 = AccessTools.Method(typeof(GameCameraPatch), "TranspileUpdateCamera", (Type[])null, (Type[])null); harmony.Patch((MethodBase)method, new HarmonyMethod(methodInfo3), new HarmonyMethod(methodInfo4), new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null); Debug("Local camera distance limits patched."); } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo methodInfo6 = AccessTools.TypeByName("PlayerController")?.GetMethod("LateUpdate", bindingAttr, null, Type.EmptyTypes, null); if (methodInfo6 != null) { MethodInfo methodInfo7 = AccessTools.Method(typeof(GameCameraPatch), "TranspilePlayerControllerMouseInput", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo7), (HarmonyMethod)null, (HarmonyMethod)null); Debug("Zoomed mouse sensitivity patched at PlayerController.LateUpdate."); } MethodInfo methodInfo8 = AccessTools.Method(type, "GetCameraPosition", (Type[])null, (Type[])null); if (methodInfo8 != null) { MethodInfo methodInfo9 = AccessTools.Method(typeof(GameCameraPatch), "PrefixGetCameraPosition", (Type[])null, (Type[])null); MethodInfo methodInfo10 = AccessTools.Method(typeof(GameCameraPatch), "PostfixGetCameraPosition", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo8, new HarmonyMethod(methodInfo9), new HarmonyMethod(methodInfo10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug("Vanilla first-person camera mode patched."); } Type type2 = AccessTools.TypeByName("Player"); MethodInfo methodInfo11 = type2?.GetMethod("Dodge", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null); if (methodInfo11 != null) { MethodInfo methodInfo12 = AccessTools.Method(typeof(GameCameraPatch), "PrefixPlayerDodge", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo11, new HarmonyMethod(methodInfo12), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug("First-person roll direction patched."); } MethodInfo methodInfo13 = type2?.GetMethod("SetMouseLook", bindingAttr, null, new Type[1] { typeof(Vector2) }, null); if (methodInfo13 != null) { MethodInfo methodInfo14 = AccessTools.Method(typeof(GameCameraPatch), "PrefixPlayerSetMouseLook", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo13, new HarmonyMethod(methodInfo14), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug("Alt free-look movement heading patched before Player.SetMouseLook."); } MethodInfo method2 = type.GetMethod("RayTestPoint", bindingAttr, null, new Type[4] { typeof(Vector3), typeof(Vector3), typeof(float), typeof(Vector3).MakeByRefType() }, null); if (method2 != null) { MethodInfo methodInfo15 = AccessTools.Method(typeof(GameCameraPatch), "PrefixRayTestPoint4", (Type[])null, (Type[])null); harmony.Patch((MethodBase)method2, new HarmonyMethod(methodInfo15), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug("Camera collision (RayTestPoint) patched."); } MethodInfo method3 = type.GetMethod("RayTestPoint", bindingAttr, null, new Type[5] { typeof(Vector3), typeof(Vector3), typeof(Vector3), typeof(float), typeof(float).MakeByRefType() }, null); if (method3 != null) { MethodInfo methodInfo16 = AccessTools.Method(typeof(GameCameraPatch), "PrefixRayTestPoint5", (Type[])null, (Type[])null); harmony.Patch((MethodBase)method3, new HarmonyMethod(methodInfo16), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method4 = type.GetMethod("RayTest", bindingAttr, null, new Type[3] { typeof(Vector3), typeof(Vector3), typeof(float) }, null); if (method4 != null) { MethodInfo methodInfo17 = AccessTools.Method(typeof(GameCameraPatch), "PrefixRayTest", (Type[])null, (Type[])null); harmony.Patch((MethodBase)method4, new HarmonyMethod(methodInfo17), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception exception) { Report(exception); } } private void PatchEnvironmentManager() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("EnvMan"); if (type == null) { Debug("EnvMan was not found; brightness controls are unavailable."); return; } MethodInfo methodInfo = FindEnvironmentMethod(type, "SetEnv", 6); if (methodInfo != null) { MethodInfo methodInfo2 = AccessTools.Method(typeof(EnvironmentPatch), "Postfix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Debug("Client brightness patched at " + methodInfo?.ToString() + "."); } else { Debug("EnvMan.SetEnv was not found; brightness controls are unavailable."); } } catch (Exception exception) { Report(exception); } } private static MethodInfo FindEnvironmentMethod(Type type, string name, int parameterCount) { if (type == null) { return null; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && methodInfo.GetParameters().Length == parameterCount) { return methodInfo; } } return null; } internal static void Report(Exception exception) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogError((object)exception); } } internal static void Debug(string message) { if ((Object)(object)Instance != (Object)null && DebugLogging != null && DebugLogging.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[Immersive Camera Enhanced] " + message)); } } private void OnDestroy() { if (harmony != null) { try { harmony.UnpatchSelf(); } catch (Exception exception) { Report(exception); } harmony = null; } if (Object.op_Implicit((Object)(object)Controller)) { Object.Destroy((Object)(object)((Component)Controller).gameObject); } Controller = null; Instance = null; } } internal static class EnvironmentPatch { [HarmonyPriority(0)] public static void Postfix(object __instance, object __0) { try { if (Plugin.ModEnabled && (Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.OnEnvironmentUpdated(__instance, __0); } } catch (Exception exception) { Plugin.Report(exception); } } } internal static class GameCameraPatch { private static readonly RaycastHit[] hitBuffer = (RaycastHit[])(object)new RaycastHit[96]; public static IEnumerable<CodeInstruction> TranspileUpdateCamera(IEnumerable<CodeInstruction> instructions) { MethodInfo scrollReplacement = AccessTools.Method(typeof(GameCameraPatch), "GetCameraScrollWheel", (Type[])null, (Type[])null); MethodInfo mouseReplacement = AccessTools.Method(typeof(GameCameraPatch), "GetCameraMouseDelta", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.operand is MethodInfo methodInfo && methodInfo.DeclaringType?.Name == "ZInput" && methodInfo.Name == "GetMouseScrollWheel") { instruction.opcode = OpCodes.Call; instruction.operand = scrollReplacement; } else if (instruction.operand is MethodInfo methodInfo2 && methodInfo2.DeclaringType?.Name == "ZInput" && methodInfo2.Name == "GetMouseDelta") { instruction.opcode = OpCodes.Call; instruction.operand = mouseReplacement; } yield return instruction; } } public static IEnumerable<CodeInstruction> TranspilePlayerControllerMouseInput(IEnumerable<CodeInstruction> instructions) { MethodInfo mouseReplacement = AccessTools.Method(typeof(GameCameraPatch), "GetCameraMouseDelta", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.operand is MethodInfo methodInfo && methodInfo.DeclaringType?.Name == "ZInput" && methodInfo.Name == "GetMouseDelta") { instruction.opcode = OpCodes.Call; instruction.operand = mouseReplacement; } yield return instruction; } } public static float GetCameraScrollWheel() { if (!((Object)(object)Plugin.Controller != (Object)null)) { return 0f; } return Plugin.Controller.ReadCameraScrollForVanilla(); } public static Vector2 GetCameraMouseDelta() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Plugin.Controller != (Object)null)) { return Vector2.zero; } return Plugin.Controller.ReadCameraMouseDeltaForVanilla(); } public static void PrefixUpdateCamera(object __instance) { try { if ((Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.PrepareGameCameraUpdate(__instance); } } catch (Exception exception) { Plugin.Report(exception); } } [HarmonyPriority(0)] public static void PostfixUpdateCamera(object __instance) { try { if ((Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.ApplyConfiguredCameraLimits(__instance); } } catch (Exception exception) { Plugin.Report(exception); } } [HarmonyPriority(0)] public static void PrefixGetCameraPosition(object __instance) { try { if ((Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.ApplyConfiguredCameraLimits(__instance); Plugin.Controller.ApplyFirstPersonCameraMode(__instance); } } catch (Exception exception) { Plugin.Report(exception); } } [HarmonyPriority(0)] public static void PostfixGetCameraPosition(object __instance, ref Vector3 __1, ref Quaternion __2) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.ApplyAdvancedCamera(__instance, ref __1, __2); } } catch (Exception exception) { Plugin.Report(exception); } } public static void PrefixPlayerDodge(object __instance, ref Vector3 __0) { try { if ((Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.ApplyFirstPersonRollDirection(__instance, ref __0); } } catch (Exception exception) { Plugin.Report(exception); } } public static void PrefixPlayerSetMouseLook(object __instance, ref Vector2 __0) { try { if ((Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.SuppressPlayerLookDuringFreeLook(__instance, ref __0); } } catch (Exception exception) { Plugin.Report(exception); } } [HarmonyPriority(0)] public static void Postfix(object __instance) { try { if (Plugin.ModEnabled && (Object)(object)Plugin.Controller != (Object)null) { Plugin.Controller.OnGameCameraUpdated(__instance); } } catch (Exception exception) { Plugin.Report(exception); } } public static bool PrefixRayTestPoint4(object __instance, Vector3 __0, Vector3 __1, float __2, ref Vector3 __3, ref bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!IsFilteringEnabled()) { return true; } try { float distance; bool flag = FindNearestSolid(__0, __1, __2, raycast: false, out distance); if (!flag) { flag = FindNearestSolid(__0, __1, __2, raycast: true, out distance); } if (flag) { __3 = __0 + ((Vector3)(ref __1)).normalized * Mathf.Max(0f, distance - 0.05f); } else { __3 = Vector3.zero; } __result = flag; return false; } catch (Exception exception) { Plugin.Report(exception); return true; } } public static bool PrefixRayTestPoint5(object __instance, Vector3 __0, Vector3 __1, Vector3 __2, float __3, ref float __4, ref bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_002d: Unknown result type (might be due to invalid IL or missing references) if (!IsFilteringEnabled()) { return true; } try { float distance; bool flag = FindNearestSolid(__0, __2, __3, raycast: false, out distance); if (!flag) { flag = FindNearestSolid(__1, __2, __3, raycast: false, out distance); } if (!flag) { flag = FindNearestSolid(__1, __2, __3, raycast: true, out distance); } __4 = (flag ? Mathf.Max(0f, distance) : __3); __result = flag; return false; } catch (Exception exception) { Plugin.Report(exception); return true; } } public static bool PrefixRayTest(object __instance, Vector3 __0, Vector3 __1, float __2, ref float __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) if (!IsFilteringEnabled()) { return true; } try { float distance; bool flag = FindNearestSolid(__0, __1, __2, raycast: false, out distance); if (!flag) { flag = FindNearestSolid(__0, __1, __2, raycast: true, out distance); } __result = (flag ? distance : __2); return false; } catch (Exception exception) { Plugin.Report(exception); return true; } } private static bool IsFilteringEnabled() { bool flag = Plugin.IgnoreVegetationCollision != null && Plugin.IgnoreVegetationCollision.Value; bool flag2 = Plugin.IgnoreHousePillarCollision != null && Plugin.IgnoreHousePillarCollision.Value; bool flag3 = Plugin.IgnoreHouseLightCollision != null && Plugin.IgnoreHouseLightCollision.Value; bool flag4 = Plugin.IgnoreEntityCollision != null && Plugin.IgnoreEntityCollision.Value; bool flag5 = Plugin.KeepFoundationFloorRoofCollision != null && Plugin.KeepFoundationFloorRoofCollision.Value; if (Plugin.ModEnabled && (flag || flag2 || flag3 || flag4 || flag5) && (Object)(object)Plugin.Controller != (Object)null) { return Plugin.Controller.HasLocalPlayer(); } return false; } private static bool FindNearestSolid(Vector3 origin, Vector3 direction, float maxDistance, bool raycast, out float distance, bool ignoreHorizontalStructuralSurfaces = false) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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) distance = maxDistance; if (maxDistance <= 0.001f) { return false; } Vector3 val = ((((Vector3)(ref direction)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref direction)).normalized : Vector3.forward); int num = ((Plugin.CameraCollisionMask != null) ? Plugin.CameraCollisionMask.Value : (-1)); int num2 = (raycast ? Physics.RaycastNonAlloc(origin, val, hitBuffer, maxDistance, num, (QueryTriggerInteraction)1) : Physics.SphereCastNonAlloc(origin, 0.22f, val, hitBuffer, maxDistance, num, (QueryTriggerInteraction)1)); bool flag = false; for (int i = 0; i < num2; i++) { RaycastHit hit = hitBuffer[i]; Collider collider = ((RaycastHit)(ref hit)).collider; if (Object.op_Implicit((Object)(object)collider) && !Plugin.Controller.ShouldIgnoreCameraCollider(collider) && (!ignoreHorizontalStructuralSurfaces || !(Mathf.Abs(((RaycastHit)(ref hit)).normal.y) > 0.7f) || !Plugin.Controller.IsHorizontalStructuralSurface(collider))) { float cameraCollisionDistance = Plugin.Controller.GetCameraCollisionDistance(hit); if (!flag || cameraCollisionDistance < distance) { distance = cameraCollisionDistance; flag = true; } } } return flag; } internal static bool TryFindNearestSolid(Vector3 origin, Vector3 direction, float maxDistance, out float distance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryFindNearestSolid(origin, direction, maxDistance, ignoreHorizontalStructuralSurfaces: false, out distance); } internal static bool TryFindNearestSolid(Vector3 origin, Vector3 direction, float maxDistance, bool ignoreHorizontalStructuralSurfaces, out float distance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0011: Unknown result type (might be due to invalid IL or missing references) if (FindNearestSolid(origin, direction, maxDistance, raycast: false, out distance, ignoreHorizontalStructuralSurfaces)) { return true; } return FindNearestSolid(origin, direction, maxDistance, raycast: true, out distance, ignoreHorizontalStructuralSurfaces); } } internal sealed class CameraCullController : MonoBehaviour { private static readonly string[] stoneTokens = new string[11] { "rock", "stone", "boulder", "ore", "oredeposit", "flint", "obsidian", "silvervein", "copperdeposit", "tin", "crystal" }; private static readonly string[] smallVegetationTokens = new string[21] { "grass", "bush", "shrub", "fern", "reed", "heath", "heather", "thistle", "dandelion", "berry", "raspberry", "blueberry", "cloudberry", "mushroom", "plant", "vine", "flax", "barley", "carrot", "turnip", "onion" }; private static readonly string[] largeTreeTokens = new string[18] { "tree", "beech", "birch", "oak", "pine", "fir", "ash", "juniper", "yggdrasil", "treelog", "treebase", "trunk", "branch", "stubbe", "treestump", "tree_stump", "ashlandstump", "swamptree" }; private static readonly string[] treeRootTokens = new string[12] { "beech", "birch", "oak", "pine", "fir", "ash", "yggdrasil", "stubbe", "treestump", "tree_stump", "ashlandstump", "swamptree" }; private static readonly string[] youngTreeTokens = new string[13] { "sapling", "seedling", "youngtree", "young_tree", "smalltree", "small_tree", "tree_small", "beech_small", "birch_small", "pine_small", "fir_small", "oak_small", "ash_small" }; private static readonly string[] explicitLeafRendererTokens = new string[11] { "leaf", "leaves", "leafmesh", "leafcard", "leafcluster", "leafclump", "canopy", "treetop", "crown", "needle", "needles" }; private static readonly string[] trunkTokens = new string[7] { "trunk", "treelog", "treebase", "stem", "bark", "wood", "branch" }; private static readonly string[] vegetationTagTokens = new string[3] { "tree", "vegetation", "foliage" }; private static readonly string[] structureTokens = new string[27] { "wall", "foundation", "floor", "roof", "ceiling", "beam", "pole", "stake", "fence", "gate", "door", "house", "building", "bridge", "ladder", "chest", "bed", "workbench", "portal", "pillar", "column", "support", "post", "verticalbeam", "stonecolumn", "stonepillar", "arch" }; private static readonly string[] housePillarTokens = new string[23] { "pillar", "pole", "support", "woodpole", "corewood", "ironbeam", "beam", "post", "column", "verticalbeam", "woodpost", "woodcolumn", "stonepillar", "stonecolumn", "marblecolumn", "blackmarblecolumn", "ironcolumn", "rockpillar", "verticalpost", "verticalsupport", "pilar", "coluna", "poste" }; private static readonly string[] explicitPillarTokens = new string[8] { "pillar", "column", "support", "post", "vertical", "pilar", "coluna", "poste" }; private static readonly string[] stoneArchTokens = new string[10] { "stone_arch", "stonearch", "arch_stone", "archstone", "marble_arch", "marblearch", "blackmarble_arch", "blackmarblearch", "grausten_arch", "graustenarch" }; private static readonly string[] woodStructureTokens = new string[10] { "wood", "finewood", "corewood", "roundlog", "logwood", "ironwood", "woodwall", "woodfloor", "woodroof", "woodceiling" }; private static readonly string[] cameraPassThroughPropTokens = new string[31] { "torch", "walltorch", "standingtorch", "lantern", "brazier", "sconce", "candle", "candlestick", "lamp", "fireplace", "ironfireplace", "bonfire", "firepit", "hearth", "lightfixture", "walllight", "wall_light", "arandela", "chandelier", "candelabra", "piece_table", "table_", "_table", "roundtable", "longtable", "woodtable", "marbletable", "workbench", "artisanstation", "magetable", "blackforge" }; private static readonly string[] darkEnvironmentTokens = new string[14] { "cave", "crypt", "dungeon", "burial", "interior", "mine", "infested", "sunken", "mist", "fog", "tomb", "temple", "frostcave", "queen" }; private static readonly string[] foundationFloorRoofTokens = new string[5] { "wall", "foundation", "floor", "ceiling", "roof" }; private static readonly string[] worldUiTokens = new string[11] { "nameplate", "name_plate", "healthbar", "health_bar", "worldtext", "world_text", "floatingtext", "floating_text", "overhead", "canvas", "hud" }; private readonly Dictionary<Renderer, bool> originalForceRenderingOff = new Dictionary<Renderer, bool>(); private readonly Dictionary<Renderer, ShadowCastingMode> originalShadowCastingMode = new Dictionary<Renderer, ShadowCastingMode>(); private readonly Dictionary<Renderer, Mesh> leafOnlyOriginalMeshes = new Dictionary<Renderer, Mesh>(); private readonly Dictionary<Renderer, Mesh> leafOnlyMeshes = new Dictionary<Renderer, Mesh>(); private readonly Dictionary<Renderer, Mesh> leafOnlyReusableMeshes = new Dictionary<Renderer, Mesh>(); private readonly Dictionary<Renderer, Mesh> leafOnlyReusableSources = new Dictionary<Renderer, Mesh>(); private readonly Dictionary<Renderer, GameObject> leafOnlyShadowObjects = new Dictionary<Renderer, GameObject>(); private readonly Dictionary<Mesh, Vector3[]> meshVertexCache = new Dictionary<Mesh, Vector3[]>(); private readonly Dictionary<Mesh, int[]> meshTriangleCache = new Dictionary<Mesh, int[]>(); private readonly Dictionary<Collider, Renderer[]> colliderRendererCache = new Dictionary<Collider, Renderer[]>(); private readonly Dictionary<Transform, Renderer[]> treeRendererCache = new Dictionary<Transform, Renderer[]>(); private readonly Dictionary<Transform, Transform> vegetationRootCache = new Dictionary<Transform, Transform>(); private readonly Dictionary<Transform, bool> vegetationRootCameraSideState = new Dictionary<Transform, bool>(); private readonly Dictionary<Renderer, bool> mobRendererClassification = new Dictionary<Renderer, bool>(); private readonly Dictionary<Transform, string> hierarchyNameCache = new Dictionary<Transform, string>(); private readonly Dictionary<Collider, bool> foundationWoodClassification = new Dictionary<Collider, bool>(); private readonly HashSet<Renderer> shapeOccluders = new HashSet<Renderer>(); private readonly HashSet<Renderer> nextShapeOccluders = new HashSet<Renderer>(); private readonly List<Renderer> shapeOccluderScratch = new List<Renderer>(128); private readonly Dictionary<Renderer, byte> shapeOccluderExitMisses = new Dictionary<Renderer, byte>(); private readonly Dictionary<Renderer, float> shapeOccluderOutsideSince = new Dictionary<Renderer, float>(); private readonly Dictionary<Renderer, bool> vegetationClassification = new Dictionary<Renderer, bool>(); private readonly Dictionary<Renderer, bool> smallVegetationClassification = new Dictionary<Renderer, bool>(); private readonly Dictionary<Collider, bool> vegetationColliderClassification = new Dictionary<Collider, bool>(); private readonly Dictionary<Collider, bool> entityColliderClassification = new Dictionary<Collider, bool>(); private readonly Dictionary<Collider, bool> structureColliderClassification = new Dictionary<Collider, bool>(); private readonly Dictionary<Collider, bool> foundationFloorRoofColliderClassification = new Dictionary<Collider, bool>(); private readonly Dictionary<Collider, bool> housePillarColliderClassification = new Dictionary<Collider, bool>(); private readonly Dictionary<Transform, CapsuleCollider> youngTreeProbeColliders = new Dictionary<Transform, CapsuleCollider>(); private readonly Dictionary<Collider, Transform> youngTreeProbeOwners = new Dictionary<Collider, Transform>(); private readonly Dictionary<Transform, Bounds> youngTreeProbeBounds = new Dictionary<Transform, Bounds>(); private readonly HashSet<Transform> youngTreeProbeDesired = new HashSet<Transform>(); private readonly List<Transform> youngTreeProbeScratch = new List<Transform>(64); private readonly Dictionary<Vector2Int, List<Renderer>> vegetationSpatialGrid = new Dictionary<Vector2Int, List<Renderer>>(); private readonly HashSet<Renderer> spatialQueryCandidates = new HashSet<Renderer>(); private readonly HashSet<Collider> shapeColliders = new HashSet<Collider>(); private readonly Collider[] shapeColliderBuffer = (Collider[])(object)new Collider[512]; private readonly Collider[] youngTreeColliderBuffer = (Collider[])(object)new Collider[512]; private GameObject occlusionCylinderObject; private CapsuleCollider occlusionCylinderCollider; private GameObject[] occlusionCylinderSlices; private SphereCollider[] occlusionCylinderSliceColliders; private Material debugCylinderMaterial; private Vector3 debugCylinderStart; private Vector3 debugCylinderEnd; private float debugCylinderCameraT; private float debugCylinderCameraRadius; private float debugCylinderRearRadius; private float debugCylinderGrowthExponent; private bool debugCylinderReady; private Vector3 mainVolumeStart; private Vector3 mainVolumeEnd; private Vector3 mainVolumeCharacterCenter; private float mainVolumeCameraT; private float mainVolumeCameraRadius; private float mainVolumeRearRadius; private float mainVolumeGrowthExponent; private bool mainVolumeReady; private Vector3 previousPlayerPosition; private bool previousPlayerPositionReady; private float towardCameraMovementStartedAt = -1f; private int spatialQueryCursor; private bool temporaryLeavesOnlyActive; private int towardCameraMovementFrames; private bool modResetApplied; private Renderer[] vegetationRenderers = (Renderer[])(object)new Renderer[0]; private Renderer[] housePillarRenderers = (Renderer[])(object)new Renderer[0]; private Coroutine scanRoutine; private const float VegetationGridCellSize = 16f; private Camera cachedCamera; private Type playerType; private MemberInfo localPlayerMember; private MemberInfo playerBoatMember; private MethodInfo playerBoatMethod; private MethodInfo playerIsCrouchingMethod; private MemberInfo playerCrouchToggledMember; private MemberInfo playerMoveDirMember; private MemberInfo playerCurrentVelocityMember; private MemberInfo playerRightItemMember; private MemberInfo playerLeftItemMember; private Type cachedItemDataType; private MemberInfo itemSharedMember; private Type cachedItemSharedType; private MemberInfo itemNameMember; private MemberInfo placementGhostMember; private Transform activePlacementGhost; private int placementGhostRefreshFrame = -1; private Type menuType; private MemberInfo menuInstanceMember; private MemberInfo menuRootMember; private MethodInfo menuIsVisibleMethod; private string tokenSource; private string protectedTokenSource; private string[] vegetationTokens = new string[0]; private string[] protectedTokens = new string[0]; private readonly HashSet<int> unknownCameraColliders = new HashSet<int>(); private const float DefaultShapeQueryInterval = 0.6f; private const float YoungTreeProbeHeight = 6f; private const float YoungTreeProbeRadiusMultiplier = 3f; private const float YoungTreeProbeMaxRadius = 4f; private const float OccluderExitPadding = 0.2f; private const float VegetationSideEnterThreshold = -0.25f; private const float VegetationSideExitThreshold = -0.8f; private const int MaxRendererProbesPerQuery = 0; private const int MaxMeshCacheEntries = 256; private const float VerboseStatusInterval = 15f; private const int MaxYoungTreeProbes = 96; private const float YoungTreeProbeRange = 48f; private static readonly string[] advancedHeightIgnoredObjectTokens = new string[19] { "chest", "table", "workbench", "portal", "bed", "forge", "station", "torch", "sconce", "lantern", "brazier", "fireplace", "hearth", "candle", "lamp", "lightfixture", "arandela", "chandelier", "candelabra" }; private MemberInfo gameCameraCameraMember; private FieldInfo gameCameraDistanceField; private FieldInfo gameCameraMinDistanceField; private FieldInfo gameCameraMaxDistanceField; private FieldInfo gameCameraMaxDistanceBoatField; private FieldInfo gameCameraZoomSensitivityField; private MethodInfo gameCameraGetOffsetedEyePosMethod; private bool gameCameraReflectionReady; private object firstPersonCameraInstance; private float savedThirdPersonDistance = 4f; private bool firstPersonDistanceApplied; private bool firstPersonScrollRequested; private int firstPersonScrollFrame = -1; private Camera firstPersonEffectsCamera; private Vector3 firstPersonSwayPreviousPosition; private bool firstPersonSwayPositionReady; private float firstPersonSwayPhase; private float firstPersonSwaySpeed; private float firstPersonCrouchOffset; private Quaternion firstPersonSwayRotation = Quaternion.identity; private int firstPersonEffectsFrame = -1; private Camera firstPersonFovCamera; private float firstPersonOriginalFov = 65f; private bool firstPersonFovApplied; private float cameraZoomMagnification = 1f; private float cameraZoomTargetMagnification = 1f; private bool cameraZoomActive; private bool cameraZoomWasHeld; private Vector2 cameraMouseDeltaSmoothed; private int cameraMouseDeltaSmoothFrame = -1; private int cameraZoomScrollFrame = -1; private int zoomInputFrame = -1; private bool zoomInputHeldCached; private Camera cameraZoomFovCamera; private float cameraZoomOriginalFov; private float cameraZoomAppliedFov; private int cameraZoomFovFrame = -1; private object cameraDistanceStateInstance; private float cameraDistanceSmoothed; private float cameraDistanceTarget; private bool cameraDistanceStateReady; private bool freeLookActive; private bool freeLookReturning; private float freeLookCharacterYaw; private float freeLookYaw; private float freeLookPitch; private int freeLookInputFrame = -1; private Quaternion freeLookInitialRotation = Quaternion.identity; private bool freeLookInitialTransformReady; private readonly RaycastHit[] advancedCameraHits = (RaycastHit[])(object)new RaycastHit[64]; private bool advancedCeilingActive; private bool advancedCeilingCheckValid; private float nextAdvancedCeilingCheckAt; private MemberInfo playerEyeMember; private bool cachedBoatState; private float nextBoatStateCheck; private MethodInfo zInputGetMouseScrollWheelMethod; private Func<float> zInputGetMouseScrollWheelDelegate; private bool zInputScrollLookupAttempted; private MethodInfo zInputGetMouseDeltaMethod; private Func<Vector2> zInputGetMouseDeltaDelegate; private bool zInputMouseDeltaLookupAttempted; private MethodInfo unityInputGetKeyMethod; private Func<KeyCode, bool> unityInputGetKeyDelegate; private bool unityInputGetKeyLookupAttempted; private MethodInfo zInputGetKeyMethod; private Func<KeyCode, bool> zInputGetKeyDelegate; private bool zInputGetKeyLookupAttempted; private float nextShapeQueryAt; private bool visualModeInitialized; private bool lastLeavesOnly; private bool lastCullHousePillars; private bool lastPreserveVegetationShadows; private float nextVerboseStatusAt; private int unknownCameraColliderLogCount; private int verboseHideTransitions; private int verboseRestoreTransitions; private float lastShapeQueryMs; private float peakShapeQueryMs; private long lastShapeQueryTicks; private long peakShapeQueryTicks; private float lastVolumeUpdateMs; private float peakVolumeUpdateMs; private long lastVolumeUpdateTicks; private long peakVolumeUpdateTicks; private long lastManagedMemoryBytes; private long peakManagedMemoryBytes; private long lastUnityAllocatedBytes; private long peakUnityAllocatedBytes; private long lastWorkingSetBytes; private float lastCpuPercent; private int lastProcessThreadCount; private long cpuSampleTimestamp; private TimeSpan cpuSampleProcessTime; private int lastGc0Collections; private int lastGc1Collections; private int lastGc2Collections; private float peakFrameMs; private int framesOver16Ms; private int framesOver33Ms; private int framesOver100Ms; private bool environmentReflectionReady; private FieldInfo currentEnvironmentField; private FieldInfo environmentNameField; private FieldInfo environmentAlwaysDarkField; private FieldInfo environmentDirectionalLightField; private FieldInfo environmentAmbientShaderIdField; private FieldInfo environmentSunFogColorField; private FieldInfo environmentSunFogShaderIdField; private MethodInfo environmentIsNightMethod; private MethodInfo environmentIsDayMethod; private static float CurrentShapeQueryInterval { get { if (Plugin.CylinderCheckInterval == null) { return 0.6f; } return Mathf.Clamp(Plugin.CylinderCheckInterval.Value, 0.05f, 2f); } } private static float CurrentCylinderRestoreDelay { get { if (Plugin.CylinderRestoreDelay == null) { return 0.6f; } return Mathf.Clamp(Plugin.CylinderRestoreDelay.Value, 0f, 2f); } } private static float CurrentMovementLeavesOnlyActivationDelay { get { if (Plugin.MovementLeavesOnlyActivationDelay == null) { return 0.5f; } return Mathf.Clamp(Plugin.MovementLeavesOnlyActivationDelay.Value, 0.1f, 5f); } } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; occlusionCylinderObject = new GameObject("ImmersiveCameraEnhancedOcclusionCylinder"); occlusionCylinderObject.transform.SetParent(((Component)this).transform, false); occlusionCylinderObject.layer = 2; occlusionCylinderCollider = occlusionCylinderObject.AddComponent<CapsuleCollider>(); occlusionCylinderCollider.direction = 1; ((Collider)occlusionCylinderCollider).isTrigger = true; ((Collider)occlusionCylinderCollider).enabled = false; occlusionCylinderSlices = (GameObject[])(object)new GameObject[8]; occlusionCylinderSliceColliders = (SphereCollider[])(object)new SphereCollider[8]; for (int i = 0; i < 8; i++) { GameObject val = new GameObject("ImmersiveCameraEnhancedOcclusionSlice" + i); val.transform.SetParent(occlusionCylinderObject.transform, false); val.layer = 2; SphereCollider val2 = val.AddComponent<SphereCollider>(); ((Collider)val2).isTrigger = true; ((Collider)val2).enabled = false; occlusionCylinderSlices[i] = val; occlusionCylinderSliceColliders[i] = val2; } Shader val3 = Shader.Find("Hidden/Internal-Colored"); if (Object.op_Implicit((Object)(object)val3)) { debugCylinderMaterial = new Material(val3) { hideFlags = (HideFlags)61 }; debugCylinderMaterial.SetInt("_ZWrite", 0); debugCylinderMaterial.SetInt("_ZTest", 8); debugCylinderMaterial.SetInt("_SrcBlend", 5); debugCylinderMaterial.SetInt("_DstBlend", 10); debugCylinderMaterial.SetInt("_Cull", 0); } } private void OnDestroy() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.sceneUnloaded -= OnSceneUnloaded; ResetWorldState(); if (Object.op_Implicit((Object)(object)occlusionCylinderObject)) { Object.Destroy((Object)(object)occlusionCylinderObject); } if (Object.op_Implicit((Object)(object)debugCylinderMaterial)) { Object.Destroy((Object)(object)debugCylinderMaterial); } occlusionCylinderCollider = null; occlusionCylinderObject = null; occlusionCylinderSlices = null; occlusionCylinderSliceColliders = null; debugCylinderMaterial = null; debugCylinderReady = false; } private void OnRenderObject() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.ModEnabled || !Plugin.ShowOcclusionCylinder.Value || !Object.op_Implicit((Object)(object)debugCylinderMaterial)) { return; } Camera current = Camera.current; if (IsGameplayCamera(current)) { debugCylinderMaterial.SetPass(0); GL.PushMatrix(); GL.Begin(1); float num = ((Plugin.CylinderDebugOpacity != null) ? Mathf.Clamp01(Plugin.CylinderDebugOpacity.Value) : 0.2f); GL.Color(new Color(0.1f, 1f, 0.25f, num)); if (debugCylinderReady && Object.op_Implicit((Object)(object)occlusionCylinderCollider) && ((Collider)occlusionCylinderCollider).enabled) { DrawDebugCone(debugCylinderStart, debugCylinderEnd, debugCylinderCameraT, debugCylinderCameraRadius, debugCylinderRearRadius, debugCylinderGrowthExponent, ((Component)current).transform.right); } GL.End(); GL.PopMatrix(); } } private static float RadiusAtNormalizedDistance(float t, float cameraT, float cameraRadius, float rearRadius, float growthExponent, float totalLength) { t = Mathf.Clamp01(t); cameraT = Mathf.Clamp(cameraT, 0.0001f, 0.9999f); float num = ((Plugin.CylinderExponentInfluencePercent != null) ? Mathf.Clamp01(Plugin.CylinderExponentInfluencePercent.Value / 100f) : 1f); float num2 = Mathf.Lerp(1f, Mathf.Max(1f, growthExponent), num); if (t <= cameraT) { float normalizedDistance = t / cameraT; normalizedDistance = QuantizeProfileDistance(normalizedDistance, totalLength * cameraT); return cameraRadius * Mathf.Pow(normalizedDistance, num2); } float normalizedDistance2 = (t - cameraT) / (1f - cameraT); normalizedDistance2 = QuantizeProfileDistance(normalizedDistance2, totalLength * (1f - cameraT)); return Mathf.Lerp(cameraRadius, rearRadius, Mathf.Pow(normalizedDistance2, num2)); } private static float QuantizeProfileDistance(float normalizedDistance, float segmentLength) { normalizedDistance = Mathf.Clamp01(normalizedDistance); if (normalizedDistance >= 0.9999f) { return 1f; } float num = ((Plugin.CylinderSlicesPerMeter != null) ? Mathf.Clamp(Plugin.CylinderSlicesPerMeter.Value, 0.5f, 12f) : 2f); int num2 = Mathf.Max(1, Mathf.CeilToInt(Mathf.Max(0.01f, segmentLength) * num)); return Mathf.Floor(normalizedDistance * (float)num2) / (float)num2; } private static void DrawDebugCone(Vector3 start, Vector3 end, float cameraT, float cameraRadius, float rearRadius, float growthExponent, Vector3 cameraRight) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_0019: 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_0020: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: 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) Vector3 val = end - start; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.01f) { return; } val /= magnitude; Vector3 val2 = Vector3.Cross(val, Vector3.up); if (((Vector3)(ref val2)).sqrMagnitude <= 0.001f) { val2 = Vector3.Cross(val, cameraRight); } ((Vector3)(ref val2)).Normalize(); Vector3 val3 = Vector3.Cross(val, val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; int num = Mathf.Clamp(Mathf.CeilToInt(magnitude * ((Plugin.CylinderSlicesPerMeter != null) ? Mathf.Clamp(Plugin.CylinderSlicesPerMeter.Value, 0.5f, 12f) : 2f)), 4, 96); float num2 = ((Plugin.CylinderSlicesPerMeter != null) ? Mathf.Clamp(Plugin.CylinderSlicesPerMeter.Value, 0.5f, 12f) : 2f); int num3 = Mathf.Clamp(Mathf.CeilToInt(magnitude * num2), 8, 64); for (int i = 0; i < num; i++) { float num4 = (float)i / (float)num; float num5 = (float)(i + 1) / (float)num; Vector3 val4 = start + val * (magnitude * num4); Vector3 val5 = start + val * (magnitude * num5); float num6 = RadiusAtNormalizedDistance(num4, cameraT, cameraRadius, rearRadius, growthExponent, magnitude); float num7 = RadiusAtNormalizedDistance(num5, cameraT, cameraRadius, rearRadius, growthExponent, magnitude); for (int j = 0; j < num3; j++) { float num8 = MathF.PI * 2f * (float)j / (float)num3; float num9 = MathF.PI * 2f * (float)(j + 1) / (float)num3; Vector3 val6 = val2 * Mathf.Cos(num8) + normalized * Mathf.Sin(num8); Vector3 val7 = val2 * Mathf.Cos(num9) + normalized * Mathf.Sin(num9); GL.Vertex(val4 + FlattenDebugOffset(val6 * num6, num6, val)); GL.Vertex(val4 + FlattenDebugOffset(val7 * num6, num6, val)); GL.Vertex(val4 + FlattenDebugOffset(val6 * num6, num6, val)); GL.Vertex(val5 + FlattenDebugOffset(val6 * num7, num7, val)); } } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { RestoreFirstPersonCamera(); ResetWorldState(); cachedCamera = null; gameCameraReflectionReady = false; gameCameraCameraMember = null; gameCameraDistanceField = null; gameCameraMinDistanceField = null; gameCameraMaxDistanceField = null; gameCameraMaxDistanceBoatField = null; gameCameraZoomSensitivityField = null; gameCameraGetOffsetedEyePosMethod = null; firstPersonCameraInstance = null; firstPersonDistanceApplied = false; firstPersonScrollRequested = false; firstPersonScrollFrame = -1; cachedBoatState = false; nextBoatStateCheck = 0f; } private void OnSceneUnloaded(Scene scene) { ResetWorldState(); cachedCamera = null; } private void Update() { try { if (!Plugin.ModEnabled) { if (!modResetApplied) { ResetWorldState(); modResetApplied = true; } return; } modResetApplied = false; RecordFramePerformance(); if (!TryGetLocalPlayer(out var player)) { ResetWorldState(); return; } ApplyLiveFirstPersonSettings(); if (IsPauseMenuVisible()) { ClearShapeOccluders(); return; } Camera gameplayCamera = GetGameplayCamera(); if (!Object.op_Implicit((Object)(object)gameplayCamera)) { ResetWorldState(); return; } if (firstPersonDistanceApplied) { ClearShapeOccluders(); return; } UpdateMovementLeavesOnly(player, gameplayCamera); SyncVisualModeState(); UpdateCameraOcclusionVolumesTimed(gameplayCamera, player); } catch (Exception exception) { Plugin.Report(exception); } } private void SyncVisualModeState() { bool flag = UsesLeavesOnly(); bool flag2 = ShouldCullHousePillars(); bool flag3 = Plugin.PreserveVegetationShadows != null && Plugin.PreserveVegetationShadows.Value; if (!visualModeInitialized) { visualModeInitialized = true; lastLeavesOnly = flag; lastCullHousePillars = flag2; lastPreserveVegetationShadows = flag3; } else if (flag != lastLeavesOnly || flag2 != lastCullHousePillars || flag3 != lastPreserveVegetationShadows) { if (flag != lastLeavesOnly || flag3 != lastPreserveVegetationShadows) { ReapplyShapeOcclusionMode(); } lastLeavesOnly = flag; lastCullHousePillars = flag2; lastPreserveVegetationShadows = flag3; nextShapeQueryAt = 0f; } } private IEnumerator DiscoverRenderers() { yield return null; if (!Plugin.ModEnabled || !TryGetLocalPlayer(out var player) || IsPauseMenuVisible()) { scanRoutine = null; yield break; } Renderer[] found; try { found = Object.FindObjectsByType<Renderer>((FindObjectsSortMode)0); } catch (Exception exception) { Plugin.Report(exception); scanRoutine = null; yield break; } List<Renderer> vegetation = new List<Renderer>(); List<Renderer> housePillars = new List<Renderer>(); for (int i = 0; i < found.Length; i++) { if ((i & 0xFF) == 0) { yield return null; } Renderer val = found[i]; if (IsVegetationRenderer(val) && (!IsSmallVegetation(val) || IsYoungTreeRenderer(val)) && IsSafeCameraOccluder(val, player)) { vegetation.Add(val); } else if (IsHousePillarRenderer(val) && IsSafeCameraOccluder(val, player)) { housePillars.Add(val); } } vegetationRenderers = vegetation.ToArray(); housePillarRenderers = housePillars.ToArray(); colliderRendererCache.Clear(); treeRendererCache.Clear(); vegetationRootCache.Clear(); mobRendererClassification.Clear(); hierarchyNameCache.Clear(); RebuildYoungTreeProbes(vegetationRenderers, player); vegetationClassification.Clear(); smallVegetationClassification.Clear(); vegetationSpatialGrid.Clear(); for (int j = 0; j < vegetationRenderers.Length; j++) { Renderer val2 = vegetationRenderers[j]; if (Object.op_Implicit((Object)(object)val2)) { vegetationClassification[val2] = true; IndexVegetationRenderer(val2); } } scanRoutine = null; } private void UpdateCameraOcclusionVolumes(Camera camera, Transform player) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) HashSet<Renderer> hashSet = nextShapeOccluders; hashSet.Clear(); mainVolumeReady = false; if (!Plugin.EnableCylinderOcclusion.Value || !Object.op_Implicit((Object)(object)camera) || !Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)occlusionCylinderCollider)) { if (Object.op_Implicit((Object)(object)occlusionCylinderCollider)) { ((Collider)occlusionCylinderCollider).enabled = false; } DisableCylinderSlices(); shapeColliders.Clear(); debugCylinderReady = false; ClearShapeOccluders(); return; } Vector3 position = ((Component)camera).transform.position; Vector3 val = (mainVolumeCharacterCenter = GetPlayerCenter(player)); Vector3 val2 = position - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.1f) { ((Collider)occlusionCylinderCollider).enabled = false; DisableCylinderSlices(); shapeColliders.Clear(); debugCylinderReady = false; ClearShapeOccluders(); return; } Vector3 val3 = val2 / magnitude; float num = Mathf.Clamp(Plugin.ConeCharacterDistance.Value, 0f, 5f); Vector3 val4 = val + val3 * num; Vector3 val5 = position - val4; float magnitude2 = ((Vector3)(ref val5)).magnitude; if (magnitude2 <= 0.1f) { ((Collider)occlusionCylinderCollider).enabled = false; DisableCylinderSlices(); shapeColliders.Clear(); debugCylinderReady = false; ClearShapeOccluders(); return; } val3 = val5 / magnitude2; float num2 = Mathf.Clamp(Plugin.BackCylinderLength.Value, 0.5f, 30f); Vector3 val6 = position + val3 * num2; Vector3 val7 = val6 - val4; float magnitude3 = ((Vector3)(ref val7)).magnitude; if (magnitude3 <= 0.1f) { ((Collider)occlusionCylinderCollider).enabled = false; DisableCylinderSlices(); shapeColliders.Clear(); debugCylinderReady = false; ClearShapeOccluders(); return; } float screenPercent = Mathf.Clamp(Plugin.CylinderCameraWidthPercent.Value, 0f, 100f); float num3 = GetWorldScreenWidth(camera, magnitude2, screenPercent) * 0.5f; num3 = Mathf.Clamp(num3, 0.01f, 8f); float num4 = Mathf.Clamp(Plugin.ConeRearRadiusMultiplier.Value, 1f, 4f); float num5 = Mathf.Clamp(num3 * num4, num3, 16f); float growthExponent = Mathf.Clamp(Plugin.ConeGrowthExponent.Value, 1f, 6f); float cameraT = Mathf.Clamp01(magnitude2 / magnitude3); Vector3 position2 = val4 + val7 * 0.5f; occlusionCylinderObject.transform.position = position2; occlusionCylinderObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, ((Vector3)(ref val7)).normalized); occlusionCylinderCollider.center = Vector3.zero; occlusionCylinderCollider.radius = Mathf.Max(0.01f, num5); occlusionCylinderCollider.height = magnitude3 + 0.02f; ((Collider)occlusionCylinderCollider).enabled = true; UpdateCylinderSlices(val4, val6, magnitude3, cameraT, num3, num5, growthExponent); debugCylinderStart = val4; debugCylinderEnd = val6; debugCylinderCameraT = cameraT; debugCylinderCameraRadius = num3; debugCylinderRearRadius = num5; debugCylinderGrowthExponent = growthExponent; debugCylinderReady = true; mainVolumeStart = val4; mainVolumeEnd = val6; mainVolumeCameraT = cameraT; mainVolumeCameraRadius = num3; mainVolumeRearRadius = num5; mainVolumeGrowthExponent = growthExponent; mainVolumeReady = true; if (Time.unscaledTime < nextShapeQueryAt) { return; } nextShapeQueryAt = Time.unscaledTime + CurrentShapeQueryInterval; bool flag = Plugin.DebugLogging != null && Plugin.DebugLogging.Value; float num6 = (flag ? Time.realtimeSinceStartup : 0f); long num7 = (flag ? Stopwatch.GetTimestamp() : 0); shapeColliders.Clear(); spatialQueryCandidates.Clear(); CollectVolumeColliders(shapeColliders); foreach (Collider shapeCollider in shapeColliders) { AddColliderRenderers(shapeCollider, player, hashSet); } ReplaceShapeOccluders(hashSet); if (flag) { long elapsedTicks = Stopwatch.GetTimestamp() - num7; RecordShapeQueryMetrics((Time.realtimeSinceStartup - num6) * 1000f, elapsedTicks); } EmitVerboseStatus(camera); } private void UpdateCameraOcclusionVolumesTimed(Camera camera, Transform player) { int num; float num2; if (Plugin.DebugLogging != null) { num = (Plugin.DebugLogging.Value ? 1 : 0); if (num != 0) { num2 = Time.realtimeSinceStartup; goto IL_0023; } } else { num = 0; } num2 = 0f; goto IL_0023; IL_0023: float num3 = num2; long num4 = ((num != 0) ? Stopwatch.GetTimestamp() : 0); UpdateCameraOcclusionVolumes(camera, player); if (num != 0) { lastVolumeUpdateMs = Mathf.Max(0f, (Time.realtimeSinceStartup - num3) * 1000f); lastVolumeUpdateTicks = Math.Max(0L, Stopwatch.GetTimestamp() - num4); peakVolumeUpdateMs = Mathf.Max(peakVolumeUpdateMs, lastVolumeUpdateMs); peakVolumeUpdateTicks = Math.Max(peakVolumeUpdateTicks, lastVolumeUpdateTicks); } } private void UpdateCylinderSlices(Vector3 start, Vector3 end, float length, float cameraT, float cameraRadius, float rearRadius, float growthExponent) { //IL_0041: 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_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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0094: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) if (occlusionCylinderSlices == null || occlusionCylinderSliceColliders == null || !Object.op_Implicit((Object)(object)occlusionCylinderObject)) { return; } if (Plugin.ShowOcclusionCylinder == null || !Plugin.ShowOcclusionCylinder.Value) { DisableCylinderSlices(); return; } int num = occlusionCylinderSliceColliders.Length; Vector3 val = end - start; Vector3 val2 = ((length > 0.001f) ? (val / length) : Vector3.up); Vector3 position = start + val * 0.5f; occlusionCylinderObject.transform.position = position; occlusionCylinderObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, val2); for (int i = 0; i < num; i++) { float num2 = ((num <= 1) ? 0f : ((float)i / (float)(num - 1))); float num3 = (num2 - 0.5f) * length; float num4 = RadiusAtNormalizedDistance(num2, cameraT, cameraRadius, rearRadius, growthExponent, length); GameObject val3 = occlusionCylinderSlices[i]; SphereCollider val4 = occlusionCylinderSliceColliders[i]; if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val4)) { val3.transform.localPosition = new Vector3(0f, num3, 0f); val3.transform.localRotation = Quaternion.identity; val4.center = Vector3.zero; val4.radius = Mathf.Max(0.01f, num4); ((Collider)val4).enabled = true; } } } private void DisableCylinderSlices() { if (occlusionCylinderSliceColliders == null) { return; } for (int i = 0; i < occlusionCylinderSliceColliders.Length; i++) { if (Object.op_Implicit((Object)(object)occlusionCylinderSliceColliders[i])) { ((Collider)occlusionCylinderSliceColliders[i]).enabled = false; } } } private static float GetWorldScreenWidth(Camera camera, float distance, float screenPercent) { if (!Object.op_Implicit((Object)(object)camera) || distance <= 0f || screenPercent <= 0f) { return 0f; } float num = ((camera.aspect > 0.01f) ? camera.aspect : 1.7777778f); float num2 = camera.fieldOfView * (MathF.PI / 180f); float num3 = 2f * Mathf.Atan(Mathf.Tan(num2 * 0.5f) * num); return 2f * distance * Mathf.Tan(num3 * 0.5f) * (screenPercent / 100f); } private void CollectVolumeColliders(HashSet<Collider> result) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (result == null || !mainVolumeReady) { return; } float num = Mathf.Max(0.01f, mainVolumeRearRadius); int num2 = Physics.OverlapCapsuleNonAlloc(mainVolumeStart, mainVolumeEnd, num, shapeColliderBuffer, Plugin.CameraCollisionMask.Value, (QueryTriggerInteraction)1); Collider val = (Object.op_Implicit((Object)(object)occlusionCylinderObject) ? occlusionCylinderObject.GetComponent<Collider>() : null); for (int i = 0; i < num2; i++) { Collider val2 = shapeColliderBuffer[i]; if (!Object.op_Implicit((Object)(object)val2) || (Object)(object)val2 == (Object)(object)val || (Object.op_Implicit((Object)(object)occlusionCylinderObject) && ((Component)val2).transform.IsChildOf(occlusionCylinderObject.transform))) { continue; } bool flag = IsVegetationCollider(val2); bool flag2 = false; if (!flag) { if (!ShouldCullHousePillars()) { continue; } flag2 = IsHousePillarCollider(val2); if (!flag2) { continue; } }