Decompiled source of WiresShadows v0.1.8

WiresShadows.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WiresShadows")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c6660f19b2435ffc628dc1d4d779ea2fd044cf44")]
[assembly: AssemblyProduct("WiresShadows")]
[assembly: AssemblyTitle("WiresShadows")]
[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 WiresShadows
{
	internal static class AmbientOcclusion
	{
		[HarmonyPatch(typeof(AmplifyOcclusionEffect), "OnEnable")]
		private static class OnAmplify
		{
			private static void Postfix()
			{
				Apply();
			}
		}

		internal static Shader BounceShader;

		private static Shader s_vanillaApply;

		private static readonly FieldInfo ApplyMat = AccessTools.Field(typeof(AmplifyOcclusionEffect), "m_applyOcclusionMat");

		internal static void Apply()
		{
			Material val = (Material)((ApplyMat != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)BounceShader == (Object)null) && BounceShader.isSupported)
			{
				if ((Object)(object)s_vanillaApply == (Object)null && (Object)(object)val.shader != (Object)(object)BounceShader)
				{
					s_vanillaApply = val.shader;
				}
				Shader val2 = ((Plugin.UseShader.Value || (Object)(object)s_vanillaApply == (Object)null) ? BounceShader : s_vanillaApply);
				if ((Object)(object)val.shader != (Object)(object)val2)
				{
					val.shader = val2;
				}
			}
		}
	}
	internal sealed class ShadowCache : MonoBehaviour
	{
		private struct AreaState
		{
			internal bool Ready;

			internal float At;
		}

		private sealed class Machine
		{
			internal Component Owner;

			internal Smelter Smelter;

			internal Windmill Windmill;

			internal Transform Turret;

			internal Quaternion LastTurn;

			internal Renderer[] Renderers;

			internal Vector3 Center;

			internal float Radius;

			internal bool Active;

			internal float Until;

			internal int StillHash;

			internal Caster[] RestGeometry;

			internal int RestVisibility;
		}

		private sealed class Tracked
		{
			internal Light Light;

			internal LightLod Lod;

			internal float NativeCacheRange = 1f;

			internal bool StagedNativeReady;

			internal Vector3 PublishedCenterBeforeStage;

			internal int Slot = -1;

			internal Tracked PromotionTo;

			internal Tracked PromotionFrom;

			internal float Reach;

			internal float Priority;

			internal bool Tiny;

			internal bool Item;

			internal ItemStand Stand;

			internal float LitAt = -10f;

			internal bool Instant;

			internal int ReleasedFrame = -1;

			internal Rigidbody Body;

			internal bool Rolling;

			internal bool Staged;

			internal readonly List<Renderer> Explicit = new List<Renderer>();

			internal readonly List<Renderer> Sheets = new List<Renderer>();

			internal readonly List<Mesh> ProxyMeshes = new List<Mesh>();

			internal readonly List<Matrix4x4> ProxyMatrices = new List<Matrix4x4>();

			internal int NearProxies;

			internal readonly List<int> ExplicitSub = new List<int>();

			internal Vector3 Center;

			internal bool Dirty;

			internal float DirtyAt;

			internal int Face = -1;

			internal int DoorFaces;

			internal bool DoorPrepared;

			internal readonly List<Transform> AddedRoots = new List<Transform>();

			internal bool ProxiesStale;

			internal bool Urgent;

			internal bool Ready;

			internal float Fade;

			internal readonly List<Renderer> Hide = new List<Renderer>();

			internal readonly List<Renderer> Show = new List<Renderer>();

			internal LightShadows OriginalShadows;

			internal bool OriginalShadowLod;

			internal bool Suppressed;

			internal bool Sconce;

			internal bool FakeFlame;

			internal float OriginalShadowStrength;

			internal float OriginalShadowNearPlane;

			internal Vector3 RootPos;

			internal Quaternion RootRot;

			internal int WantTier;

			internal int RenderTier;

			internal int RenderCube = -1;

			internal float RenderRange;

			internal float WaitSince = -1f;

			internal float WaitUntil;

			internal readonly List<Animator> Animators = new List<Animator>();

			internal readonly List<AnimatorCullingMode> AnimatorModes = new List<AnimatorCullingMode>();
		}

		private sealed class Swing
		{
			internal Door Door;

			internal Animator Animator;

			internal Renderer[] Renderers;

			internal Vector3 Center;

			internal float Radius;

			internal float Until;

			internal bool Ending;
		}

		private sealed class DropCaster
		{
			internal ItemDrop Item;

			internal Rigidbody Body;

			internal Renderer[] Renderers;

			internal Vector3 StaticPosition;

			internal Quaternion StaticRotation;

			internal Vector3 CurrentPosition;

			internal Quaternion CurrentRotation;

			internal float LastMotion;

			internal bool Stable;

			internal bool CanCacheGeometry;

			internal Caster[] CachedGeometry;

			internal Vector3 GeometryPosition;

			internal Vector3 GeometryScale;

			internal Quaternion GeometryRotation;

			internal int GeometryHash;

			internal int GeometryVisibility;

			internal bool Mounted;

			internal bool Placed;

			internal Vector3 PlacedCenter;

			internal float PlacedRadius;
		}

		private sealed class StandCaster
		{
			internal ItemStand Stand;

			internal Renderer[] Renderers;

			internal Caster[] Geometry;

			internal Vector3 Center;

			internal float Radius;

			internal int Version;

			internal bool Handoff;

			internal int ChangedFrame;
		}

		private struct ParticleCaster
		{
			internal ParticleSystemRenderer R;

			internal ParticleSystem Ps;

			internal Material Sheet;
		}

		private struct Caster
		{
			internal Renderer R;

			internal Bounds B;

			internal int Subs;

			internal float Radius;

			internal Material Sheet;

			internal int Faces(Vector3 lp)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				return FacesFor(((Bounds)(ref B)).center - lp, Radius);
			}
		}

		private sealed class Group
		{
			internal Vector3 Center;

			internal float Radius;

			internal int Hash;

			internal bool Character;

			internal bool Volatile;

			internal int Kind;

			internal Object Owner;

			internal int Start;

			internal int Count;
		}

		private const float AreaRecheck = 0.25f;

		private const float AreaGiveUp = 15f;

		private static readonly Dictionary<Vector2s, AreaState> Areas = new Dictionary<Vector2s, AreaState>();

		private static readonly List<ZDO> AreaObjects = new List<ZDO>();

		private static readonly Func<ZNetScene, ZDO, bool> PrefabValid = AccessTools.MethodDelegate<Func<ZNetScene, ZDO, bool>>(AccessTools.Method(typeof(ZNetScene), "IsPrefabZDOValid", (Type[])null, (Type[])null), (object)null, true);

		private const float VanillaShadowDistance = 20f;

		private static readonly List<int> BudgetOrder = new List<int>(32);

		private static Vector3 s_budgetCam;

		private static Tracked[] s_budgetSlots;

		private static readonly Comparison<int> BudgetNearer = delegate(int a, int b)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = s_budgetSlots[a].Center - s_budgetCam;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			val = s_budgetSlots[b].Center - s_budgetCam;
			return sqrMagnitude.CompareTo(((Vector3)(ref val)).sqrMagnitude);
		};

		private static readonly List<Machine> Machines = new List<Machine>();

		private static readonly Dictionary<Smelter, Machine> MachineBySmelter = new Dictionary<Smelter, Machine>();

		private static readonly HashSet<Renderer> MachineHidden = new HashSet<Renderer>();

		private const float MachineSettle = 2.5f;

		private static readonly FieldRef<Windmill, Transform> Propeller = AccessTools.FieldRefAccess<Windmill, Transform>("m_propeller");

		private static readonly FieldRef<Windmill, Transform> Bom = AccessTools.FieldRefAccess<Windmill, Transform>("m_bom");

		private static readonly FieldInfo GrindstoneField = AccessTools.Field(typeof(Windmill), "m_grindstone");

		private static bool s_machine;

		internal static Shader FrontBackShader;

		private readonly RenderTexture[] _tierRG = (RenderTexture[])(object)new RenderTexture[4];

		private readonly RenderTexture[] _tierFlatRG = (RenderTexture[])(object)new RenderTexture[4];

		private Material _frontBackMat;

		private static readonly int FrontBackId = Shader.PropertyToID("_WireFrontBack");

		internal static ShadowCache Instance;

		internal static Shader DistanceShader;

		private static readonly List<Tracked> Lights = new List<Tracked>();

		private static readonly Dictionary<Light, Tracked> ByLight = new Dictionary<Light, Tracked>();

		private static readonly FieldRef<LightLod, bool> ShadowLod = AccessTools.FieldRefAccess<LightLod, bool>("m_shadowLod");

		private static readonly int LightsId = Shader.PropertyToID("_WireShadowLights");

		private static readonly int CountId = Shader.PropertyToID("_WireShadowCount");

		private static readonly int CenterId = Shader.PropertyToID("_WireLightCenter");

		private const int NearMax = 32;

		private const int FarMax = 64;

		private const int MaxSlots = 96;

		private const float SettleSeconds = 0.15f;

		private const float UrgentMargin = 12f;

		private const float MovedDistance = 0.25f;

		private const int LoadingFacesPerFrame = 6;

		private const float KeepMargin = 15f;

		private const float SwapMargin = 10f;

		private const float NearSwapMargin = 2.5f;

		private RenderTexture _dynMaps;

		private readonly float[] _dynActive = new float[96];

		private RenderTexture _farDynMaps;

		private static readonly int FarDynMapsId = Shader.PropertyToID("_WireFarDynMaps");

		private const int NativeDepthBits = 16;

		private int _dynNearCapacity;

		private int _dynFarCapacity;

		private readonly int[] _dynPhysical = new int[96];

		private readonly int[] _dynNearOwners = new int[32];

		private readonly int[] _dynFarOwners = new int[64];

		private readonly float[] _dynPhysicalUniform = new float[96];

		private static readonly int DynPhysicalId = Shader.PropertyToID("_WireDynPhysicalSlot");

		private bool _dynPhysicalDirty;

		private readonly List<int> _movingDenied = new List<int>(8);

		private static Vector3 s_sortCam;

		private static Tracked[] s_sortSlots;

		private static readonly Comparison<int> NearerFirst = delegate(int a, int b)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = s_sortSlots[a].Center - s_sortCam;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			val = s_sortSlots[b].Center - s_sortCam;
			return sqrMagnitude.CompareTo(((Vector3)(ref val)).sqrMagnitude);
		};

		private readonly float[] _farMovingDist = new float[96];

		private readonly int[] _dynFacesLast = new int[96];

		private readonly RectInt[] _dynRect = (RectInt[])(object)new RectInt[576];

		private readonly RectInt[] _nativeMovingTouched = (RectInt[])(object)new RectInt[576];

		private static readonly int DynMapsId = Shader.PropertyToID("_WireDynMaps");

		private static readonly int DynActiveId = Shader.PropertyToID("_WireDynActive");

		private bool _active;

		private Tracked[] _slots = new Tracked[0];

		private readonly Vector4[] _slotData = (Vector4[])(object)new Vector4[96];

		private Material _combine;

		private CommandBuffer _staticCb;

		private const float ClothPush = 0.15f;

		private static readonly Dictionary<Renderer, bool> ClothRenderers = new Dictionary<Renderer, bool>();

		private static readonly List<Material> ClothMats = new List<Material>();

		private static readonly Dictionary<(Material, Shader, bool), Material> ClipMaterials = new Dictionary<(Material, Shader, bool), Material>();

		private static MaterialPropertyBlock _proxyProps;

		private static MaterialPropertyBlock _structProps;

		private static readonly int NearCutId = Shader.PropertyToID("_WireNearCut");

		internal static Shader CombineShader;

		internal static Shader NativeCopyShader;

		private CommandBuffer _nativeCopyCb;

		private readonly float[] _nativeActive = new float[96];

		private readonly float[] _nativeInvRanges = new float[96];

		private RenderTexture _nativeMovingNear;

		private RenderTexture _nativeMovingFar;

		private RenderTexture _nativeMovingFlat;

		private Material _nativeMovingCopyMat;

		private readonly float[] _nativeMovingActive = new float[96];

		private readonly float[] _nativeMovingInvRanges = new float[96];

		private bool _nativeMovingFailed;

		private static readonly int NativeMovingNearId = Shader.PropertyToID("_WireNativeMovingNearMaps");

		private static readonly int NativeMovingFarId = Shader.PropertyToID("_WireNativeMovingFarMaps");

		private static readonly int NativeMovingSourceId = Shader.PropertyToID("_WireNativeMovingSource");

		private static readonly int NativeMovingActiveId = Shader.PropertyToID("_WireNativeMovingActive");

		private static readonly int NativeMovingRangesId = Shader.PropertyToID("_WireNativeMovingInvRanges");

		private static bool? _supportsShadowmap;

		private readonly float[] _uploadedDynActive = new float[96];

		private readonly float[] _uploadedNativeMovingActive = new float[96];

		private readonly float[] _uploadedNativeMovingRanges = new float[96];

		private bool _hasUploadedDynActive;

		private bool _hasUploadedNativeMovingActive;

		private bool _hasUploadedNativeMovingRanges;

		private static readonly int DynFaceMaskId = Shader.PropertyToID("_WireDynFaceMask");

		private readonly float[] _dynFaceMask = new float[96];

		private readonly float[] _uploadedDynFaceMask = new float[96];

		private bool _hasUploadedDynFaceMask;

		private static readonly int NativeInvRangeId = Shader.PropertyToID("_WireNativeInvRange");

		private static readonly int NativeActiveId = Shader.PropertyToID("_WireNativeActive");

		private static readonly int NativeRangesId = Shader.PropertyToID("_WireNativeInvRanges");

		private int _farResolution;

		private static readonly int NearCountId = Shader.PropertyToID("_WireNearCount");

		private Camera _camera;

		private int _resolution;

		private bool _rendering;

		private int _ultra;

		private int _near;

		private static readonly List<Light> PieceLights = new List<Light>();

		private static readonly List<Light> GoneLights = new List<Light>();

		private static readonly FieldRef<LightLod, float> LodBaseRange = AccessTools.FieldRefAccess<LightLod, float>("m_baseRange");

		private static readonly List<Swing> Swings = new List<Swing>();

		private static readonly HashSet<Renderer> SwingHidden = new HashSet<Renderer>();

		private const float SwingSeconds = 0.4f;

		private static readonly FieldRef<Player, GameObject> PlacementGhost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		private GameObject _ghost;

		private Renderer[] _ghostRenderers = (Renderer[])(object)new Renderer[0];

		private Vector3 _ghostLocalCenter;

		private Vector3 _ghostCenter;

		private float _ghostRadius;

		private int _ghostHash;

		private bool _ghostActive;

		private const float ItemRadius = 0.8f;

		private static readonly Dictionary<ItemDrop, DropCaster> Drops = new Dictionary<ItemDrop, DropCaster>();

		private static readonly HashSet<Renderer> DropVisuals = new HashSet<Renderer>();

		private static readonly List<DropCaster> PlacedDrops = new List<DropCaster>();

		private static readonly List<ItemDrop> LostDrops = new List<ItemDrop>();

		private static int _dropChangedFrame = -100;

		private readonly int[] _pickupInvalidFaces = new int[96];

		internal static readonly List<ItemDrop> Items = new List<ItemDrop>();

		internal static readonly List<ItemDrop> Resting = new List<ItemDrop>();

		private static readonly List<StandCaster> Stands = new List<StandCaster>();

		private static readonly List<StandCaster> PendingStands = new List<StandCaster>();

		private static readonly HashSet<Renderer> StandVisuals = new HashSet<Renderer>();

		private static int _standChangedFrame = -100;

		private static readonly HashSet<Piece> Ghosts = new HashSet<Piece>();

		private static Transform s_placed;

		private static bool s_broken;

		private static readonly List<Renderer> Effects = new List<Renderer>(128);

		private static readonly List<Renderer> EffectScratch = new List<Renderer>(16);

		private static readonly List<ParticleCaster> Particles = new List<ParticleCaster>(64);

		private static readonly Dictionary<Material, Material> Sheets = new Dictionary<Material, Material>();

		private static readonly int SheetCutId = Shader.PropertyToID("_WireSheetCut");

		private static int s_sheetPass = -2;

		private static int s_sheetGsPass = -2;

		private static readonly List<Renderer> ChangedPieceRenderers = new List<Renderer>(16);

		private static readonly List<Character> GoneCharacterScratch = new List<Character>(16);

		private const float VramShare = 0.2f;

		private int _nearMovingCap = 32;

		private int _farMovingCap = 8;

		private int _fitKey = int.MinValue;

		private int _fitRes;

		private int _fitSlots;

		private int _fitNearMoving;

		private int _fitFarMoving;

		private RenderTexture _movScratch;

		private int _movRes;

		private static bool s_unsupportedLogged;

		private bool _batchingReassign;

		private const float OffscreenWeight = 3f;

		private const float ScreenWeight = 4f;

		private const float TinyRank = 1000f;

		private const float ItemSettle = 0.3f;

		private const float TurnDot = 0.9f;

		private static readonly Plane[] ReassignFrustum = (Plane[])(object)new Plane[6];

		private Vector3 _lastForward;

		private float _nextTurnReassign;

		private Vector3 _lastReassignEye;

		private const float MovedReassign = 2f;

		private const int MaxPromotions = 3;

		private readonly Vector4[] _lightNow = (Vector4[])(object)new Vector4[96];

		private static readonly int LightNowId = Shader.PropertyToID("_WireLightNow");

		private static readonly List<int> DynCandidates = new List<int>();

		private static readonly int[] DynFaces = new int[96];

		private static readonly int[] DynDraw = new int[96];

		private static readonly int[] DynFaceHash = new int[576];

		private static readonly int[] DynFaceLp = new int[576];

		private readonly int[] _faceLp = new int[576];

		private static readonly int[] FaceHashNow = new int[6];

		private static readonly int[] StableHashNow = new int[6];

		private static readonly int[] DynFaceStable = new int[576];

		private readonly int[] _faceStable = new int[576];

		private static readonly int[] DynPartial = new int[96];

		private readonly RectInt[] _dynVolRect = (RectInt[])(object)new RectInt[576];

		private readonly int[] _faceHash = new int[576];

		private static readonly Vector3[] DynOrigin = (Vector3[])(object)new Vector3[96];

		private static readonly Vector3[] FaceForward = (Vector3[])(object)new Vector3[6]
		{
			Vector3.right,
			Vector3.left,
			Vector3.up,
			Vector3.down,
			Vector3.forward,
			Vector3.back
		};

		private static readonly Vector3[] FaceUp = (Vector3[])(object)new Vector3[6]
		{
			Vector3.down,
			Vector3.down,
			Vector3.forward,
			Vector3.back,
			Vector3.down,
			Vector3.down
		};

		private static readonly Matrix4x4[] FaceViewBasis = BuildFaceViews();

		private CommandBuffer _frameCb;

		private bool _framePending;

		private bool _benchmarkSkipMovingGpu;

		private static bool s_benchVanillaShadows;

		private static readonly Color Empty = new Color(60000f, 0f, 0f, 0f);

		private Material _distMaterial;

		private static readonly Dictionary<Character, Renderer[]> CharacterRenderers = new Dictionary<Character, Renderer[]>();

		private static int s_gsPass = -2;

		private static readonly Matrix4x4[] GsVP = (Matrix4x4[])(object)new Matrix4x4[6];

		private static readonly Dictionary<int, int> GsMask = new Dictionary<int, int>();

		private static readonly List<int> GsOrder = new List<int>();

		private static readonly int FaceVPId = Shader.PropertyToID("_WireFaceVP");

		private static readonly int FaceMaskId = Shader.PropertyToID("_WireFaceMask");

		private static readonly int SliceBaseId = Shader.PropertyToID("_WireSliceBase");

		private static readonly List<int> FaceRenderers = new List<int>();

		private static readonly List<RectInt> FaceRects = new List<RectInt>();

		private const int VolatileBit = 64;

		private readonly List<int>[] _groupsBySlot = new List<int>[96];

		private static readonly List<int> LightCasters = new List<int>();

		private static readonly List<int> LightCasterFaces = new List<int>();

		internal const int KindCharacter = 1;

		internal const int KindSwing = 2;

		internal const int KindMachine = 4;

		internal const int KindDrop = 8;

		internal const int KindGhost = 16;

		internal const int KindStand = 32;

		private static readonly int[] FaceKindsNow = new int[6];

		private static readonly int[] DynFaceKinds = new int[576];

		private static readonly int[] DynFaceReasons = new int[576];

		private static readonly List<Caster> Casters = new List<Caster>();

		private static readonly List<Group> Groups = new List<Group>();

		private static int _groupCount;

		private static bool _benchSampling;

		private static long _benchGatherTicks;

		private static long _benchHashTicks;

		private static int _benchSamples;

		private static int _benchGroups;

		private static int _benchCandidates;

		private static int _benchFaces;

		private static int _benchCharacterFaces;

		private static int _benchSwingFaces;

		private static int _benchMachineFaces;

		private static int _benchDropFaces;

		private static int _benchGhostFaces;

		private static int _benchStandFaces;

		private static int _benchChangedHashFaces;

		private static int _benchNewFaces;

		private static int _benchMovingLightFaces;

		private static int _benchPickupFaces;

		private static int _benchCoarseExtraFaceLinks;

		private static int _benchPreciseAddedFaceLinks;

		private static int _benchPartialFaces;

		private static int _benchFullFaces;

		private static int _benchDraws;

		private const int MovingGridWidth = 16;

		private const float MovingGridSize = 24f;

		private const float MovingGridHalf = 192f;

		private static readonly List<int>[] MovingGrid = new List<int>[256];

		private static readonly List<int> MovingGridTouched = new List<int>(64);

		private static readonly List<int> MovingGridOverflow = new List<int>(16);

		private static readonly List<int> MovingGridQuery = new List<int>(128);

		private static float MovingGridX;

		private static float MovingGridZ;

		private static float MovingGridMaxRadius;

		private static readonly Dictionary<Renderer, int> SubCounts = new Dictionary<Renderer, int>();

		private const float DimEdge = 1f;

		private static readonly List<Renderer[]> Fragments = new List<Renderer[]>(32);

		private static readonly int EffectLayer = LayerMask.NameToLayer("effect");

		private static readonly List<Vector4> GatherLights = new List<Vector4>(64);

		private static float _arrivalStreamUntil = -10f;

		private static float _fillUntil = -10f;

		private const float FillSeconds = 8f;

		private const int FillFacesPerFrame = 1;

		private const int UrgentFacesPerFrame = 6;

		private static readonly Plane[] FillFrustum = (Plane[])(object)new Plane[6];

		private static bool _teleporting;

		private static bool _reassignSoon;

		private static float _spawnedAt = -10f;

		private static readonly List<Renderer> ChangedForceOff = new List<Renderer>();

		private static readonly List<Renderer> ChangedShadowMode = new List<Renderer>();

		private static readonly List<ShadowCastingMode> PriorShadowModes = new List<ShadowCastingMode>();

		private static readonly List<Renderer> Renderers = new List<Renderer>();

		private static readonly Plane[] Frustum = (Plane[])(object)new Plane[6];

		private static readonly HashSet<Transform> Roots = new HashSet<Transform>();

		private static Collider[] Hits = (Collider[])(object)new Collider[2048];

		private static int OverflowReports;

		private static readonly Dictionary<Material, bool> TagCache = new Dictionary<Material, bool>();

		internal static int StaticLayerMask;

		private static readonly Dictionary<Mesh, bool> SheetCache = new Dictionary<Mesh, bool>();

		private static readonly Dictionary<Material, bool> CasterCache = new Dictionary<Material, bool>();

		private static readonly List<Material> Materials = new List<Material>();

		private static readonly FieldRef<LightFlicker, Vector3> FlickerBase = AccessTools.FieldRefAccess<LightFlicker, Vector3>("m_basePosition");

		private static readonly List<LODGroup> s_lodGroups = new List<LODGroup>();

		private static readonly Dictionary<int, bool> FarLods = new Dictionary<int, bool>(4096);

		private static Collider[] ProxyHits = (Collider[])(object)new Collider[64];

		private static Mesh _cube;

		private static readonly FieldRef<LightLod, float> BaseRange = AccessTools.FieldRefAccess<LightLod, float>("m_baseRange");

		internal static Shader LightingShader;

		internal const int TierCount = 4;

		private bool _tiered;

		private readonly RenderTexture[] _pool = (RenderTexture[])(object)new RenderTexture[4];

		private readonly List<bool>[] _poolUsed = new List<bool>[4]
		{
			new List<bool>(),
			new List<bool>(),
			new List<bool>(),
			new List<bool>()
		};

		private readonly float[] _mapTier = new float[96];

		private readonly float[] _mapCube = new float[96];

		private long _poolBudget;

		private static readonly int[] TierIds = new int[4]
		{
			Shader.PropertyToID("_WireTier0"),
			Shader.PropertyToID("_WireTier1"),
			Shader.PropertyToID("_WireTier2"),
			Shader.PropertyToID("_WireTier3")
		};

		private static readonly int MapTierId = Shader.PropertyToID("_WireMapTier");

		private static readonly int MapCubeId = Shader.PropertyToID("_WireMapCube");

		private static readonly int TierResId = Shader.PropertyToID("_WireTierRes");

		private static readonly int TieredId = Shader.PropertyToID("_WireTiered");

		private bool _tiersFailed;

		private readonly int[] _waiting = new int[4];

		private static int GameLimit => LightLod.m_shadowLimit;

		private static bool GameOff => GameLimit == 0;

		private static bool GameLimited => GameLimit > 0;

		private static bool OnePass
		{
			get
			{
				if ((Object)(object)FrontBackShader != (Object)null && FrontBackShader.isSupported && (Object)(object)CombineShader != (Object)null)
				{
					return CombineShader.passCount >= 5;
				}
				return false;
			}
		}

		internal static int SlotCount => Mathf.Clamp(24, 1, 32);

		internal static int FarCount => Mathf.Clamp(40, 0, 64);

		internal static int UltraCount => Mathf.Clamp(24, 0, 64 - FarCount);

		private int UltraStart => _slots.Length - _ultra;

		private static bool AreaLoaded(Vector3 p)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return true;
			}
			Vector2s zone = ZoneSystem.GetZone(p);
			float time = Time.time;
			if (Areas.TryGetValue(zone, out var value) && time - value.At < 0.25f)
			{
				return value.Ready;
			}
			if (Areas.Count > 256)
			{
				Areas.Clear();
			}
			bool flag = AreaReady(p, zone);
			Areas[zone] = new AreaState
			{
				Ready = flag,
				At = time
			};
			return flag;
		}

		private static bool AreaReady(Vector3 p, Vector2s zone)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			if (ZDOMan.instance == null)
			{
				return true;
			}
			if (!ZoneSystem.instance.IsZoneLoaded(zone))
			{
				return false;
			}
			AreaObjects.Clear();
			ZDOMan.instance.FindSectorObjects(zone, new SimulationDistance(1, 0, false), AreaObjects, (List<ZDO>)null);
			bool result = true;
			foreach (ZDO areaObject in AreaObjects)
			{
				if (PrefabValid(instance, areaObject) && (Object)(object)instance.FindInstance(areaObject) == (Object)null)
				{
					result = false;
					break;
				}
			}
			AreaObjects.Clear();
			return result;
		}

		private static bool ReadyToRender(Tracked t)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t.Light == (Object)null)
			{
				return true;
			}
			if (AreaLoaded(((Component)t.Light).transform.position))
			{
				t.WaitSince = -1f;
				return true;
			}
			if (t.WaitSince < 0f)
			{
				t.WaitSince = Time.time;
			}
			if (Time.time - t.WaitSince >= 15f)
			{
				t.WaitSince = -1f;
				return true;
			}
			t.WaitUntil = Time.time + 0.25f;
			return false;
		}

		private static bool BeyondGame(Tracked t, Vector3 player, float margin)
		{
			//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)
			if (!GameLimited || (Object)(object)t.Light == (Object)null)
			{
				return false;
			}
			float num = (((Object)(object)t.Lod != (Object)null) ? t.Lod.m_shadowDistance : 20f);
			return Vector3.Distance(((Component)t.Light).transform.position, player) >= num + margin;
		}

		private void HoldToGameBudget(List<int> candidates, int[] draw, Vector3 cam)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (!GameLimited || candidates.Count == 0)
			{
				return;
			}
			int num = GameLimit * 6;
			int num2 = 0;
			BudgetOrder.Clear();
			BudgetOrder.AddRange(candidates);
			s_budgetCam = cam;
			s_budgetSlots = _slots;
			BudgetOrder.Sort(BudgetNearer);
			candidates.Clear();
			foreach (int item in BudgetOrder)
			{
				int num3 = 0;
				for (int num4 = draw[item]; num4 != 0; num4 &= num4 - 1)
				{
					num3++;
				}
				if (num3 <= 0 || num2 + num3 <= num)
				{
					num2 += num3;
					candidates.Add(item);
				}
			}
		}

		internal static void RegisterMachine(Smelter smelter)
		{
			if ((Object)(object)smelter == (Object)null || ZNetView.m_forceDisableInit || MachineBySmelter.ContainsKey(smelter) || (((Object)smelter).name.IndexOf("eitrrefinery", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)smelter).name.IndexOf("spinningwheel", StringComparison.OrdinalIgnoreCase) < 0 && (Object)(object)smelter.m_windmill == (Object)null && (Object)(object)((Component)smelter).GetComponent<Windmill>() == (Object)null))
			{
				return;
			}
			List<Transform> list = new List<Transform>();
			if (smelter.m_animators != null)
			{
				Animator[] animators = smelter.m_animators;
				foreach (Animator val in animators)
				{
					if ((Object)(object)val != (Object)null)
					{
						list.Add(((Component)val).transform);
					}
				}
			}
			Windmill val2 = (((Object)(object)smelter.m_windmill != (Object)null) ? smelter.m_windmill : ((Component)smelter).GetComponent<Windmill>());
			if ((Object)(object)val2 != (Object)null)
			{
				if ((Object)(object)Propeller.Invoke(val2) != (Object)null)
				{
					list.Add(Propeller.Invoke(val2));
				}
				if ((Object)(object)Bom.Invoke(val2) != (Object)null)
				{
					list.Add(Bom.Invoke(val2));
				}
				object? obj = GrindstoneField?.GetValue(val2);
				Transform val3 = (Transform)((obj is Transform) ? obj : null);
				if (val3 != null && (Object)(object)val3 != (Object)null)
				{
					list.Add(val3);
				}
			}
			AddMachine((Component)(object)smelter, list, smelter, val2, null);
		}

		internal static void RegisterTurret(Turret turret)
		{
			if ((Object)(object)turret == (Object)null || ZNetView.m_forceDisableInit || Machines.Exists((Machine m) => (Object)(object)m.Owner == (Object)(object)turret))
			{
				return;
			}
			List<Transform> list = new List<Transform>();
			GameObject[] array = (GameObject[])(object)new GameObject[4] { turret.m_turretBody, turret.m_turretNeck, turret.m_turretBodyArmed, turret.m_turretBodyUnarmed };
			foreach (GameObject val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val.transform);
				}
			}
			AddMachine((Component)(object)turret, list, null, null, ((Object)(object)turret.m_turretBody != (Object)null) ? turret.m_turretBody.transform : null);
		}

		private static void AddMachine(Component owner, List<Transform> roots, Smelter smelter, Windmill wm, Transform turret)
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			List<Renderer> list = new List<Renderer>();
			Renderer[] componentsInChildren;
			foreach (Transform root in roots)
			{
				componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!(val is ParticleSystemRenderer) && (int)val.shadowCastingMode != 0 && !SeeThrough(val) && !list.Contains(val))
					{
						list.Add(val);
					}
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			Bounds bounds = list[0].bounds;
			foreach (Renderer item2 in list)
			{
				((Bounds)(ref bounds)).Encapsulate(item2.bounds);
			}
			Machine obj = new Machine
			{
				Owner = owner,
				Smelter = smelter,
				Windmill = wm,
				Turret = turret,
				LastTurn = (((Object)(object)turret != (Object)null) ? turret.rotation : Quaternion.identity),
				Renderers = list.ToArray(),
				Center = ((Bounds)(ref bounds)).center
			};
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			obj.Radius = ((Vector3)(ref extents)).magnitude + 0.5f;
			obj.StillHash = Quantize(((Bounds)(ref bounds)).center, 100f) * 13 + 7;
			Machine machine = obj;
			Machines.Add(machine);
			if ((Object)(object)smelter != (Object)null)
			{
				MachineBySmelter[smelter] = machine;
			}
			componentsInChildren = machine.Renderers;
			foreach (Renderer item in componentsInChildren)
			{
				MachineHidden.Add(item);
			}
			s_machine = true;
			PieceChanged(machine.Center, (Object)(object)owner);
			s_machine = false;
		}

		private static void CacheRestMachineGeometry(Machine m)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			Caster[] array = new Caster[m.Renderers.Length];
			for (int i = 0; i < array.Length; i++)
			{
				Renderer val = m.Renderers[i];
				if ((Object)(object)val == (Object)null)
				{
					m.RestGeometry = null;
					return;
				}
				if (!SubCounts.TryGetValue(val, out var value))
				{
					if (SubCounts.Count > 8192)
					{
						SubCounts.Clear();
					}
					SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
					int num;
					if (val2 == null || !((Object)(object)val2.sharedMesh != (Object)null))
					{
						MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
						num = ((component == null || !((Object)(object)component.sharedMesh != (Object)null)) ? 1 : component.sharedMesh.subMeshCount);
					}
					else
					{
						num = val2.sharedMesh.subMeshCount;
					}
					value = num;
					SubCounts[val] = value;
				}
				Bounds bounds = val.bounds;
				int num2 = i;
				Caster caster = new Caster
				{
					R = val,
					B = bounds
				};
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				caster.Radius = ((Vector3)(ref extents)).magnitude;
				caster.Subs = value;
				array[num2] = caster;
			}
			m.RestVisibility = DropGeometryVisibility(m.Renderers);
			m.RestGeometry = array;
		}

		internal static void MachineAnimation(Smelter smelter, bool active)
		{
			if (!((Object)(object)smelter == (Object)null) && MachineBySmelter.TryGetValue(smelter, out var value))
			{
				if (value.Active && !active)
				{
					value.Until = Time.time + 2.5f;
				}
				if (active && !value.Active)
				{
					value.RestGeometry = null;
				}
				value.Active = active;
			}
		}

		private void AddMachineGroups(Vector3 cam, float far)
		{
			//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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			for (int num = Machines.Count - 1; num >= 0; num--)
			{
				Machine machine = Machines[num];
				if ((Object)(object)machine.Owner == (Object)null)
				{
					if (machine.Smelter != null)
					{
						MachineBySmelter.Remove(machine.Smelter);
					}
					Renderer[] renderers = machine.Renderers;
					foreach (Renderer item in renderers)
					{
						MachineHidden.Remove(item);
					}
					Machines.RemoveAt(num);
				}
				else
				{
					Vector3 val = machine.Center - cam;
					if (!(((Vector3)(ref val)).sqrMagnitude > (far + machine.Radius) * (far + machine.Radius)))
					{
						if ((Object)(object)machine.Turret != (Object)null && Quaternion.Angle(machine.Turret.rotation, machine.LastTurn) > 0.05f)
						{
							machine.LastTurn = machine.Turret.rotation;
							machine.Until = Time.time + 0.3f;
						}
						if (machine.Active || Time.time < machine.Until || ((Object)(object)machine.Windmill != (Object)null && machine.Windmill.GetPowerOutput() > 0f))
						{
							machine.RestGeometry = null;
							AddGroup(machine.Center, machine.Radius, Time.frameCount, character: false, machine.Renderers, checkCasting: false, 4);
						}
						else
						{
							int num2 = DropGeometryVisibility(machine.Renderers);
							if (machine.RestGeometry == null || machine.RestVisibility != num2)
							{
								CacheRestMachineGeometry(machine);
							}
							if (machine.RestGeometry != null)
							{
								AddCachedCasterGroup(machine.Center, machine.Radius, machine.StillHash ^ machine.RestVisibility, machine.RestGeometry, 4);
							}
							else
							{
								AddGroup(machine.Center, machine.Radius, machine.StillHash ^ num2, character: false, machine.Renderers, checkCasting: false, 4);
							}
						}
					}
				}
			}
		}

		private void MakeOnePassFaces()
		{
			//IL_002a: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			ReleaseOnePassFaces();
			if (OnePass)
			{
				for (int i = 0; i < 4; i++)
				{
					int num = TierRes(i);
					_tierRG[i] = new RenderTexture(num, num, 16, (RenderTextureFormat)13)
					{
						dimension = (TextureDimension)4,
						useMipMap = false,
						filterMode = (FilterMode)0,
						name = "WireTierFaceRG" + i
					};
					_tierRG[i].Create();
					_tierFlatRG[i] = new RenderTexture(num, num, 0, (RenderTextureFormat)13)
					{
						dimension = (TextureDimension)2,
						useMipMap = false,
						filterMode = (FilterMode)0,
						name = "WireTierFlatRG" + i
					};
					_tierFlatRG[i].Create();
				}
			}
		}

		private void ReleaseOnePassFaces()
		{
			for (int i = 0; i < 4; i++)
			{
				if ((Object)(object)_tierRG[i] != (Object)null)
				{
					_tierRG[i].Release();
					_tierRG[i] = null;
				}
				if ((Object)(object)_tierFlatRG[i] != (Object)null)
				{
					_tierFlatRG[i].Release();
					_tierFlatRG[i] = null;
				}
			}
		}

		private void DrawUntaggedOnePass(Tracked t)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			if (t.Explicit.Count == 0 && t.ProxyMeshes.Count == 0 && t.Sheets.Count == 0)
			{
				return;
			}
			if ((Object)(object)_frontBackMat == (Object)null)
			{
				_frontBackMat = new Material(FrontBackShader)
				{
					hideFlags = (HideFlags)61
				};
			}
			if (_proxyProps == null)
			{
				_proxyProps = new MaterialPropertyBlock();
				_proxyProps.SetFloat("_WireProxy", 1f);
				_structProps = new MaterialPropertyBlock();
				_structProps.SetFloat("_WireProxy", 2f);
			}
			foreach (Renderer sheet in t.Sheets)
			{
				if ((Object)(object)sheet == (Object)null || !sheet.enabled || !((Component)sheet).gameObject.activeInHierarchy)
				{
					continue;
				}
				sheet.GetSharedMaterials(Materials);
				object obj;
				if (IsClothRenderer(sheet) && !sheet.isPartOfStaticBatch)
				{
					MeshFilter component = ((Component)sheet).GetComponent<MeshFilter>();
					if (component != null)
					{
						obj = component.sharedMesh;
						goto IL_00ff;
					}
				}
				obj = null;
				goto IL_00ff;
				IL_00ff:
				Mesh val = (Mesh)obj;
				? val2;
				if (!((Object)(object)val != (Object)null))
				{
					val2 = default(Matrix4x4);
				}
				else
				{
					Bounds bounds = sheet.bounds;
					Vector3 val3 = ((Bounds)(ref bounds)).center - t.Center;
					val2 = Matrix4x4.Translate(((Vector3)(ref val3)).normalized * 0.15f) * sheet.localToWorldMatrix;
				}
				Matrix4x4 val4 = (Matrix4x4)val2;
				for (int i = 0; i < Materials.Count; i++)
				{
					if ((Object)(object)Materials[i] != (Object)null)
					{
						if ((Object)(object)val != (Object)null && i < val.subMeshCount)
						{
							_staticCb.DrawMesh(val, val4, ClipMaterial(Materials[i], FrontBackShader), i, 2);
						}
						else
						{
							_staticCb.DrawRenderer(sheet, ClipMaterial(Materials[i], FrontBackShader), i, 2);
						}
					}
				}
			}
			for (int j = 0; j < t.ProxyMeshes.Count; j++)
			{
				_staticCb.DrawMesh(t.ProxyMeshes[j], t.ProxyMatrices[j], _frontBackMat, 0, 1, (j < t.NearProxies) ? _proxyProps : _structProps);
			}
			for (int k = 0; k < t.Explicit.Count; k++)
			{
				Renderer val5 = t.Explicit[k];
				if (!((Object)(object)val5 == (Object)null) && val5.enabled && ((Component)val5).gameObject.activeInHierarchy)
				{
					val5.GetSharedMaterials(Materials);
					int num = t.ExplicitSub[k];
					Material val6 = ((num < Materials.Count) ? Materials[num] : null);
					bool item = StandVisuals.Contains(val5) || DropVisuals.Contains(val5);
					Material val7 = (((Object)(object)val6 != (Object)null) ? ClipMaterial(val6, FrontBackShader, item) : _frontBackMat);
					_staticCb.DrawRenderer(val5, val7, num, 0);
					_staticCb.DrawRenderer(val5, val7, num, 1);
				}
			}
		}

		private void TierFaceOnePass(Tracked t, int face, bool rendering)
		{
			//IL_0051: 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_0063: Expected O, but got Unknown
			//IL_00a1: 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_0081: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			int num = (rendering ? t.RenderTier : ((int)_mapTier[t.Slot]));
			int num2 = (rendering ? t.RenderCube : ((int)_mapCube[t.Slot]));
			if (num >= 0 && num2 >= 0)
			{
				if ((Object)(object)_combine == (Object)null)
				{
					_combine = new Material(CombineShader)
					{
						hideFlags = (HideFlags)61
					};
				}
				if (_nativeCopyCb == null)
				{
					_nativeCopyCb = new CommandBuffer
					{
						name = "Wire's Shadows native depth conversion"
					};
				}
				_nativeCopyCb.Clear();
				_nativeCopyCb.SetRenderTarget(new RenderTargetIdentifier((Texture)(object)_pool[num], 0, (CubemapFace)(-1), num2 * 6 + face));
				_nativeCopyCb.SetGlobalFloat(NativeInvRangeId, 1f / (rendering ? t.RenderRange : t.NativeCacheRange));
				_nativeCopyCb.SetGlobalTexture(FrontBackId, RenderTargetIdentifier.op_Implicit((Texture)(object)_tierFlatRG[num]));
				_nativeCopyCb.DrawProcedural(Matrix4x4.identity, _combine, 4, (MeshTopology)0, 3);
				Graphics.ExecuteCommandBuffer(_nativeCopyCb);
			}
		}

		private static bool IsSconce(Light light)
		{
			if ((Object)(object)light == (Object)null)
			{
				return false;
			}
			Piece componentInParent = ((Component)light).GetComponentInParent<Piece>();
			string text = (((Object)(object)componentInParent != (Object)null) ? ((Object)componentInParent).name : ((Object)((Component)light).transform.root).name).ToLowerInvariant();
			if (!text.Contains("sconce") && !text.Contains("walltorch") && !text.Contains("wall_torch") && !text.Contains("walllantern") && !text.Contains("wall_lantern") && !text.Contains("walllight"))
			{
				return text.Contains("wall_light");
			}
			return true;
		}

		private void UploadDynPhysical()
		{
			if (_dynPhysicalDirty)
			{
				_dynPhysicalDirty = false;
				Shader.SetGlobalFloatArray(DynPhysicalId, _dynPhysicalUniform);
			}
		}

		private void ResetDynPool()
		{
			for (int i = 0; i < 96; i++)
			{
				_dynPhysical[i] = -1;
				_dynPhysicalUniform[i] = -1f;
			}
			for (int j = 0; j < 32; j++)
			{
				_dynNearOwners[j] = -1;
			}
			for (int k = 0; k < 64; k++)
			{
				_dynFarOwners[k] = -1;
			}
			_dynPhysicalDirty = false;
			Shader.SetGlobalFloatArray(DynPhysicalId, _dynPhysicalUniform);
		}

		private void FreeDynSlot(int sl)
		{
			if (sl >= 0 && sl < 96)
			{
				int num = _dynPhysical[sl];
				if (num >= 0)
				{
					((sl < _near) ? _dynNearOwners : _dynFarOwners)[num] = -1;
					_dynPhysical[sl] = -1;
					_dynPhysicalUniform[sl] = -1f;
					_dynPhysicalDirty = true;
				}
			}
		}

		private bool EvictFurther(int sl, Vector3 cam)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0095: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			if (_framePending)
			{
				return false;
			}
			Tracked tracked = _slots[sl];
			if (tracked == null)
			{
				return false;
			}
			Vector3 val = tracked.Center - cam;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			bool num = sl < _near;
			int[] array = (num ? _dynNearOwners : _dynFarOwners);
			int num2 = (num ? _dynNearCapacity : _dynFarCapacity);
			int num3 = -1;
			float num4 = sqrMagnitude * 1.5625f;
			for (int i = 0; i < num2; i++)
			{
				int num5 = array[i];
				if (num5 >= 0 && num5 != sl)
				{
					Tracked tracked2 = _slots[num5];
					float num6;
					if (tracked2 == null)
					{
						num6 = float.MaxValue;
					}
					else
					{
						val = tracked2.Center - cam;
						num6 = ((Vector3)(ref val)).sqrMagnitude;
					}
					float num7 = num6;
					if (num7 > num4)
					{
						num4 = num7;
						num3 = num5;
					}
				}
			}
			if (num3 < 0)
			{
				return false;
			}
			_dynFacesLast[num3] = 0;
			_dynActive[num3] = 0f;
			_nativeMovingActive[num3] = 0f;
			for (int j = 0; j < 6; j++)
			{
				_faceHash[num3 * 6 + j] = 0;
			}
			FreeDynSlot(num3);
			return true;
		}

		private float FarMovingCutoff(Vector3 cam)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			int farMovingCap = _farMovingCap;
			int num = 0;
			for (int i = _near; i < UltraStart && i < _slots.Length; i++)
			{
				Tracked tracked = _slots[i];
				if (tracked != null && tracked.Ready && !tracked.Tiny)
				{
					float[] farMovingDist = _farMovingDist;
					int num2 = num++;
					Vector3 val = tracked.Center - cam;
					farMovingDist[num2] = ((Vector3)(ref val)).sqrMagnitude;
				}
			}
			if (num <= farMovingCap)
			{
				return float.MaxValue;
			}
			if (farMovingCap <= 0)
			{
				return -1f;
			}
			Array.Sort(_farMovingDist, 0, num);
			return _farMovingDist[farMovingCap - 1];
		}

		private bool EnsureDynSlot(int sl)
		{
			if (_dynPhysical[sl] >= 0)
			{
				return true;
			}
			bool num = sl < _near;
			int[] array = (num ? _dynNearOwners : _dynFarOwners);
			int num2 = (num ? _dynNearCapacity : _dynFarCapacity);
			int num3 = -1;
			for (int i = 0; i < num2; i++)
			{
				if (array[i] < 0)
				{
					num3 = i;
					break;
				}
			}
			if (num3 < 0)
			{
				return false;
			}
			array[num3] = sl;
			_dynPhysical[sl] = num3;
			_dynPhysicalUniform[sl] = num3;
			_dynPhysicalDirty = true;
			return true;
		}

		private void DynTarget(int sl, out RenderTexture maps, out int cube)
		{
			maps = ((sl < _near) ? _dynMaps : _farDynMaps);
			cube = _dynPhysical[sl];
		}

		internal void InvalidateMovingFaces()
		{
			for (int i = 0; i < _faceHash.Length; i++)
			{
				_faceHash[i] = int.MinValue;
			}
		}

		private static bool IsClothRenderer(Renderer r)
		{
			if (!ClothRenderers.TryGetValue(r, out var value))
			{
				r.GetSharedMaterials(ClothMats);
				foreach (Material clothMat in ClothMats)
				{
					if ((Object)(object)clothMat != (Object)null && (Object)(object)clothMat.shader != (Object)null && ((Object)clothMat.shader).name == "Custom/Vegetation" && clothMat.HasProperty("_PushClothMode") && clothMat.GetFloat("_PushClothMode") > 0.5f)
					{
						value = true;
						break;
					}
				}
				if (ClothRenderers.Count > 4096)
				{
					ClothRenderers.Clear();
				}
				ClothRenderers[r] = value;
			}
			return value;
		}

		private static Material ClipMaterial(Material orig, Shader shader, bool item = false)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!ClipMaterials.TryGetValue((orig, shader, item), out var value) || (Object)(object)value == (Object)null)
			{
				value = new Material(shader)
				{
					hideFlags = (HideFlags)61
				};
				Texture val = (orig.HasProperty("_MainTex") ? orig.mainTexture : null);
				if ((Object)(object)val != (Object)null)
				{
					value.mainTexture = val;
					value.mainTextureScale = orig.mainTextureScale;
					value.mainTextureOffset = orig.mainTextureOffset;
				}
				value.SetFloat("_Cutoff", orig.HasProperty("_Cutoff") ? orig.GetFloat("_Cutoff") : 0.5f);
				bool flag = (Object)(object)val != (Object)null && !item && orig.HasProperty("_Cutoff");
				value.SetFloat("_WireClip", flag ? 1f : 0f);
				if (!flag)
				{
					value.SetFloat("_Cutoff", 0f);
				}
				ClipMaterials[(orig, shader, item)] = value;
			}
			return value;
		}

		private static bool SupportsShadowmap()
		{
			if (!_supportsShadowmap.HasValue)
			{
				_supportsShadowmap = SystemInfo.SupportsRenderTextureFormat((RenderTextureFormat)3);
			}
			return _supportsShadowmap.Value;
		}

		private static void UploadArrayIfChanged(int shaderId, float[] values, float[] previous, ref bool uploaded)
		{
			bool flag = !uploaded;
			if (!flag)
			{
				for (int i = 0; i < values.Length; i++)
				{
					if (values[i] != previous[i])
					{
						flag = true;
						break;
					}
				}
			}
			if (flag)
			{
				Array.Copy(values, previous, values.Length);
				Shader.SetGlobalFloatArray(shaderId, values);
				uploaded = true;
			}
		}

		private void UploadDynActive()
		{
			UploadArrayIfChanged(DynActiveId, _dynActive, _uploadedDynActive, ref _hasUploadedDynActive);
			for (int i = 0; i < 96; i++)
			{
				_dynFaceMask[i] = ((_dynActive[i] > 0.5f) ? ((float)_dynFacesLast[i]) : 0f);
			}
			UploadArrayIfChanged(DynFaceMaskId, _dynFaceMask, _uploadedDynFaceMask, ref _hasUploadedDynFaceMask);
		}

		private void UploadNativeMovingActive()
		{
			UploadArrayIfChanged(NativeMovingActiveId, _nativeMovingActive, _uploadedNativeMovingActive, ref _hasUploadedNativeMovingActive);
		}

		private void UploadNativeMovingRanges()
		{
			UploadArrayIfChanged(NativeMovingRangesId, _nativeMovingInvRanges, _uploadedNativeMovingRanges, ref _hasUploadedNativeMovingRanges);
		}

		private void ReleaseNativeMovingResources()
		{
			if ((Object)(object)_nativeMovingNear != (Object)null)
			{
				_nativeMovingNear.Release();
			}
			if ((Object)(object)_nativeMovingFar != (Object)null)
			{
				_nativeMovingFar.Release();
			}
			if ((Object)(object)_nativeMovingFlat != (Object)null)
			{
				_nativeMovingFlat.Release();
			}
			if ((Object)(object)_nativeMovingCopyMat != (Object)null)
			{
				Object.Destroy((Object)(object)_nativeMovingCopyMat);
			}
			_nativeMovingNear = (_nativeMovingFar = (_nativeMovingFlat = null));
			_nativeMovingCopyMat = null;
			Array.Clear(_nativeMovingActive, 0, 96);
			UploadNativeMovingActive();
		}

		private bool EnsureNativeMovingTier(bool near)
		{
			//IL_00d6: 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)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			if (_nativeMovingFailed || (Object)(object)NativeCopyShader == (Object)null)
			{
				return false;
			}
			if (!SupportsShadowmap())
			{
				_nativeMovingFailed = true;
				Plugin.Log.LogWarning((object)"[native-moving] Shadowmap unsupported; using existing moving filter.");
				return false;
			}
			RenderTexture val = (near ? _dynMaps : _farDynMaps);
			if ((Object)(object)val == (Object)null || !val.IsCreated())
			{
				return false;
			}
			int movRes = _movRes;
			int num = (near ? _dynNearCapacity : _dynFarCapacity);
			RenderTexture val2 = (near ? _nativeMovingNear : _nativeMovingFar);
			if ((Object)(object)val2 != (Object)null && val2.IsCreated() && ((Texture)val2).width == movRes && val2.volumeDepth == 6 * num)
			{
				return true;
			}
			RenderTexture val3 = val2;
			int num2 = (((Object)(object)val3 != (Object)null && val3.IsCreated()) ? (val3.volumeDepth / 6) : 0);
			val2 = new RenderTexture(movRes, movRes, 16, (RenderTextureFormat)3)
			{
				dimension = (TextureDimension)6,
				volumeDepth = num * 6,
				useMipMap = false,
				filterMode = (FilterMode)1,
				name = (near ? "WireNativeMovingNearDepth" : "WireNativeMovingFarDepth")
			};
			if (!val2.Create())
			{
				val2.Release();
				_nativeMovingFailed = true;
				Plugin.Log.LogWarning((object)"[native-moving] Depth array allocation failed; using old moving shadow filter.");
				return false;
			}
			if ((Object)(object)val3 != (Object)null && num2 > 0)
			{
				int[] array = (near ? _dynNearOwners : _dynFarOwners);
				for (int i = 0; i < num2; i++)
				{
					int num3 = array[i];
					if (num3 >= 0 && !(_nativeMovingActive[num3] <= 0.5f))
					{
						for (int j = 0; j < 6; j++)
						{
							Graphics.CopyTexture((Texture)(object)val3, i * 6 + j, 0, (Texture)(object)val2, i * 6 + j, 0);
						}
					}
				}
				val3.Release();
				Object.Destroy((Object)(object)val3);
			}
			if (near)
			{
				_nativeMovingNear = val2;
			}
			else
			{
				_nativeMovingFar = val2;
			}
			Shader.SetGlobalTexture(near ? NativeMovingNearId : NativeMovingFarId, (Texture)(object)val2);
			Plugin.Note("[native-moving] " + (near ? "NEAR" : "FAR") + " comparison depth array ready: " + num + " slots, " + movRes + "px faces.");
			return true;
		}

		private bool QueueNativeMovingFace(Tracked t, RenderTexture src, int srcSlice, int cube, int face, RectInt touched)
		{
			//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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			bool flag = t.Slot < _near;
			if (_nativeMovingFailed || (flag ? ((Object)(object)_nativeMovingNear == (Object)null) : ((Object)(object)_nativeMovingFar == (Object)null)))
			{
				return false;
			}
			if ((Object)(object)_nativeMovingFlat == (Object)null || ((Texture)_nativeMovingFlat).width != ((Texture)src).width)
			{
				if ((Object)(object)_nativeMovingFlat != (Object)null)
				{
					_nativeMovingFlat.Release();
				}
				_nativeMovingFlat = new RenderTexture(((Texture)src).width, ((Texture)src).width, 0, (RenderTextureFormat)13)
				{
					dimension = (TextureDimension)2,
					useMipMap = false,
					filterMode = (FilterMode)0,
					name = "WireMovingDepthConversionScratch"
				};
				if (!_nativeMovingFlat.Create())
				{
					_nativeMovingFailed = true;
					ReleaseNativeMovingResources();
					return false;
				}
			}
			if ((Object)(object)_nativeMovingCopyMat == (Object)null)
			{
				_nativeMovingCopyMat = new Material(NativeCopyShader)
				{
					hideFlags = (HideFlags)61
				};
			}
			RenderTexture val = (flag ? _nativeMovingNear : _nativeMovingFar);
			int num = cube * 6 + face;
			int num2;
			if (((RectInt)(ref touched)).width > 0 && ((RectInt)(ref touched)).height > 0 && ((RectInt)(ref touched)).x >= 0 && ((RectInt)(ref touched)).y >= 0 && ((RectInt)(ref touched)).xMax <= ((Texture)src).width && ((RectInt)(ref touched)).yMax <= ((Texture)src).height)
			{
				if (((RectInt)(ref touched)).width >= ((Texture)src).width)
				{
					num2 = ((((RectInt)(ref touched)).height < ((Texture)src).height) ? 1 : 0);
					if (num2 == 0)
					{
						goto IL_01c1;
					}
				}
				else
				{
					num2 = 1;
				}
				_frameCb.CopyTexture(RenderTargetIdentifier.op_Implicit((Texture)(object)src), srcSlice, 0, ((RectInt)(ref touched)).x, ((RectInt)(ref touched)).y, ((RectInt)(ref touched)).width, ((RectInt)(ref touched)).height, RenderTargetIdentifier.op_Implicit((Texture)(object)_nativeMovingFlat), 0, 0, ((RectInt)(ref touched)).x, ((RectInt)(ref touched)).y);
				goto IL_01e1;
			}
			num2 = 0;
			goto IL_01c1;
			IL_01c1:
			_frameCb.CopyTexture(RenderTargetIdentifier.op_Implicit((Texture)(object)src), srcSlice, 0, RenderTargetIdentifier.op_Implicit((Texture)(object)_nativeMovingFlat), 0, 0);
			goto IL_01e1;
			IL_01e1:
			_frameCb.SetRenderTarget(new RenderTargetIdentifier((Texture)(object)val, 0, (CubemapFace)(-1), num));
			_frameCb.SetGlobalTexture(NativeMovingSourceId, RenderTargetIdentifier.op_Implicit((Texture)(object)_nativeMovingFlat));
			_frameCb.SetGlobalFloat(NativeInvRangeId, 1f / Mathf.Max(1f, Range(t)));
			if (num2 != 0)
			{
				_frameCb.EnableScissorRect(new Rect((float)((RectInt)(ref touched)).x, (float)((RectInt)(ref touched)).y, (float)((RectInt)(ref touched)).width, (float)((RectInt)(ref touched)).height));
			}
			_frameCb.DrawProcedural(Matrix4x4.identity, _nativeMovingCopyMat, 1, (MeshTopology)0, 3);
			if (num2 != 0)
			{
				_frameCb.DisableScissorRect();
			}
			return true;
		}

		private void InitNativeMovingSlot(Tracked t, int cube)
		{
			//IL_004d: 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)
			RenderTexture val = ((t.Slot < _near) ? _nativeMovingNear : _nativeMovingFar);
			if (!((Object)(object)val == (Object)null))
			{
				float num = (SystemInfo.usesReversedZBuffer ? 0f : 1f);
				for (int i = 0; i < 6; i++)
				{
					_frameCb.SetRenderTarget(new RenderTargetIdentifier((Texture)(object)val, 0, (CubemapFace)(-1), cube * 6 + i));
					_frameCb.ClearRenderTarget(true, false, Color.clear, num);
				}
			}
		}

		private void ReleaseNativeResources()
		{
			Array.Clear(_nativeActive, 0, 96);
			Shader.SetGlobalFloatArray(NativeActiveId, _nativeActive);
		}

		private void AbortStage(Tracked t)
		{
			DropTierRender(t);
			t.StagedNativeReady = false;
			if (t.Staged)
			{
				t.Staged = false;
			}
		}

		internal static void Register(LightLod lod)
		{
			Register(((Object)(object)lod != (Object)null) ? ((Component)lod).GetComponent<Light>() : null, lod);
		}

		internal static void RegisterPiece(Component piece)
		{
			piece.GetComponentsInChildren<Light>(true, PieceLights);
			foreach (Light pieceLight in PieceLights)
			{
				if ((Object)(object)((Component)pieceLight).GetComponent<LightLod>() == (Object)null)
				{
					Register(pieceLight, null);
				}
			}
		}

		internal static void UnregisterPiece(Piece piece)
		{
			((Component)piece).GetComponentsInChildren<Light>(true, PieceLights);
			foreach (Light pieceLight in PieceLights)
			{
				if ((Object)(object)((Component)pieceLight).GetComponent<LightLod>() == (Object)null)
				{
					Unregister(pieceLight);
				}
			}
		}

		private static void Forget()
		{
			GoneLights.Clear();
			foreach (KeyValuePair<Light, Tracked> item in ByLight)
			{
				if ((Object)(object)item.Key == (Object)null)
				{
					GoneLights.Add(item.Key);
				}
			}
			foreach (Light goneLight in GoneLights)
			{
				ByLight.Remove(goneLight);
			}
		}

		private static bool IsWispLight(Light light)
		{
			if ((Object)(object)light == (Object)null || (Object)(object)((Component)light).GetComponentInParent<Piece>() != (Object)null)
			{
				return false;
			}
			Transform val = ((Component)light).transform;
			while ((Object)(object)val != (Object)null)
			{
				string name = ((Object)val).name;
				if (name.IndexOf("wisplight", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("wisp", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("demister", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void DisableWispShadows(Light light, LightLod lod)
		{
			if ((Object)(object)lod != (Object)null)
			{
				ShadowLod.Invoke(lod) = false;
			}
			light.shadows = (LightShadows)0;
		}

		internal static void WispDemisterAwake(Demister demister)
		{
			if ((Object)(object)demister == (Object)null)
			{
				return;
			}
			Transform val = ((Component)demister).transform;
			while ((Object)(object)val != (Object)null)
			{
				Light component = ((Component)val).GetComponent<Light>();
				if ((Object)(object)component != (Object)null && IsWispLight(component))
				{
					DisableWispShadows(component, ((Component)component).GetComponent<LightLod>());
					break;
				}
				val = val.parent;
			}
		}

		private static void Register(Light light, LightLod lod)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)light == (Object)null || (int)light.type != 2 || ZNetView.m_forceDisableInit || ByLight.ContainsKey(light))
			{
				return;
			}
			if (IsWispLight(light))
			{
				DisableWispShadows(light, lod);
				return;
			}
			if ((Object)(object)((Component)light).GetComponentInParent<Character>() != (Object)null)
			{
				MovingLight(light, on: true, "carried");
				return;
			}
			bool flag = LooseItemGlow(light);
			if ((Object)(object)((Component)light).GetComponentInParent<Ship>() != (Object)null || (Object)(object)((Component)light).GetComponentInParent<Vagon>() != (Object)null)
			{
				MovingLight(light, on: true, "vehicle");
				return;
			}
			Rigidbody componentInParent = ((Component)light).GetComponentInParent<Rigidbody>();
			bool flag2 = (Object)(object)((Component)light).GetComponentInParent<ItemStand>() != (Object)null || (Object)(object)((Component)light).GetComponentInParent<ArmorStand>() != (Object)null;
			if (flag || flag2 || !((Object)(object)componentInParent != (Object)null) || componentInParent.isKinematic)
			{
				LightFlicker component = ((Component)light).GetComponent<LightFlicker>();
				Tracked tracked = new Tracked
				{
					Light = light,
					Lod = lod,
					Tiny = flag,
					Item = (flag2 || (Object)(object)((Component)light).GetComponentInParent<ItemDrop>() != (Object)null),
					Stand = ((Component)light).GetComponentInParent<ItemStand>(),
					Body = (((Object)(object)componentInParent != (Object)null && !componentInParent.isKinematic && !flag2) ? componentInParent : null),
					OriginalShadows = light.shadows,
					OriginalShadowLod = ((Object)(object)lod != (Object)null && ShadowLod.Invoke(lod)),
					OriginalShadowStrength = light.shadowStrength,
					OriginalShadowNearPlane = light.shadowNearPlane,
					Sconce = IsSconce(light),
					FakeFlame = ((Object)(object)component != (Object)null)
				};
				Lights.Add(tracked);
				ByLight[light] = tracked;
				_reassignSoon = true;
				if ((Object)(object)lod == (Object)null && (Object)(object)((Component)light).GetComponent<LightWatch>() == (Object)null)
				{
					((Component)light).gameObject.AddComponent<LightWatch>().Light = light;
				}
				if ((Object)(object)Instance != (Object)null && Instance._active)
				{
					Suppress(tracked);
				}
			}
		}

		private static bool LooseItemGlow(Light light)
		{
			ItemDrop componentInParent = ((Component)light).GetComponentInParent<ItemDrop>();
			if ((Object)(object)componentInParent != (Object)null && !componentInParent.IsPiece() && (Object)(object)((Component)light).GetComponentInParent<ItemStand>() == (Object)null)
			{
				return (Object)(object)((Component)light).GetComponentInParent<ArmorStand>() == (Object)null;
			}
			return false;
		}

		internal static void Unregister(LightLod lod)
		{
			Unregister(((Object)(object)lod != (Object)null) ? ((Component)lod).GetComponent<Light>() : null);
		}

		private static void Unregister(Light light)
		{
			if (light != null && ByLight.TryGetValue(light, out var value))
			{
				if ((Object)(object)Instance != (Object)null)
				{
					Instance.Release(value);
				}
				ByLight.Remove(light);
				Lights.Remove(value);
			}
		}

		internal static void LightEnabled(Light light)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance == (Object)null || !Instance._active || (Object)(object)light == (Object)null)
			{
				return;
			}
			if (Loading() || TeleportStreaming())
			{
				_reassignSoon = true;
			}
			else
			{
				if (!ByLight.TryGetValue(light, out var value))
				{
					return;
				}
				ShadowCache instance = Instance;
				if (value.Slot < 0)
				{
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer == (Object)null || Reach(value, ((Component)localPlayer).transform.position) > 60f)
					{
						return;
					}
					value.LitAt = Time.time;
					instance.Reassign();
					if (value.Slot < 0)
					{
						return;
					}
				}
				value.Instant = true;
				if (!value.Ready || value.Dirty || value.Face >= 0)
				{
					instance.RenderNow(value);
				}
				value.Instant = false;
				float num = (((Object)(object)value.Lod != (Object)null && value.Lod.m_lightLod) ? LodBaseRange.Invoke(value.Lod) : 0f);
				value.Fade = ((num > 0f) ? Mathf.Clamp01(light.range / num) : 1f);
				instance.UpdateGlobals();
			}
		}

		internal static void MovingLight(Light light, bool on, string why)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)light == (Object)null || (int)light.type != 2)
			{
				return;
			}
			if (IsWispLight(light))
			{
				DisableWispShadows(light, ((Component)light).GetComponent<LightLod>());
			}
			else
			{
				if (on && why == "carried" && !IsTorch(light))
				{
					return;
				}
				light.shadows = (LightShadows)(on ? 2 : 0);
				if (!on)
				{
					return;
				}
				float num = 0.3f;
				if (why == "rolling")
				{
					Renderer[] componentsInChildren = ((Component)((Component)light).transform.root).GetComponentsInChildren<Renderer>();
					foreach (Renderer val in componentsInChildren)
					{
						if (!(val is ParticleSystemRenderer))
						{
							float num2 = num;
							Vector3 position = ((Component)light).transform.position;
							Bounds bounds = val.bounds;
							float num3 = Vector3.Distance(position, ((Bounds)(ref bounds)).center);
							bounds = val.bounds;
							Vector3 extents = ((Bounds)(ref bounds)).extents;
							num = Mathf.Max(num2, num3 + ((Vector3)(ref extents)).magnitude);
						}
					}
				}
				light.shadowNearPlane = Mathf.Max(light.shadowNearPlane, num);
				light.shadowStrength = 1f;
			}
		}

		private static bool IsTorch(Light light)
		{
			Transform val = ((Component)light).transform;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name.IndexOf("torch", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private void UpdateGhost()
		{
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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)
			Player localPlayer = Player.m_localPlayer;
			GameObject val = (((Object)(object)localPlayer != (Object)null) ? PlacementGhost.Invoke(localPlayer) : null);
			_ghostActive = (Object)(object)val != (Object)null && val.activeInHierarchy;
			if (!_ghostActive)
			{
				return;
			}
			if ((Object)(object)val != (Object)(object)_ghost)
			{
				_ghost = val;
				_ghostRenderers = Array.FindAll(val.GetComponentsInChildren<Renderer>(), (Renderer r) => !(r is ParticleSystemRenderer) && !(r is TrailRenderer) && !(r is LineRenderer));
				if (_ghostRenderers.Length == 0)
				{
					_ghostActive = false;
					return;
				}
				Bounds bounds = _ghostRenderers[0].bounds;
				Renderer[] ghostRenderers = _ghostRenderers;
				foreach (Renderer val2 in ghostRenderers)
				{
					((Bounds)(ref bounds)).Encapsulate(val2.bounds);
				}
				_ghostLocalCenter = val.transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				_ghostRadius = ((Vector3)(ref extents)).magnitude + 0.3f;
			}
			if (_ghostRenderers.Length == 0)
			{
				_ghostActive = false;
				return;
			}
			Transform transform = val.transform;
			_ghostCenter = transform.TransformPoint(_ghostLocalCenter);
			_ghostHash = Quantize(transform.position, 50f) * 31 + Quantize(transform.eulerAngles, 0.5f);
		}

		internal static void DoorMoved(Door door)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			ShadowCache instance = Instance;
			if ((Object)(object)instance == (Object)null || !instance._active)
			{
				return;
			}
			Swing swing = Swings.Find((Swing x) => (Object)(object)x.Door == (Object)(object)door);
			Renderer[] array2;
			if (swing == null)
			{
				Renderer[] array = Array.FindAll(((Component)door).GetComponentsInChildren<Renderer>(), (Renderer r) => (int)r.shadowCastingMode != 0 && !SeeThrough(r));
				if (array.Length == 0)
				{
					return;
				}
				Bounds bounds = array[0].bounds;
				array2 = array;
				foreach (Renderer val in array2)
				{
					((Bounds)(ref bounds)).Encapsulate(val.bounds);
				}
				Swing obj = new Swing
				{
					Door = door,
					Animator = ((Component)door).GetComponentInChildren<Animator>(),
					Renderers = array,
					Center = ((Bounds)(ref bounds)).center
				};
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				obj.Radius = ((Vector3)(ref extents)).magnitude + 0.5f;
				swing = obj;
				Swings.Add(swing);
			}
			swing.Until = Time.time + 0.4f;
			swing.Ending = false;
			array2 = swing.Renderers;
			foreach (Renderer item in array2)
			{
				SwingHidden.Add(item);
			}
			for (int num2 = 0; num2 < instance._slots.Length; num2++)
			{
				Tracked tracked = instance._slots[num2];
				if (tracked != null && !((Object)(object)tracked.Light == (Object)null) && Reaches(tracked, swing))
				{
					if (!tracked.Ready || tracked.Face >= 0 || tracked.Dirty)
					{
						tracked.DoorFaces = 0;
						tracked.DoorPrepared = false;
						tracked.Dirty = true;
						tracked.DirtyAt = Time.time;
					}
					else
					{
						int num3 = FacesFor(swing.Center - RestingPosition(tracked.Light), swing.Radius);
						tracked.DoorFaces |= num3;
						tracked.DoorPrepared = false;
					}
				}
			}
			instance.WakeRenders();
		}

		private static void PlaceDrop(DropCaster d)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			d.Placed = true;
			Bounds val = default(Bounds);
			bool flag = true;
			Renderer[] renderers = d.Renderers;
			foreach (Renderer val2 in renderers)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					DropVisuals.Remove(val2);
					if (flag)
					{
						val = val2.bounds;
						flag = false;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
					}
				}
			}
			d.PlacedCenter = (flag ? d.CurrentPosition : ((Bounds)(ref val)).center);
			float placedRadius;
			if (!flag)
			{
				Vector3 extents = ((Bounds)(ref val)).extents;
				placedRadius = ((Vector3)(ref extents)).magnitude + 0.1f;
			}
			else
			{
				placedRadius = 0.8f;
			}
			d.PlacedRadius = placedRadius;
			PlacedDrops.Add(d);
			_dropChangedFrame = Time.frameCount;
			MarkDropFaces(d.CurrentPosition);
			QueueStaticItemChange(d.PlacedCenter, d.PlacedRadius);
		}

		private static void UnplaceDrop(DropCaster d)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (d.Placed)
			{
				PlacedDrops.Remove(d);
				QueueStaticItemChange(d.PlacedCenter, d.PlacedRadius);
			}
		}

		private static void MarkDropFaces(Vector3 pos)
		{
			//IL_004c: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			ShadowCache instance = Instance;
			if ((Object)(object)instance == (Object)null || !instance._active)
			{
				return;
			}
			for (int i = 0; i < instance._slots.Length; i++)
			{
				Tracked tracked = instance._slots[i];
				if (tracked != null && !((Object)(object)tracked.Light == (Object)null) && tracked.Ready)
				{
					float num = Range(tracked) + 0.8f;
					Vector3 val = tracked.Center - pos;
					if (((Vector3)(ref val)).sqrMagnitude <= num * num)
					{
						instance._pickupInvalidFaces[i] |= FacesFor(pos - tracked.Center, 0.8f);
					}
				}
			}
		}

		private static DropCaster GetDrop(ItemDrop it, Vector3 pos)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			if (Drops.TryGetValue(it, out var value))
			{
				return value;
			}
			value = new DropCaster
			{
				Item = it,
				Body = ((Component)it).GetComponent<Rigidbody>(),
				Mounted = ((Object)(object)((Component)it).GetComponentInParent<ItemStand>() != (Object)null),
				CurrentPosition = pos,
				StaticPosition = pos,
				CurrentRotation = ((Component)it).transform.rotation,
				StaticRotation = ((Component)it).transform.rotation,
				LastMotion = Time.time
			};
			value.Renderers = Array.FindAll(((Component)it).GetComponentsInChildren<Renderer>(true), (Renderer r) => !(r is ParticleSystemRenderer) && !(r is TrailRenderer) && !(r is LineRenderer) && !SeeThrough(r));
			value.CanCacheGeometry = (Object)(object)((Component)it).GetComponentInChildren<Animator>(true) == (Object)null && (Object)(object)((Component)it).GetComponentInChildren<Animation>(true) == (Object)null;
			Renderer[] renderers = value.Renderers;
			for (int num = 0; num < renderers.Length; num++)
			{
				if (!(renderers[num] is MeshRenderer))
				{
					value.CanCacheGeometry = false;
				}
			}
			if (!value.Mounted)
			{
				renderers = value.Renderers;
				foreach (Renderer item in renderers)
				{
					DropVisuals.Add(item);
				}
			}
			Drops[it] = value;
			_dropChangedFrame = Time.frameCount;
			return value;
		}

		private static void ReviewResting()
		{
			//IL_0054: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			for (int num = Resting.Count - 1; num >= 0; num--)
			{
				ItemDrop val = Resting[num];
				bool flag;
				DropCaster value;
				if ((Object)(object)val == (Object)null)
				{
					flag = false;
				}
				else if (!Drops.TryGetValue(val, out value))
				{
					flag = true;
				}
				else
				{
					int num2;
					if (value.Mounted || value.Placed)
					{
						Vector3 val2 = ((Component)val).transform.position - value.CurrentPosition;
						num2 = ((((Vector3)(ref val2)).sqrMagnitude > 0.0004f) ? 1 : 0);
					}
					else
					{
						num2 = 1;
					}
					flag = (byte)num2 != 0;
				}
				if ((Object)(object)val == (Object)null || flag)
				{
					if (flag)
					{
						Items.Add(val);
					}
					Resting[num] = Resting[Resting.Count - 1];
					Resting.RemoveAt(Resting.Count - 1);
				}
			}
		}

		internal static void DropRemoved(ItemDrop item)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Resting.Remove(item);
			if (item == null || !Drops.TryGetValue(item, out var value))
			{
				Items.Remove(item);
				return;
			}
			_dropChangedFrame = Time.frameCount;
			MarkDropFaces(value.CurrentPosition);
			UnplaceDrop(value);
			if (value.Renderers != null)
			{
				Renderer[] renderers = value.Renderers;
				foreach (Renderer item2 in renderers)
				{
					DropVisuals.Remove(item2);
				}
			}
			Drops.Remove(item);
			Items.Remove(item);
		}

		private static void CleanupDroppedItems()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			LostDrops.Clear();
			foreach (KeyValuePair<ItemDrop, DropCaster> drop in Drops)
			{
				if ((Object)(object)drop.Key == (Object)null || !((Behaviour)drop.Key).isActiveAndEnabled)
				{
					DropCaster value = drop.Value;
					_dropChangedFrame = Time.frameCount;
					MarkDropFaces(value.CurrentPosition);
					UnplaceDrop(value);
					Renderer[] renderers = value.Renderers;
					foreach (Renderer item in renderers)
					{
						DropVisuals.Remove(item);
					}
					LostDrops.Add(drop.Key);
				}
			}
			foreach (ItemDrop lostDrop in LostDrops)
			{
				Drops.Remove(lostDrop);
			}
			LostDrops.Clear();
		}

		private static bool Swinging(Animator a)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)a == (Object)null || !((Behaviour)a).isActiveAndEnabled)
			{
				return false;
			}
			if (!a.IsInTransition(0))
			{
				AnimatorStateInfo currentAnimatorStateInfo = a.GetCurrentAnimatorStateInfo(0);
				return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime < 1f;
			}
			return true;
		}

		private static bool Reaches(Tracked t, Swing w)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			float num = Range(t) + w.Radius;
			Vector3 val = t.Center - w.Center;
			return ((Vector3)(ref val)).sqrMagnitude < num * num;
		}

		private void UpdateSwings()
		{
			for (int num = Swings.Count - 1; num >= 0; num--)
			{
				Swing swing = Swings[num];
				if ((Object)(object)swing.Door == (Object)null)
				{
					Renderer[] renderers = swing.Renderers;
					foreach (Renderer item in renderers)
					{
						SwingHidden.Remove(item);
					}
					Swings.RemoveAt(num);
				}
				else if (!swing.Ending)
				{
					if (!(Time.time < swing.Until) && !Swinging(swing.Animator))
					{
						swing.Ending = true;
						Renderer[] renderers = swing.Renderers;
						foreach (Renderer item2 in renderers)
						{
							SwingHidden.Remove(item2);
						}
						for (int j = 0; j < _slots.Length; j++)
						{
							Tracked tracked = _slots[j];
							if (tracked != null && !((Object)(object)tracked.Light == (Object)null) && Reaches(tracked, swing))
							{
								tracked.DoorFaces = 0;
								tracked.DoorPrepared = false;
								tracked.Dirty = true;
								tracked.DirtyAt = Time.time;
							}
						}
						WakeRenders();
					}
				}
				else
				{
					bool flag = false;
					for (int k = 0; k < _slots.Length; k++)
					{
						if (flag)
						{
							break;
						}
						Tracked tracked2 = _slots[k];
						flag = tracked2 != null && (Object)(object)tracked2.Light != (Object)null && (tracked2.Dirty || tracked2.Face >= 0) && Reaches(tracked2, swing);
					}
					if (!flag)
					{
						Swings.RemoveAt(num);
					}
				}
			}
		}

		internal static void RefreshStand(ItemStand stand)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: 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_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)stand == (Object)null)
			{
				return;
			}
			StandCaster standCaster = Stands.Find((StandCaster s) => (Object)(object)s.Stand == (Object)(object)stand);
			if (standCaster == null)
			{
				standCaster = new StandCaster
				{
					Stand = stand,
					Version = ((Object)stand).GetInstanceID()
				};
				Stands.Add(standCaster);
			}
			Vector3 center = standCaster.Center;
			float radius = standCaster.Radius;
			bool flag = standCaster.Geometry != null && standCaster.Geometry.Length != 0;
			if (standCaster.Renderers != null)
			{
				Renderer[] renderers = standCaster.Renderers;
				foreach (Renderer item in renderers)
				{
					StandVisuals.Remove(item);
				}
			}
			GameObject val = ItemStandVisual.CurrentItem(stand);
			if ((Object)(object)val == (Object)null)
			{
				standCaster.Renderers = (Renderer[])(object)new Renderer[0];
				standCaster.Geometry = new Caster[0];
				standCaster.Center = ((Component)stand).transform.position;
				standCaster.Radius = 0.5f;
			}
			else
			{
				standCaster.Renderers = Array.FindAll(val.GetComponentsInChildren<Renderer>(true), (Renderer r) => (Object)(object)r != (Object)null && !(r is ParticleSystemRenderer) && !(r is TrailRenderer) && !(r is LineRenderer) && !SeeThrough(r));
				Bounds val2 = default(Bounds);
				bool flag2 = true;
				List<Caster> list = new List<Caster>(standCaster.Renderers.Length);
				Renderer[] renderers = standCaster.Renderers;
				Vector3 extents;
				foreach (Renderer val3 in renderers)
				{
					StandVisuals.Add(val3);
					if (flag2)
					{
						val2 = val3.bounds;
						flag2 = false;
					}
					else
					{
						((Bounds)(ref val2)).Encapsulate(val3.bounds);
					}
					SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((val3 is SkinnedMeshRenderer) ? val3 : null);
					int num2;
					if (val4 == null || !((Object)(object)val4.sharedMesh != (Object)null))
					{
						MeshFilter component = ((Component)val3).GetComponent<MeshFilter>();
						num2 = ((component == null || !((Object)(object)component.sharedMesh != (Object)null)) ? 1 : component.sharedMesh.subMeshCount);
					}
					else
					{
						num2 = val4.sharedMesh.subMeshCount;
					}
					int subs = num2;
					Bounds bounds = val3.bounds;
					Caster item2 = new Caster
					{
						R = val3,
						B = bounds
					};
					extents = ((Bounds)(ref bounds)).extents;
					item2.Radius = ((Vector3)(ref extents)).magnitude;
					item2.Subs = subs;
					list.Add(item2);
				}
				standCaster.Geometry = list.ToArray();
				standCaster.Center = (flag2 ? ((Component)stand).transform.position : ((Bounds)(ref val2)).center);
				StandCaster standCaster2 = standCaster;
				float radius2;
				if (!flag2)
				{
					extents = ((Bounds)(ref val2)).extents;
					radius2 = ((Vector3)(ref extents)).magnitude + 0.5f;
				}
				else
				{
					radius2 = 0.5f;
				}
				standCaster2.Radius = radius2;
			}
			standCaster.Version++;
			standCaster.ChangedFrame = (_standChangedFrame = Time.frameCount);
			if (flag)
			{
				QueueStaticItemChange(center, radius);
			}
			if (standCaster.Geometry.Length != 0)
			{
				QueueStaticItemChange(standCaster.Center, standCaster.Radius);
				standCaster.Handoff = true;
			}
			else
			{
				standCaster.Handoff = false;
			}
			if (standCaster.Handoff)
			{
				if (!PendingStands.Contains(standCaster))
				{
					PendingStands.Add(standCaster);
				}
			}
			else
			{
				PendingStands.Remove(standCaster);
			}
		}

		private static void UnregisterStand(ItemStand stand)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			for (int num = Stands.Count - 1; num >= 0; num--)
			{
				StandCaster standCaster = Stands[num];
				if (!((Object)(object)standCaster.Stand != (Object)(object)stand))
				{
					if (standCaster.Renderers != null)
					{
						Renderer[] renderers = standCaster.Renderers;
						foreach (Renderer item in renderers)
						{
							StandVisuals.Remove(item);
						}
					}
					QueueStaticItemChange(standCaster.Center, standCaster.Radius);
					PendingStands.Remove(standCaster);
					Stands.RemoveAt(num);
					_standChangedFrame = Time.frameCount;
				}
			}
		}

		private static void QueueStaticItemChange(Vector3 center, float radius)
		{
			//IL_004c: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			ShadowCache instance = Instance;
			if ((Object)(object)instance == (Object)null || !instance._active)
			{
				return;
			}
			Tracked[] slots = instance._slots;
			foreach (Tracked tracked in slots)
			{
				if (tracked == null || (Object)(object)tracked.Light == (Object)null)
				{
					continue;
				}
				float num = Range(tracked) + radius;
				Vector3 val = tracked.Center - center;
				if (!(((Vector3)(ref val)).sqrMagnitude > num * num))
				{
					int num2 = FacesFor(center - tracked.Center, radius);
					if (tracked.Face >= 0)
					{
						instance.AbortStage(tracked);
						tracked.Face = -1;
						tracked.Dirty = true;
					}
					else if (tracked.Ready && !tracked.Dirty)
					{
						tracked.DoorFaces |= num2;
					}
					else
					{
						tracked.Dirty = true;
					}
					tracked.DirtyAt = Time.time;
					tracked.DoorPrepared = false;
				}
			}
			instance.WakeRenders();
		}

		private void UpdateStandHandoffs()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			for (int num = PendingStands.Count - 1; num >= 0; num--)
			{
				StandCaster standCaster = PendingStands[num];
				if (!standCaster.Handoff)
				{
					PendingStands.RemoveAt(num);
				}
				else if (Time.frameCount > standCaster.ChangedFrame)
				{
					bool flag = false;
					Tracked[] slots = _slots;
					foreach (Tracked tracked in slots)
					{
						if (tracked != null && !((Object)(object)tracked.Light == (Objec