using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ScrapVisbility")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ScrapVisbility")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8a6853bd-bdc9-4741-95c7-5aa2c8c6a6f9")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace Extraction; [BepInPlugin("robert.lethalcompany.extraction", "Extraction", "0.2.49")] public sealed class Plugin : BaseUnityPlugin { private struct CubeShape { public Vector3 Center; public Vector3 Size; public CubeShape(Vector3 center, Vector3 size) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Center = center; Size = size; } } private struct DynamicBoundarySegment { public int Axis; public int Sign; public float FixedCoord; public float FromCoord; public float ToCoord; public DynamicBoundarySegment(int axis, int sign, float fixedCoord, float fromCoord, float toCoord) { Axis = axis; Sign = sign; FixedCoord = fixedCoord; FromCoord = fromCoord; ToCoord = toCoord; } } private struct ShipDoorAudioState { internal readonly bool Mute; internal readonly float Volume; internal ShipDoorAudioState(bool mute, float volume) { Mute = mute; Volume = volume; } } private sealed class ScrapGlowState { private readonly GrabbableObject _item; private readonly Dictionary _originalBlocks = new Dictionary(); private GameObject _lightObject; internal ScrapGlowState(GrabbableObject item) { _item = item; } internal void Apply() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00ed: 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_0117: 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_0133: 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_01bd: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_item == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)_item).GetComponentsInChildren(true); Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.03f, 0.02f, 1f); float num = Mathf.Max(0f, (_cubeScrapGlowEmissionStrength != null) ? _cubeScrapGlowEmissionStrength.Value : 4f); Color val2 = val * Mathf.Max(1f, num); Renderer[] array = componentsInChildren; foreach (Renderer val3 in array) { if (!((Object)(object)val3 == (Object)null) && val3.enabled && !(val3 is ParticleSystemRenderer)) { MaterialPropertyBlock val4 = new MaterialPropertyBlock(); val3.GetPropertyBlock(val4); _originalBlocks[val3] = val4; MaterialPropertyBlock val5 = new MaterialPropertyBlock(); val3.GetPropertyBlock(val5); val5.SetColor("_Color", val); val5.SetColor("_BaseColor", val); val5.SetColor("_TintColor", val); val5.SetColor("_MainColor", val); val5.SetColor("_EmissionColor", val2); val5.SetColor("_EmissiveColor", val2); val5.SetFloat("_UseEmissiveIntensity", 1f); val5.SetFloat("_EmissiveIntensity", num); val3.SetPropertyBlock(val5); } } float num2 = Mathf.Max(0f, (_cubeScrapGlowLightIntensity != null) ? _cubeScrapGlowLightIntensity.Value : 1.25f); if (num2 > 0f) { _lightObject = new GameObject("Extraction_CubeScrap_RedGlowLight"); _lightObject.transform.SetParent(((Component)_item).transform, false); _lightObject.transform.localPosition = Vector3.up * 0.15f; Light val6 = _lightObject.AddComponent(); val6.type = (LightType)2; val6.color = val; val6.intensity = num2; val6.range = Mathf.Max(0.25f, (_cubeScrapGlowLightRange != null) ? _cubeScrapGlowLightRange.Value : 2.25f); val6.shadows = (LightShadows)0; val6.renderMode = (LightRenderMode)1; } } internal void Restore() { foreach (KeyValuePair originalBlock in _originalBlocks) { if ((Object)(object)originalBlock.Key != (Object)null) { originalBlock.Key.SetPropertyBlock(originalBlock.Value); } } _originalBlocks.Clear(); if ((Object)(object)_lightObject != (Object)null) { Object.Destroy((Object)(object)_lightObject); _lightObject = null; } } } internal sealed class ScrapValueHighlighter : MonoBehaviour { private GrabbableObject item; private GameObject textObject; private TextMesh textMesh; private MeshRenderer textRenderer; private Material textMaterial; private GameObject lightObject; private Light glowLight; private readonly List targetRenderers = new List(); private readonly Dictionary blocks = new Dictionary(); private int lastValue = -999999; private string lastName = string.Empty; private Color lastColor = Color.clear; private bool textVisible; private float lastGoodTextVisibleTime; private static readonly FieldInfo fieldIsHeld = typeof(GrabbableObject).GetField("isHeld", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo fieldIsPocketed = typeof(GrabbableObject).GetField("isPocketed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo fieldIsHeldByEnemy = typeof(GrabbableObject).GetField("isHeldByEnemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo fieldPlayerHeldBy = typeof(GrabbableObject).GetField("playerHeldBy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo fieldCurrentlyHeldObjectServer = typeof(PlayerControllerB).GetField("currentlyHeldObjectServer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo fieldCurrentlyHeldObject = typeof(PlayerControllerB).GetField("currentlyHeldObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal void Init(GrabbableObject grabbable) { item = grabbable; CacheTargetRenderers(); CreateText(); CreateApparatusLight(); SetVisualsActive(active: false); } private void CacheTargetRenderers() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown targetRenderers.Clear(); blocks.Clear(); if ((Object)(object)item == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { string lowerName = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); if (!ShouldSkipRenderer(val, lowerName)) { targetRenderers.Add(val); blocks[val] = new MaterialPropertyBlock(); } } } } private bool ShouldSkipRenderer(Renderer renderer, string lowerName) { if ((Object)(object)renderer == (Object)null) { return true; } if (!renderer.enabled) { return true; } if (string.IsNullOrEmpty(lowerName)) { lowerName = ((Object)((Component)renderer).gameObject).name.ToLowerInvariant(); } string text = ((object)renderer).GetType().Name.ToLowerInvariant(); if (text.Contains("particle") || text.Contains("trail") || text.Contains("line")) { return true; } if (lowerName.Contains("scan") || lowerName.Contains("scannode") || lowerName.Contains("scan node") || lowerName.Contains("trigger") || lowerName.Contains("collider") || lowerName.Contains("collision") || lowerName.Contains("hitbox") || lowerName.Contains("interact") || lowerName.Contains("scrapvisibility") || lowerName.Contains("mapdot") || lowerName.Contains("radar") || lowerName.Contains("audio") || lowerName.Contains("sound") || lowerName.Contains("light") || lowerName.Contains("vfx") || lowerName.Contains("sfx")) { return true; } return false; } private void CreateText() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected O, but got Unknown //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)textObject != (Object)null) { return; } textObject = new GameObject("ScrapVisibility_3DText"); textObject.transform.SetParent(GetScrapTextRoot(), false); textObject.transform.position = ((Component)this).transform.position + Vector3.up * 0.5f; textObject.transform.rotation = Quaternion.identity; textObject.transform.localScale = Vector3.one; textMesh = textObject.AddComponent(); textMesh.text = string.Empty; textMesh.alignment = (TextAlignment)1; textMesh.anchor = (TextAnchor)4; textMesh.fontSize = 90; textMesh.characterSize = 0.022f; textMesh.color = Color.white; Font builtinResource = Resources.GetBuiltinResource("Arial.ttf"); if ((Object)(object)builtinResource != (Object)null) { textMesh.font = builtinResource; } textRenderer = textObject.GetComponent(); if ((Object)(object)textRenderer == (Object)null) { textRenderer = textObject.AddComponent(); } if ((Object)(object)textMesh.font != (Object)null && (Object)(object)textMesh.font.material != (Object)null) { textMaterial = new Material(textMesh.font.material); } else { Shader val = Shader.Find("GUI/Text Shader"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Transparent"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Sprites/Default"); } textMaterial = new Material(val); } ((Object)textMaterial).name = "ScrapVisibility_ReadableTextMaterial"; textMaterial.renderQueue = 3000; if (textMaterial.HasProperty("_Cull")) { textMaterial.SetInt("_Cull", 0); } if (textMaterial.HasProperty("_ZWrite")) { textMaterial.SetInt("_ZWrite", 0); } if (textMaterial.HasProperty("_Color")) { textMaterial.SetColor("_Color", Color.white); } if (textMaterial.HasProperty("_FaceColor")) { textMaterial.SetColor("_FaceColor", Color.white); } ((Renderer)textRenderer).sharedMaterial = textMaterial; ((Renderer)textRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)textRenderer).receiveShadows = false; } private void CreateApparatusLight() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)lightObject != (Object)null)) { lightObject = new GameObject("ScrapVisibility_ApparatusStyleLight"); lightObject.transform.SetParent(((Component)this).transform, false); lightObject.transform.localPosition = Vector3.zero; glowLight = lightObject.AddComponent(); glowLight.type = (LightType)2; glowLight.color = Color.white; glowLight.intensity = 6f; glowLight.range = 6f; ((Behaviour)glowLight).enabled = false; glowLight.shadows = (LightShadows)2; glowLight.renderMode = (LightRenderMode)1; glowLight.cullingMask = -1; glowLight.bounceIntensity = 1.2f; } } private void LateUpdate() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { DestroySelf(); return; } if ((Object)(object)item.itemProperties == (Object)null) { ClearGlow(); SetVisualsActive(active: false); return; } PlayerControllerB localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer == (Object)null || !localPlayer.isPlayerControlled || localPlayer.isPlayerDead) { ClearGlow(); SetVisualsActive(active: false); return; } if (IsHeldByAnyone(localPlayer)) { ClearGlow(); SetVisualsActive(active: false); return; } if (!((Component)item).gameObject.activeInHierarchy) { ClearGlow(); SetVisualsActive(active: false); return; } if (!TryGetBounds(out var bounds)) { ClearGlow(); SetVisualsActive(active: false); return; } float num = Vector3.Distance(((Component)localPlayer).transform.position, ((Bounds)(ref bounds)).center); if (_scrapVisibilityMaxDistance != null && num > _scrapVisibilityMaxDistance.Value) { ClearGlow(); SetVisualsActive(active: false); } else { UpdateVisuals(bounds, num); SetVisualsActive(active: true); } } private PlayerControllerB GetLocalPlayer() { if ((Object)(object)GameNetworkManager.Instance == (Object)null) { return null; } return GameNetworkManager.Instance.localPlayerController; } private bool IsHeldByAnyone(PlayerControllerB localPlayer) { if (GetBoolField(fieldIsHeld)) { return true; } if (GetBoolField(fieldIsPocketed)) { return true; } if (GetBoolField(fieldIsHeldByEnemy)) { return true; } if (GetObjectField(fieldPlayerHeldBy) != null) { return true; } if ((Object)(object)localPlayer != (Object)null) { object playerObjectField = GetPlayerObjectField(localPlayer, fieldCurrentlyHeldObjectServer); object playerObjectField2 = GetPlayerObjectField(localPlayer, fieldCurrentlyHeldObject); if (playerObjectField == item || playerObjectField2 == item) { return true; } } Transform parent = ((Component)item).transform.parent; if ((Object)(object)parent != (Object)null) { string text = ((Object)parent).name.ToLowerInvariant(); if (text.Contains("player") || text.Contains("hand") || text.Contains("hold") || text.Contains("itemholder") || text.Contains("pocket")) { return true; } } return false; } private bool GetBoolField(FieldInfo field) { if (field == null || (Object)(object)item == (Object)null) { return false; } object value = field.GetValue(item); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private object GetObjectField(FieldInfo field) { if (field == null || (Object)(object)item == (Object)null) { return null; } return field.GetValue(item); } private object GetPlayerObjectField(PlayerControllerB player, FieldInfo field) { if (field == null || (Object)(object)player == (Object)null) { return null; } return field.GetValue(player); } private bool TryGetBounds(out Bounds bounds) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //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) bounds = new Bounds(((Component)this).transform.position, Vector3.one * 0.25f); bool flag = false; foreach (Renderer targetRenderer in targetRenderers) { if ((Object)(object)targetRenderer == (Object)null) { continue; } string lowerName = ((Object)((Component)targetRenderer).gameObject).name.ToLowerInvariant(); if (!ShouldSkipRenderer(targetRenderer, lowerName) && ((Component)targetRenderer).gameObject.activeInHierarchy) { if (!flag) { bounds = targetRenderer.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(targetRenderer.bounds); } } } return flag; } private void UpdateVisuals(Bounds bounds, float distance) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)item.itemProperties != (Object)null && item.itemProperties.isScrap; int num = Mathf.Max(0, item.scrapValue); string text = "Item"; if ((Object)(object)item.itemProperties != (Object)null && !string.IsNullOrEmpty(item.itemProperties.itemName)) { text = item.itemProperties.itemName; } Color scrapDisplayColor = GetScrapDisplayColor(flag, num); if (ScrapIsRegisteredInsideCubeForVisuals(item)) { ((Color)(ref scrapDisplayColor))..ctor(1f, 0.03f, 0.02f, 1f); } float num2 = 0.78f + Mathf.Sin(Time.time * GetPulseSpeed()) * 0.22f; Color tintColor = Color.Lerp(Color.white, scrapDisplayColor, GetTintStrength()); tintColor.a = 1f; Color emissionColor = scrapDisplayColor * GetEmissionStrength() * num2; emissionColor.a = 1f; ApplyGlow(tintColor, emissionColor); if (num != lastValue || text != lastName || scrapDisplayColor != lastColor) { lastValue = num; lastName = text; lastColor = scrapDisplayColor; if ((Object)(object)textMesh != (Object)null) { if (flag) { textMesh.text = text + "\n$" + num; } else { textMesh.text = text; } } } UpdateApparatusLight(bounds, flag, num, scrapDisplayColor, num2); UpdateText(bounds, distance, scrapDisplayColor); } private void UpdateApparatusLight(Bounds bounds, bool isScrap, int value, Color color, float pulse) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)glowLight == (Object)null)) { float lightMultiplierForItem = GetLightMultiplierForItem(isScrap, value); ((Component)glowLight).transform.position = ((Bounds)(ref bounds)).center; glowLight.color = color; glowLight.intensity = GetLightIntensity() * lightMultiplierForItem * pulse; glowLight.range = GetLightRange() * lightMultiplierForItem; glowLight.bounceIntensity = 1.5f + lightMultiplierForItem * 0.35f; } } private float GetLightMultiplierForItem(bool isScrap, int value) { if (!isScrap) { return 1.25f; } if (value >= 300) { return 2.25f; } if (value >= 150) { return 1.8f; } if (value >= 100) { return 1.45f; } if (value >= 50) { return 1.15f; } return 0.9f; } private void ApplyGlow(Color tintColor, Color emissionColor) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (_showScrapModelGlow == null || !_showScrapModelGlow.Value) { ClearGlow(); return; } foreach (Renderer targetRenderer in targetRenderers) { if (!((Object)(object)targetRenderer == (Object)null)) { if (!blocks.TryGetValue(targetRenderer, out var value)) { value = new MaterialPropertyBlock(); blocks[targetRenderer] = value; } targetRenderer.GetPropertyBlock(value); value.SetColor("_Color", tintColor); value.SetColor("_BaseColor", tintColor); value.SetColor("_EmissionColor", emissionColor); value.SetColor("_EmissiveColor", emissionColor); targetRenderer.SetPropertyBlock(value); } } } private void ClearGlow() { foreach (Renderer targetRenderer in targetRenderers) { if (!((Object)(object)targetRenderer == (Object)null)) { targetRenderer.SetPropertyBlock((MaterialPropertyBlock)null); } } } private void UpdateText(Bounds bounds, float distance, Color color) { //IL_0066: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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) if ((Object)(object)textObject == (Object)null || (Object)(object)textMesh == (Object)null) { return; } Transform scrapTextRoot = GetScrapTextRoot(); if ((Object)(object)textObject.transform.parent != (Object)(object)scrapTextRoot) { textObject.transform.SetParent(scrapTextRoot, true); } textObject.transform.position = GetStableLabelPosition(bounds); Camera main = Camera.main; if ((Object)(object)main != (Object)null) { textObject.transform.rotation = ((Component)main).transform.rotation; } textVisible = IsObjectVisibleForText(bounds); textMesh.characterSize = GetTextSize(); textObject.transform.localScale = Vector3.one; textMesh.color = color; if ((Object)(object)textMaterial != (Object)null) { if (textMaterial.HasProperty("_Color")) { textMaterial.SetColor("_Color", color); } if (textMaterial.HasProperty("_FaceColor")) { textMaterial.SetColor("_FaceColor", color); } } } private Vector3 GetStableLabelPosition(Bounds bounds) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) return ((Bounds)(ref bounds)).center + Vector3.up * (((Bounds)(ref bounds)).extents.y + GetTextHeightOffset()); } private Vector3 GetParentScaleCompensatedLocalScale(float desiredWorldScale) { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_006d: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) Transform val = (((Object)(object)textObject != (Object)null) ? textObject.transform.parent : null); if ((Object)(object)val == (Object)null) { return Vector3.one * desiredWorldScale; } Vector3 lossyScale = val.lossyScale; return new Vector3(desiredWorldScale / SafeSignedScale(lossyScale.x), desiredWorldScale / SafeSignedScale(lossyScale.y), desiredWorldScale / SafeSignedScale(lossyScale.z)); } private float SafeSignedScale(float value) { if (Mathf.Abs(value) < 0.001f) { return (value < 0f) ? (-0.001f) : 0.001f; } return value; } private bool IsObjectVisibleForText(Bounds bounds) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0078: 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_0084: 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_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_009f: 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_00a7: 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) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ea: 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) //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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_014b: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: 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_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) if (_hideScrapTextBehindWalls == null || !_hideScrapTextBehindWalls.Value) { return true; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return true; } Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; Vector3[] array = (Vector3[])(object)new Vector3[15] { center, center + new Vector3(0f, extents.y, 0f), center - new Vector3(0f, extents.y, 0f), center + new Vector3(extents.x, 0f, 0f), center - new Vector3(extents.x, 0f, 0f), center + new Vector3(0f, 0f, extents.z), center - new Vector3(0f, 0f, extents.z), center + new Vector3(extents.x, extents.y, extents.z), center + new Vector3(0f - extents.x, extents.y, extents.z), center + new Vector3(extents.x, extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, extents.y, 0f - extents.z), center + new Vector3(extents.x, 0f - extents.y, extents.z), center + new Vector3(0f - extents.x, 0f - extents.y, extents.z), center + new Vector3(extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z) }; Vector3[] array2 = array; foreach (Vector3 point in array2) { if (PointIsOnScreenAndNotBlocked(main, point)) { lastGoodTextVisibleTime = Time.time; return true; } } float num = ((_scrapTextVisibilityGraceTime != null) ? Mathf.Max(0f, _scrapTextVisibilityGraceTime.Value) : 0.2f); return Time.time - lastGoodTextVisibleTime <= num; } private bool PointIsOnScreenAndNotBlocked(Camera cam, Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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) //IL_0080: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: 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) Vector3 val = cam.WorldToViewportPoint(point); if (val.z < 0f) { return false; } float num = ((_scrapScreenEdgeMargin != null) ? Mathf.Clamp(_scrapScreenEdgeMargin.Value, 0f, 0.35f) : 0.12f); if (val.x < 0f - num || val.x > 1f + num) { return false; } if (val.y < 0f - num || val.y > 1f + num) { return false; } Vector3 position = ((Component)cam).transform.position; Vector3 val2 = point - position; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.05f) { return true; } Vector3 normalized = ((Vector3)(ref val2)).normalized; position += normalized * 0.25f; float num2 = ((_scrapTextOcclusionPadding != null) ? Mathf.Clamp(_scrapTextOcclusionPadding.Value, 0.01f, 1f) : 0.12f); float num3 = Mathf.Max(0.05f, magnitude - num2); RaycastHit[] array = Physics.RaycastAll(position, normalized, num3, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return true; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); PlayerControllerB localPlayer = GetLocalPlayer(); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val3 = array2[i]; if ((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) { continue; } Transform transform = ((Component)((RaycastHit)(ref val3)).collider).transform; if ((Object)(object)textObject != (Object)null && transform.IsChildOf(textObject.transform)) { continue; } if (transform.IsChildOf(((Component)item).transform)) { return true; } GrabbableObject componentInParent = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)(object)item) { return true; } if ((!((Object)(object)localPlayer != (Object)null) || !transform.IsChildOf(((Component)localPlayer).transform)) && !((Object)(object)componentInParent != (Object)null)) { string text = ((Object)transform).name.ToLowerInvariant(); if (!text.Contains("player") && !text.Contains("camera") && !text.Contains("hand") && !text.Contains("itemholder") && !text.Contains("held") && !text.Contains("helmet") && !text.Contains("scan") && !text.Contains("trigger")) { return false; } } } return true; } private void SetVisualsActive(bool active) { bool flag = active && textVisible && _showScrapValueText != null && _showScrapValueText.Value; bool enabled = active && _showScrapLight != null && _showScrapLight.Value; if ((Object)(object)textObject != (Object)null && textObject.activeSelf != flag) { textObject.SetActive(flag); } if ((Object)(object)glowLight != (Object)null) { ((Behaviour)glowLight).enabled = enabled; } } private float GetTintStrength() { if (_scrapTintStrength == null) { return 1f; } return Mathf.Clamp01(_scrapTintStrength.Value); } private float GetEmissionStrength() { if (_scrapEmissionStrength == null) { return 5.5f; } return Mathf.Clamp(_scrapEmissionStrength.Value, 0f, 12f); } private float GetPulseSpeed() { if (_scrapPulseSpeed == null) { return 2.8f; } return Mathf.Max(0f, _scrapPulseSpeed.Value); } private float GetLightIntensity() { if (_scrapLightIntensity == null) { return 6f; } return Mathf.Clamp(_scrapLightIntensity.Value, 0f, 30f); } private float GetLightRange() { if (_scrapLightRange == null) { return 6f; } return Mathf.Clamp(_scrapLightRange.Value, 0f, 20f); } private float GetTextSize() { if (_scrapTextSize == null) { return 0.022f; } return Mathf.Clamp(_scrapTextSize.Value, 0.005f, 0.14f); } private float GetTextHeightOffset() { if (_scrapTextHeightOffset == null) { return 0.22f; } return Mathf.Clamp(_scrapTextHeightOffset.Value, 0f, 2f); } internal void DestroySelf() { ClearGlow(); if ((Object)(object)textObject != (Object)null) { Object.Destroy((Object)(object)textObject); textObject = null; } if ((Object)(object)lightObject != (Object)null) { Object.Destroy((Object)(object)lightObject); lightObject = null; } if ((Object)(object)textMaterial != (Object)null) { Object.Destroy((Object)(object)textMaterial); textMaterial = null; } Object.Destroy((Object)(object)this); } private void OnDestroy() { ClearGlow(); if ((Object)(object)textObject != (Object)null) { Object.Destroy((Object)(object)textObject); } if ((Object)(object)lightObject != (Object)null) { Object.Destroy((Object)(object)lightObject); } if ((Object)(object)textMaterial != (Object)null) { Object.Destroy((Object)(object)textMaterial); } } } [HarmonyPatch(typeof(EntranceTeleport), "StartOpeningEntrance")] private static class EntranceTeleport_StartOpeningEntrance_Patch { private static bool Prefix(EntranceTeleport __instance) { if (_disableFacilityExitInteractions == null || !_disableFacilityExitInteractions.Value) { return true; } ForceFacilityExitInteractionsDisabled(); D("Blocked facility entrance/fire-exit interaction: " + GetEntranceDebugName(__instance)); return false; } } [HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayer")] private static class EntranceTeleport_TeleportPlayer_Patch { private static bool Prefix(EntranceTeleport __instance) { if (_disableFacilityExitInteractions == null || !_disableFacilityExitInteractions.Value) { return true; } ForceFacilityExitInteractionsDisabled(); D("Blocked facility entrance/fire-exit teleport: " + GetEntranceDebugName(__instance)); return false; } } [HarmonyPatch(typeof(StartOfRound), "OpenShipDoors")] private static class StartOfRound_OpenShipDoors_Patch { private static void Postfix() { if (_keepShipDoorsClosed != null && _keepShipDoorsClosed.Value && !IsAtTheCompany()) { ForceShipDoorsClosedNow(); D("OpenShipDoors ran normally. Extraction hides the moving vanilla ship door and keeps the closed-door overlay."); } } } [HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")] private static class StartOfRound_OpeningDoorsSequence_Patch { private static void Postfix() { if (_keepShipDoorsClosed != null && _keepShipDoorsClosed.Value && !IsAtTheCompany()) { ForceShipDoorsClosedNow(); D("openingDoorsSequence ran normally. Extraction hides the moving vanilla ship door and keeps the closed-door overlay."); } } } [HarmonyPatch(typeof(HangarShipDoor), "SetDoorOpen")] private static class HangarShipDoor_SetDoorOpen_Patch { private static void Postfix(HangarShipDoor __instance) { if (_keepShipDoorsClosed != null && _keepShipDoorsClosed.Value && !IsAtTheCompany()) { ForceShipDoorsClosedNow(); } } } [HarmonyPatch(typeof(HangarShipDoor), "PlayDoorAnimation")] private static class HangarShipDoor_PlayDoorAnimation_Patch { private static void Postfix(HangarShipDoor __instance) { if (_keepShipDoorsClosed != null && _keepShipDoorsClosed.Value && !IsAtTheCompany()) { ForceShipDoorsClosedNow(); } } } [HarmonyPatch(typeof(StartOfRound), "ShipLeave")] private static class StartOfRound_ShipLeave_Patch { private static void Prefix() { D("[" + NetRoleDebugName() + "] StartOfRound.ShipLeave prefix fired."); DebugLogStateSnapshot("ShipLeave prefix before LocalShipLeavePrefix", force: true); LocalShipLeavePrefix(); } } [HarmonyPatch(typeof(StartOfRound), "ShipHasLeft")] private static class StartOfRound_ShipHasLeft_Patch { private static void Postfix() { _debugShipHasLeftCount++; D($"[{NetRoleDebugName()}] StartOfRound.ShipHasLeft postfix fired. count={_debugShipHasLeftCount}"); DebugLogStateSnapshot("ShipHasLeft before quota/reset", force: true); ApplyPendingQuotaValueOnHost("StartOfRound.ShipHasLeft postfix"); ResetRoundState(); } } [HarmonyPatch(typeof(HUDManager), "FillEndGameStats")] private static class HUDManager_FillEndGameStats_Patch { private static void Prefix() { D("HUDManager.FillEndGameStats prefix fired."); ApplyPendingQuotaValueOnHost("HUDManager.FillEndGameStats prefix"); } } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")] private static class RoundManager_FinishGeneratingNewLevelClientRpc_Patch { private static void Postfix() { NotifyPlayersFinishedGeneratingNewLevel(); } } [HarmonyPatch(typeof(TimeOfDay), "VoteShipToLeaveEarly")] private static class TimeOfDay_VoteShipToLeaveEarly_Patch { private static bool Prefix() { if (!BaseGameSpectatorVoteToLeaveDisabled()) { return true; } D("Blocked vanilla dead-spectator vote to leave early because DisableBaseGameSpectatorVoteToLeave is true."); if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("Vote to leave disabled", "The vanilla spectator vote to leave early is disabled by this mod.", false, false, "LC_Tip1"); } return false; } private static void Postfix() { if (!BaseGameSpectatorVoteToLeaveDisabled()) { ObserveBaseGameVoteToLeave("local vanilla VoteShipToLeaveEarly called"); } } } [HarmonyPatch(typeof(TimeOfDay), "SetShipLeaveEarlyServerRpc")] private static class TimeOfDay_SetShipLeaveEarlyServerRpc_Patch { private static bool Prefix() { if (!BaseGameSpectatorVoteToLeaveDisabled()) { return true; } D("Blocked vanilla SetShipLeaveEarlyServerRpc because DisableBaseGameSpectatorVoteToLeave is true."); return false; } } [HarmonyPatch(typeof(TimeOfDay), "AddVoteForShipToLeaveEarlyClientRpc")] private static class TimeOfDay_AddVoteForShipToLeaveEarlyClientRpc_Patch { private static void Postfix() { if (!BaseGameSpectatorVoteToLeaveDisabled()) { ObserveBaseGameVoteToLeave("vanilla AddVoteForShipToLeaveEarlyClientRpc fired"); } } } [HarmonyPatch(typeof(TimeOfDay), "SetShipLeaveEarlyClientRpc")] private static class TimeOfDay_SetShipLeaveEarlyClientRpc_Patch { private static void Postfix() { if (!BaseGameSpectatorVoteToLeaveDisabled()) { ObserveBaseGameVoteToLeave("vanilla SetShipLeaveEarlyClientRpc fired"); } } } [HarmonyPatch(typeof(HUDManager), "DisplaySpectatorVoteTip")] private static class HUDManager_DisplaySpectatorVoteTip_Patch { private static bool Prefix() { return !BaseGameSpectatorVoteToLeaveDisabled(); } } [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageServerRpc")] private static class HUDManager_AddPlayerChatMessageServerRpc_Patch { private static bool Prefix(string chatMessage, int playerId) { try { if (!IsServer()) { return true; } return !HandleChatCommand(chatMessage, playerId); } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Chat command handler failed: {arg}"); return true; } } } [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] private static class HUDManager_PingScan_performed_Patch { private static bool Prefix() { bool flag = ShouldBlockManualScanner(); if (flag) { D("Blocked manual right click scan because integrated scrap visibility is enabled."); } return !flag; } } [CompilerGenerated] private sealed class d__512 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int token; public Vector3 position; public string source; private int 5__1; private PlayerControllerB 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__512(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = 0; goto IL_0200; case 1: <>1__state = -1; goto IL_0087; case 2: <>1__state = -1; goto IL_0087; case 3: { <>1__state = -1; if (RoundStartTeleportSucceededLocally(position)) { _localCompletedRoundStartCubeTeleportToken = token; D($"Applied and completed round-start cube teleport locally. token={token}, source={source}, attempt={5__1 + 1}, pos={position}"); } else { D($"Applied round-start cube teleport locally but landing was not confirmed yet. Same-token retries remain allowed. token={token}, source={source}, attempt={5__1 + 1}, pos={position}"); } if (_localPendingRoundStartCubeTeleportToken == token) { _localPendingRoundStartCubeTeleportToken = -1; } return false; } IL_0087: if (_cubeExtractionPassed || ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving)) { break; } 5__2 = StartOfRound.Instance?.localPlayerController; if (IsLivingControlledConnectedPlayer(5__2)) { TeleportLocalPlayer(position, toShip: false); _lastLocalRoundStartCubeTeleportApplyTime = Time.realtimeSinceStartup; _localAppliedRoundStartCubeTeleportToken = token; <>2__current = null; <>1__state = 3; return true; } 5__1++; goto IL_0200; IL_0200: if (5__1 < 28) { if (5__1 > 0) { <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 1; return true; } <>2__current = null; <>1__state = 2; return true; } break; } if (_localPendingRoundStartCubeTeleportToken == token) { _localPendingRoundStartCubeTeleportToken = -1; } D($"Failed to apply round-start cube teleport locally before retry attempts ended. token={token}, source={source}"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__500 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Vector3 center; public int acceptedSyncSerial; public int cubeRoundId; private int 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__500(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>1__state = -2; } private bool MoveNext() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; _clientCubeVisualRefreshRunning = true; <>1__state = -3; 5__1 = 0; goto IL_02c5; case 1: { <>1__state = -3; if (acceptedSyncSerial != _clientAcceptedCubeSyncSerial) { D($"Stopped stale client visual refresh. capturedSerial={acceptedSyncSerial}, currentSerial={_clientAcceptedCubeSyncSerial}, capturedRoundId={cubeRoundId}, currentRoundId={_currentCubeNetworkRoundId}"); result = false; break; } if (cubeRoundId > 0 && cubeRoundId != _currentCubeNetworkRoundId) { D($"Stopped old-round client visual refresh. capturedRoundId={cubeRoundId}, currentRoundId={_currentCubeNetworkRoundId}"); result = false; break; } if (!_cubeNetworkRoundActive || !_hasCube) { D($"Stopped client visual refresh because cube/round inactive. active={_cubeNetworkRoundActive}, hasCube={_hasCube}, capturedSerial={acceptedSyncSerial}, currentSerial={_clientAcceptedCubeSyncSerial}, capturedRound={cubeRoundId}, currentRound={_currentCubeNetworkRoundId}"); result = false; break; } if (Vector3.Distance(center, _cubeCenter) > 0.15f) { D($"Stopped client visual refresh because center changed. capturedCenter={center}, currentCenter={_cubeCenter}"); result = false; break; } if ((Object)(object)_cubeVisual == (Object)null) { CreateOrMoveCubeVisual(_cubeCenter); } else { if (!_cubeVisual.activeSelf) { _cubeVisual.SetActive(true); } ForceCubeVisualVisible(); UpdateCubePulseVisual(force: true); } D($"Client forced Extraction Area visual visibility nudge {5__1 + 1}/6. visualExists={(Object)(object)_cubeVisual != (Object)null}, active={(Object)(object)_cubeVisual != (Object)null && _cubeVisual.activeSelf}, dynamicReady={_cubeDynamicFootprintReady}, cells={_cubeDynamicFootprintCells.Count}"); 5__1++; goto IL_02c5; } IL_02c5: if (5__1 < 6) { <>2__current = (object)new WaitForSeconds(0.75f); <>1__state = 1; result = true; } else { <>m__Finally1(); result = false; } goto end_IL_0000; } <>m__Finally1(); end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; _clientCubeVisualRefreshRunning = false; D($"[{NetRoleDebugName()}] ClientCubeVisualRefreshRoutine finished. capturedSerial={acceptedSyncSerial}, capturedRound={cubeRoundId}, currentSerial={_clientAcceptedCubeSyncSerial}, currentRound={_currentCubeNetworkRoundId}, {CubeStateDebugLine()}"); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__254 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ulong clientId; public string reason; private float[] 5__1; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__254(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = new float[3] { 0.35f, 1.25f, 3f }; 5__2 = 0; break; case 1: <>1__state = -1; if (!IsServer() || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.ConnectedClientsIds.Contains(clientId)) { return false; } SendFullExtractionStateToClient(clientId, $"{reason} attempt {5__2 + 1}", allowLateJoinTeleport: false); 5__2++; break; } if (5__2 < 5__1.Length) { <>2__current = (object)new WaitForSeconds(5__1[5__2]); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__478 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__478(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__479 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public IEnumerator original; public string source; private bool 5__1; private object 5__2; private Exception 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__479(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (original == null) { return false; } break; case 1: <>1__state = -1; ForceShipDoorsClosedNow(); 5__2 = null; break; } try { 5__1 = original.MoveNext(); 5__2 = (5__1 ? original.Current : null); } catch (Exception ex) { 5__3 = ex; D("Ship door coroutine wrapper from " + source + " failed: " + 5__3.Message); throw; } ForceShipDoorsClosedNow(); if (5__1) { <>2__current = 5__2; <>1__state = 1; return true; } ForceShipDoorsClosedNow(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__536 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float seconds; private float 5__1; private PlayerControllerB 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__536(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = Time.realtimeSinceStartup + Mathf.Max(0.25f, seconds); break; case 1: <>1__state = -1; 5__2 = null; break; } if (Time.realtimeSinceStartup < 5__1) { 5__2 = StartOfRound.Instance?.localPlayerController; if (!IsLivingControlledConnectedPlayer(5__2)) { return false; } if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving) { return false; } ApplyPlayerInsideFactoryState(5__2); <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__434 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string reason; private float 5__1; private float 5__2; private float 5__3; private int 5__4; private float 5__5; private float 5__6; private float 5__7; private string 5__8; private int 5__9; private int 5__10; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__434(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!IsServer() || !_hasCube || (Object)(object)StartOfRound.Instance == (Object)null) { return false; } _roundStartTeleportRoutineRunning = true; 5__1 = Mathf.Max(0f, (_roundStartTeleportDelay != null) ? _roundStartTeleportDelay.Value : 1.25f); if (5__1 > 0f) { <>2__current = (object)new WaitForSeconds(5__1); <>1__state = 1; return true; } <>2__current = null; <>1__state = 2; return true; case 1: <>1__state = -1; goto IL_00de; case 2: <>1__state = -1; goto IL_00de; case 3: <>1__state = -1; goto IL_017e; case 4: { <>1__state = -1; break; } IL_00de: 5__2 = Mathf.Max(0f, (_roundStartTeleportWaitForLandingSeconds != null) ? _roundStartTeleportWaitForLandingSeconds.Value : 12f); 5__3 = Time.realtimeSinceStartup; goto IL_017e; IL_017e: if (!IsRoundStartFacilityTeleportMomentSafe()) { if (!(5__2 <= 0f) && !(Time.realtimeSinceStartup - 5__3 >= 5__2)) { <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 3; return true; } D($"Round-start teleport landing wait expired after {5__2:0.0}s. Applying anyway."); } if (!IsServer() || !_hasCube || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.shipIsLeaving || _cubeExtractionPassed) { _roundStartTeleportRoutineRunning = false; return false; } _roundStartCubeTeleportToken++; 5__4 = _roundStartCubeTeleportToken; _roundStartTeleportTargetsByClient.Clear(); 5__5 = Mathf.Max(2f, (_roundStartTeleportRetrySeconds != null) ? _roundStartTeleportRetrySeconds.Value : 12f); 5__6 = Mathf.Clamp((_roundStartTeleportRetryInterval != null) ? _roundStartTeleportRetryInterval.Value : 0.75f, 0.15f, 3f); 5__7 = Time.realtimeSinceStartup + 5__5; _roundStartCubeTeleportWindowOpen = true; _roundStartCubeTeleportWindowEndTime = 5__7; 5__8 = (RoundStartTeleportUsesCube() ? "the Extraction Area" : "random facility spot"); D($"Started token-safe round-start facility teleport token={5__4}, destination={5__8}, reason={reason}, retrySeconds={5__5:0.0}, interval={5__6:0.00}"); 5__9 = 0; break; } if (Time.realtimeSinceStartup <= 5__7) { 5__9++; if (IsServer() && _hasCube && !((Object)(object)StartOfRound.Instance == (Object)null) && !StartOfRound.Instance.shipIsLeaving && !_cubeExtractionPassed) { 5__10 = TeleportAllControlledPlayersIntoFacilityOnHost(5__4, reason, 5__9); if (5__9 == 1 || 5__10 > 0) { D($"Round-start teleport pass {5__9} sent/applied token={5__4} to {5__10} living controlled player(s)."); } BroadcastCubePosition(); <>2__current = (object)new WaitForSeconds(5__6); <>1__state = 4; return true; } } _roundStartCubeTeleportWindowOpen = false; _roundStartCubeTeleportWindowEndTime = 0f; _roundStartTeleportRoutineRunning = false; BroadcastCubePosition(); D($"Round-start facility teleport retry window closed. token={5__4}"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__257 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__257(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; D("[" + NetRoleDebugName() + "] SpawnCubeAfterFrame entered. Pre-reset: " + RoundStateDebugLine() + " | " + CubeStateDebugLine()); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; D("[" + NetRoleDebugName() + "] SpawnCubeAfterFrame after one frame. Beginning new cube state setup."); _processedThisTakeoff = false; _cubeEffectiveHeightOverride = -1f; _cubeExtractionPassed = false; _earlyExtractionCountdownActive = false; _earlyExtractionCountdownEndTime = 0f; _earlyExtractionCountdownSecondsRemaining = 0; _earlyExtractionTriggered = false; ClearBaseGameSpectatorVoteToLeaveState("round cube spawn start", resetVanillaTimeOfDayFields: true); CaptureNormalShipLeaveAutomaticallyTime("round cube spawn start"); _earlyVoteEligible = false; _earlyVoteCount = 0; _earlyVoteRequired = 0; _localEarlyVoteSubmitted = false; _earlyVoteRosterKey = string.Empty; _earlyExtractionVotes.Clear(); _clientTrustedEarlyVotePlayers.Clear(); _lastEarlyVoteSyncSignature = string.Empty; _currentCubeScrapRawValue = 0; _currentCubeScrapCount = 0; _roundStartCubeTeleportWindowOpen = false; _roundStartCubeTeleportWindowEndTime = 0f; _roundStartTeleportRequested = false; _roundStartTeleportFloorReady = false; _roundStartTeleportStarted = false; _roundStartTeleportRoutineRunning = false; _cubePostReadyPlacementFinalized = false; _authoritativeCubeFootprintReadyForClients = false; _cubeDynamicFootprintAuthoritativeFromHost = false; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _cubeNetworkRoundActive = IsServer(); _currentCubeNetworkRoundId = (IsServer() ? _currentCubeNetworkRoundId : (-1)); _clientAcceptedCubeSyncSerial++; _trackedPressedVoteKeys.Clear(); _roundStartTeleportRequestTime = 0f; _roundStartTeleportRequestReason = string.Empty; _roundStartTeleportTargetsByClient.Clear(); _lastInsideFactoryBestEffortTimeByClient.Clear(); _lastInsideAudioLightingBestEffortTimeByClient.Clear(); _cachedInteriorEntranceReachabilityAnchors.Clear(); _cachedInteriorEntranceReachabilityAnchorsFrame = -1; _localPendingRoundStartCubeTeleportToken = -1; _localAppliedRoundStartCubeTeleportToken = -1; _localCompletedRoundStartCubeTeleportToken = -1; if (IsServer()) { _hostCubeNetworkRoundId++; if (_hostCubeNetworkRoundId <= 0) { _hostCubeNetworkRoundId = 1; } _currentCubeNetworkRoundId = _hostCubeNetworkRoundId; _cubeNetworkRoundActive = true; _cubeCenter = PickCubePosition(); _hasCube = true; D($"Host picked Extraction Area center: {_cubeCenter} for cubeRoundId={_currentCubeNetworkRoundId}"); DebugLogStateSnapshot("host picked cube before visual/broadcast", force: true); CreateOrMoveCubeVisual(_cubeCenter); DebugLogStateSnapshot("host after local visual create before first cube sync", force: true); BroadcastCubePosition(); if (_teleportPlayersToCubeOnRoundStart.Value) { RequestRoundStartCubeTeleport("round start cube placed"); } } else { D("Client finished dungeon generation. Waiting for host cube sync."); DebugLogStateSnapshot("client waiting for cube sync after dungeon generation", force: true); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string ModGuid = "robert.lethalcompany.extraction"; public const string ModName = "Extraction"; public const string ModVersion = "0.2.49"; private const string MsgCubeSync = "Extraction_CubeSync_v1"; private const string MsgTeleport = "Extraction_Teleport_v1"; private const string MsgQuotaSync = "Extraction_QuotaSync_v1"; private const string MsgCubeClosed = "Extraction_CubeClosed_v1"; private const string MsgEarlyVoteRequest = "Extraction_EarlyVoteRequest_v1"; private const string MsgEarlyVoteSync = "Extraction_EarlyVoteSync_v1"; private const string MsgRoundStartCubeTeleport = "Extraction_RoundStartCubeTeleport_v1"; internal static Plugin Instance; internal static ManualLogSource Log; private static Harmony _harmony; private static ConfigEntry _debugLogging; private static ConfigEntry _enableDebugCommands; private static ConfigEntry _hostOnlyDebugCommands; private static ConfigEntry _debugStateSnapshots; private static ConfigEntry _debugStateSnapshotInterval; private static ConfigEntry _debugVoteInput; private static ConfigEntry _debugInsideCubeChecks; private static ConfigEntry _debugCubeSyncPayloads; private static ConfigEntry _cubeSize; private static ConfigEntry _cubeHeight; private static ConfigEntry _cubeVisualAlpha; private static ConfigEntry _groundSnapRayStartHeight; private static ConfigEntry _groundSnapRayDistance; private static ConfigEntry _applyCompanyBuyingRate; private static ConfigEntry _requireAllControlledPlayersAlive; private static ConfigEntry _minDistanceFromShip; private static ConfigEntry _cubePlacementWallClearance; private static ConfigEntry _cubePlacementFloorInset; private static ConfigEntry _cubePlacementMaxFloorDrop; private static ConfigEntry _cubePlacementSearchRadius; private static ConfigEntry _cubePlacementSearchStep; private static ConfigEntry _cubePlacementMaxCandidates; private static ConfigEntry _cubePlacementRejectDangerTriggers; private static ConfigEntry _cubePlacementRequireNavMesh; private static ConfigEntry _cubePlacementRequireReachablePathFromEntrance; private static ConfigEntry _cubePlacementRejectBackfaceGeometry; private static ConfigEntry _cubePlacementPreferScrapSpawnAnchors; private static ConfigEntry _cubePlacementUseEntrancesAndFireExitsOnly; private static ConfigEntry _adaptiveForcefieldBounds; private static ConfigEntry _adaptiveForcefieldDynamicFootprint; private static ConfigEntry _forceFullSizeFootprint; private static ConfigEntry _adaptiveForcefieldFreezeShapeAfterBuild; private static ConfigEntry _adaptiveForcefieldSimplifyMesh; private static ConfigEntry _adaptiveForcefieldClearance; private static ConfigEntry _adaptiveForcefieldMinimumSide; private static ConfigEntry _adaptiveForcefieldFloorProbeStep; private static ConfigEntry _adaptiveForcefieldBoundaryInset; private static ConfigEntry _showInsideCubeHud; private static ConfigEntry _showInsideCubeTips; private static ConfigEntry _teleportPlayersToCubeOnRoundStart; private static ConfigEntry _roundStartTeleportToCube; private static ConfigEntry _roundStartTeleportDelay; private static ConfigEntry _roundStartTeleportRetrySeconds; private static ConfigEntry _roundStartTeleportRetryInterval; private static ConfigEntry _roundStartTeleportMaxWaitForFloorReady; private static ConfigEntry _roundStartTeleportMaintainInsideSeconds; private static ConfigEntry _roundStartTeleportWaitForLandingSeconds; private static ConfigEntry _enableCubeLight; private static ConfigEntry _cubeLightIntensity; private static ConfigEntry _cubeLightRange; private static ConfigEntry _enableCubeScrapGlow; private static ConfigEntry _cubeScrapGlowRefreshInterval; private static ConfigEntry _cubeScrapGlowEmissionStrength; private static ConfigEntry _cubeScrapGlowLightIntensity; private static ConfigEntry _cubeScrapGlowLightRange; private static ConfigEntry _enableEarlyExtractionVote; private static ConfigEntry _earlyExtractionVoteKey; private static ConfigEntry _earlyExtractionVoteSyncInterval; private static ConfigEntry _earlyExtractionCountdownSeconds; private static ConfigEntry _earlyExtractionVoteInsideToleranceMeters; private static ConfigEntry _earlyExtractionVoteLeaveGraceSeconds; private static ConfigEntry _roundStartTeleportReapplyIntervalSeconds; private static ConfigEntry _disableBaseGameSpectatorVoteToLeave; private static ConfigEntry _keepShipDoorsClosed; private static ConfigEntry _disableFacilityExitInteractions; private static ConfigEntry _enableScrapVisibility; private static ConfigEntry _disableManualRightClickScan; private static ConfigEntry _showScrapValueText; private static ConfigEntry _showScrapModelGlow; private static ConfigEntry _showScrapLight; private static ConfigEntry _hideScrapTextBehindWalls; private static ConfigEntry _scrapVisibilityMaxDistance; private static ConfigEntry _scrapVisibilityRefreshInterval; private static ConfigEntry _scrapTextSize; private static ConfigEntry _scrapTextHeightOffset; private static ConfigEntry _scrapTintStrength; private static ConfigEntry _scrapEmissionStrength; private static ConfigEntry _scrapLightIntensity; private static ConfigEntry _scrapLightRange; private static ConfigEntry _scrapPulseSpeed; private static ConfigEntry _scrapTextOcclusionPadding; private static ConfigEntry _scrapScreenEdgeMargin; private static ConfigEntry _scrapTextVisibilityGraceTime; private static GameObject _cubeVisual; private static string _cubeVisualMeshSignature = string.Empty; private static bool _clientCubeVisualRefreshRunning; private static GameObject _cubeLightObject; private static GameObject _shipDoorClosedOverlay; private static GameObject _shipDoorFallbackPanel; private static Material _shipDoorFallbackMaterial; private static bool _shipDoorOverlaySourceMissingLogged; private static readonly Dictionary _shipDoorOriginalRendererStates = new Dictionary(); private static readonly Dictionary _shipDoorOriginalAudioStates = new Dictionary(); private static readonly Dictionary _glowingCubeScrap = new Dictionary(); private static bool _localPlayerInsideCube; private static float _cubeScrapGlowTimer; private GUIStyle _insideCubeHudStyle; private static Vector3 _cubeCenter; private static Vector3 _cubeDimensions = new Vector3(6f, 6f, 6f); private static float _cubeEffectiveHeightOverride = -1f; private static bool _cubeDynamicFootprintReady; private static float _cubeDynamicFootprintCellSize = 0.75f; private static float _cubeDynamicFootprintBottomY; private static float _cubeDynamicFootprintHorizontalSize = 6f; private static float _cubeDynamicFootprintHeight = 6f; private static Bounds _cubeDynamicFootprintBounds; private static readonly HashSet _cubeDynamicFootprintCells = new HashSet(); private static bool _cubeDynamicFootprintLocked; private static Vector3 _cubeDynamicFootprintLockedCenter; private static float _cubeDynamicFootprintLockedSize; private static float _cubeDynamicFootprintLockedHeight; private static float _cubeDynamicFootprintLockedCellSize; private static bool _cubeDynamicFootprintAuthoritativeFromHost; private static bool _cubeDynamicFootprintWaitingForAuthoritativeHostSync; private static bool _authoritativeCubeFootprintReadyForClients; private static int _hostCubeNetworkRoundId; private static int _currentCubeNetworkRoundId = -1; private static int _lastAcceptedCubeNetworkRoundId = -1; private static bool _cubeNetworkRoundActive; private static int _clientAcceptedCubeSyncSerial; private static Mesh _cubeDynamicFootprintSurfaceMesh; private static Mesh _cubeDynamicFootprintFrameMesh; private static Mesh _cubeDynamicFootprintBandMesh; private static bool _hasCube; private static bool _processedThisTakeoff; private static bool _messagesRegistered; private static bool _clientConnectCallbackRegistered; private static NetworkManager _registeredNetworkManager; private static NetworkManager _lastObservedNetworkManager; private static bool _networkSessionStateInitialized; private static bool _lastObservedIsListening; private static bool _lastObservedIsClient; private static bool _lastObservedIsServer; private static ulong _lastObservedLocalClientId = ulong.MaxValue; private static int _lastObservedThisClientPlayerId = -999; private static RoundManager _eventSubscribedRoundManager; private static bool _cubeExtractionPassed; private static float _cubeScrapValueTimer; private static int _currentCubeScrapRawValue; private static int _currentCubeScrapCount; private static int _pendingQuotaValue; private static int _pendingRawValue; private static int _pendingItemCount; private static bool _pendingQuotaApplied; private static Transform _scrapTextRoot; private static float _scrapVisibilityAttachTimer; private static readonly HashSet _earlyExtractionVotes = new HashSet(); private static bool _earlyVoteEligible; private static int _earlyVoteCount; private static int _earlyVoteRequired; private static bool _localEarlyVoteSubmitted; private static bool _earlyExtractionCountdownActive; private static float _earlyExtractionCountdownEndTime; private static int _earlyExtractionCountdownSecondsRemaining; private static bool _earlyExtractionTriggered; private static bool _baseGameVoteToLeaveUrgencyActive; private static bool _baseGameVoteToLeaveObserved; private static bool _normalShipLeaveAutomaticallyTimeCaptured; private static float _normalShipLeaveAutomaticallyTime = -1f; private static string _earlyVoteRosterKey = string.Empty; private static string _lastEarlyVoteSyncSignature = string.Empty; private static float _earlyVoteSyncTimer; private static bool _earlyVoteRequestPendingAck; private static int _earlyVoteRequestPendingPlayerId = -1; private static int _earlyVoteRequestSequence; private static float _earlyVoteRequestNextSendTime; private static float _earlyVoteRequestStopTime; private static bool _earlyVoteRequestTimeoutLogged; private static readonly Dictionary _earlyVoteLeftCubeSince = new Dictionary(); private static readonly HashSet _clientTrustedEarlyVotePlayers = new HashSet(); private static bool _roundStartCubeTeleportWindowOpen; private static int _roundStartCubeTeleportToken; private static int _localAppliedRoundStartCubeTeleportToken = -1; private static int _localCompletedRoundStartCubeTeleportToken = -1; private static int _localPendingRoundStartCubeTeleportToken = -1; private static float _lastLocalRoundStartCubeTeleportApplyTime; private static float _roundStartCubeTeleportWindowEndTime; private static bool _roundStartTeleportRequested; private static bool _roundStartTeleportFloorReady; private static bool _roundStartTeleportStarted; private static float _roundStartTeleportRequestTime; private static string _roundStartTeleportRequestReason = string.Empty; private static bool _roundStartTeleportRoutineRunning; private static bool _cubePostReadyPlacementFinalized; private static readonly Dictionary _roundStartTeleportTargetsByClient = new Dictionary(); private static readonly Dictionary _lastInsideFactoryBestEffortTimeByClient = new Dictionary(); private static readonly Dictionary _lastInsideAudioLightingBestEffortTimeByClient = new Dictionary(); private static Type _audioReverbTriggerType; private static bool _audioReverbTriggerTypeSearched; private static readonly List _cachedInteriorEntranceReachabilityAnchors = new List(); private static int _cachedInteriorEntranceReachabilityAnchorsFrame = -1; private static bool _legacyInputFailureLogged; private static bool _inputSystemFailureLogged; private static readonly HashSet _trackedPressedVoteKeys = new HashSet(); private static float _debugStateSnapshotTimer; private static float _debugVoteBlockLogTimer; private static string _lastDebugVoteBlockReason = string.Empty; private static float _debugHostVoteGateLogTimer; private static string _lastDebugHostVoteGateReason = string.Empty; private static float _debugInsideCubeLogTimer; private static bool _lastDebugInsideCubeState; private static float _debugCubeSyncLogTimer; private static int _debugCubeSyncSendCount; private static int _debugCubeSyncReceiveCount; private static int _debugCubeSyncRejectCount; private static int _debugEarlyVoteRequestSendCount; private static int _debugEarlyVoteRequestReceiveCount; private static int _debugEarlyVoteSyncReceiveCount; private static int _debugRoundResetCount; private static int _debugShipHasLeftCount; private static bool _navMeshReflectionInitialized; private static bool _navMeshReflectionAvailable; private static bool _navMeshUnavailableLogged; private static Type _navMeshType; private static Type _navMeshHitType; private static MethodInfo _navMeshSamplePositionMethod; private static Type _navMeshPathType; private static MethodInfo _navMeshCalculatePathMethod; private static PropertyInfo _navMeshPathStatusProperty; private static bool _navMeshPathUnavailableLogged; private static bool _entrancePathUnavailableLogged; private static PropertyInfo _navMeshHitPositionProperty; private static FieldInfo _navMeshHitPositionField; private float _lateSyncTimer; private float _exitInteractionClampTimer; private void Awake() { //IL_0d47: Unknown result type (might be due to invalid IL or missing references) //IL_0d51: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _debugLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugLogging", true, "Write detailed Extraction logs to the BepInEx console/log file."); _enableDebugCommands = ((BaseUnityPlugin)this).Config.Bind("Debug", "EnableChatDebugCommands", true, "Enables chat commands: tpcube, endday, cubepos, countcube, extractionhelp, extractionstate, extractionplayers, extractionvotes."); _hostOnlyDebugCommands = ((BaseUnityPlugin)this).Config.Bind("Debug", "HostOnlyDebugCommands", true, "Only the host can use debug commands."); _debugStateSnapshots = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugStateSnapshots", true, "Writes periodic host/client diagnostic snapshots while a round is active. Use this when tracking desync after death/respawn."); _debugStateSnapshotInterval = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugStateSnapshotIntervalSeconds", 5f, "Seconds between periodic Extraction diagnostic snapshots while DebugStateSnapshots is true."); _debugVoteInput = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugVoteInput", true, "Logs every early extraction vote input gate and vote network request. Useful when the R prompt is visible but voting fails."); _debugInsideCubeChecks = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugInsideCubeChecks", true, "Logs local player inside Extraction Area checks when the result changes or periodically while active."); _debugCubeSyncPayloads = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugCubeSyncPayloads", true, "Logs detailed cube sync payload data including round id, cell counts, hashes, shape source, and stale sync rejection."); _cubeSize = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubeSizeMeters", 6f, "Horizontal size of the Extraction Area in meters. This controls width and depth only."); _cubeHeight = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubeHeightMeters", 6f, "Requested roof height of the Extraction Area in meters. The mod will try to place the area where this full height fits. If it cannot, it retries at 80% height steps."); _cubeVisualAlpha = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubeVisualAlpha", 0.1f, "Transparency of the Extraction Area visual. 0 is invisible. 1 is solid. Default is 0.1."); _groundSnapRayStartHeight = ((BaseUnityPlugin)this).Config.Bind("Cube", "GroundSnapRayStartHeight", 6f, "How far above the picked node to start the downward floor snap ray."); _groundSnapRayDistance = ((BaseUnityPlugin)this).Config.Bind("Cube", "GroundSnapRayDistance", 20f, "How far below the picked node to search for floor when placing the Extraction Area."); _minDistanceFromShip = ((BaseUnityPlugin)this).Config.Bind("Cube", "MinimumDistanceFromShip", 25, "Try to place the Extraction Area at least this many meters from the ship/elevator transform."); _cubePlacementWallClearance = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementWallClearanceMeters", 2.5f, "Extra empty space required past the Extraction Area footprint when choosing a spawn position. Higher values keep the placement farther from walls and map edges."); _cubePlacementFloorInset = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementFloorSampleInsetMeters", 0.2f, "How far inside the Extraction Area edge the floor safety samples are checked. Smaller values are stricter near voids and ledges."); _cubePlacementMaxFloorDrop = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementMaxFloorDropMeters", 1.25f, "Maximum allowed drop from an inside AI node to the snapped floor. Prevents snapping the Extraction Area down into pits, lower catwalk kill boxes, or the void."); _cubePlacementSearchRadius = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementSearchRadiusMeters", 12f, "How far around each inside AI node to search for a centered safe cube position."); _cubePlacementSearchStep = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementSearchStepMeters", 1.5f, "Grid step used while searching around an inside AI node for a safe cube position."); _cubePlacementMaxCandidates = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementMaxCandidates", 8000, "Maximum number of cube placement candidates to test before using the safest emergency fallback."); _cubePlacementRejectDangerTriggers = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementRejectDangerTriggers", true, "Reject cube positions overlapping kill boxes, death triggers, out-of-bounds triggers, pits, or other dangerous trigger volumes."); _cubePlacementRequireNavMesh = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementRequireNavMesh", true, "Require the Extraction Area teleport spot to be close to the facility navmesh when Unity exposes it. This helps prevent out-of-map or unreachable placements."); _cubePlacementRequireReachablePathFromEntrance = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementRequireReachablePathFromEntrance", true, "Require the Extraction Area center/player spawn spot to have a complete NavMesh path from an interior entrance. This is the main guard against inaccessible prefab corners, voids, and out-of-map rooms."); _cubePlacementRejectBackfaceGeometry = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementRejectBackfaceGeometry", true, "Reject spots where physics rays detect the player is on the back side of one-sided level geometry. This catches many out-of-bounds/backside-wall cases."); _cubePlacementPreferScrapSpawnAnchors = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementPreferScrapSpawnAnchors", true, "Legacy fallback only. Ignored when CubePlacementUseEntrancesAndFireExitsOnly is true."); _cubePlacementUseEntrancesAndFireExitsOnly = ((BaseUnityPlugin)this).Config.Bind("Cube", "CubePlacementUseEntrancesAndFireExitsOnly", true, "If true, the Extraction Area only spawns at the real underground/interior side of main entrances and fire exits. This avoids slow wide-area searches, surface door spawns, and unreachable prefab corners."); _adaptiveForcefieldBounds = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldBounds", true, "If true, the Extraction Area forcefield uses adaptive environment shaping instead of clipping through walls, ledges, pits, and non-navmesh space. Props are ignored."); _adaptiveForcefieldDynamicFootprint = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldDynamicFootprint", true, "If true, the Extraction Area uses a connected navmesh footprint that can form L shapes and wrap around invalid walkable space instead of only resizing as a box."); _forceFullSizeFootprint = ((BaseUnityPlugin)this).Config.Bind("Cube", "ForceFullSizeFootprint", false, "If true, the Extraction Area always uses the full configured box size for its visual and detection area. It will not shrink or carve around walls, ceilings, pits, or navmesh cells. This can clip through the level by design."); _adaptiveForcefieldFreezeShapeAfterBuild = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldFreezeShapeAfterBuild", true, "If true, the Extraction Area calculates its dynamic footprint once when spawned, then never recalculates it until the Extraction Area is moved for a new round."); _adaptiveForcefieldSimplifyMesh = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldSimplifyMesh", true, "If true, merges dynamic forcefield cell slices into long faces and main corners after the footprint is finalized."); _adaptiveForcefieldClearance = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldClearanceMeters", 0.18f, "Gap kept between the forcefield wall and nearby level geometry or ceiling when adaptive bounds are enabled."); _adaptiveForcefieldMinimumSide = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldMinimumSideMeters", 1.25f, "Smallest horizontal side the Extraction Area forcefield may shrink to when adaptive bounds are enabled."); _adaptiveForcefieldFloorProbeStep = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldFloorProbeStepMeters", 0.45f, "Step size used to stop the adaptive Extraction Area bounds before non-navmesh cells, floor gaps, pits, or unsupported catwalk edges."); _adaptiveForcefieldBoundaryInset = ((BaseUnityPlugin)this).Config.Bind("Cube", "AdaptiveForcefieldBoundaryInsetMeters", 0f, "Deprecated. Boundary inset is ignored and kept at 0 so the forcefield footprint is not artificially shrunken."); if (_adaptiveForcefieldBoundaryInset != null && _adaptiveForcefieldBoundaryInset.Value > 0f) { _adaptiveForcefieldBoundaryInset.Value = 0f; } _showInsideCubeHud = ((BaseUnityPlugin)this).Config.Bind("HUD", "ShowInsideCubeHud", true, "Show an on-screen message while your local player is inside the Extraction Area."); _showInsideCubeTips = ((BaseUnityPlugin)this).Config.Bind("HUD", "ShowInsideCubeEnterExitTips", true, "Legacy config. No longer used because cube detection now only updates the HUD overlay."); _teleportPlayersToCubeOnRoundStart = ((BaseUnityPlugin)this).Config.Bind("Rules", "TeleportPlayersToCubeOnRoundStart", true, "Master toggle for round-start facility teleport. If false, players stay wherever vanilla puts them."); _roundStartTeleportToCube = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartTeleportToCube", true, "If true, round-start teleport sends players to the Extraction Area. If false, players are sent to a random safe facility position and must find the Extraction Area."); _roundStartTeleportDelay = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartCubeTeleportDelaySeconds", 1.25f, "Delay after the game reports players finished generating the floor before the teleport routine begins."); _roundStartTeleportRetrySeconds = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartCubeTeleportRetrySeconds", 12f, "How long the host keeps resending the same round-start teleport token. Clients only apply that token once."); _roundStartTeleportRetryInterval = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartCubeTeleportRetryIntervalSeconds", 0.75f, "How often the host resends the same round-start teleport token during the retry window."); _roundStartTeleportMaxWaitForFloorReady = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartCubeTeleportMaxWaitForFloorReadySeconds", 45f, "Fallback only. If the game never fires the fully-ready level callback, start round-start facility teleport after this many seconds."); _roundStartTeleportMaintainInsideSeconds = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartMaintainInsideStateSeconds", 8f, "After round-start teleport, keep reapplying inside-factory player flags for this long to stop vanilla from snapping players back to ship state."); _roundStartTeleportWaitForLandingSeconds = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartWaitForLandingMaxSeconds", 12f, "Maximum extra time to wait for the ship/round start state before applying the facility teleport."); _enableCubeLight = ((BaseUnityPlugin)this).Config.Bind("Visuals", "EnableCubeLight", true, "Adds a yellow point light inside the Extraction Area."); _cubeLightIntensity = ((BaseUnityPlugin)this).Config.Bind("Visuals", "CubeLightIntensity", 2.2f, "Point light intensity for the Extraction Area."); _cubeLightRange = ((BaseUnityPlugin)this).Config.Bind("Visuals", "CubeLightRange", 7.5f, "Point light range for the Extraction Area."); _enableCubeScrapGlow = ((BaseUnityPlugin)this).Config.Bind("Visuals", "EnableCubeScrapGlow", true, "Loose scrap currently inside the Extraction Area glows red. This is visual only."); _cubeScrapGlowRefreshInterval = ((BaseUnityPlugin)this).Config.Bind("Visuals", "CubeScrapGlowRefreshInterval", 0.15f, "How often to refresh red glow state for scrap inside the Extraction Area."); _cubeScrapGlowEmissionStrength = ((BaseUnityPlugin)this).Config.Bind("Visuals", "CubeScrapGlowEmissionStrength", 4f, "Red emission strength used on scrap that is inside the Extraction Area."); _cubeScrapGlowLightIntensity = ((BaseUnityPlugin)this).Config.Bind("Visuals", "CubeScrapGlowLightIntensity", 1.25f, "Small red point light intensity on scrap that is inside the Extraction Area. Set to 0 to disable item lights."); _cubeScrapGlowLightRange = ((BaseUnityPlugin)this).Config.Bind("Visuals", "CubeScrapGlowLightRange", 2.25f, "Small red point light range on scrap that is inside the Extraction Area."); _enableEarlyExtractionVote = ((BaseUnityPlugin)this).Config.Bind("Rules", "EnableEarlyExtractionVote", true, "If true, living players can vote from inside the Extraction Area to extract early. Players do not all need to be inside at the same time."); _earlyExtractionVoteKey = ((BaseUnityPlugin)this).Config.Bind("Rules", "EarlyExtractionVoteKey", (KeyCode)114, "Key used to vote for early extraction while the local living player is inside the Extraction Area."); _earlyExtractionVoteSyncInterval = ((BaseUnityPlugin)this).Config.Bind("Rules", "EarlyExtractionVoteSyncInterval", 0.2f, "How often the host refreshes the early extraction vote HUD state while eligible."); _earlyExtractionCountdownSeconds = ((BaseUnityPlugin)this).Config.Bind("Rules", "EarlyExtractionCountdownSeconds", 10f, "Seconds to wait after all living players have voted before early extraction starts. If a voter leaves the Extraction Area, only that player's vote is removed and the other votes stay."); _earlyExtractionVoteInsideToleranceMeters = ((BaseUnityPlugin)this).Config.Bind("Rules", "EarlyExtractionVoteInsideToleranceMeters", 0.75f, "Extra horizontal tolerance used only for early extraction voting. This stops edge jitter from removing votes when the full-size box is enabled."); _earlyExtractionVoteLeaveGraceSeconds = ((BaseUnityPlugin)this).Config.Bind("Rules", "EarlyExtractionVoteLeaveGraceSeconds", 1.5f, "How long a recorded voter may be outside the Extraction Area before only their vote is removed."); _roundStartTeleportReapplyIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind("Rules", "RoundStartCubeTeleportReapplyIntervalSeconds", 0.65f, "Minimum seconds between reapplying the same round-start teleport token on clients. Reapplying protects against vanilla/modded snapback after landing."); _disableBaseGameSpectatorVoteToLeave = ((BaseUnityPlugin)this).Config.Bind("Rules", "DisableBaseGameSpectatorVoteToLeave", false, "If true, blocks the vanilla dead-spectator vote to leave early. This does not affect the Extraction Area early extraction vote."); _keepShipDoorsClosed = ((BaseUnityPlugin)this).Config.Bind("Rules", "KeepShipDoorsClosed", true, "If true, players see and collide with a closed ship door overlay and the door buttons are disabled. Vanilla door coroutines are allowed to run so level loading does not get stuck."); _disableFacilityExitInteractions = ((BaseUnityPlugin)this).Config.Bind("Rules", "DisableFacilityExitInteractions", true, "If true, main entrances and fire exits cannot be used and their interact prompts are hidden. Players must leave through the Extraction Area."); if (Mathf.Approximately(_cubeSize.Value, 3f)) { _cubeSize.Value = 6f; } if (Mathf.Approximately(_cubeVisualAlpha.Value, 0.5f)) { _cubeVisualAlpha.Value = 0.1f; } if (Mathf.Approximately(_cubePlacementWallClearance.Value, 0.65f) || Mathf.Approximately(_cubePlacementWallClearance.Value, 1.75f)) { _cubePlacementWallClearance.Value = 2.5f; } if (Mathf.Approximately(_cubePlacementFloorInset.Value, 0.45f)) { _cubePlacementFloorInset.Value = 0.2f; } if (_cubePlacementMaxCandidates.Value == 4500) { _cubePlacementMaxCandidates.Value = 8000; } if (Mathf.Approximately(_cubePlacementSearchRadius.Value, 9f)) { _cubePlacementSearchRadius.Value = 12f; } if (Mathf.Approximately(_roundStartTeleportDelay.Value, 2.5f) || Mathf.Approximately(_roundStartTeleportDelay.Value, 0.75f)) { _roundStartTeleportDelay.Value = 1.25f; } if (Mathf.Approximately(_roundStartTeleportRetrySeconds.Value, 0f) || Mathf.Approximately(_roundStartTeleportRetrySeconds.Value, 16f) || Mathf.Approximately(_roundStartTeleportRetrySeconds.Value, 28f)) { _roundStartTeleportRetrySeconds.Value = 12f; } if (Mathf.Approximately(_roundStartTeleportRetryInterval.Value, 0f) || Mathf.Approximately(_roundStartTeleportRetryInterval.Value, 1f)) { _roundStartTeleportRetryInterval.Value = 0.75f; } _enableScrapVisibility = ((BaseUnityPlugin)this).Config.Bind("General", "Enable integrated scrap visibility", true, "If true, the Extraction Area uses the original ScrapVisibility highlighter code inside this plugin. This includes tools/non-scrap items."); _disableManualRightClickScan = ((BaseUnityPlugin)this).Config.Bind("General", "Disable manual right click scan", true, "If true, normal right click scan is blocked."); _showScrapModelGlow = ((BaseUnityPlugin)this).Config.Bind("Display", "Show model glow", true, "Tints the real item model."); _showScrapValueText = ((BaseUnityPlugin)this).Config.Bind("Display", "Show 3D text", true, "Show item name and value above scrap, and item names above tools/non-scrap items."); _showScrapLight = ((BaseUnityPlugin)this).Config.Bind("Display", "Show apparatus style light", true, "Adds a real 3D point light to items."); _hideScrapTextBehindWalls = ((BaseUnityPlugin)this).Config.Bind("Display", "Hide text behind walls", true, "If true, text label hides when the item itself is blocked by walls."); _scrapVisibilityMaxDistance = ((BaseUnityPlugin)this).Config.Bind("Visibility", "Max display distance", 120f, "Maximum distance for item highlights and labels."); _scrapVisibilityRefreshInterval = ((BaseUnityPlugin)this).Config.Bind("Performance", "Refresh interval", 1f, "How often the mod searches for items."); _scrapTintStrength = ((BaseUnityPlugin)this).Config.Bind("Display", "Tint strength", 1f, "How strongly the model gets tinted."); _scrapEmissionStrength = ((BaseUnityPlugin)this).Config.Bind("Display", "Emission strength", 5.5f, "How strongly the material emission is pushed."); _scrapTextSize = ((BaseUnityPlugin)this).Config.Bind("Display", "Text size", 0.022f, "Base size of the 3D text above items."); _scrapTextHeightOffset = ((BaseUnityPlugin)this).Config.Bind("Display", "Text height offset", 0.38f, "How far above the item the text floats."); _scrapLightIntensity = ((BaseUnityPlugin)this).Config.Bind("Display", "Light intensity", 6f, "Base brightness of the apparatus style light."); _scrapLightRange = ((BaseUnityPlugin)this).Config.Bind("Display", "Light range", 6f, "Base range of the apparatus style light."); _scrapPulseSpeed = ((BaseUnityPlugin)this).Config.Bind("Display", "Pulse speed", 2.8f, "How fast the glow pulses."); _scrapTextOcclusionPadding = ((BaseUnityPlugin)this).Config.Bind("Display", "Text occlusion padding", 0.12f, "How much of the end of the ray to ignore when checking if the item is blocked."); _scrapScreenEdgeMargin = ((BaseUnityPlugin)this).Config.Bind("Display", "Screen edge margin", 0.12f, "Extra margin around the screen so text still shows near the edge/peripheral view."); _scrapTextVisibilityGraceTime = ((BaseUnityPlugin)this).Config.Bind("Display", "Text visibility grace time", 0.2f, "How long text stays visible after one bad raycast. Helps stop flicker while moving."); _applyCompanyBuyingRate = ((BaseUnityPlugin)this).Config.Bind("Payout", "ApplyCompanyBuyingRate", false, "If true, cube scrap payout is multiplied by the current company buying rate. If false, full scrap value goes toward quota."); _requireAllControlledPlayersAlive = ((BaseUnityPlugin)this).Config.Bind("Rules", "RequireAllControlledPlayersAlive", false, "If true, extraction and Extraction Area payout only work when every controlled connected player is alive. If false, Extraction Area payout works as long as at least one controlled player is alive."); _harmony = new Harmony("robert.lethalcompany.extraction"); _harmony.PatchAll(); D("Plugin loaded. Harmony patches applied."); DebugLogStateSnapshot("plugin-awake", force: true); } private void Update() { EnsureFreshNetworkSessionState(); EnsureMessageHandlers(); EnsureRoundManagerEventSubscription(); UpdateInsideCubeHudState(); UpdateCubeScrapValueCacheLoop(); UpdateEarlyExtractionVoteSystem(); UpdatePendingEarlyVoteRequestResend(); UpdateClientTrustedVoteLeaveCancel(); HandleEarlyExtractionVoteInput(); UpdateQueuedRoundStartCubeTeleportFallback(); UpdateLateJoinTeleportWindowTimeout(); UpdateBaseGameVoteToLeaveUrgencyState(); UpdateShipDoorsLockedClosed(); UpdateFacilityExitInteractionsLocked(); UpdateCubePulseVisual(); UpdateScrapVisibilityLoop(); UpdateExtractionDiagnosticSnapshotLoop(); if (_enableScrapVisibility == null || !_enableScrapVisibility.Value) { UpdateCubeScrapGlowLoop(); } else if (_glowingCubeScrap.Count > 0) { ClearAllCubeScrapGlow(); } if (IsServer() && _hasCube && (Object)(object)NetworkManager.Singleton != (Object)null) { _lateSyncTimer += Time.deltaTime; if (_lateSyncTimer >= 5f) { _lateSyncTimer = 0f; BroadcastCubePosition(); } } } private void OnGUI() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Expected O, but got Unknown //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) if (_showInsideCubeHud == null || !_showInsideCubeHud.Value || !_localPlayerInsideCube) { return; } if (_insideCubeHudStyle == null) { _insideCubeHudStyle = new GUIStyle(GUI.skin.box); _insideCubeHudStyle.alignment = (TextAnchor)4; _insideCubeHudStyle.fontStyle = (FontStyle)1; _insideCubeHudStyle.normal.textColor = new Color(1f, 0.9f, 0.05f, 1f); } _insideCubeHudStyle.fontSize = Mathf.Clamp(Mathf.RoundToInt((float)Screen.height * 0.027f), 16, 24); _insideCubeHudStyle.wordWrap = true; _insideCubeHudStyle.clipping = (TextClipping)1; _insideCubeHudStyle.padding = new RectOffset(12, 12, 8, 8); string arg = (_cubeExtractionPassed ? "EXTRACTION CLOSED" : ("EXTRACTION IN " + GetShipTakeoffCountdownText())); string text = $"INSIDE EXTRACTION AREA\n{arg}\nSCRAP IN AREA: ${_currentCubeScrapRawValue}"; if (_enableEarlyExtractionVote != null && _enableEarlyExtractionVote.Value && _earlyVoteEligible && !_cubeExtractionPassed) { if (_earlyExtractionCountdownActive) { int num = Mathf.Max(0, _earlyExtractionCountdownSecondsRemaining); text = text + $"\nEARLY EXTRACT: EXTRACTING IN {num} SECOND" + ((num == 1) ? string.Empty : "S"); } else { object obj; if (_earlyExtractionVoteKey == null) { obj = "R"; } else { KeyCode value = _earlyExtractionVoteKey.Value; obj = ((object)(KeyCode)(ref value)).ToString().ToUpperInvariant(); } string text2 = (string)obj; text += $"\nEARLY EXTRACT: {_earlyVoteCount}/{_earlyVoteRequired} VOTES"; text += $"\nALIVE PLAYERS: {_earlyVoteRequired}"; text = (_localEarlyVoteSubmitted ? (text + "\nVOTE LOCKED IN") : (LocalPlayerCanUseVoteInput() ? (text + "\nPRESS " + text2 + " TO VOTE") : (text + "\nCLOSE CHAT OR MENU TO VOTE"))); } } float num2 = Mathf.Min(760f, Mathf.Max(280f, (float)Screen.width - 48f)); float num3 = Mathf.Max(86f, _insideCubeHudStyle.CalcHeight(new GUIContent(text), num2)); Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num2) * 0.5f, 95f, num2, num3); GUI.Label(val, text, _insideCubeHudStyle); } private void OnDestroy() { ClearAllScrapVisibilityHighlighters(); ClearAllCubeScrapGlow(); DestroyCubeLight(); RestoreVanillaShipDoorVisualAndAudio(); SetClosedShipDoorOverlayActive(active: false); try { UnregisterNetworkMessageHandlers("plugin destroy"); if ((Object)(object)_eventSubscribedRoundManager != (Object)null) { _eventSubscribedRoundManager.OnFinishedGeneratingDungeon -= OnFinishedGeneratingDungeonEvent; } } catch { } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void EnsureFreshNetworkSessionState() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { if (_networkSessionStateInitialized || _messagesRegistered || (Object)(object)_registeredNetworkManager != (Object)null) { UnregisterNetworkMessageHandlers("NetworkManager became null"); ResetMainScriptRuntimeStateForNetworkSession("NetworkManager became null / left lobby", destroyVisual: true, resetNetworkRoundIds: true); } _lastObservedNetworkManager = null; _networkSessionStateInitialized = false; _lastObservedIsListening = false; _lastObservedIsClient = false; _lastObservedIsServer = false; _lastObservedLocalClientId = ulong.MaxValue; _lastObservedThisClientPlayerId = -999; return; } bool isListening = singleton.IsListening; bool isClient = singleton.IsClient; bool isServer = singleton.IsServer; ulong num = ((isListening || isClient || isServer) ? singleton.LocalClientId : ulong.MaxValue); int num2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)); if (!_networkSessionStateInitialized) { SetObservedNetworkSessionState(singleton, isListening, isClient, isServer, num, num2); return; } bool flag = singleton != _lastObservedNetworkManager; bool flag2 = !_lastObservedIsListening && isListening; bool flag3 = _lastObservedIsListening && !isListening; bool flag4 = isListening && (_lastObservedIsClient != isClient || _lastObservedIsServer != isServer); bool flag5 = isListening && _lastObservedLocalClientId != ulong.MaxValue && num != ulong.MaxValue && _lastObservedLocalClientId != num; if (flag || flag2 || flag3 || flag4 || flag5) { string reason = $"network session changed managerChanged={flag}, started={flag2}, stopped={flag3}, roleChanged={flag4}, localClientChanged={flag5}, oldClient={_lastObservedLocalClientId}, newClient={num}"; UnregisterNetworkMessageHandlers(reason); ResetMainScriptRuntimeStateForNetworkSession(reason, destroyVisual: true, resetNetworkRoundIds: true); SetObservedNetworkSessionState(singleton, isListening, isClient, isServer, num, num2); } else { if (isListening && !isServer && num2 >= 0 && _lastObservedThisClientPlayerId >= 0 && _lastObservedThisClientPlayerId != num2) { string reason2 = $"local player id changed after reconnect/rehost oldPlayer={_lastObservedThisClientPlayerId}, newPlayer={num2}"; ResetMainScriptRuntimeStateForNetworkSession(reason2, destroyVisual: true, resetNetworkRoundIds: false); } SetObservedNetworkSessionState(singleton, isListening, isClient, isServer, num, num2); } } private static void SetObservedNetworkSessionState(NetworkManager nm, bool isListening, bool isClient, bool isServer, ulong localClientId, int thisClientPlayerId) { _lastObservedNetworkManager = nm; _networkSessionStateInitialized = true; _lastObservedIsListening = isListening; _lastObservedIsClient = isClient; _lastObservedIsServer = isServer; _lastObservedLocalClientId = localClientId; _lastObservedThisClientPlayerId = thisClientPlayerId; } private static void UnregisterNetworkMessageHandlers(string reason) { NetworkManager val = _registeredNetworkManager ?? NetworkManager.Singleton; try { if (_messagesRegistered && ((val != null) ? val.CustomMessagingManager : null) != null) { TryUnregisterNamedMessage(val, "Extraction_CubeSync_v1"); TryUnregisterNamedMessage(val, "Extraction_Teleport_v1"); TryUnregisterNamedMessage(val, "Extraction_QuotaSync_v1"); TryUnregisterNamedMessage(val, "Extraction_CubeClosed_v1"); TryUnregisterNamedMessage(val, "Extraction_EarlyVoteRequest_v1"); TryUnregisterNamedMessage(val, "Extraction_EarlyVoteSync_v1"); TryUnregisterNamedMessage(val, "Extraction_RoundStartCubeTeleport_v1"); } if (_clientConnectCallbackRegistered && (Object)(object)val != (Object)null) { val.OnClientConnectedCallback -= OnClientConnected; } } catch (Exception ex) { D("[" + NetRoleDebugName() + "] Network handler unregister had a non-fatal error. reason=" + reason + ", error=" + ex.Message); } if (_messagesRegistered || _clientConnectCallbackRegistered || (Object)(object)_registeredNetworkManager != (Object)null) { D("[" + NetRoleDebugName() + "] Cleared registered network handlers. reason=" + reason); } _messagesRegistered = false; _clientConnectCallbackRegistered = false; _registeredNetworkManager = null; } private static void TryUnregisterNamedMessage(NetworkManager nm, string messageName) { try { nm.CustomMessagingManager.UnregisterNamedMessageHandler(messageName); } catch { } } private static void ResetMainScriptRuntimeStateForNetworkSession(string reason, bool destroyVisual, bool resetNetworkRoundIds) { //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) D($"[{NetRoleDebugName()}] Reinitializing Extraction runtime state. reason={reason}, destroyVisual={destroyVisual}, resetNetworkRoundIds={resetNetworkRoundIds}. BEFORE: {RoundStateDebugLine()} | {CubeStateDebugLine()} | {VoteStateDebugLine()}"); try { ClearAllScrapVisibilityHighlighters(); } catch { } try { ClearAllCubeScrapGlow(); } catch { } try { RestoreVanillaShipDoorVisualAndAudio(); } catch { } try { SetClosedShipDoorOverlayActive(active: false); } catch { } _processedThisTakeoff = false; _cubeExtractionPassed = false; _cubeEffectiveHeightOverride = -1f; _cubePostReadyPlacementFinalized = false; _authoritativeCubeFootprintReadyForClients = false; _cubeDynamicFootprintAuthoritativeFromHost = false; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _localPlayerInsideCube = false; _currentCubeScrapRawValue = 0; _currentCubeScrapCount = 0; _cubeScrapValueTimer = 0f; _cubeScrapGlowTimer = 0f; _pendingQuotaValue = 0; _pendingRawValue = 0; _pendingItemCount = 0; _pendingQuotaApplied = false; _earlyExtractionVotes.Clear(); _clientTrustedEarlyVotePlayers.Clear(); _earlyVoteLeftCubeSince.Clear(); _earlyVoteEligible = false; _earlyVoteCount = 0; _earlyVoteRequired = 0; _localEarlyVoteSubmitted = false; _earlyExtractionCountdownActive = false; _earlyExtractionCountdownEndTime = 0f; _earlyExtractionCountdownSecondsRemaining = 0; _earlyExtractionTriggered = false; _earlyVoteRosterKey = string.Empty; _lastEarlyVoteSyncSignature = string.Empty; _earlyVoteSyncTimer = 0f; _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _earlyVoteRequestSequence = 0; _earlyVoteRequestNextSendTime = 0f; _earlyVoteRequestStopTime = 0f; _earlyVoteRequestTimeoutLogged = false; _baseGameVoteToLeaveUrgencyActive = false; _baseGameVoteToLeaveObserved = false; _normalShipLeaveAutomaticallyTimeCaptured = false; _normalShipLeaveAutomaticallyTime = -1f; _roundStartCubeTeleportWindowOpen = false; _roundStartCubeTeleportToken = 0; _localAppliedRoundStartCubeTeleportToken = -1; _localCompletedRoundStartCubeTeleportToken = -1; _localPendingRoundStartCubeTeleportToken = -1; _lastLocalRoundStartCubeTeleportApplyTime = 0f; _roundStartCubeTeleportWindowEndTime = 0f; _roundStartTeleportRequested = false; _roundStartTeleportFloorReady = false; _roundStartTeleportStarted = false; _roundStartTeleportRequestTime = 0f; _roundStartTeleportRequestReason = string.Empty; _roundStartTeleportRoutineRunning = false; _roundStartTeleportTargetsByClient.Clear(); _lastInsideFactoryBestEffortTimeByClient.Clear(); _lastInsideAudioLightingBestEffortTimeByClient.Clear(); _cachedInteriorEntranceReachabilityAnchors.Clear(); _cachedInteriorEntranceReachabilityAnchorsFrame = -1; _trackedPressedVoteKeys.Clear(); _debugVoteBlockLogTimer = 0f; _lastDebugVoteBlockReason = string.Empty; _debugHostVoteGateLogTimer = 0f; _lastDebugHostVoteGateReason = string.Empty; _debugInsideCubeLogTimer = 0f; _lastDebugInsideCubeState = false; _debugCubeSyncLogTimer = 0f; if (resetNetworkRoundIds) { _hostCubeNetworkRoundId = 0; _currentCubeNetworkRoundId = -1; _lastAcceptedCubeNetworkRoundId = -1; _cubeNetworkRoundActive = false; } _clientAcceptedCubeSyncSerial++; if (destroyVisual) { DestroyCubeVisual(); _cubeCenter = Vector3.zero; _cubeDimensions = new Vector3(6f, 6f, 6f); _hasCube = false; } else { ResetDynamicAreaFootprint(); } DebugLogStateSnapshot("runtime reinitialized for network session", force: true); } private static void EnsureMessageHandlers() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.CustomMessagingManager : null) != null && (!_messagesRegistered || _registeredNetworkManager != singleton)) { if (_messagesRegistered && _registeredNetworkManager != singleton) { UnregisterNetworkMessageHandlers("registered NetworkManager changed before EnsureMessageHandlers"); } singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_CubeSync_v1", new HandleNamedMessageDelegate(OnCubeSyncMessage)); singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_Teleport_v1", new HandleNamedMessageDelegate(OnTeleportMessage)); singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_QuotaSync_v1", new HandleNamedMessageDelegate(OnQuotaSyncMessage)); singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_CubeClosed_v1", new HandleNamedMessageDelegate(OnCubeClosedMessage)); singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_EarlyVoteRequest_v1", new HandleNamedMessageDelegate(OnEarlyVoteRequestMessage)); singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_EarlyVoteSync_v1", new HandleNamedMessageDelegate(OnEarlyVoteSyncMessage)); singleton.CustomMessagingManager.RegisterNamedMessageHandler("Extraction_RoundStartCubeTeleport_v1", new HandleNamedMessageDelegate(OnRoundStartCubeTeleportMessage)); _messagesRegistered = true; _registeredNetworkManager = singleton; if (!_clientConnectCallbackRegistered) { singleton.OnClientConnectedCallback += OnClientConnected; _clientConnectCallbackRegistered = true; } D(string.Format("[{0}] Registered custom multiplayer message handlers. localClient={1}, managerHash={2}", NetRoleDebugName(), ((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.LocalClientId.ToString() : "null", ((object)singleton).GetHashCode())); DebugLogStateSnapshot("message handlers registered", force: true); } } private static void EnsureRoundManagerEventSubscription() { RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)_eventSubscribedRoundManager == (Object)(object)instance) { return; } if ((Object)(object)_eventSubscribedRoundManager != (Object)null) { try { _eventSubscribedRoundManager.OnFinishedGeneratingDungeon -= OnFinishedGeneratingDungeonEvent; } catch { } } _eventSubscribedRoundManager = instance; _eventSubscribedRoundManager.OnFinishedGeneratingDungeon += OnFinishedGeneratingDungeonEvent; D("Subscribed to RoundManager.OnFinishedGeneratingDungeon event."); } private static void OnFinishedGeneratingDungeonEvent() { D("RoundManager.OnFinishedGeneratingDungeon event fired."); BeginCubeSpawnAfterDungeonGeneration(); } private static void OnClientConnected(ulong clientId) { NetworkManager singleton = NetworkManager.Singleton; if (!IsServer()) { if ((Object)(object)singleton != (Object)null && clientId == singleton.LocalClientId) { ResetMainScriptRuntimeStateForNetworkSession($"local client connected/rejoined callback clientId={clientId}", destroyVisual: true, resetNetworkRoundIds: true); SetObservedNetworkSessionState(singleton, singleton.IsListening, singleton.IsClient, singleton.IsServer, singleton.LocalClientId, ((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)); } return; } ResetPerClientRuntimeStateOnHost(clientId, "client connected/rejoined"); if (_hasCube) { SendFullExtractionStateToClient(clientId, "client connected/rejoined immediate", allowLateJoinTeleport: true); if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(DelayedFullExtractionStateSyncToClient(clientId, "client connected/rejoined delayed resync")); } } } private static void ResetPerClientRuntimeStateOnHost(ulong clientId, string reason) { _roundStartTeleportTargetsByClient.Remove(clientId); _lastInsideFactoryBestEffortTimeByClient.Remove(clientId); _lastInsideAudioLightingBestEffortTimeByClient.Remove(clientId); int num = FindPlayerIdByClientId(clientId); if (num >= 0) { _earlyExtractionVotes.Remove(num); _clientTrustedEarlyVotePlayers.Remove(num); _earlyVoteLeftCubeSince.Remove(num); if (_earlyExtractionCountdownActive && _earlyExtractionVotes.Count < _earlyVoteRequired) { CancelEarlyExtractionCountdownOnHost($"player {num} rejoined and needs a fresh vote"); } } _lastEarlyVoteSyncSignature = string.Empty; D($"[{NetRoleDebugName()}] Reset per-client Extraction state for client {clientId}. playerId={num}, reason={reason}. {VoteStateDebugLine()} | {CubeStateDebugLine()}"); } [IteratorStateMachine(typeof(d__254))] private static IEnumerator DelayedFullExtractionStateSyncToClient(ulong clientId, string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__254(0) { clientId = clientId, reason = reason }; } private static void SendFullExtractionStateToClient(ulong clientId, string reason, bool allowLateJoinTeleport) { //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) if (!IsServer() || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.ConnectedClientsIds.Contains(clientId)) { return; } D($"[{NetRoleDebugName()}] Sending full Extraction state to client {clientId}. reason={reason}, allowLateJoinTeleport={allowLateJoinTeleport}. {CubeStateDebugLine()} | {VoteStateDebugLine()}"); DebugLogStateSnapshot($"full state sync to client {clientId}", force: true); if (_hasCube) { SendCubePosition(clientId); SendCubeClosedState(clientId, _cubeExtractionPassed); } SendEarlyVoteSync(clientId); bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving; if (!_hasCube || !RoundStartTeleportEnabled() || _cubeExtractionPassed || flag || !(_roundStartCubeTeleportWindowOpen || allowLateJoinTeleport)) { return; } if (!_roundStartCubeTeleportWindowOpen && allowLateJoinTeleport) { _roundStartCubeTeleportToken++; if (_roundStartCubeTeleportToken <= 0) { _roundStartCubeTeleportToken = 1; } _roundStartCubeTeleportWindowOpen = true; _roundStartCubeTeleportWindowEndTime = Time.realtimeSinceStartup + Mathf.Max(2f, (_roundStartTeleportRetrySeconds != null) ? _roundStartTeleportRetrySeconds.Value : 12f); D($"[{NetRoleDebugName()}] Opened a late-join round-start teleport window for client {clientId}. token={_roundStartCubeTeleportToken}, reason={reason}"); } if (!_roundStartTeleportTargetsByClient.TryGetValue(clientId, out var value)) { value = (RoundStartTeleportUsesCube() ? GetCubeSafeTeleportPosition() : PickRandomFacilityPlayerSpawnPosition((int)clientId, _roundStartCubeTeleportToken)); _roundStartTeleportTargetsByClient[clientId] = value; } SendRoundStartCubeTeleport(clientId, _roundStartCubeTeleportToken, value, reason); } internal static void BeginCubeSpawnAfterDungeonGeneration() { if (!((Object)(object)Instance == (Object)null)) { ((MonoBehaviour)Instance).StartCoroutine(SpawnCubeAfterFrame()); } } [IteratorStateMachine(typeof(d__257))] private static IEnumerator SpawnCubeAfterFrame() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__257(0); } private static void FinalizeCubePlacementAfterLevelReady() { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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) //IL_007f: 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_009b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_012d: 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_013a: Unknown result type (might be due to invalid IL or missing references) if (!IsServer() || !_hasCube || _cubePostReadyPlacementFinalized) { return; } _cubePostReadyPlacementFinalized = true; if (_cubePlacementUseEntrancesAndFireExitsOnly == null || _cubePlacementUseEntrancesAndFireExitsOnly.Value) { D("Post-ready cube placement skipped because entrance/fire-exit only placement is enabled."); return; } try { if (TryPickPostReadyCubePosition(out var center, out var detail)) { if (Vector3.Distance(_cubeCenter, center) > 0.35f) { D($"Post-ready cube placement moved the Extraction Area from {_cubeCenter} to {center}. reason={detail}"); _cubeCenter = center; _hasCube = true; CreateOrMoveCubeVisual(_cubeCenter); BroadcastCubePosition(); } else { D("Post-ready cube placement kept existing cube position. reason=" + detail); } return; } if (IsCubePlacementSafe(_cubeCenter, out var rejectReason)) { D("Post-ready cube placement found no better anchor, but current cube position still passed strict validation."); return; } D("Post-ready cube placement rejected current cube position: " + rejectReason); if (TryPickEntranceFallbackCubePosition(out var center2)) { D($"Post-ready cube placement used entrance fallback: {center2}"); _cubeCenter = center2; _hasCube = true; CreateOrMoveCubeVisual(_cubeCenter); BroadcastCubePosition(); } else { Log.LogWarning((object)$"[Extraction] Post-ready cube placement could not find a better strict position. Keeping current cube at {_cubeCenter}. Last reject: {rejectReason}"); } } catch (Exception ex) { Log.LogWarning((object)$"[Extraction] Post-ready cube placement failed. Keeping current cube at {_cubeCenter}. Error: {ex.Message}"); } } private static bool TryPickPostReadyCubePosition(out Vector3 center, out string detail) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; detail = string.Empty; if (_cubePlacementUseEntrancesAndFireExitsOnly == null || _cubePlacementUseEntrancesAndFireExitsOnly.Value) { detail = "entrance/fire-exit only placement is already final; no post-ready scrap/grid relocation"; return false; } if ((_cubePlacementPreferScrapSpawnAnchors == null || _cubePlacementPreferScrapSpawnAnchors.Value) && TryPickScrapAnchoredCubePosition(out center, out detail)) { return true; } return false; } private static bool TryPickScrapAnchoredCubePosition(out Vector3 center, out string detail) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; detail = string.Empty; GrabbableObject[] array; try { array = Object.FindObjectsOfType(); } catch (Exception ex) { detail = "FindObjectsOfType failed: " + ex.Message; return false; } if (array == null || array.Length == 0) { detail = "no grabbable scrap objects exist yet"; return false; } StartOfRound instance = StartOfRound.Instance; Vector3 val = (((Object)(object)instance != (Object)null && (Object)(object)instance.elevatorTransform != (Object)null) ? instance.elevatorTransform.position : Vector3.zero); int num = Mathf.Max(0, (_minDistanceFromShip != null) ? _minDistanceFromShip.Value : 25); float num2 = Mathf.Max(0.5f, (_cubeSize != null) ? _cubeSize.Value : 6f); float halfSize = num2 * 0.5f; int seed = (((Object)(object)instance != (Object)null) ? instance.randomMapSeed : Environment.TickCount) ^ 0x51A9C0DE; Random rng = new Random(seed); List list = (from g in array.Where(IsScrapUsableAsPlacementAnchor) orderby Mathf.Max(0, g.scrapValue) descending select g).ThenBy((GrabbableObject _) => rng.Next()).Take(96).ToList(); if (list.Count == 0) { detail = "no usable scrap anchors found"; return false; } List list2 = BuildScrapAnchorOffsets(halfSize); float num3 = float.NegativeInfinity; Vector3 val2 = Vector3.zero; string text = string.Empty; int num4 = 0; int num5 = 0; string arg = string.Empty; foreach (GrabbableObject item in list) { if ((Object)(object)item == (Object)null) { continue; } Vector3 position = ((Component)item).transform.position; foreach (Vector3 item2 in list2) { Vector3 current2 = item2; num4++; if (!TrySnapCubeCenterToGroundStrict(position + current2, out var center2, out var rejectReason)) { arg = rejectReason; continue; } if (val != Vector3.zero) { float num6 = Vector3.Distance(center2, val); if (num6 < (float)num) { arg = $"scrap anchor candidate too close to ship ({num6:0.0}m < {num}m)"; continue; } } if (!IsCubePlacementSafe(center2, out var rejectReason2)) { arg = rejectReason2; continue; } num5++; float num7 = ScoreCubePlacementCandidate(center2, val, strict: true); num7 += (float)Mathf.Clamp(item.scrapValue, 0, 300) * 0.05f; num7 -= ((Vector3)(ref current2)).magnitude * 0.35f; if (num7 > num3) { num3 = num7; val2 = center2; text = (((Object)(object)item.itemProperties != (Object)null) ? item.itemProperties.itemName : ((Object)item).name); } } } if (num3 > float.NegativeInfinity) { center = val2; detail = $"scrap-anchored placement near {text}; anchors={list.Count}, tested={num4}, safe={num5}, score={num3:0.0}"; return true; } detail = $"no strict safe scrap-anchored cube placement found; anchors={list.Count}, tested={num4}, lastReject={arg}"; D(detail); return false; } private static bool IsScrapUsableAsPlacementAnchor(GrabbableObject item) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00b3: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).transform == (Object)null || (Object)(object)item.itemProperties == (Object)null) { return false; } if (!item.itemProperties.isScrap) { return false; } if (!((Component)item).gameObject.activeInHierarchy) { return false; } if (item.isHeld || item.isPocketed || (Object)(object)item.playerHeldBy != (Object)null || item.isHeldByEnemy) { return false; } Vector3 position = ((Component)item).transform.position; if (float.IsNaN(position.x) || float.IsNaN(position.y) || float.IsNaN(position.z) || float.IsInfinity(position.x) || float.IsInfinity(position.y) || float.IsInfinity(position.z)) { return false; } if (position.y > 100f || position.y < -500f) { return false; } return true; } private static List BuildScrapAnchorOffsets(float halfSize) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp((_cubePlacementSearchStep != null) ? _cubePlacementSearchStep.Value : 1.5f, 0.75f, 3f); float num2 = Mathf.Clamp(Mathf.Max(halfSize + 1.5f, 5f), 4f, 7.5f); List list = new List(); list.Add(Vector3.zero); Vector3 item = default(Vector3); for (float num3 = 0f - num2; num3 <= num2 + 0.01f; num3 += num) { for (float num4 = 0f - num2; num4 <= num2 + 0.01f; num4 += num) { ((Vector3)(ref item))..ctor(num3, 0f, num4); if (!(((Vector3)(ref item)).sqrMagnitude < 0.01f) && !(((Vector3)(ref item)).sqrMagnitude > num2 * num2)) { list.Add(item); } } } return (from o in list orderby ((Vector3)(ref o)).sqrMagnitude group o by new { X = Mathf.RoundToInt(o.x * 100f), Z = Mathf.RoundToInt(o.z * 100f) } into g select g.First()).ToList(); } private static Vector3 PickCubePosition() { //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) float cubeRequestedHeight = GetCubeRequestedHeight(); float num = cubeRequestedHeight; float num2 = 1.5f; string text = string.Empty; int num3 = 0; while (num >= num2 - 0.01f) { num3++; _cubeEffectiveHeightOverride = Mathf.Max(num2, num); for (int i = 1; i <= 30; i++) { if (TryPickCubePositionForCurrentHeight(out var center, out var detail)) { if (!Mathf.Approximately(_cubeEffectiveHeightOverride, cubeRequestedHeight)) { D($"Extraction Area requested height {cubeRequestedHeight:0.00}m did not fit after full-height attempts. Using {_cubeEffectiveHeightOverride:0.00}m on height step {num3}, placement attempt {i}/30. {detail}"); } else { D($"Extraction Area requested height {cubeRequestedHeight:0.00}m fit on placement attempt {i}/30. {detail}"); } return center; } text = detail; } D($"Extraction Area height {_cubeEffectiveHeightOverride:0.00}m failed 30 placement attempts. Stepping down to 80% height. Last reject={text}"); num *= 0.8f; } _cubeEffectiveHeightOverride = num2; Log.LogWarning((object)$"[Extraction] No placement accepted after 30 attempts per requested height ladder step. Last reject={text}. Falling back with height={GetCubeConfiguredHeight():0.00}m."); if (TryPickInsideAINodeEmergencyCubePosition(out var center2, out var detail2)) { Log.LogWarning((object)$"[Extraction] Height-ladder emergency fallback used: {center2}. {detail2}"); return center2; } RoundManager instance = RoundManager.Instance; StartOfRound instance2 = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.insideAINodes != null && instance.insideAINodes.Length != 0) { return PickEmergencyCubePosition(instance.insideAINodes[Random.Range(0, instance.insideAINodes.Length)].transform.position); } return ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.elevatorTransform != (Object)null) ? (instance2.elevatorTransform.position + Vector3.up * 2f) : Vector3.zero; } private static bool TryPickCubePositionForCurrentHeight(out Vector3 center, out string detail) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; detail = string.Empty; if (_cubePlacementUseEntrancesAndFireExitsOnly == null || _cubePlacementUseEntrancesAndFireExitsOnly.Value) { if (TryPickEntranceOrFireExitCubePosition(out var center2, out var detail2)) { center = center2; detail = $"picked interior entrance/fire-exit center={center2}; {detail2}"; return true; } if (TryPickAnyDeepEntrancePointCubePosition(out var center3, out var detail3)) { center = center3; detail = "surface-to-interior pair lookup failed but deep entrance destination worked; " + detail3; return true; } if (TryPickInsideAINodeEmergencyCubePosition(out var center4, out var detail4)) { center = center4; detail = "entrance-only fallback used inside AI node; " + detail4; return true; } detail = "entrance-only placement failed with no inside AI node fallback"; return false; } int[] array = new int[2] { 0, 1 }; ShuffleArrayInPlace(array); string text = string.Empty; for (int i = 0; i < array.Length; i++) { if (array[i] == 0) { if (TryPickEntranceFallbackCubePosition(out var center5)) { center = center5; detail = "picked entrance-connected fallback"; return true; } text = "entrance-connected fallback failed"; continue; } RoundManager instance = RoundManager.Instance; if ((Object)(object)instance != (Object)null && instance.insideAINodes != null && instance.insideAINodes.Length != 0) { Vector3 val = PickEmergencyCubePosition(instance.insideAINodes[Random.Range(0, instance.insideAINodes.Length)].transform.position); if (HasRequiredCubeHeightClearance(val, out var rejectReason)) { center = val; detail = "picked old emergency cube position"; return true; } text = "old emergency cube position failed height clearance: " + rejectReason; } else { text = "no round manager inside AI nodes"; } } detail = text; return false; } private static void ShuffleArrayInPlace(T[] array) { if (array != null) { for (int num = array.Length - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); T val = array[num]; array[num] = array[num2]; array[num2] = val; } } } private static void ShuffleListInPlace(IList list) { if (list != null) { for (int num = list.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); T value = list[num]; list[num] = list[index]; list[index] = value; } } } private static List BuildPlacementOffsets(float halfSize) { //IL_0008: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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) //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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: 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) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0237: 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) List list = new List(); list.Add(Vector3.zero); if (halfSize >= 2f) { float num = Mathf.Clamp((_cubePlacementSearchRadius != null) ? _cubePlacementSearchRadius.Value : 12f, 3f, 18f); float num2 = Mathf.Clamp((_cubePlacementSearchStep != null) ? _cubePlacementSearchStep.Value : 1.5f, 0.75f, 4f); Vector3 item = default(Vector3); for (float num3 = 0f - num; num3 <= num + 0.01f; num3 += num2) { for (float num4 = 0f - num; num4 <= num + 0.01f; num4 += num2) { ((Vector3)(ref item))..ctor(num3, 0f, num4); if (!(((Vector3)(ref item)).sqrMagnitude > num * num) && !(((Vector3)(ref item)).sqrMagnitude < 0.01f)) { list.Add(item); } } } } else { float num5 = Mathf.Max(1.25f, halfSize * 0.75f); float num6 = Mathf.Max(2.25f, halfSize * 1.5f); float num7 = Mathf.Max(3.25f, halfSize * 2.4f); Vector3[] obj = new Vector3[8] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val = Vector3.forward + Vector3.left; obj[4] = ((Vector3)(ref val)).normalized; val = Vector3.forward + Vector3.right; obj[5] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.left; obj[6] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.right; obj[7] = ((Vector3)(ref val)).normalized; Vector3[] array = (Vector3[])(object)obj; float[] array2 = new float[3] { num5, num6, num7 }; float[] array3 = array2; foreach (float num8 in array3) { Vector3[] array4 = array; foreach (Vector3 val2 in array4) { list.Add(val2 * num8); } } } return (from o in list group o by new { X = Mathf.RoundToInt(o.x * 100f), Z = Mathf.RoundToInt(o.z * 100f) } into g select g.First()).ToList(); } private static bool TryPickEntranceOrFireExitCubePosition(out Vector3 center, out string detail) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_0138: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0282: 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_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; detail = string.Empty; List interiorEntranceTeleportsForCubePlacement = GetInteriorEntranceTeleportsForCubePlacement(); if (interiorEntranceTeleportsForCubePlacement.Count == 0) { detail = "no actual interior-side EntranceTeleport objects found"; return false; } StartOfRound instance = StartOfRound.Instance; Vector3 shipPos = (((Object)(object)instance != (Object)null && (Object)(object)instance.elevatorTransform != (Object)null) ? instance.elevatorTransform.position : Vector3.zero); List list = interiorEntranceTeleportsForCubePlacement.OrderBy((EntranceTeleport _) => Random.Range(0, int.MaxValue)).ThenByDescending((EntranceTeleport e) => (shipPos == Vector3.zero) ? 0f : Vector3.Distance(GetEntranceTeleportAnchorPosition(e), shipPos)).ToList(); float num = Mathf.Max(0.5f, (_cubeSize != null) ? _cubeSize.Value : 6f); float half = num * 0.5f; List list2 = BuildEntranceCubeOffsets(half); string text = string.Empty; int num2 = 0; foreach (EntranceTeleport item in list) { Vector3 entranceTeleportAnchorPosition = GetEntranceTeleportAnchorPosition(item); Vector3 entranceInteriorForward = GetEntranceInteriorForward(item); Quaternion val = Quaternion.AngleAxis(Mathf.Atan2(entranceInteriorForward.x, entranceInteriorForward.z) * 57.29578f, Vector3.up); foreach (Vector3 item2 in list2) { num2++; Vector3 val2 = val * item2; Vector3 basePosition = entranceTeleportAnchorPosition + val2; if (!TrySnapCubeCenterToGroundStrict(basePosition, out var center2, out var rejectReason)) { text = rejectReason; continue; } if (!IsEntranceCubePlacementSafe(center2, out var rejectReason2)) { text = rejectReason2; continue; } center = center2; detail = $"strict entrance={GetEntranceDebugName(item)}, anchor={entranceTeleportAnchorPosition}, tested={num2}"; return true; } } foreach (EntranceTeleport item3 in list) { Vector3 entranceTeleportAnchorPosition2 = GetEntranceTeleportAnchorPosition(item3); Vector3 entranceInteriorForward2 = GetEntranceInteriorForward(item3); Quaternion val3 = Quaternion.AngleAxis(Mathf.Atan2(entranceInteriorForward2.x, entranceInteriorForward2.z) * 57.29578f, Vector3.up); foreach (Vector3 item4 in list2) { num2++; Vector3 val4 = val3 * item4; Vector3 basePosition2 = entranceTeleportAnchorPosition2 + val4; if (!TrySnapCubeCenterToGroundStrict(basePosition2, out var center3, out var rejectReason3)) { text = rejectReason3; continue; } if (!IsEmergencyCubePlacementUsable(center3, out var rejectReason4)) { text = rejectReason4; continue; } center = center3; detail = $"soft entrance={GetEntranceDebugName(item3)}, anchor={entranceTeleportAnchorPosition2}, tested={num2}, lastStrictReject={text}"; return true; } } detail = $"no usable interior entrance/fire-exit placement accepted; entrances={interiorEntranceTeleportsForCubePlacement.Count}, tested={num2}, lastReject={text}"; return false; } private static List GetInteriorEntranceTeleportsForCubePlacement() { //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) //IL_0070: 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) List list = new List(); try { EntranceTeleport[] array = Object.FindObjectsOfType(); if (array == null) { return list; } EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && val.isEntranceToBuilding) { Vector3 entranceTeleportAnchorPosition = GetEntranceTeleportAnchorPosition(val); if (!EntranceDestinationLooksLikeInteriorSide(entranceTeleportAnchorPosition)) { D($"Rejected surface entrance destination because it did not look like an interior point: {GetEntranceDebugName(val)}, destination={entranceTeleportAnchorPosition}"); } else { list.Add(val); } } } } catch (Exception ex) { D("Failed to collect surface-to-interior entrance/fire-exit destinations: " + ex.Message); } return (from g in list.GroupBy(delegate(EntranceTeleport e) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) Vector3 entranceTeleportAnchorPosition2 = GetEntranceTeleportAnchorPosition(e); return new { X = Mathf.RoundToInt(entranceTeleportAnchorPosition2.x * 10f), Y = Mathf.RoundToInt(entranceTeleportAnchorPosition2.y * 10f), Z = Mathf.RoundToInt(entranceTeleportAnchorPosition2.z * 10f) }; }) select g.First()).ToList(); } private static bool EntranceDestinationLooksLikeInteriorSide(Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (position == Vector3.zero) { return false; } try { RoundManager instance = RoundManager.Instance; if ((Object)(object)instance != (Object)null && instance.insideAINodes != null && instance.insideAINodes.Length != 0) { float num = float.MaxValue; float num2 = float.MaxValue; GameObject[] insideAINodes = instance.insideAINodes; Vector3 val2; foreach (GameObject val in insideAINodes) { if (!((Object)(object)val == (Object)null)) { val2 = val.transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; } } } try { if (instance.outsideAINodes != null) { GameObject[] outsideAINodes = instance.outsideAINodes; foreach (GameObject val3 in outsideAINodes) { if (!((Object)(object)val3 == (Object)null)) { val2 = val3.transform.position - position; float sqrMagnitude2 = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude2 < num2) { num2 = sqrMagnitude2; } } } } } catch { num2 = float.MaxValue; } StartOfRound instance2 = StartOfRound.Instance; float num3 = float.MaxValue; try { if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.elevatorTransform != (Object)null) { val2 = instance2.elevatorTransform.position - position; num3 = ((Vector3)(ref val2)).sqrMagnitude; } } catch { num3 = float.MaxValue; } if (num == float.MaxValue) { return false; } if (num2 < float.MaxValue && num2 + 1f < num) { return false; } if (num3 < num) { return false; } } } catch { } return true; } private static Vector3 GetEntranceTeleportAnchorPosition(EntranceTeleport entrance) { //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_0082: 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) //IL_006d: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entrance == (Object)null) { return Vector3.zero; } try { if (entrance.isEntranceToBuilding && (Object)(object)entrance.exitScript != (Object)null && (Object)(object)entrance.exitScript.entrancePoint != (Object)null) { return entrance.exitScript.entrancePoint.position; } } catch { } return ((Object)(object)((Component)entrance).transform != (Object)null) ? ((Component)entrance).transform.position : Vector3.zero; } private static Vector3 GetEntranceInteriorForward(EntranceTeleport entrance) { //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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entrance == (Object)null) { return Vector3.forward; } try { if (entrance.isEntranceToBuilding && (Object)(object)entrance.exitScript != (Object)null) { Transform val = (((Object)(object)entrance.exitScript.entrancePoint != (Object)null) ? entrance.exitScript.entrancePoint : ((Component)entrance.exitScript).transform); if ((Object)(object)val != (Object)null) { Vector3 forward = val.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude >= 0.01f) { return ((Vector3)(ref forward)).normalized; } } } } catch { } if ((Object)(object)((Component)entrance).transform == (Object)null) { return Vector3.forward; } Vector3 forward2 = ((Component)entrance).transform.forward; forward2.y = 0f; if (((Vector3)(ref forward2)).sqrMagnitude < 0.01f) { forward2 = Vector3.forward; } return ((Vector3)(ref forward2)).normalized; } private static string GetEntranceDebugName(EntranceTeleport entrance) { if ((Object)(object)entrance == (Object)null) { return ""; } try { return $"{((Object)entrance).name}/id={entrance.entranceId}/isEntranceToBuilding={entrance.isEntranceToBuilding}"; } catch { return ((Object)entrance).name ?? ""; } } private static List BuildEntranceCubeOffsets(float half) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return new List { Vector3.zero }; } private static bool TryPickInsideAINodeEmergencyCubePosition(out Vector3 center, out string detail) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_012f: 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_014b: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; detail = string.Empty; try { RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || instance.insideAINodes == null || instance.insideAINodes.Length == 0) { detail = "no insideAINodes"; return false; } StartOfRound instance2 = StartOfRound.Instance; Vector3 shipPos = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.elevatorTransform != (Object)null) ? instance2.elevatorTransform.position : Vector3.zero); List list = (from n in instance.insideAINodes where (Object)(object)n != (Object)null select n into _ orderby Random.Range(0, int.MaxValue) select _).ThenByDescending((GameObject n) => (shipPos == Vector3.zero) ? 0f : Vector3.Distance(n.transform.position, shipPos)).ToList(); string arg = string.Empty; foreach (GameObject item in list) { if (!TrySnapCubeCenterToGroundStrict(item.transform.position, out var center2, out var rejectReason)) { arg = rejectReason; continue; } if (!IsEmergencyCubePlacementUsable(center2, out var rejectReason2)) { arg = rejectReason2; continue; } center = center2; detail = $"insideAINode={((Object)item).name}, tested={list.Count}"; return true; } detail = $"insideAINodes={list.Count}, lastReject={arg}"; return false; } catch (Exception ex) { detail = ex.Message; return false; } } private static bool TryPickAnyDeepEntrancePointCubePosition(out Vector3 center, out string detail) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020b: 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_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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024b: 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) center = Vector3.zero; detail = string.Empty; try { EntranceTeleport[] array = Object.FindObjectsOfType(); if (array == null) { detail = "no EntranceTeleport objects"; return false; } List list = new List(); EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { if ((Object)(object)val == (Object)null) { continue; } try { if ((Object)(object)val.exitScript != (Object)null && (Object)(object)val.exitScript.entrancePoint != (Object)null) { Vector3 pnt3 = val.exitScript.entrancePoint.position; if (EntranceDestinationLooksLikeInteriorSide(pnt3) && !list.Any((Vector3 existing) => Vector3.Distance(existing, pnt3) < 1f)) { list.Add(pnt3); } } } catch { } try { if ((Object)(object)val.entrancePoint != (Object)null) { Vector3 pnt2 = val.entrancePoint.position; if (EntranceDestinationLooksLikeInteriorSide(pnt2) && !list.Any((Vector3 existing) => Vector3.Distance(existing, pnt2) < 1f)) { list.Add(pnt2); } } } catch { } try { if ((Object)(object)((Component)val).transform != (Object)null) { Vector3 pnt = ((Component)val).transform.position; if (EntranceDestinationLooksLikeInteriorSide(pnt) && !list.Any((Vector3 existing) => Vector3.Distance(existing, pnt) < 1f)) { list.Add(pnt); } } } catch { } } ShuffleListInPlace(list); string arg = string.Empty; foreach (Vector3 item in list) { if (!TrySnapCubeCenterToGroundStrict(item, out var center2, out var rejectReason)) { arg = rejectReason; continue; } if (!IsEmergencyCubePlacementUsable(center2, out var rejectReason2)) { arg = rejectReason2; continue; } center = center2; detail = $"deepPoint={item}, candidates={list.Count}"; return true; } detail = $"deep candidates={list.Count}, lastReject={arg}"; return false; } catch (Exception ex) { detail = ex.Message; return false; } } private static bool IsEntranceCubePlacementSafe(Vector3 center, out string rejectReason) { //IL_0008: 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_0050: 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) rejectReason = string.Empty; if (!IsEmergencyCubePlacementUsable(center, out rejectReason)) { return false; } if (ForceFullSizeFootprintEnabled()) { return true; } float cubeHorizontalSize = GetCubeHorizontalSize(); float half = cubeHorizontalSize * 0.5f; float cubeConfiguredHeight = GetCubeConfiguredHeight(); float bottomY = center.y - cubeConfiguredHeight * 0.5f; if (HasSolidOverlapInCubeInterior(center, bottomY, half, out rejectReason)) { return false; } if (HasWallOrBlockerTooClose(center, bottomY, half, out rejectReason)) { return false; } return true; } private static bool TryPickEntranceFallbackCubePosition(out Vector3 center) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00e0: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; List interiorEntranceReachabilityAnchors = GetInteriorEntranceReachabilityAnchors(); if (interiorEntranceReachabilityAnchors.Count == 0) { return false; } ShuffleListInPlace(interiorEntranceReachabilityAnchors); float num = Mathf.Max(0.5f, (_cubeSize != null) ? _cubeSize.Value : 6f); float halfSize = num * 0.5f; List list = (from _ in BuildPlacementOffsets(halfSize) orderby Random.Range(0, int.MaxValue) select _).ThenBy((Vector3 o) => ((Vector3)(ref o)).sqrMagnitude).ToList(); string text = string.Empty; foreach (Vector3 item in interiorEntranceReachabilityAnchors) { foreach (Vector3 item2 in list) { if (!TrySnapCubeCenterToGroundStrict(item + item2, out var center2, out var rejectReason)) { text = rejectReason; continue; } if (IsCubePlacementSafe(center2, out var rejectReason2)) { D($"Picked strict entrance-connected fallback cube center: {center2}"); center = center2; return true; } text = rejectReason2; } } foreach (Vector3 item3 in interiorEntranceReachabilityAnchors) { foreach (Vector3 item4 in list) { if (!TrySnapCubeCenterToGroundStrict(item3 + item4, out var center3, out var rejectReason3)) { text = rejectReason3; continue; } if (IsEmergencyCubePlacementUsable(center3, out var rejectReason4)) { D($"Picked player-safe entrance-connected emergency cube center: {center3}"); center = center3; return true; } text = rejectReason4; } } D("No entrance fallback cube placement accepted. Last reject: " + text); return false; } private static Vector3 PickEmergencyCubePosition(Vector3 fallbackBase) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_012a: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (TrySnapCubeCenterToGroundStrict(fallbackBase, out var center, out var _) && IsEmergencyCubePlacementUsable(center, out var _)) { return center; } RoundManager instance = RoundManager.Instance; if ((Object)(object)instance != (Object)null && instance.insideAINodes != null) { foreach (GameObject item in instance.insideAINodes.Where((GameObject n) => (Object)(object)n != (Object)null && n.activeInHierarchy)) { if (!TrySnapCubeCenterToGroundStrict(item.transform.position, out var center2, out var _) || !IsEmergencyCubePlacementUsable(center2, out var _)) { continue; } return center2; } } if (TryPickEntranceFallbackCubePosition(out var center3)) { return center3; } Vector3 val = fallbackBase + Vector3.up * (GetCubeConfiguredHeight() * 0.5f); Log.LogWarning((object)$"[Extraction] Last-resort cube placement used because no strict/entrance-connected spot was accepted: {val}"); return val; } private static bool TrySnapCubeCenterToGroundStrict(Vector3 basePosition, out Vector3 center, out string rejectReason) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_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_009c: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: 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_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; rejectReason = string.Empty; float cubeHorizontalSize = GetCubeHorizontalSize(); float cubeConfiguredHeight = GetCubeConfiguredHeight(); float num = Mathf.Max(0.25f, (_groundSnapRayStartHeight != null) ? _groundSnapRayStartHeight.Value : 6f); float num2 = Mathf.Max(1f, (_groundSnapRayDistance != null) ? _groundSnapRayDistance.Value : 20f); float num3 = Mathf.Clamp((_cubePlacementMaxFloorDrop != null) ? _cubePlacementMaxFloorDrop.Value : 1.25f, 0.25f, 6f); float num4 = 0.85f; Vector3 val = basePosition + Vector3.up * num; float num5 = num + num2; try { RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, num5, -1, (QueryTriggerInteraction)1); if (array != null && array.Length != 0) { foreach (RaycastHit item in array.OrderByDescending((RaycastHit h) => ((RaycastHit)(ref h)).point.y)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ((RaycastHit)(ref current)).collider.isTrigger || ((RaycastHit)(ref current)).normal.y < 0.62f) { continue; } float num6 = ((RaycastHit)(ref current)).point.y - basePosition.y; float num7 = basePosition.y - ((RaycastHit)(ref current)).point.y; if (num6 > num4) { rejectReason = $"floor snap hit was too far above node; rise={num6:0.00}m"; continue; } if (num7 > num3) { rejectReason = $"floor snap would drop cube too far; drop={num7:0.00}m > {num3:0.00}m"; continue; } center = new Vector3(basePosition.x, ((RaycastHit)(ref current)).point.y + cubeConfiguredHeight * 0.5f, basePosition.z); return true; } } } catch (Exception ex) { rejectReason = "strict ground snap raycast failed: " + ex.Message; return false; } if (string.IsNullOrEmpty(rejectReason)) { rejectReason = $"no strict floor snap under {basePosition}"; } return false; } private static bool IsCubePlacementSafe(Vector3 center, out string rejectReason) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_0116: 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) //IL_012e: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; float cubeHorizontalSize = GetCubeHorizontalSize(); float num = cubeHorizontalSize * 0.5f; float cubeConfiguredHeight = GetCubeConfiguredHeight(); float num2 = center.y - cubeConfiguredHeight * 0.5f; float num3 = Mathf.Clamp((_cubePlacementFloorInset != null) ? _cubePlacementFloorInset.Value : 0.2f, 0.05f, Mathf.Max(0.06f, num - 0.05f)); float num4 = Mathf.Max(0.1f, num - num3); if (OverlapsDangerousTrigger(center, new Vector3(num + 0.35f, cubeConfiguredHeight * 0.5f + 0.35f, num + 0.35f), out rejectReason)) { return false; } if (!HasRequiredCubeHeightClearance(center, out rejectReason)) { return false; } if (ForceFullSizeFootprintEnabled()) { return IsFullSizeCubeCenterPlacementUsable(center, num2, out rejectReason); } Vector3[] array = (Vector3[])(object)new Vector3[13] { Vector3.zero, new Vector3(num4, 0f, 0f), new Vector3(0f - num4, 0f, 0f), new Vector3(0f, 0f, num4), new Vector3(0f, 0f, 0f - num4), new Vector3(num4, 0f, num4), new Vector3(num4, 0f, 0f - num4), new Vector3(0f - num4, 0f, num4), new Vector3(0f - num4, 0f, 0f - num4), new Vector3(num4 * 0.55f, 0f, num4 * 0.55f), new Vector3(num4 * 0.55f, 0f, (0f - num4) * 0.55f), new Vector3((0f - num4) * 0.55f, 0f, num4 * 0.55f), new Vector3((0f - num4) * 0.55f, 0f, (0f - num4) * 0.55f) }; float num5 = float.PositiveInfinity; float num6 = float.NegativeInfinity; for (int i = 0; i < array.Length; i++) { Vector3 val = center + array[i]; if (!TryFindFloorAt(val, num2, out var floorHit)) { rejectReason = $"missing floor support sample #{i} at {val}"; return false; } num5 = Mathf.Min(num5, ((RaycastHit)(ref floorHit)).point.y); num6 = Mathf.Max(num6, ((RaycastHit)(ref floorHit)).point.y); if (Mathf.Abs(((RaycastHit)(ref floorHit)).point.y - num2) > 0.35f) { rejectReason = $"unsafe floor height sample #{i}; expectedY={num2:0.00}, hitY={((RaycastHit)(ref floorHit)).point.y:0.00}"; return false; } } if (num6 - num5 > 0.45f) { rejectReason = $"cube footprint crosses uneven floor/ledge; variance={num6 - num5:0.00}m"; return false; } if (HasSolidOverlapInCubeInterior(center, num2, num, out rejectReason)) { return false; } if (HasWallOrBlockerTooClose(center, num2, num, out rejectReason)) { return false; } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(center.x, num2 + 0.85f, center.z); if (!IsPlayerTeleportPositionSafe(val2, out rejectReason)) { rejectReason = "cube center player teleport unsafe: " + rejectReason; return false; } if (CubePlacementRequiresNavMesh() && IsNavMeshReflectionAvailable()) { if (!TrySampleNavMeshPosition(val2, 2.25f, out var navPosition)) { rejectReason = $"no navmesh near cube center teleport spot {val2}"; return false; } float num7 = Vector2.Distance(new Vector2(val2.x, val2.z), new Vector2(navPosition.x, navPosition.z)); if (num7 > 1.35f || Mathf.Abs(navPosition.y - (val2.y - 0.85f)) > 1f) { rejectReason = $"navmesh sample too far from cube center; nav={navPosition}, player={val2}, planar={num7:0.00}"; return false; } } if (!IsReachableFromInteriorEntrance(val2, out rejectReason)) { rejectReason = "cube center is not reachable from an interior entrance: " + rejectReason; return false; } if (HasBackfaceGeometryNearPlayerSpot(val2, out rejectReason)) { rejectReason = "cube center failed backface/out-of-bounds check: " + rejectReason; return false; } return true; } private static bool IsFullSizeCubeCenterPlacementUsable(Vector3 center, float bottomY, out string rejectReason) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x, bottomY + 0.85f, center.z); if (!IsPlayerTeleportPositionSafe(val, out rejectReason)) { rejectReason = "full-size cube center player teleport unsafe: " + rejectReason; return false; } if (CubePlacementRequiresNavMesh() && IsNavMeshReflectionAvailable()) { if (!TrySampleNavMeshPosition(val, 2.5f, out var navPosition)) { rejectReason = $"full-size cube center is not near navmesh at {val}"; return false; } float num = Vector2.Distance(new Vector2(val.x, val.z), new Vector2(navPosition.x, navPosition.z)); if (num > 1.65f || Mathf.Abs(navPosition.y - (val.y - 0.85f)) > 1.25f) { rejectReason = $"full-size cube navmesh sample too far; nav={navPosition}, player={val}, planar={num:0.00}"; return false; } } if (!IsReachableFromInteriorEntrance(val, out rejectReason)) { rejectReason = "full-size cube center is not reachable from an interior entrance: " + rejectReason; return false; } if (HasBackfaceGeometryNearPlayerSpot(val, out rejectReason)) { rejectReason = "full-size cube center failed backface/out-of-bounds check: " + rejectReason; return false; } return true; } private static bool IsEmergencyCubePlacementUsable(Vector3 center, out string rejectReason) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0053: 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_007e: 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) rejectReason = string.Empty; float cubeHorizontalSize = GetCubeHorizontalSize(); float num = cubeHorizontalSize * 0.5f; float num2 = center.y - GetCubeConfiguredHeight() * 0.5f; Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(center.x, num2 + 0.85f, center.z); if (OverlapsDangerousTrigger(center, new Vector3(0.85f, 1.9f, 0.85f), out rejectReason)) { return false; } if (!HasRequiredCubeHeightClearance(center, out rejectReason)) { return false; } if (!IsPlayerTeleportPositionSafe(position, out rejectReason)) { return false; } if (CubePlacementRequiresNavMesh() && IsNavMeshReflectionAvailable() && !TrySampleNavMeshPosition(position, 2.5f, out var _)) { rejectReason = "emergency cube center is not near navmesh"; return false; } return true; } private static bool TryFindFloorAt(Vector3 sample, float expectedFloorY, out RaycastHit floorHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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) floorHit = default(RaycastHit); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(sample.x, expectedFloorY + 2.4f, sample.z); try { RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, 4.8f, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return false; } foreach (RaycastHit item in array.OrderByDescending((RaycastHit h) => ((RaycastHit)(ref h)).point.y)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ((RaycastHit)(ref current)).collider.isTrigger || (Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() != (Object)null || ((RaycastHit)(ref current)).normal.y < 0.62f || ((RaycastHit)(ref current)).point.y > expectedFloorY + 0.35f || ((RaycastHit)(ref current)).point.y < expectedFloorY - 0.45f || IsDangerousColliderName(((RaycastHit)(ref current)).collider)) { continue; } floorHit = current; return true; } } catch (Exception ex) { D($"Floor safety ray failed at {sample}: {ex.Message}"); } return false; } private static bool HasSolidOverlapInCubeInterior(Vector3 center, float bottomY, float half, out string rejectReason) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_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_0053: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x, bottomY + 1.55f, center.z); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Max(0.25f, half - 0.18f), 1.25f, Mathf.Max(0.25f, half - 0.18f)); try { Collider[] array = Physics.OverlapBox(val, val2, Quaternion.identity, -1, (QueryTriggerInteraction)1); if (array == null) { return false; } Collider[] array2 = array; foreach (Collider c in array2) { if (!ShouldIgnoreCubeInteriorOverlap(c, bottomY)) { rejectReason = "cube interior overlaps solid geometry/prop: " + GetColliderPath(c); return true; } } } catch (Exception ex) { D("Cube interior overlap check failed: " + ex.Message); } return false; } private static bool ShouldIgnoreCubeInteriorOverlap(Collider c, float bottomY) { //IL_0080: 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_0088: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)c == (Object)null) { return true; } if (c.isTrigger) { return true; } if ((Object)(object)_cubeVisual != (Object)null && (Object)(object)((Component)c).transform != (Object)null && ((Component)c).transform.IsChildOf(_cubeVisual.transform)) { return true; } if ((Object)(object)((Component)c).GetComponentInParent() != (Object)null) { return true; } Bounds bounds = c.bounds; if (((Bounds)(ref bounds)).max.y < bottomY + 0.2f) { return true; } string text = GetColliderPath(c).ToLowerInvariant(); if (text.Contains("ainode") || text.Contains("navmesh") || text.Contains("scan") || text.Contains("audio") || text.Contains("sound")) { return true; } return false; } private static bool HasWallOrBlockerTooClose(Vector3 center, float bottomY, float half, out string rejectReason) { //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; float num = Mathf.Clamp((_cubePlacementWallClearance != null) ? _cubePlacementWallClearance.Value : 2.5f, 0.25f, 4f); float num2 = half + num; float[] array = new float[4] { 0.75f, 1.45f, 2.25f, 3.05f }; Vector3[] obj = new Vector3[8] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val = Vector3.forward + Vector3.left; obj[4] = ((Vector3)(ref val)).normalized; val = Vector3.forward + Vector3.right; obj[5] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.left; obj[6] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.right; obj[7] = ((Vector3)(ref val)).normalized; Vector3[] array2 = (Vector3[])(object)obj; float[] array3 = array; Vector3 val2 = default(Vector3); foreach (float num3 in array3) { ((Vector3)(ref val2))..ctor(center.x, bottomY + num3, center.z); Vector3[] array4 = array2; foreach (Vector3 val3 in array4) { try { RaycastHit[] array5 = Physics.RaycastAll(val2, val3, num2, -1, (QueryTriggerInteraction)1); if (array5 == null || array5.Length == 0) { continue; } foreach (RaycastHit item in array5.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance)) { RaycastHit current = item; if (ShouldIgnorePlacementHit(current, bottomY)) { continue; } rejectReason = $"wall/blocker too close at height {num3:0.00}; hit={GetColliderPath(((RaycastHit)(ref current)).collider)}, distance={((RaycastHit)(ref current)).distance:0.00}, point={((RaycastHit)(ref current)).point}"; return true; } } catch (Exception ex) { D($"Wall safety ray failed from {val2}: {ex.Message}"); } } } return false; } private static bool ShouldIgnorePlacementHit(RaycastHit hit, float bottomY) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null) { return true; } if (((RaycastHit)(ref hit)).collider.isTrigger) { return true; } if ((Object)(object)_cubeVisual != (Object)null && (Object)(object)((Component)((RaycastHit)(ref hit)).collider).transform != (Object)null && ((Component)((RaycastHit)(ref hit)).collider).transform.IsChildOf(_cubeVisual.transform)) { return true; } if ((Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent() != (Object)null) { return true; } if (Mathf.Abs(((RaycastHit)(ref hit)).normal.y) > 0.7f) { return true; } Bounds bounds = ((RaycastHit)(ref hit)).collider.bounds; if (((Bounds)(ref bounds)).max.y < bottomY + 0.2f) { return true; } string text = GetColliderPath(((RaycastHit)(ref hit)).collider).ToLowerInvariant(); if (text.Contains("ainode") || text.Contains("navmesh") || text.Contains("scan") || text.Contains("audio") || text.Contains("sound")) { return true; } return false; } private static float ScoreCubePlacementCandidate(Vector3 center, Vector3 shipPos, bool strict) { //IL_0015: 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_0047: 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_008b: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: 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) float num = 0f; float cubeHorizontalSize = GetCubeHorizontalSize(); float num2 = cubeHorizontalSize * 0.5f; float num3 = center.y - GetCubeConfiguredHeight() * 0.5f; float num4 = MeasureOpenSpaceScore(center, num3, num2); num += num4 * (strict ? 12f : 5f); num = ((!HasWallOrBlockerTooClose(center, num3, num2, out var rejectReason)) ? (num + 80f) : (num - 80f)); num = ((!HasSolidOverlapInCubeInterior(center, num3, num2, out rejectReason)) ? (num + 45f) : (num - 100f)); if (OverlapsDangerousTrigger(center, new Vector3(num2 + 0.35f, num2 + 0.35f, num2 + 0.35f), out var _)) { num -= 500f; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x, num3 + 0.85f, center.z); num = ((!IsPlayerTeleportPositionSafe(val, out var _)) ? (num - 160f) : (num + 60f)); if (CubePlacementRequiresNavMesh() && IsNavMeshReflectionAvailable()) { if (TrySampleNavMeshPosition(val, 2.25f, out var navPosition)) { float num5 = Vector2.Distance(new Vector2(val.x, val.z), new Vector2(navPosition.x, navPosition.z)); num += Mathf.Max(0f, 30f - num5 * 15f); } else { num -= 120f; } } if (shipPos != Vector3.zero) { num += Mathf.Min(Vector3.Distance(center, shipPos), 100f) * 0.05f; } return num; } private static float MeasureOpenSpaceScore(Vector3 center, float bottomY, float half) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp((_cubePlacementWallClearance != null) ? _cubePlacementWallClearance.Value : 2.5f, 0.25f, 4f); float num2 = half + num + 4f; float[] array = new float[2] { 1f, 1.85f }; Vector3[] obj = new Vector3[8] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val = Vector3.forward + Vector3.left; obj[4] = ((Vector3)(ref val)).normalized; val = Vector3.forward + Vector3.right; obj[5] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.left; obj[6] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.right; obj[7] = ((Vector3)(ref val)).normalized; Vector3[] array2 = (Vector3[])(object)obj; List list = new List(); float[] array3 = array; Vector3 val2 = default(Vector3); foreach (float num3 in array3) { ((Vector3)(ref val2))..ctor(center.x, bottomY + num3, center.z); Vector3[] array4 = array2; foreach (Vector3 val3 in array4) { float item = num2; try { RaycastHit[] array5 = Physics.RaycastAll(val2, val3, num2, -1, (QueryTriggerInteraction)1); if (array5 != null) { foreach (RaycastHit item2 in array5.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance)) { RaycastHit current = item2; if (ShouldIgnorePlacementHit(current, bottomY)) { continue; } item = ((RaycastHit)(ref current)).distance; break; } } } catch { item = 0f; } list.Add(item); } } if (list.Count == 0) { return 0f; } float num4 = list.Min(); float num5 = list.Average(); float num6 = list.Max(); return num4 * 2.5f + num5 - (num6 - num4) * 0.35f; } private static bool OverlapsDangerousTrigger(Vector3 center, Vector3 halfExtents, out string rejectReason) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; if (_cubePlacementRejectDangerTriggers != null && !_cubePlacementRejectDangerTriggers.Value) { return false; } try { Collider[] array = Physics.OverlapBox(center, halfExtents, Quaternion.identity, -1, (QueryTriggerInteraction)2); if (array == null) { return false; } Collider[] array2 = array; foreach (Collider val in array2) { if (!((Object)(object)val == (Object)null) && val.isTrigger && IsDangerousColliderName(val)) { rejectReason = "overlaps dangerous trigger: " + GetColliderPath(val); return true; } } } catch (Exception ex) { D("Danger trigger overlap check failed: " + ex.Message); } return false; } private static bool IsDangerousColliderName(Collider c) { if ((Object)(object)c == (Object)null) { return false; } string text = GetColliderPath(c).ToLowerInvariant(); return text.Contains("kill") || text.Contains("death") || text.Contains("dead") || text.Contains("outofbounds") || text.Contains("out of bounds") || (text.Contains("bounds") && text.Contains("out")) || text.Contains("void") || text.Contains("pit") || text.Contains("fall") || text.Contains("hazard") || text.Contains("damage") || text.Contains("drown"); } private static string GetColliderPath(Collider c) { if ((Object)(object)c == (Object)null) { return ""; } try { Transform val = ((Component)c).transform; List list = new List(); while ((Object)(object)val != (Object)null && list.Count < 8) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } catch { return ((Object)c).name ?? ""; } } private static bool CubePlacementRequiresNavMesh() { return _cubePlacementRequireNavMesh != null && _cubePlacementRequireNavMesh.Value; } private static bool IsNavMeshReflectionAvailable() { EnsureNavMeshReflection(); return _navMeshReflectionAvailable; } private static void EnsureNavMeshReflection() { if (_navMeshReflectionInitialized) { return; } _navMeshReflectionInitialized = true; try { _navMeshType = Type.GetType("UnityEngine.AI.NavMesh, UnityEngine.AIModule"); _navMeshHitType = Type.GetType("UnityEngine.AI.NavMeshHit, UnityEngine.AIModule"); if (_navMeshType == null || _navMeshHitType == null) { return; } _navMeshSamplePositionMethod = _navMeshType.GetMethod("SamplePosition", BindingFlags.Static | BindingFlags.Public, null, new Type[4] { typeof(Vector3), _navMeshHitType.MakeByRefType(), typeof(float), typeof(int) }, null); _navMeshPathType = Type.GetType("UnityEngine.AI.NavMeshPath, UnityEngine.AIModule"); if (_navMeshPathType != null) { _navMeshCalculatePathMethod = _navMeshType.GetMethod("CalculatePath", BindingFlags.Static | BindingFlags.Public, null, new Type[4] { typeof(Vector3), typeof(Vector3), typeof(int), _navMeshPathType }, null); _navMeshPathStatusProperty = _navMeshPathType.GetProperty("status", BindingFlags.Instance | BindingFlags.Public); } _navMeshHitPositionProperty = _navMeshHitType.GetProperty("position", BindingFlags.Instance | BindingFlags.Public); _navMeshHitPositionField = _navMeshHitType.GetField("position", BindingFlags.Instance | BindingFlags.Public); _navMeshReflectionAvailable = _navMeshSamplePositionMethod != null && (_navMeshHitPositionProperty != null || _navMeshHitPositionField != null); } catch { _navMeshReflectionAvailable = false; } if (!_navMeshReflectionAvailable && !_navMeshUnavailableLogged) { _navMeshUnavailableLogged = true; D("Unity NavMesh reflection is unavailable. Cube placement will use physics-only safety checks."); } } private static bool TrySampleNavMeshPosition(Vector3 position, float maxDistance, out Vector3 navPosition) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) navPosition = Vector3.zero; EnsureNavMeshReflection(); if (!_navMeshReflectionAvailable) { return false; } try { object obj = Activator.CreateInstance(_navMeshHitType); object[] array = new object[4] { position, obj, maxDistance, -1 }; if (!(bool)_navMeshSamplePositionMethod.Invoke(null, array)) { return false; } object obj2 = array[1]; object obj3 = ((_navMeshHitPositionProperty != null) ? _navMeshHitPositionProperty.GetValue(obj2, null) : _navMeshHitPositionField.GetValue(obj2)); if (obj3 is Vector3) { navPosition = (Vector3)obj3; return true; } } catch (Exception ex) { D("NavMesh sample failed: " + ex.Message); } return false; } private static bool CubePlacementRequiresReachablePathFromEntrance() { return _cubePlacementRequireReachablePathFromEntrance != null && _cubePlacementRequireReachablePathFromEntrance.Value; } private static bool IsNavMeshPathReflectionAvailable() { EnsureNavMeshReflection(); bool flag = _navMeshReflectionAvailable && _navMeshPathType != null && _navMeshCalculatePathMethod != null && _navMeshPathStatusProperty != null; if (!flag && !_navMeshPathUnavailableLogged) { _navMeshPathUnavailableLogged = true; D("Unity NavMesh path reflection is unavailable. Entrance reachability checks will be skipped."); } return flag; } private static List GetInteriorEntranceReachabilityAnchors() { //IL_0080: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if (_cachedInteriorEntranceReachabilityAnchorsFrame == Time.frameCount) { return new List(_cachedInteriorEntranceReachabilityAnchors); } List list = new List(); try { EntranceTeleport[] array = Object.FindObjectsOfType(); if (array != null) { EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { if ((Object)(object)val == (Object)null || !val.isEntranceToBuilding) { continue; } Vector3 anchor = GetEntranceTeleportAnchorPosition(val); if (EntranceDestinationLooksLikeInteriorSide(anchor)) { if (TrySampleNavMeshPosition(anchor, 5f, out var navPosition)) { anchor = navPosition; } if (!list.Any((Vector3 a) => Vector3.Distance(a, anchor) < 1f)) { list.Add(anchor); } } } } } catch (Exception ex) { D("Failed to collect interior entrance reachability anchors: " + ex.Message); } _cachedInteriorEntranceReachabilityAnchors.Clear(); _cachedInteriorEntranceReachabilityAnchors.AddRange(list); _cachedInteriorEntranceReachabilityAnchorsFrame = Time.frameCount; return list; } private static bool IsReachableFromInteriorEntrance(Vector3 playerPosition, out string rejectReason) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; if (!CubePlacementRequiresReachablePathFromEntrance()) { return true; } if (!IsNavMeshPathReflectionAvailable()) { return true; } if (!TrySampleNavMeshPosition(playerPosition, 2.5f, out var navPosition)) { rejectReason = "target is not on reachable navmesh"; return false; } List interiorEntranceReachabilityAnchors = GetInteriorEntranceReachabilityAnchors(); if (interiorEntranceReachabilityAnchors.Count == 0) { if (!_entrancePathUnavailableLogged) { _entrancePathUnavailableLogged = true; D("No interior EntranceTeleport anchors were found. Entrance path reachability check will be skipped this round."); } return true; } string rejectReason2 = string.Empty; foreach (Vector3 item in interiorEntranceReachabilityAnchors) { Vector3 navPosition2 = item; if (!TrySampleNavMeshPosition(item, 5f, out navPosition2)) { rejectReason2 = $"entrance anchor not on navmesh: {item}"; } else if (TryHasCompleteNavMeshPath(navPosition2, navPosition, out rejectReason2)) { return true; } } rejectReason = (string.IsNullOrEmpty(rejectReason2) ? "no complete navmesh path from any interior entrance" : rejectReason2); return false; } private static bool TryHasCompleteNavMeshPath(Vector3 source, Vector3 target, out string rejectReason) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; if (!IsNavMeshPathReflectionAvailable()) { return true; } try { object obj = Activator.CreateInstance(_navMeshPathType); object[] parameters = new object[4] { source, target, -1, obj }; if (!(bool)_navMeshCalculatePathMethod.Invoke(null, parameters)) { rejectReason = $"NavMesh.CalculatePath failed from {source} to {target}"; return false; } object value = _navMeshPathStatusProperty.GetValue(obj, null); string text = ((value != null) ? value.ToString() : string.Empty); if (text.IndexOf("Complete", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } rejectReason = "navmesh path from entrance is " + text; return false; } catch (Exception ex) { rejectReason = "NavMesh path check failed: " + ex.Message; return true; } } private static bool HasBackfaceGeometryNearPlayerSpot(Vector3 playerPosition, out string rejectReason) { //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) //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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0070: 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) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008f: 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_0099: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0120: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0196: 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_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: 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_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; if (_cubePlacementRejectBackfaceGeometry != null && !_cubePlacementRejectBackfaceGeometry.Value) { return false; } bool queriesHitBackfaces = Physics.queriesHitBackfaces; try { Physics.queriesHitBackfaces = true; Vector3[] obj = new Vector3[8] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val = Vector3.forward + Vector3.left; obj[4] = ((Vector3)(ref val)).normalized; val = Vector3.forward + Vector3.right; obj[5] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.left; obj[6] = ((Vector3)(ref val)).normalized; val = Vector3.back + Vector3.right; obj[7] = ((Vector3)(ref val)).normalized; Vector3[] array = (Vector3[])(object)obj; float[] array2 = new float[3] { 0.65f, 1.35f, 1.85f }; float[] array3 = array2; foreach (float num in array3) { Vector3 val2 = playerPosition + Vector3.up * num; Vector3[] array4 = array; for (int j = 0; j < array4.Length; j++) { Vector3 val3 = array4[j]; RaycastHit[] array5 = Physics.RaycastAll(val2, val3, 5.5f, -1, (QueryTriggerInteraction)1); if (array5 == null) { continue; } foreach (RaycastHit item in array5.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ((RaycastHit)(ref current)).distance < 0.05f || ShouldIgnorePlacementHit(current, playerPosition.y - 0.85f)) { continue; } val = ((RaycastHit)(ref current)).normal; float num2 = Vector3.Dot(((Vector3)(ref val)).normalized, ((Vector3)(ref val3)).normalized); if (num2 > 0.18f && Mathf.Abs(((RaycastHit)(ref current)).normal.y) < 0.75f) { rejectReason = $"backface/out-of-bounds geometry detected: {GetColliderPath(((RaycastHit)(ref current)).collider)}, facing={num2:0.00}, point={((RaycastHit)(ref current)).point}"; return true; } break; } } } } catch (Exception ex) { D("Backface geometry check failed: " + ex.Message); } finally { Physics.queriesHitBackfaces = queriesHitBackfaces; } return false; } private static void CreateOrMoveCubeVisual(Vector3 center) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) _cubeCenter = center; float cubeHorizontalSize = GetCubeHorizontalSize(); float cubeConfiguredHeight = GetCubeConfiguredHeight(); bool flag = false; bool flag2 = CubeDynamicFootprintEnabled(); string text = BuildCubeVisualMeshSignature(center, cubeHorizontalSize, cubeConfiguredHeight, flag2); bool flag3 = (Object)(object)_cubeVisual == (Object)null || _cubeVisualMeshSignature != text; if ((Object)(object)_cubeVisual == (Object)null) { flag = true; _cubeVisual = new GameObject("Extraction_Area_ClientVisual"); MeshFilter val = _cubeVisual.AddComponent(); val.sharedMesh = (flag2 ? CreateDynamicFootprintForcefieldMesh(center, cubeHorizontalSize, cubeConfiguredHeight) : CreateDoubleSidedOpenBottomUnitCubeMesh()); MeshRenderer val2 = _cubeVisual.AddComponent(); ((Renderer)val2).sharedMaterial = CreateTransparentYellowMaterial(); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).allowOcclusionWhenDynamic = false; } else { MeshRenderer component = _cubeVisual.GetComponent(); if ((Object)(object)component != (Object)null) { if ((Object)(object)((Renderer)component).sharedMaterial == (Object)null) { ((Renderer)component).sharedMaterial = CreateTransparentYellowMaterial(); } else { ApplyTransparentMaterialSettings(((Renderer)component).sharedMaterial); } ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; ((Renderer)component).allowOcclusionWhenDynamic = false; } if (flag3) { MeshFilter component2 = _cubeVisual.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.sharedMesh = (flag2 ? CreateDynamicFootprintForcefieldMesh(center, cubeHorizontalSize, cubeConfiguredHeight) : CreateDoubleSidedOpenBottomUnitCubeMesh()); } } } bool flag4 = Vector3.Distance(_cubeVisual.transform.position, center) > 0.01f; _cubeVisual.transform.position = center; _cubeVisual.transform.rotation = Quaternion.identity; _cubeVisual.transform.localScale = (Vector3)(flag2 ? Vector3.one : new Vector3(cubeHorizontalSize, cubeConfiguredHeight, cubeHorizontalSize)); if (!_cubeVisual.activeSelf) { _cubeVisual.SetActive(true); } EnsureCubeForcefieldDetailObjects(); if (flag3) { RefreshCubeForcefieldDetailMeshes(flag2); _cubeVisualMeshSignature = text; } ForceCubeVisualVisible(); UpdateCubeLight(center, Mathf.Max(cubeHorizontalSize, cubeConfiguredHeight)); UpdateCubePulseVisual(force: true); _cubeCenter = center; _hasCube = true; if (flag || flag4 || flag3) { string text2 = ((flag2 && _cubeDynamicFootprintReady) ? $"dynamic footprint cells={_cubeDynamicFootprintCells.Count}, cell={_cubeDynamicFootprintCellSize:0.00}m, bounds={CurrentCubeBounds()}" : $"box bounds={CurrentCubeBounds()}"); D($"Created/moved local double-sided open-bottom forcefield visual at {center}. Horizontal={cubeHorizontalSize:0.00}m, maxRoof={cubeConfiguredHeight:0.00}m, actualRoof={(_cubeDynamicFootprintReady ? _cubeDynamicFootprintHeight : cubeConfiguredHeight):0.00}m. Alpha {_cubeVisualAlpha.Value}. Shape={text2}. meshRefresh={flag3}"); } } private static string BuildCubeVisualMeshSignature(Vector3 center, float horizontalSize, float configuredHeight, bool dynamicFootprint) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) if (!dynamicFootprint || !_cubeDynamicFootprintReady) { return $"box|{horizontalSize:0.000}|{configuredHeight:0.000}"; } int dynamicFootprintCellHash = GetDynamicFootprintCellHash(); return $"dynamic|{center.x:0.000}|{center.y:0.000}|{center.z:0.000}|{horizontalSize:0.000}|{configuredHeight:0.000}|{_cubeDynamicFootprintCellSize:0.000}|{_cubeDynamicFootprintBottomY:0.000}|{_cubeDynamicFootprintHeight:0.000}|{_cubeDynamicFootprintCells.Count}|{dynamicFootprintCellHash}|{((Bounds)(ref _cubeDynamicFootprintBounds)).center.x:0.000}|{((Bounds)(ref _cubeDynamicFootprintBounds)).center.y:0.000}|{((Bounds)(ref _cubeDynamicFootprintBounds)).center.z:0.000}|{((Bounds)(ref _cubeDynamicFootprintBounds)).extents.x:0.000}|{((Bounds)(ref _cubeDynamicFootprintBounds)).extents.y:0.000}|{((Bounds)(ref _cubeDynamicFootprintBounds)).extents.z:0.000}"; } private static int GetDynamicFootprintCellHash() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) int num = 17; List dynamicFootprintCellsForSync = GetDynamicFootprintCellsForSync(); for (int i = 0; i < dynamicFootprintCellsForSync.Count; i++) { int num2 = num * 31; Vector2Int val = dynamicFootprintCellsForSync[i]; num = num2 + ((Vector2Int)(ref val)).x; int num3 = num * 31; val = dynamicFootprintCellsForSync[i]; num = num3 + ((Vector2Int)(ref val)).y; } return num; } private static void ForceCubeVisualVisible() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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)_cubeVisual == (Object)null) { return; } try { SetLayerRecursively(_cubeVisual, 0); Renderer[] componentsInChildren = _cubeVisual.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { val.enabled = true; val.forceRenderingOff = false; val.shadowCastingMode = (ShadowCastingMode)0; val.receiveShadows = false; val.allowOcclusionWhenDynamic = false; if ((Object)(object)val.sharedMaterial == (Object)null) { val.sharedMaterial = CreateTransparentYellowMaterial(); } else { ApplyTransparentMaterialSettings(val.sharedMaterial); } } } MeshFilter[] componentsInChildren2 = _cubeVisual.GetComponentsInChildren(true); MeshFilter[] array2 = componentsInChildren2; foreach (MeshFilter val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.sharedMesh == (Object)null)) { val2.sharedMesh.RecalculateBounds(); Bounds bounds = val2.sharedMesh.bounds; ((Bounds)(ref bounds)).Expand(2f); val2.sharedMesh.bounds = bounds; } } } catch (Exception ex) { D("Force cube visual visible failed: " + ex.Message); } } private static void SetLayerRecursively(GameObject obj, int layer) { if (!((Object)(object)obj == (Object)null)) { obj.layer = layer; Transform transform = obj.transform; for (int i = 0; i < transform.childCount; i++) { SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer); } } } private static bool ForceFullSizeFootprintEnabled() { return _forceFullSizeFootprint != null && _forceFullSizeFootprint.Value; } private static bool CubeDynamicFootprintEnabled() { if (ForceFullSizeFootprintEnabled()) { return false; } if (!IsServer()) { if (_cubeDynamicFootprintAuthoritativeFromHost && _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) { return true; } if (_cubeDynamicFootprintWaitingForAuthoritativeHostSync) { return false; } } if (_adaptiveForcefieldBounds != null && !_adaptiveForcefieldBounds.Value) { return false; } return _adaptiveForcefieldDynamicFootprint == null || _adaptiveForcefieldDynamicFootprint.Value; } private static float GetCubeHorizontalSize() { return Mathf.Max(0.5f, (_cubeSize != null) ? _cubeSize.Value : 6f); } private static float GetCubeRequestedHeight() { return Mathf.Max(1.5f, (_cubeHeight != null) ? _cubeHeight.Value : GetCubeHorizontalSize()); } private static float GetCubeConfiguredHeight() { if (ForceFullSizeFootprintEnabled()) { return GetCubeRequestedHeight(); } return Mathf.Max(1.5f, (_cubeEffectiveHeightOverride > 0.01f) ? _cubeEffectiveHeightOverride : GetCubeRequestedHeight()); } private static float DynamicAreaLocalBottomY() { return _cubeDynamicFootprintBottomY - _cubeCenter.y; } private static float DynamicAreaLocalTopY() { return DynamicAreaLocalBottomY() + Mathf.Max(0.5f, _cubeDynamicFootprintHeight); } private static float DynamicAreaLocalMiddleY() { return (DynamicAreaLocalBottomY() + DynamicAreaLocalTopY()) * 0.5f; } private static int CubeCellKey(int x, int z) { return (x + 128) * 1000 + (z + 128); } private static bool CubeFootprintHasCell(int x, int z) { return _cubeDynamicFootprintCells.Contains(CubeCellKey(x, z)); } private static void GetDynamicCellLocalEdges(int x, int z, float cell, out float minX, out float maxX, out float minZ, out float maxZ) { float num = DynamicAreaBoundaryInset(); minX = ((float)x - 0.5f) * cell; maxX = ((float)x + 0.5f) * cell; minZ = ((float)z - 0.5f) * cell; maxZ = ((float)z + 0.5f) * cell; if (!CubeFootprintHasCell(x - 1, z)) { minX += num; } if (!CubeFootprintHasCell(x + 1, z)) { maxX -= num; } if (!CubeFootprintHasCell(x, z - 1)) { minZ += num; } if (!CubeFootprintHasCell(x, z + 1)) { maxZ -= num; } if (maxX < minX) { maxX = (minX = (minX + maxX) * 0.5f); } if (maxZ < minZ) { maxZ = (minZ = (minZ + maxZ) * 0.5f); } } private static Vector3 CubeCellCenterWorld(Vector3 cubeCenter, int x, int z, float cellSize) { //IL_0001: 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_0012: 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_0025: Unknown result type (might be due to invalid IL or missing references) return new Vector3(cubeCenter.x + (float)x * cellSize, cubeCenter.y, cubeCenter.z + (float)z * cellSize); } private static void RebuildDynamicAreaFootprint(Vector3 center, float horizontalSize, float configuredHeight) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: 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_00a4: 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_00ab: 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_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) _cubeDynamicFootprintAuthoritativeFromHost = false; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _cubeDynamicFootprintCells.Clear(); _cubeDynamicFootprintReady = false; float num = Mathf.Clamp((_adaptiveForcefieldFloorProbeStep != null) ? _adaptiveForcefieldFloorProbeStep.Value : 0.75f, 0.35f, 1.25f); float num2 = horizontalSize * 0.5f; float num3 = center.y - configuredHeight * 0.5f; int num4 = Mathf.Clamp(Mathf.CeilToInt(num2 / num), 2, 14); _cubeDynamicFootprintCellSize = num; _cubeDynamicFootprintBottomY = num3; _cubeDynamicFootprintHorizontalSize = horizontalSize; _cubeDynamicFootprintHeight = configuredHeight; HashSet hashSet = new HashSet(); for (int i = -num4; i <= num4; i++) { for (int j = -num4; j <= num4; j++) { Vector3 val = CubeCellCenterWorld(center, i, j, num); if (!(Mathf.Abs(val.x - center.x) > num2 + 0.05f) && !(Mathf.Abs(val.z - center.z) > num2 + 0.05f) && IsDynamicAreaCellWalkable(val, num3, num, configuredHeight)) { hashSet.Add(CubeCellKey(i, j)); } } } Queue queue = new Queue(); bool flag = false; Vector2Int[] array = (Vector2Int[])(object)new Vector2Int[9] { new Vector2Int(0, 0), new Vector2Int(1, 0), new Vector2Int(-1, 0), new Vector2Int(0, 1), new Vector2Int(0, -1), new Vector2Int(1, 1), new Vector2Int(1, -1), new Vector2Int(-1, 1), new Vector2Int(-1, -1) }; Vector2Int[] array2 = array; for (int k = 0; k < array2.Length; k++) { Vector2Int item = array2[k]; if (hashSet.Contains(CubeCellKey(((Vector2Int)(ref item)).x, ((Vector2Int)(ref item)).y))) { _cubeDynamicFootprintCells.Add(CubeCellKey(((Vector2Int)(ref item)).x, ((Vector2Int)(ref item)).y)); queue.Enqueue(item); flag = true; break; } } if (!flag && hashSet.Count > 0) { int num5 = 0; int num6 = 0; float num7 = float.PositiveInfinity; for (int l = -num4; l <= num4; l++) { for (int m = -num4; m <= num4; m++) { if (hashSet.Contains(CubeCellKey(l, m))) { float num8 = l * l + m * m; if (num8 < num7) { num7 = num8; num5 = l; num6 = m; } } } } _cubeDynamicFootprintCells.Add(CubeCellKey(num5, num6)); queue.Enqueue(new Vector2Int(num5, num6)); flag = true; } Vector2Int[] array3 = (Vector2Int[])(object)new Vector2Int[4] { new Vector2Int(1, 0), new Vector2Int(-1, 0), new Vector2Int(0, 1), new Vector2Int(0, -1) }; while (queue.Count > 0) { Vector2Int val2 = queue.Dequeue(); Vector2Int[] array4 = array3; for (int n = 0; n < array4.Length; n++) { Vector2Int val3 = array4[n]; int num9 = ((Vector2Int)(ref val2)).x + ((Vector2Int)(ref val3)).x; int num10 = ((Vector2Int)(ref val2)).y + ((Vector2Int)(ref val3)).y; int item2 = CubeCellKey(num9, num10); if (hashSet.Contains(item2) && !_cubeDynamicFootprintCells.Contains(item2)) { _cubeDynamicFootprintCells.Add(item2); queue.Enqueue(new Vector2Int(num9, num10)); } } } if (_cubeDynamicFootprintCells.Count == 0) { _cubeDynamicFootprintCells.Add(CubeCellKey(0, 0)); D("Dynamic extraction area footprint could not find walkable cells. Falling back to the center cell only."); } _cubeDynamicFootprintHeight = configuredHeight; CalculateDynamicAreaFootprintBounds(center, horizontalSize, _cubeDynamicFootprintHeight); _cubeDynamicFootprintReady = true; _cubeDynamicFootprintLocked = true; _cubeDynamicFootprintLockedCenter = center; _cubeDynamicFootprintLockedSize = horizontalSize; _cubeDynamicFootprintLockedHeight = configuredHeight; _cubeDynamicFootprintLockedCellSize = _cubeDynamicFootprintCellSize; InvalidateDynamicAreaMeshes(); D($"Dynamic extraction area footprint finalized and locked: cells={_cubeDynamicFootprintCells.Count}, cell={_cubeDynamicFootprintCellSize:0.00}m, roofHeight={_cubeDynamicFootprintHeight:0.00}m/{configuredHeight:0.00}m, bounds={_cubeDynamicFootprintBounds}"); } private static bool IsDynamicAreaCellWalkable(Vector3 cellCenter, float bottomY, float cellSize, float height) { //IL_0001: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) if (!TryFindFloorAt(cellCenter, bottomY, out var floorHit)) { return false; } if (Mathf.Abs(((RaycastHit)(ref floorHit)).point.y - bottomY) > 0.48f) { return false; } if (!DynamicAreaCellHasRequestedHeightClearance(cellCenter, bottomY, height)) { return false; } if (IsNavMeshReflectionAvailable() && !DynamicAreaCellHasNavMeshSupportAroundFootprint(cellCenter, ((RaycastHit)(ref floorHit)).point.y, cellSize)) { return false; } Vector3 center = default(Vector3); ((Vector3)(ref center))..ctor(cellCenter.x, bottomY + height * 0.5f, cellCenter.z); Vector3 halfExtents = default(Vector3); ((Vector3)(ref halfExtents))..ctor(cellSize * 0.46f, height * 0.5f, cellSize * 0.46f); if (OverlapsDangerousTrigger(center, halfExtents, out var _)) { return false; } if (!IsNavMeshReflectionAvailable() && DynamicAreaCellHasStructuralWallBlockingSolid(cellCenter, bottomY, cellSize, height)) { return false; } return true; } private static bool HasRequiredCubeHeightClearance(Vector3 center, out string rejectReason) { //IL_0021: 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_005c: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //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) //IL_012f: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; if (ForceFullSizeFootprintEnabled()) { return true; } float cubeConfiguredHeight = GetCubeConfiguredHeight(); float bottomY = center.y - cubeConfiguredHeight * 0.5f; float num = GetCubeHorizontalSize() * 0.5f; float num2 = Mathf.Max(0.1f, num - 0.18f); Vector3[] array = (Vector3[])(object)new Vector3[9] { Vector3.zero, new Vector3(num2, 0f, 0f), new Vector3(0f - num2, 0f, 0f), new Vector3(0f, 0f, num2), new Vector3(0f, 0f, 0f - num2), new Vector3(num2, 0f, num2), new Vector3(num2, 0f, 0f - num2), new Vector3(0f - num2, 0f, num2), new Vector3(0f - num2, 0f, 0f - num2) }; Vector3[] array2 = array; Vector3 val2 = default(Vector3); foreach (Vector3 val in array2) { ((Vector3)(ref val2))..ctor(center.x + val.x, center.y, center.z + val.z); if (!DynamicAreaColumnHasRequestedHeightClearance(val2, bottomY, cubeConfiguredHeight, out var rejectReason2)) { rejectReason = $"requested Extraction Area height {cubeConfiguredHeight:0.00}m does not fit at {val2}: {rejectReason2}"; return false; } } return true; } private static bool DynamicAreaCellHasRequestedHeightClearance(Vector3 cellCenter, float bottomY, float height) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string rejectReason; return DynamicAreaColumnHasRequestedHeightClearance(cellCenter, bottomY, height, out rejectReason); } private static bool DynamicAreaColumnHasRequestedHeightClearance(Vector3 worldPoint, float bottomY, float height, out string rejectReason) { //IL_0058: 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_006b: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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) rejectReason = string.Empty; float num = Mathf.Clamp((_adaptiveForcefieldClearance != null) ? _adaptiveForcefieldClearance.Value : 0.18f, 0.02f, 0.65f); float num2 = bottomY + 0.35f; float num3 = bottomY + Mathf.Max(1.5f, height); float num4 = Mathf.Max(0.25f, num3 - num2 + num); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(worldPoint.x, num2, worldPoint.z); try { RaycastHit[] array = Physics.RaycastAll(val, Vector3.up, num4, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return true; } foreach (RaycastHit item in array.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ShouldIgnoreDynamicAreaCeilingHit(((RaycastHit)(ref current)).collider, bottomY)) { continue; } if (((RaycastHit)(ref current)).point.y < num3 + num) { rejectReason = $"ceiling/structure hit at y={((RaycastHit)(ref current)).point.y:0.00}, requiredTop={num3:0.00}, object={GetColliderPath(((RaycastHit)(ref current)).collider)}"; return false; } return true; } } catch (Exception ex) { rejectReason = "height ray failed: " + ex.Message; return false; } return true; } private static float DynamicAreaBoundaryInset() { return 0f; } private static bool DynamicAreaCellHasNavMeshSupportAroundFootprint(Vector3 cellCenter, float floorY, float cellSize) { //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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_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_0083: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(0.03f, cellSize * 0.5f); float num2 = Mathf.Clamp(Mathf.Max(0.12f, cellSize * 0.28f), 0.12f, 0.32f); Vector3[] array = (Vector3[])(object)new Vector3[9] { Vector3.zero, new Vector3(num, 0f, 0f), new Vector3(0f - num, 0f, 0f), new Vector3(0f, 0f, num), new Vector3(0f, 0f, 0f - num), new Vector3(num, 0f, num), new Vector3(num, 0f, 0f - num), new Vector3(0f - num, 0f, num), new Vector3(0f - num, 0f, 0f - num) }; Vector3[] array2 = array; Vector3 val2 = default(Vector3); foreach (Vector3 val in array2) { ((Vector3)(ref val2))..ctor(cellCenter.x + val.x, floorY + 0.05f, cellCenter.z + val.z); if (!TrySampleNavMeshPosition(val2, num2, out var navPosition)) { return false; } Vector3 val3 = navPosition - val2; val3.y = 0f; if (((Vector3)(ref val3)).magnitude > num2 + 0.025f) { return false; } if (Mathf.Abs(navPosition.y - floorY) > 0.9f) { return false; } } return true; } private static bool DynamicAreaCellHasStructuralWallBlockingSolid(Vector3 cellCenter, float bottomY, float cellSize, float height) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(cellCenter.x, bottomY + Mathf.Min(1.55f, height * 0.45f), cellCenter.z); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Max(0.12f, cellSize * 0.42f), 1.22f, Mathf.Max(0.12f, cellSize * 0.42f)); try { Collider[] array = Physics.OverlapBox(val, val2, Quaternion.identity, -1, (QueryTriggerInteraction)1); if (array == null) { return false; } Collider[] array2 = array; foreach (Collider c in array2) { if (!ShouldIgnoreDynamicAreaStructuralWallOverlap(c, bottomY)) { return true; } } } catch (Exception ex) { D($"Dynamic area wall fallback check failed at {cellCenter}: {ex.Message}"); } return false; } private static bool ShouldIgnoreDynamicAreaStructuralWallOverlap(Collider c, float bottomY) { //IL_0080: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) if ((Object)(object)c == (Object)null) { return true; } if (c.isTrigger) { return true; } if ((Object)(object)_cubeVisual != (Object)null && (Object)(object)((Component)c).transform != (Object)null && ((Component)c).transform.IsChildOf(_cubeVisual.transform)) { return true; } if ((Object)(object)((Component)c).GetComponentInParent() != (Object)null) { return true; } Bounds bounds = c.bounds; if (((Bounds)(ref bounds)).max.y < bottomY + 0.22f) { return true; } if (((Bounds)(ref bounds)).min.y <= bottomY + 0.08f && ((Bounds)(ref bounds)).max.y <= bottomY + 0.38f) { return true; } string text = GetColliderPath(c).ToLowerInvariant(); if (text.Contains("ainode") || text.Contains("navmesh") || text.Contains("scan") || text.Contains("audio") || text.Contains("sound")) { return true; } if (text.Contains("prop") || text.Contains("pipe") || text.Contains("machine") || text.Contains("socket") || text.Contains("valve") || text.Contains("steam") || text.Contains("lung") || text.Contains("apparatus") || text.Contains("scrap") || text.Contains("item") || text.Contains("rail") || text.Contains("fence") || text.Contains("terminal") || text.Contains("interact") || text.Contains("button")) { return true; } if (text.Contains("wall") || text.Contains("door") || text.Contains("frame") || text.Contains("collider") || text.Contains("collision")) { return false; } return true; } private static void CalculateDynamicAreaFootprintBounds(Vector3 center, float horizontalSize, float height) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float cubeDynamicFootprintBottomY = _cubeDynamicFootprintBottomY; float num2 = cubeDynamicFootprintBottomY + Mathf.Max(0.5f, height); bool flag = false; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(float.PositiveInfinity, cubeDynamicFootprintBottomY, float.PositiveInfinity); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(float.NegativeInfinity, num2, float.NegativeInfinity); int num3 = Mathf.Clamp(Mathf.CeilToInt(horizontalSize * 0.5f / num), 2, 14); for (int i = -num3; i <= num3; i++) { for (int j = -num3; j <= num3; j++) { if (CubeFootprintHasCell(i, j)) { flag = true; GetDynamicCellLocalEdges(i, j, num, out var minX, out var maxX, out var minZ, out var maxZ); float num4 = center.x + minX; float num5 = center.x + maxX; float num6 = center.z + minZ; float num7 = center.z + maxZ; val.x = Mathf.Min(val.x, num4); val.z = Mathf.Min(val.z, num6); val2.x = Mathf.Max(val2.x, num5); val2.z = Mathf.Max(val2.z, num7); } } } if (!flag) { _cubeDynamicFootprintBounds = new Bounds(center, new Vector3(horizontalSize, height, horizontalSize)); return; } Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor((val.x + val2.x) * 0.5f, (cubeDynamicFootprintBottomY + num2) * 0.5f, (val.z + val2.z) * 0.5f); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(Mathf.Max(0.1f, val2.x - val.x), Mathf.Max(0.1f, num2 - cubeDynamicFootprintBottomY), Mathf.Max(0.1f, val2.z - val.z)); _cubeDynamicFootprintBounds = new Bounds(val3, val4); } private static float CalculateCeilingLimitedDynamicAreaHeight(Vector3 center, float bottomY, float configuredHeight) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_016e: Unknown result type (might be due to invalid IL or missing references) float num = configuredHeight; float num2 = Mathf.Clamp(2.05f, 1.25f, configuredHeight); float num3 = bottomY + 0.35f; float num4 = Mathf.Max(1f, configuredHeight + 1.5f); float num5 = Mathf.Clamp((_adaptiveForcefieldClearance != null) ? _adaptiveForcefieldClearance.Value : 0.18f, 0.02f, 0.65f); float num6 = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); int num7 = Mathf.Clamp(Mathf.CeilToInt(_cubeDynamicFootprintHorizontalSize * 0.5f / num6), 2, 14); bool flag = false; Vector3 val = default(Vector3); for (int i = -num7; i <= num7; i++) { for (int j = -num7; j <= num7; j++) { if (!CubeFootprintHasCell(i, j)) { continue; } ((Vector3)(ref val))..ctor(center.x + (float)i * num6, num3, center.z + (float)j * num6); RaycastHit[] array; try { array = Physics.RaycastAll(val, Vector3.up, num4, -1, (QueryTriggerInteraction)1); } catch { continue; } if (array == null || array.Length == 0) { continue; } foreach (RaycastHit item in array.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ShouldIgnoreDynamicAreaCeilingHit(((RaycastHit)(ref current)).collider, bottomY)) { continue; } float num8 = ((RaycastHit)(ref current)).point.y - bottomY - num5; if (num8 >= num2) { num = Mathf.Min(num, num8); flag = true; } break; } } } float num9 = Mathf.Clamp(num, num2, configuredHeight); if (flag && num9 < configuredHeight - 0.05f) { D($"Extraction Area roof height clamped by ceiling: {configuredHeight:0.00}m -> {num9:0.00}m"); } return num9; } private static bool ShouldIgnoreDynamicAreaCeilingHit(Collider c, float bottomY) { //IL_0080: 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_0088: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)c == (Object)null) { return true; } if (c.isTrigger) { return true; } if ((Object)(object)_cubeVisual != (Object)null && (Object)(object)((Component)c).transform != (Object)null && ((Component)c).transform.IsChildOf(_cubeVisual.transform)) { return true; } if ((Object)(object)((Component)c).GetComponentInParent() != (Object)null) { return true; } Bounds bounds = c.bounds; if (((Bounds)(ref bounds)).max.y < bottomY + 0.35f) { return true; } string text = GetColliderPath(c).ToLowerInvariant(); if (text.Contains("ainode") || text.Contains("navmesh") || text.Contains("scan") || text.Contains("audio") || text.Contains("sound") || text.Contains("trigger")) { return true; } if (text.Contains("prop") || text.Contains("pipe") || text.Contains("machine") || text.Contains("socket") || text.Contains("valve") || text.Contains("steam") || text.Contains("lung") || text.Contains("apparatus") || text.Contains("scrap") || text.Contains("item") || text.Contains("rail") || text.Contains("fence") || text.Contains("terminal") || text.Contains("interact") || text.Contains("button")) { return true; } return false; } private static bool DynamicAreaFootprintFreezeEnabled() { return _adaptiveForcefieldFreezeShapeAfterBuild == null || _adaptiveForcefieldFreezeShapeAfterBuild.Value; } private static bool DynamicAreaFootprintSimplifyMeshEnabled() { return _adaptiveForcefieldSimplifyMesh == null || _adaptiveForcefieldSimplifyMesh.Value; } private static void InvalidateDynamicAreaMeshes() { _cubeDynamicFootprintSurfaceMesh = null; _cubeDynamicFootprintFrameMesh = null; _cubeDynamicFootprintBandMesh = null; } private static void ResetDynamicAreaFootprint() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) _cubeDynamicFootprintAuthoritativeFromHost = false; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _cubeDynamicFootprintCells.Clear(); _cubeDynamicFootprintReady = false; _cubeDynamicFootprintLocked = false; _cubeDynamicFootprintLockedCenter = Vector3.zero; _cubeDynamicFootprintLockedSize = 0f; _cubeDynamicFootprintLockedHeight = 0f; _cubeDynamicFootprintLockedCellSize = 0f; _cubeDynamicFootprintBounds = new Bounds(Vector3.zero, Vector3.zero); InvalidateDynamicAreaMeshes(); } private static bool EnsureDynamicAreaFootprintBuilt(Vector3 center, float horizontalSize, float configuredHeight) { //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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if (!IsServer() && _cubeDynamicFootprintAuthoritativeFromHost && _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) { return false; } float num = Mathf.Clamp((_adaptiveForcefieldFloorProbeStep != null) ? _adaptiveForcefieldFloorProbeStep.Value : 0.75f, 0.35f, 1.25f); bool flag = DynamicAreaFootprintFreezeEnabled(); bool flag2 = _cubeDynamicFootprintLocked && Vector3.Distance(center, _cubeDynamicFootprintLockedCenter) > 0.15f; bool flag3 = _cubeDynamicFootprintLocked && Mathf.Abs(horizontalSize - _cubeDynamicFootprintLockedSize) > 0.05f; bool flag4 = _cubeDynamicFootprintLocked && Mathf.Abs(configuredHeight - _cubeDynamicFootprintLockedHeight) > 0.05f; bool flag5 = _cubeDynamicFootprintLocked && Mathf.Abs(num - _cubeDynamicFootprintLockedCellSize) > 0.01f; if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0 || !flag || flag2 || flag3 || flag4 || flag5) { if (_cubeDynamicFootprintReady && flag && (flag2 || flag3 || flag4 || flag5)) { D($"Dynamic extraction area footprint unlocked for new placement/config. oldCenter={_cubeDynamicFootprintLockedCenter}, newCenter={center}, oldHorizontal={_cubeDynamicFootprintLockedSize:0.00}, newHorizontal={horizontalSize:0.00}, oldHeight={_cubeDynamicFootprintLockedHeight:0.00}, newHeight={configuredHeight:0.00}"); } RebuildDynamicAreaFootprint(center, horizontalSize, configuredHeight); return true; } return false; } private static int GetDynamicFootprintHalfCells() { float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float num2 = Mathf.Max(0.5f, _cubeDynamicFootprintHorizontalSize); return Mathf.Clamp(Mathf.CeilToInt(num2 * 0.5f / num), 2, 14); } private static Mesh CreateDynamicFootprintForcefieldMesh(Vector3 center, float horizontalSize, float configuredHeight) { //IL_0001: 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_0033: Expected O, but got Unknown //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) EnsureDynamicAreaFootprintBuilt(center, horizontalSize, configuredHeight); if ((Object)(object)_cubeDynamicFootprintSurfaceMesh != (Object)null) { return _cubeDynamicFootprintSurfaceMesh; } bool flag = DynamicAreaFootprintSimplifyMeshEnabled(); Mesh val = new Mesh(); ((Object)val).name = (flag ? "Extraction_DynamicFootprint_Forcefield_Surface_Final" : "Extraction_DynamicFootprint_Forcefield_Surface"); List list = new List(); List list2 = new List(); List list3 = new List(); if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0) { _cubeDynamicFootprintSurfaceMesh = CreateDoubleSidedOpenBottomUnitCubeMesh(); return _cubeDynamicFootprintSurfaceMesh; } float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float num2 = Mathf.Max(0.5f, _cubeDynamicFootprintHeight); float bottom = DynamicAreaLocalBottomY(); float num3 = DynamicAreaLocalTopY(); int dynamicFootprintHalfCells = GetDynamicFootprintHalfCells(); for (int i = -dynamicFootprintHalfCells; i <= dynamicFootprintHalfCells; i++) { int j = -dynamicFootprintHalfCells; while (j <= dynamicFootprintHalfCells) { for (; j <= dynamicFootprintHalfCells && !CubeFootprintHasCell(j, i); j++) { } if (j > dynamicFootprintHalfCells) { break; } int num4 = j; for (; j <= dynamicFootprintHalfCells && CubeFootprintHasCell(j, i); j++) { } int num5 = j - 1; float num6 = DynamicAreaBoundaryInset(); float num7 = ((float)num4 - 0.5f) * num + ((!CubeFootprintHasCell(num4 - 1, i)) ? num6 : 0f); float num8 = ((float)num5 + 0.5f) * num - ((!CubeFootprintHasCell(num5 + 1, i)) ? num6 : 0f); float num9 = ((float)i - 0.5f) * num + ((!RunHasAdjacentCells(num4, num5, i, 0, -1)) ? num6 : 0f); float num10 = ((float)i + 0.5f) * num - ((!RunHasAdjacentCells(num4, num5, i, 0, 1)) ? num6 : 0f); AddDoubleSidedQuad(list, list2, list3, new Vector3(num7, num3, num9), new Vector3(num7, num3, num10), new Vector3(num8, num3, num10), new Vector3(num8, num3, num9)); } } foreach (DynamicBoundarySegment dynamicBoundarySegment in GetDynamicBoundarySegments()) { AddDynamicBoundaryWallQuad(list, list2, list3, dynamicBoundarySegment, bottom, num3); } val.SetVertices(list); val.SetUVs(0, list2); val.SetTriangles(list3, 0, true); val.RecalculateNormals(); val.RecalculateBounds(); _cubeDynamicFootprintSurfaceMesh = val; return val; } private static void RefreshCubeForcefieldDetailMeshes(bool dynamicFootprint) { if (!((Object)(object)_cubeVisual == (Object)null)) { Transform val = _cubeVisual.transform.Find("Extraction_Forcefield_Frame"); MeshFilter val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 != (Object)null) { val2.sharedMesh = (dynamicFootprint ? CreateDynamicFootprintFrameMesh() : CreateForcefieldFrameMesh()); } Transform val3 = _cubeVisual.transform.Find("Extraction_Forcefield_ScanBands"); MeshFilter val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val4.sharedMesh = (dynamicFootprint ? CreateDynamicFootprintBandMesh() : CreateForcefieldBandMesh()); } } } private static bool RunHasAdjacentCells(int startX, int endX, int z, int dx, int dz) { for (int i = startX; i <= endX; i++) { if (CubeFootprintHasCell(i + dx, z + dz)) { return true; } } return false; } private static List GetDynamicBoundarySegments() { List list = new List(); if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0) { return list; } float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); int dynamicFootprintHalfCells = GetDynamicFootprintHalfCells(); for (int i = -dynamicFootprintHalfCells; i <= dynamicFootprintHalfCells; i++) { int j = -dynamicFootprintHalfCells; while (j <= dynamicFootprintHalfCells) { for (; j <= dynamicFootprintHalfCells && (!CubeFootprintHasCell(i, j) || CubeFootprintHasCell(i + 1, j)); j++) { } if (j > dynamicFootprintHalfCells) { break; } int num2 = j; for (; j <= dynamicFootprintHalfCells && CubeFootprintHasCell(i, j) && !CubeFootprintHasCell(i + 1, j); j++) { } int num3 = j - 1; list.Add(new DynamicBoundarySegment(0, 1, ((float)i + 0.5f) * num, ((float)num2 - 0.5f) * num, ((float)num3 + 0.5f) * num)); } j = -dynamicFootprintHalfCells; while (j <= dynamicFootprintHalfCells) { for (; j <= dynamicFootprintHalfCells && (!CubeFootprintHasCell(i, j) || CubeFootprintHasCell(i - 1, j)); j++) { } if (j > dynamicFootprintHalfCells) { break; } int num4 = j; for (; j <= dynamicFootprintHalfCells && CubeFootprintHasCell(i, j) && !CubeFootprintHasCell(i - 1, j); j++) { } int num5 = j - 1; list.Add(new DynamicBoundarySegment(0, -1, ((float)i - 0.5f) * num, ((float)num4 - 0.5f) * num, ((float)num5 + 0.5f) * num)); } } for (int k = -dynamicFootprintHalfCells; k <= dynamicFootprintHalfCells; k++) { int l = -dynamicFootprintHalfCells; while (l <= dynamicFootprintHalfCells) { for (; l <= dynamicFootprintHalfCells && (!CubeFootprintHasCell(l, k) || CubeFootprintHasCell(l, k + 1)); l++) { } if (l > dynamicFootprintHalfCells) { break; } int num6 = l; for (; l <= dynamicFootprintHalfCells && CubeFootprintHasCell(l, k) && !CubeFootprintHasCell(l, k + 1); l++) { } int num7 = l - 1; list.Add(new DynamicBoundarySegment(1, 1, ((float)k + 0.5f) * num, ((float)num6 - 0.5f) * num, ((float)num7 + 0.5f) * num)); } l = -dynamicFootprintHalfCells; while (l <= dynamicFootprintHalfCells) { for (; l <= dynamicFootprintHalfCells && (!CubeFootprintHasCell(l, k) || CubeFootprintHasCell(l, k - 1)); l++) { } if (l > dynamicFootprintHalfCells) { break; } int num8 = l; for (; l <= dynamicFootprintHalfCells && CubeFootprintHasCell(l, k) && !CubeFootprintHasCell(l, k - 1); l++) { } int num9 = l - 1; list.Add(new DynamicBoundarySegment(1, -1, ((float)k - 0.5f) * num, ((float)num8 - 0.5f) * num, ((float)num9 + 0.5f) * num)); } } return list; } private static void AddDynamicBoundaryWallQuad(List verts, List uvs, List tris, DynamicBoundarySegment segment, float bottom, float top) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) float num = DynamicAreaBoundaryInset(); float num2 = segment.FromCoord + num; float num3 = segment.ToCoord - num; if (num3 < num2) { float num4 = (segment.FromCoord + segment.ToCoord) * 0.5f; num2 = num4; num3 = num4; } float num5 = segment.FixedCoord - (float)segment.Sign * num; if (segment.Axis == 0) { if (segment.Sign > 0) { AddDoubleSidedQuad(verts, uvs, tris, new Vector3(num5, bottom, num3), new Vector3(num5, bottom, num2), new Vector3(num5, top, num2), new Vector3(num5, top, num3)); } else { AddDoubleSidedQuad(verts, uvs, tris, new Vector3(num5, bottom, num2), new Vector3(num5, bottom, num3), new Vector3(num5, top, num3), new Vector3(num5, top, num2)); } } else if (segment.Sign > 0) { AddDoubleSidedQuad(verts, uvs, tris, new Vector3(num2, bottom, num5), new Vector3(num3, bottom, num5), new Vector3(num3, top, num5), new Vector3(num2, top, num5)); } else { AddDoubleSidedQuad(verts, uvs, tris, new Vector3(num3, bottom, num5), new Vector3(num2, bottom, num5), new Vector3(num2, top, num5), new Vector3(num3, top, num5)); } } private static void AddDynamicBoundaryBandQuad(List verts, List uvs, List tris, DynamicBoundarySegment segment, float yMin, float yMax) { AddDynamicBoundaryWallQuad(verts, uvs, tris, segment, yMin, yMax); } private static void AddDynamicPost(List verts, List uvs, List tris, HashSet postKeys, float x, float z, float thickness, float bottom, float top) { //IL_005d: 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) int item = Mathf.RoundToInt((x + 128f) * 50f) * 100000 + Mathf.RoundToInt((z + 128f) * 50f); if (postKeys.Add(item)) { float num = Mathf.Max(0.05f, top - bottom); AddBoxToMesh(verts, uvs, tris, new Vector3(x, (bottom + top) * 0.5f, z), new Vector3(thickness, num, thickness)); } } private static void AddDynamicBoundaryFrameBoxes(List verts, List uvs, List tris, DynamicBoundarySegment segment, HashSet postKeys, float thickness, float bottom, float top) { //IL_0108: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) float num = DynamicAreaBoundaryInset(); float num2 = segment.FromCoord + num; float num3 = segment.ToCoord - num; if (num3 < num2) { float num4 = (segment.FromCoord + segment.ToCoord) * 0.5f; num2 = num4; num3 = num4; } float num5 = segment.FixedCoord - (float)segment.Sign * num; float num6 = Mathf.Max(0.01f, num3 - num2); float num7 = (num2 + num3) * 0.5f; float num8 = (bottom + top) * 0.5f; if (segment.Axis == 0) { AddBoxToMesh(verts, uvs, tris, new Vector3(num5, top, num7), new Vector3(thickness, thickness, num6 + thickness)); AddBoxToMesh(verts, uvs, tris, new Vector3(num5, num8, num7), new Vector3(thickness * 0.75f, thickness * 0.75f, num6 + thickness)); AddDynamicPost(verts, uvs, tris, postKeys, num5, num2, thickness, bottom, top); AddDynamicPost(verts, uvs, tris, postKeys, num5, num3, thickness, bottom, top); } else { AddBoxToMesh(verts, uvs, tris, new Vector3(num7, top, num5), new Vector3(num6 + thickness, thickness, thickness)); AddBoxToMesh(verts, uvs, tris, new Vector3(num7, num8, num5), new Vector3(num6 + thickness, thickness * 0.75f, thickness * 0.75f)); AddDynamicPost(verts, uvs, tris, postKeys, num2, num5, thickness, bottom, top); AddDynamicPost(verts, uvs, tris, postKeys, num3, num5, thickness, bottom, top); } } private static Mesh CreateDynamicFootprintFrameMesh() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if ((Object)(object)_cubeDynamicFootprintFrameMesh != (Object)null) { return _cubeDynamicFootprintFrameMesh; } if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0) { return CreateForcefieldFrameMesh(); } bool flag = DynamicAreaFootprintSimplifyMeshEnabled(); Mesh val = new Mesh(); ((Object)val).name = (flag ? "Extraction_DynamicFootprint_Forcefield_Frame_Final" : "Extraction_DynamicFootprint_Forcefield_Frame"); List list = new List(); List list2 = new List(); List list3 = new List(); float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float bottom = DynamicAreaLocalBottomY(); float top = DynamicAreaLocalTopY(); float thickness = Mathf.Clamp(num * 0.06f, 0.025f, 0.075f); HashSet postKeys = new HashSet(); foreach (DynamicBoundarySegment dynamicBoundarySegment in GetDynamicBoundarySegments()) { AddDynamicBoundaryFrameBoxes(list, list2, list3, dynamicBoundarySegment, postKeys, thickness, bottom, top); } val.SetVertices(list); val.SetUVs(0, list2); val.SetTriangles(list3, 0, true); val.RecalculateNormals(); val.RecalculateBounds(); _cubeDynamicFootprintFrameMesh = val; return val; } private static Mesh CreateDynamicFootprintBandMesh() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if ((Object)(object)_cubeDynamicFootprintBandMesh != (Object)null) { return _cubeDynamicFootprintBandMesh; } if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0) { return CreateForcefieldBandMesh(); } bool flag = DynamicAreaFootprintSimplifyMeshEnabled(); Mesh val = new Mesh(); ((Object)val).name = (flag ? "Extraction_DynamicFootprint_Forcefield_Bands_Final" : "Extraction_DynamicFootprint_Forcefield_Bands"); List list = new List(); List list2 = new List(); List list3 = new List(); float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float num2 = Mathf.Max(0.5f, _cubeDynamicFootprintHeight); float num3 = DynamicAreaLocalBottomY(); float[] array = new float[6] { num3 + num2 * 0.16f, num3 + num2 * 0.32f, num3 + num2 * 0.48f, num3 + num2 * 0.64f, num3 + num2 * 0.8f, num3 + num2 * 0.94f }; float num4 = Mathf.Clamp(num * 0.035f, 0.01f, 0.035f); List dynamicBoundarySegments = GetDynamicBoundarySegments(); foreach (DynamicBoundarySegment item in dynamicBoundarySegments) { float[] array2 = array; foreach (float num5 in array2) { AddDynamicBoundaryBandQuad(list, list2, list3, item, num5 - num4, num5 + num4); } } val.SetVertices(list); val.SetUVs(0, list2); val.SetTriangles(list3, 0, true); val.RecalculateNormals(); val.RecalculateBounds(); _cubeDynamicFootprintBandMesh = val; return val; } private static Mesh CreateDoubleSidedOpenBottomUnitCubeMesh() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00e8: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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) Mesh val = new Mesh(); ((Object)val).name = "Extraction_DoubleSided_OpenBottom_UnitCube"; List verts = new List(); List uvs = new List(); List tris = new List(); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(-0.5f, -0.5f, -0.5f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(0.5f, -0.5f, -0.5f); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(0.5f, 0.5f, -0.5f); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(-0.5f, 0.5f, -0.5f); Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor(-0.5f, -0.5f, 0.5f); Vector3 val7 = default(Vector3); ((Vector3)(ref val7))..ctor(0.5f, -0.5f, 0.5f); Vector3 val8 = default(Vector3); ((Vector3)(ref val8))..ctor(0.5f, 0.5f, 0.5f); Vector3 val9 = default(Vector3); ((Vector3)(ref val9))..ctor(-0.5f, 0.5f, 0.5f); AddFace(val6, val7, val8, val9); AddFace(val3, val2, val5, val4); AddFace(val2, val6, val9, val5); AddFace(val7, val3, val4, val8); AddFace(val5, val9, val8, val4); val.SetVertices(verts); val.SetUVs(0, uvs); val.SetTriangles(tris, 0, true); val.RecalculateNormals(); val.RecalculateBounds(); return val; void AddFace(Vector3 a, Vector3 b, Vector3 c, Vector3 d) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_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_008f: 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) int count = verts.Count; verts.Add(a); verts.Add(b); verts.Add(c); verts.Add(d); uvs.Add(new Vector2(0f, 0f)); uvs.Add(new Vector2(1f, 0f)); uvs.Add(new Vector2(1f, 1f)); uvs.Add(new Vector2(0f, 1f)); tris.Add(count); tris.Add(count + 1); tris.Add(count + 2); tris.Add(count); tris.Add(count + 2); tris.Add(count + 3); tris.Add(count + 2); tris.Add(count + 1); tris.Add(count); tris.Add(count + 3); tris.Add(count + 2); tris.Add(count); } } private static Material CreateTransparentYellowMaterial() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) return CreateTransparentForcefieldMaterial("Extraction_ForcefieldGlass_DoubleSided", new Color(1f, 0.86f, 0.02f, 1f), Mathf.Clamp01((_cubeVisualAlpha != null) ? _cubeVisualAlpha.Value : 0.1f), 1.55f); } private static Material CreateTransparentForcefieldMaterial(string materialName, Color color, float alpha, float emissionStrength) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Transparent") ?? Shader.Find("Legacy Shaders/Transparent/Diffuse") ?? Shader.Find("Sprites/Default") ?? Shader.Find("HDRP/Lit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard"); Material val2 = new Material(val); ((Object)val2).name = materialName; ApplyForcefieldMaterialSettings(val2, color, alpha, emissionStrength); return val2; } private static void ApplyTransparentMaterialSettings(Material mat) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) ApplyForcefieldMaterialSettings(mat, new Color(1f, 0.86f, 0.02f, 1f), Mathf.Clamp01((_cubeVisualAlpha != null) ? _cubeVisualAlpha.Value : 0.1f), 1.55f); } private static void ApplyForcefieldMaterialSettings(Material mat, Color color, float alpha, float emissionStrength) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007c: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mat == (Object)null)) { alpha = Mathf.Clamp01(alpha); Color val = default(Color); ((Color)(ref val))..ctor(color.r, color.g, color.b, alpha); mat.color = val; SetColorIfPresent(mat, "_Color", val); SetColorIfPresent(mat, "_BaseColor", val); SetColorIfPresent(mat, "_UnlitColor", val); SetColorIfPresent(mat, "_TintColor", val); SetColorIfPresent(mat, "_MainColor", val); Color value = color * Mathf.Max(0f, emissionStrength); value.a = 1f; SetColorIfPresent(mat, "_EmissionColor", value); SetColorIfPresent(mat, "_EmissiveColor", value); SetFloatIfPresent(mat, "_UseEmissiveIntensity", 1f); SetFloatIfPresent(mat, "_EmissiveIntensity", Mathf.Max(0f, emissionStrength)); mat.EnableKeyword("_EMISSION"); SetFloatIfPresent(mat, "_SurfaceType", 1f); SetFloatIfPresent(mat, "_BlendMode", 0f); SetFloatIfPresent(mat, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(mat, "_AlphaClip", 0f); SetFloatIfPresent(mat, "_TransparentZWrite", 0f); SetFloatIfPresent(mat, "_ZWrite", 0f); SetFloatIfPresent(mat, "_ZTestDepthEqualForOpaque", 4f); SetFloatIfPresent(mat, "_Cull", 0f); SetFloatIfPresent(mat, "_CullMode", 0f); SetFloatIfPresent(mat, "_CullModeForward", 0f); SetFloatIfPresent(mat, "_DoubleSidedEnable", 1f); SetFloatIfPresent(mat, "_DoubleSidedNormalMode", 0f); SetFloatIfPresent(mat, "_SrcBlend", 5f); SetFloatIfPresent(mat, "_DstBlend", 10f); SetFloatIfPresent(mat, "_AlphaSrcBlend", 5f); SetFloatIfPresent(mat, "_AlphaDstBlend", 10f); SetFloatIfPresent(mat, "_Mode", 3f); mat.SetOverrideTag("RenderType", "Transparent"); mat.SetOverrideTag("Queue", "Transparent"); mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); mat.EnableKeyword("_ALPHABLEND_ON"); mat.EnableKeyword("_ENABLE_FOG_ON_TRANSPARENT"); mat.DisableKeyword("_ALPHATEST_ON"); mat.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mat.renderQueue = 3000; mat.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1; } } private static void EnsureCubeForcefieldDetailObjects() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0064: 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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cubeVisual == (Object)null)) { Transform val = _cubeVisual.transform.Find("Extraction_Forcefield_Frame"); if ((Object)(object)val == (Object)null) { GameObject val2 = new GameObject("Extraction_Forcefield_Frame"); val2.transform.SetParent(_cubeVisual.transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; MeshFilter val3 = val2.AddComponent(); val3.sharedMesh = CreateForcefieldFrameMesh(); MeshRenderer val4 = val2.AddComponent(); ((Renderer)val4).sharedMaterial = CreateTransparentForcefieldMaterial("Extraction_Forcefield_EdgeGlow", new Color(1f, 0.86f, 0.02f, 1f), 0.34f, 3.75f); ((Renderer)val4).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val4).receiveShadows = false; ((Renderer)val4).allowOcclusionWhenDynamic = false; } Transform val5 = _cubeVisual.transform.Find("Extraction_Forcefield_ScanBands"); if ((Object)(object)val5 == (Object)null) { GameObject val6 = new GameObject("Extraction_Forcefield_ScanBands"); val6.transform.SetParent(_cubeVisual.transform, false); val6.transform.localPosition = Vector3.zero; val6.transform.localRotation = Quaternion.identity; val6.transform.localScale = Vector3.one; MeshFilter val7 = val6.AddComponent(); val7.sharedMesh = CreateForcefieldBandMesh(); MeshRenderer val8 = val6.AddComponent(); ((Renderer)val8).sharedMaterial = CreateTransparentForcefieldMaterial("Extraction_Forcefield_GlassBands", new Color(1f, 0.86f, 0.02f, 1f), 0.18f, 2.65f); ((Renderer)val8).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val8).receiveShadows = false; ((Renderer)val8).allowOcclusionWhenDynamic = false; } } } private static Mesh CreateForcefieldFrameMesh() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0171: 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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh(); ((Object)val).name = "Extraction_Forcefield_OpenBottom_Frame"; List list = new List(); List list2 = new List(); List list3 = new List(); float num = 0.505f; float num2 = 0.014f; AddBoxToMesh(list, list2, list3, new Vector3(0f - num, 0f, 0f - num), new Vector3(num2, 1.01f, num2)); AddBoxToMesh(list, list2, list3, new Vector3(num, 0f, 0f - num), new Vector3(num2, 1.01f, num2)); AddBoxToMesh(list, list2, list3, new Vector3(0f - num, 0f, num), new Vector3(num2, 1.01f, num2)); AddBoxToMesh(list, list2, list3, new Vector3(num, 0f, num), new Vector3(num2, 1.01f, num2)); AddBoxToMesh(list, list2, list3, new Vector3(0f, num, 0f - num), new Vector3(1.01f, num2, num2)); AddBoxToMesh(list, list2, list3, new Vector3(0f, num, num), new Vector3(1.01f, num2, num2)); AddBoxToMesh(list, list2, list3, new Vector3(0f - num, num, 0f), new Vector3(num2, num2, 1.01f)); AddBoxToMesh(list, list2, list3, new Vector3(num, num, 0f), new Vector3(num2, num2, 1.01f)); AddBoxToMesh(list, list2, list3, new Vector3(0f, 0f, 0f - num), new Vector3(1.01f, num2 * 0.75f, num2 * 0.75f)); AddBoxToMesh(list, list2, list3, new Vector3(0f, 0f, num), new Vector3(1.01f, num2 * 0.75f, num2 * 0.75f)); AddBoxToMesh(list, list2, list3, new Vector3(0f - num, 0f, 0f), new Vector3(num2 * 0.75f, num2 * 0.75f, 1.01f)); AddBoxToMesh(list, list2, list3, new Vector3(num, 0f, 0f), new Vector3(num2 * 0.75f, num2 * 0.75f, 1.01f)); val.SetVertices(list); val.SetUVs(0, list2); val.SetTriangles(list3, 0, true); val.RecalculateNormals(); val.RecalculateBounds(); return val; } private static Mesh CreateForcefieldBandMesh() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_006a: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh(); ((Object)val).name = "Extraction_Forcefield_OpenBottom_ScanBands"; List list = new List(); List list2 = new List(); List list3 = new List(); float num = 0.512f; float num2 = 0.012f; float[] array = new float[6] { -0.34f, -0.18f, -0.02f, 0.14f, 0.3f, 0.44f }; float[] array2 = array; foreach (float num3 in array2) { AddDoubleSidedQuad(list, list2, list3, new Vector3(-0.5f, num3 - num2, num), new Vector3(0.5f, num3 - num2, num), new Vector3(0.5f, num3 + num2, num), new Vector3(-0.5f, num3 + num2, num)); AddDoubleSidedQuad(list, list2, list3, new Vector3(0.5f, num3 - num2, 0f - num), new Vector3(-0.5f, num3 - num2, 0f - num), new Vector3(-0.5f, num3 + num2, 0f - num), new Vector3(0.5f, num3 + num2, 0f - num)); AddDoubleSidedQuad(list, list2, list3, new Vector3(0f - num, num3 - num2, -0.5f), new Vector3(0f - num, num3 - num2, 0.5f), new Vector3(0f - num, num3 + num2, 0.5f), new Vector3(0f - num, num3 + num2, -0.5f)); AddDoubleSidedQuad(list, list2, list3, new Vector3(num, num3 - num2, 0.5f), new Vector3(num, num3 - num2, -0.5f), new Vector3(num, num3 + num2, -0.5f), new Vector3(num, num3 + num2, 0.5f)); } float num4 = 0.512f; float num5 = 0.01f; AddBoxToMesh(list, list2, list3, new Vector3(0f, num4, 0f), new Vector3(1.01f, num5, num5)); AddBoxToMesh(list, list2, list3, new Vector3(0f, num4, 0f), new Vector3(num5, num5, 1.01f)); val.SetVertices(list); val.SetUVs(0, list2); val.SetTriangles(list3, 0, true); val.RecalculateNormals(); val.RecalculateBounds(); return val; } private static void AddBoxToMesh(List verts, List uvs, List tris, Vector3 center, Vector3 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_001d: 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_0029: 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_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) //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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00a4: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00dd: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) Vector3 val = size * 0.5f; Vector3 val2 = center + new Vector3(0f - val.x, 0f - val.y, 0f - val.z); Vector3 val3 = center + new Vector3(val.x, 0f - val.y, 0f - val.z); Vector3 val4 = center + new Vector3(val.x, val.y, 0f - val.z); Vector3 val5 = center + new Vector3(0f - val.x, val.y, 0f - val.z); Vector3 val6 = center + new Vector3(0f - val.x, 0f - val.y, val.z); Vector3 val7 = center + new Vector3(val.x, 0f - val.y, val.z); Vector3 val8 = center + new Vector3(val.x, val.y, val.z); Vector3 val9 = center + new Vector3(0f - val.x, val.y, val.z); AddDoubleSidedQuad(verts, uvs, tris, val6, val7, val8, val9); AddDoubleSidedQuad(verts, uvs, tris, val3, val2, val5, val4); AddDoubleSidedQuad(verts, uvs, tris, val2, val6, val9, val5); AddDoubleSidedQuad(verts, uvs, tris, val7, val3, val4, val8); AddDoubleSidedQuad(verts, uvs, tris, val5, val9, val8, val4); AddDoubleSidedQuad(verts, uvs, tris, val2, val3, val7, val6); } private static void AddDoubleSidedQuad(List verts, List uvs, List tris, Vector3 a, Vector3 b, Vector3 c, Vector3 d) { //IL_0009: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) int count = verts.Count; verts.Add(a); verts.Add(b); verts.Add(c); verts.Add(d); uvs.Add(new Vector2(0f, 0f)); uvs.Add(new Vector2(1f, 0f)); uvs.Add(new Vector2(1f, 1f)); uvs.Add(new Vector2(0f, 1f)); tris.Add(count); tris.Add(count + 1); tris.Add(count + 2); tris.Add(count); tris.Add(count + 2); tris.Add(count + 3); tris.Add(count + 2); tris.Add(count + 1); tris.Add(count); tris.Add(count + 3); tris.Add(count + 2); tris.Add(count); } private static void UpdateCubePulseVisual(bool force = false) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube || (Object)(object)_cubeVisual == (Object)null) { return; } EnsureCubeForcefieldDetailObjects(); bool flag = !_cubeExtractionPassed && _earlyExtractionCountdownActive; bool flag2 = !_cubeExtractionPassed && !flag && _baseGameVoteToLeaveUrgencyActive; Color color = (_cubeExtractionPassed ? new Color(1f, 0.02f, 0.015f, 1f) : (flag ? new Color(0.05f, 1f, 0.18f, 1f) : (flag2 ? new Color(1f, 0.05f, 0.85f, 1f) : new Color(1f, 0.86f, 0.02f, 1f)))); float num = Mathf.Clamp01((_cubeVisualAlpha != null) ? _cubeVisualAlpha.Value : 0.1f); float alpha = Mathf.Clamp01(num * (_cubeExtractionPassed ? 1.45f : (flag ? 1.35f : (flag2 ? 1.35f : 1f)))); float alpha2 = Mathf.Clamp01(0.25f + num * 1.35f); float alpha3 = Mathf.Clamp01(0.1f + num * 0.85f); float emissionStrength = (_cubeExtractionPassed ? 2.65f : (flag ? 3.15f : (flag2 ? 3f : 1.55f))); float emissionStrength2 = (_cubeExtractionPassed ? 5.8f : (flag ? 6.6f : (flag2 ? 6.25f : 3.75f))); float emissionStrength3 = (_cubeExtractionPassed ? 3.6f : (flag ? 4.6f : (flag2 ? 4.3f : 2.65f))); MeshRenderer component = _cubeVisual.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).sharedMaterial != (Object)null) { ApplyForcefieldMaterialSettings(((Renderer)component).sharedMaterial, color, alpha, emissionStrength); } Transform val = _cubeVisual.transform.Find("Extraction_Forcefield_Frame"); MeshRenderer val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 != (Object)null && (Object)(object)((Renderer)val2).sharedMaterial != (Object)null) { ApplyForcefieldMaterialSettings(((Renderer)val2).sharedMaterial, color, alpha2, emissionStrength2); } Transform val3 = _cubeVisual.transform.Find("Extraction_Forcefield_ScanBands"); if ((Object)(object)val3 != (Object)null) { float num2 = Mathf.PingPong(Time.time * 0.035f, 0.055f) - 0.0275f; val3.localPosition = new Vector3(0f, num2, 0f); MeshRenderer component2 = ((Component)val3).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)((Renderer)component2).sharedMaterial != (Object)null) { ApplyForcefieldMaterialSettings(((Renderer)component2).sharedMaterial, color, alpha3, emissionStrength3); } } if ((Object)(object)_cubeLightObject != (Object)null) { Light component3 = _cubeLightObject.GetComponent(); if ((Object)(object)component3 != (Object)null) { float num3 = Mathf.Max(0f, (_cubeLightIntensity != null) ? _cubeLightIntensity.Value : 2.2f); component3.color = color; component3.intensity = num3 * (_cubeExtractionPassed ? 1.45f : (flag ? 1.65f : (flag2 ? 1.5f : 0.95f))); } } } private static void SetFloatIfPresent(Material mat, string property, float value) { if ((Object)(object)mat != (Object)null && mat.HasProperty(property)) { mat.SetFloat(property, value); } } private static void SetColorIfPresent(Material mat, string property, Color value) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mat != (Object)null && mat.HasProperty(property)) { mat.SetColor(property, value); } } private static void UpdateCubeLight(Vector3 center, float size) { //IL_0095: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if (_enableCubeLight == null || !_enableCubeLight.Value) { DestroyCubeLight(); return; } if ((Object)(object)_cubeLightObject == (Object)null) { _cubeLightObject = new GameObject("Extraction_Area_YellowLight"); Light val = _cubeLightObject.AddComponent(); val.type = (LightType)2; val.color = new Color(1f, 0.86f, 0.05f, 1f); val.shadows = (LightShadows)0; val.renderMode = (LightRenderMode)1; } _cubeLightObject.transform.position = center; _cubeLightObject.transform.rotation = Quaternion.identity; Light component = _cubeLightObject.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; component.color = new Color(1f, 0.86f, 0.05f, 1f); component.intensity = Mathf.Max(0f, (_cubeLightIntensity != null) ? _cubeLightIntensity.Value : 2.2f); component.range = Mathf.Max(size, (_cubeLightRange != null) ? _cubeLightRange.Value : (size * 2.5f)); } } private static void DestroyCubeLight() { if ((Object)(object)_cubeLightObject != (Object)null) { Object.Destroy((Object)(object)_cubeLightObject); _cubeLightObject = null; } } private static void DestroyCubeVisual() { D("[" + NetRoleDebugName() + "] DestroyCubeVisual called. BEFORE: " + CubeStateDebugLine()); if ((Object)(object)_cubeVisual != (Object)null) { Object.Destroy((Object)(object)_cubeVisual); _cubeVisual = null; } _cubeVisualMeshSignature = string.Empty; _clientCubeVisualRefreshRunning = false; DestroyCubeLight(); ClearAllCubeScrapGlow(); ResetDynamicAreaFootprint(); _hasCube = false; _processedThisTakeoff = false; _lateReset(); D("[" + NetRoleDebugName() + "] DestroyCubeVisual finished. AFTER: " + CubeStateDebugLine()); } private static void _lateReset() { if ((Object)(object)Instance != (Object)null) { Instance._lateSyncTimer = 0f; } } private static Bounds CurrentCubeBounds() { //IL_0037: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_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_004c: Unknown result type (might be due to invalid IL or missing references) if (!ForceFullSizeFootprintEnabled() && _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) { return _cubeDynamicFootprintBounds; } float cubeHorizontalSize = GetCubeHorizontalSize(); float cubeConfiguredHeight = GetCubeConfiguredHeight(); return new Bounds(_cubeCenter, new Vector3(cubeHorizontalSize, cubeConfiguredHeight, cubeHorizontalSize)); } private static bool PositionIsInsideCube(Vector3 position) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube) { return false; } if (!IsServer() && _cubeDynamicFootprintWaitingForAuthoritativeHostSync) { return false; } if (!ForceFullSizeFootprintEnabled() && _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) { return PositionIsInsideDynamicAreaFootprint(position); } Bounds val = CurrentCubeBounds(); return ((Bounds)(ref val)).Contains(position); } private static float EarlyVoteInsideTolerance() { return Mathf.Clamp((_earlyExtractionVoteInsideToleranceMeters != null) ? _earlyExtractionVoteInsideToleranceMeters.Value : 0.75f, 0f, 3f); } private static float EarlyVoteLeaveGraceSeconds() { return Mathf.Clamp((_earlyExtractionVoteLeaveGraceSeconds != null) ? _earlyExtractionVoteLeaveGraceSeconds.Value : 1.5f, 0f, 10f); } private static bool PositionIsInsideCubeWithVoteTolerance(Vector3 position) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_012e: 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_0138: 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_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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) float num = EarlyVoteInsideTolerance(); if (num <= 0.001f) { return PositionIsInsideCube(position); } if (!_hasCube) { return false; } if (!IsServer() && _cubeDynamicFootprintWaitingForAuthoritativeHostSync) { return false; } if (!ForceFullSizeFootprintEnabled() && _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) { if (PositionIsInsideDynamicAreaFootprint(position)) { return true; } Vector3[] array = (Vector3[])(object)new Vector3[8] { position + new Vector3(num, 0f, 0f), position + new Vector3(0f - num, 0f, 0f), position + new Vector3(0f, 0f, num), position + new Vector3(0f, 0f, 0f - num), position + new Vector3(num, 0f, num), position + new Vector3(num, 0f, 0f - num), position + new Vector3(0f - num, 0f, num), position + new Vector3(0f - num, 0f, 0f - num) }; for (int i = 0; i < array.Length; i++) { if (PositionIsInsideDynamicAreaFootprint(array[i])) { return true; } } return false; } Bounds val = CurrentCubeBounds(); ((Bounds)(ref val)).Expand(new Vector3(num * 2f, Mathf.Max(0.5f, num), num * 2f)); return ((Bounds)(ref val)).Contains(position); } private static bool PositionIsInsideDynamicAreaFootprint(Vector3 position) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float num2 = _cubeDynamicFootprintBottomY - 0.5f; float num3 = _cubeDynamicFootprintBottomY + _cubeDynamicFootprintHeight + 0.85f; if (position.y < num2 || position.y > num3) { return false; } Vector3 val = position - _cubeCenter; int num4 = Mathf.FloorToInt(val.x / num + 0.5f); int num5 = Mathf.FloorToInt(val.z / num + 0.5f); if (!CubeFootprintHasCell(num4, num5)) { return false; } float num6 = val.x - (float)num4 * num; float num7 = val.z - (float)num5 * num; float num8 = num * 0.5f; float num9 = DynamicAreaBoundaryInset(); if (num6 < 0f - num8 + num9 && !CubeFootprintHasCell(num4 - 1, num5)) { return false; } if (num6 > num8 - num9 && !CubeFootprintHasCell(num4 + 1, num5)) { return false; } if (num7 < 0f - num8 + num9 && !CubeFootprintHasCell(num4, num5 - 1)) { return false; } if (num7 > num8 - num9 && !CubeFootprintHasCell(num4, num5 + 1)) { return false; } return true; } private static bool BoundsIntersectsDynamicAreaFootprint(Bounds bounds) { //IL_00ca: 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_00f7: Unknown result type (might be due to invalid IL or missing references) if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0) { return false; } float cell = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float num = Mathf.Max(0.5f, _cubeDynamicFootprintHeight); int dynamicFootprintHalfCells = GetDynamicFootprintHalfCells(); Vector3 val = default(Vector3); Bounds val2 = default(Bounds); for (int i = -dynamicFootprintHalfCells; i <= dynamicFootprintHalfCells; i++) { for (int j = -dynamicFootprintHalfCells; j <= dynamicFootprintHalfCells; j++) { if (CubeFootprintHasCell(i, j)) { GetDynamicCellLocalEdges(i, j, cell, out var minX, out var maxX, out var minZ, out var maxZ); ((Vector3)(ref val))..ctor(_cubeCenter.x + (minX + maxX) * 0.5f, _cubeDynamicFootprintBottomY + num * 0.5f, _cubeCenter.z + (minZ + maxZ) * 0.5f); ((Bounds)(ref val2))..ctor(val, new Vector3(Mathf.Max(0.02f, maxX - minX), num, Mathf.Max(0.02f, maxZ - minZ))); if (((Bounds)(ref val2)).Intersects(bounds)) { return true; } } } } return false; } private static bool ObjectIntersectsCube(GameObject obj) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube || (Object)(object)obj == (Object)null) { return false; } Bounds val = CurrentCubeBounds(); bool flag = !ForceFullSizeFootprintEnabled() && _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0; bool flag2 = false; Collider[] componentsInChildren = obj.GetComponentsInChildren(true); Collider[] array = componentsInChildren; foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger) { flag2 = true; if (flag ? BoundsIntersectsDynamicAreaFootprint(val2.bounds) : ((Bounds)(ref val)).Intersects(val2.bounds)) { return true; } } } Renderer[] componentsInChildren2 = obj.GetComponentsInChildren(true); Renderer[] array2 = componentsInChildren2; foreach (Renderer val3 in array2) { if (!((Object)(object)val3 == (Object)null) && val3.enabled) { flag2 = true; if (flag ? BoundsIntersectsDynamicAreaFootprint(val3.bounds) : ((Bounds)(ref val)).Intersects(val3.bounds)) { return true; } } } return !flag2 && PositionIsInsideCube(obj.transform.position); } private static bool PlayerIntersectsCube(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } return ObjectIntersectsCube(((Component)player).gameObject); } private static bool PlayerBodyPositionInsideCube(PlayerControllerB player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_005a: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube || (Object)(object)player == (Object)null) { return false; } Vector3 position = ((Component)player).transform.position; return PositionIsInsideCube(position) || PositionIsInsideCube(position + Vector3.up * 0.75f) || PositionIsInsideCube(position + Vector3.up * 1.45f); } private static bool PlayerBodyPositionInsideCubeForVoting(PlayerControllerB player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_005a: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube || (Object)(object)player == (Object)null) { return false; } Vector3 position = ((Component)player).transform.position; return PositionIsInsideCubeWithVoteTolerance(position) || PositionIsInsideCubeWithVoteTolerance(position + Vector3.up * 0.75f) || PositionIsInsideCubeWithVoteTolerance(position + Vector3.up * 1.45f); } private static bool ScrapIntersectsCube(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return false; } return ObjectIntersectsCube(((Component)item).gameObject); } private static bool LocalPlayerShouldExtract() { //IL_0075: 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) if (!_hasCube || (Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) { return false; } PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if (localPlayerController.isPlayerDead || !localPlayerController.isPlayerControlled) { return false; } bool flag = PlayerIntersectsCube(localPlayerController); if (!flag) { D($"Local player not inside Extraction Area. playerPos={((Component)localPlayerController).transform.position}, cubeBounds={CurrentCubeBounds()}"); } return flag; } private static bool LocalPlayerInsideCubeNoLog() { if (!_hasCube || (Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) { return false; } PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if (localPlayerController.isPlayerDead || !localPlayerController.isPlayerControlled) { return false; } return PlayerBodyPositionInsideCube(localPlayerController); } private static void UpdateInsideCubeHudState() { DebugLogInsideCubeResult(_localPlayerInsideCube = LocalPlayerInsideCubeNoLog(), "UpdateInsideCubeHudState"); } private static void UpdateCubeScrapValueCacheLoop() { if (!_hasCube) { _currentCubeScrapRawValue = 0; _currentCubeScrapCount = 0; return; } _cubeScrapValueTimer += Time.deltaTime; if (!(_cubeScrapValueTimer < 0.2f) || _localPlayerInsideCube) { _cubeScrapValueTimer = 0f; RefreshCubeScrapValueCache(); } } private static void RefreshCubeScrapValueCache() { int num = 0; int num2 = 0; try { GrabbableObject[] array = Object.FindObjectsOfType(); foreach (GrabbableObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && val.itemProperties.isScrap && !val.isHeld && !val.isPocketed && !((Object)(object)val.playerHeldBy != (Object)null) && ScrapIntersectsCube(val)) { num++; num2 += Mathf.Max(0, val.scrapValue); } } } catch { } _currentCubeScrapCount = num; _currentCubeScrapRawValue = num2; } private static void UpdateEarlyExtractionVoteSystem() { if (_enableEarlyExtractionVote == null || !_enableEarlyExtractionVote.Value) { if (IsServer()) { ResetEarlyExtractionVotesOnHost("early extraction voting disabled", forceSync: false); } } else if (IsServer()) { UpdateEarlyExtractionVoteStateOnHost(); } } private static void UpdateEarlyExtractionVoteStateOnHost() { float num = Mathf.Max(1f, (_earlyExtractionVoteSyncInterval != null) ? _earlyExtractionVoteSyncInterval.Value : 1f); _earlyVoteSyncTimer += Time.deltaTime; bool flag = _earlyVoteSyncTimer >= num; if (flag) { _earlyVoteSyncTimer = 0f; } StartOfRound instance = StartOfRound.Instance; if (!_hasCube || (Object)(object)instance == (Object)null || instance.shipIsLeaving || _cubeExtractionPassed || _earlyExtractionTriggered) { string reason = $"cube inactive/closed/shipLeaving gate. hasCube={_hasCube}, sorNull={(Object)(object)instance == (Object)null}, shipLeaving={(Object)(object)instance != (Object)null && instance.shipIsLeaving}, cubeClosed={_cubeExtractionPassed}, earlyTriggered={_earlyExtractionTriggered}"; DebugLogHostVoteGate(reason, flag); ResetEarlyExtractionVotesOnHost("cube inactive, closed, or ship leaving", flag); return; } if (!TryGetLivingPlayersForEarlyExtraction(out var livingPlayerIds, out var rosterKey)) { DebugLogHostVoteGate("no living controlled players available for early extraction voting", flag); ResetEarlyExtractionVotesOnHost("no living controlled players available for early extraction voting", flag); return; } DebugLogHostVoteGate($"eligible alive roster [{rosterKey}] livingCount={livingPlayerIds.Count}. Players may vote individually from inside the Extraction Area.", flag); if (_earlyVoteRosterKey != rosterKey) { D("Early extraction alive roster changed from [" + _earlyVoteRosterKey + "] to [" + rosterKey + "]. Keeping valid existing votes instead of resetting the whole vote."); _earlyVoteRosterKey = rosterKey; } PruneVotesToLivingRoster(livingPlayerIds); RemoveVotesForPlayersWhoLeftCube(livingPlayerIds, "host vote state update"); _earlyVoteEligible = livingPlayerIds.Count > 0; _earlyVoteRequired = livingPlayerIds.Count; _earlyVoteCount = _earlyExtractionVotes.Count; _localEarlyVoteSubmitted = IsLocalPlayerVoteRecorded(); if (_earlyExtractionCountdownActive && _earlyVoteCount < _earlyVoteRequired) { CancelEarlyExtractionCountdownOnHost($"votes dropped below alive count {_earlyVoteCount}/{_earlyVoteRequired}"); } if (_earlyExtractionCountdownActive) { UpdateEarlyExtractionCountdownOnHost(); BroadcastEarlyVoteSyncIfChanged(force: false); return; } BroadcastEarlyVoteSyncIfChanged(flag); if (_earlyVoteRequired > 0 && _earlyVoteCount >= _earlyVoteRequired) { StartEarlyExtractionCountdownOnHost($"all living players voted {_earlyVoteCount}/{_earlyVoteRequired}"); } } private static void HandleEarlyExtractionVoteInput() { //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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) KeyCode val = (KeyCode)((_earlyExtractionVoteKey == null) ? 114 : ((int)_earlyExtractionVoteKey.Value)); string localVoteInputBlockReason = GetLocalVoteInputBlockReason(); bool flag = !string.IsNullOrEmpty(localVoteInputBlockReason); if (_localPlayerInsideCube || _earlyVoteEligible || flag) { DebugLogVoteBlock(flag ? localVoteInputBlockReason : "vote input open"); } if (!flag && WasKeyPressedThisFrame(val)) { D($"[{NetRoleDebugName()}] Local early extraction vote key pressed. key={val}. Submitting vote request. {VoteStateDebugLine()} | {CubeStateDebugLine()}"); SubmitLocalEarlyExtractionVote(); } } private static bool WasKeyPressedThisFrame(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if ((int)key == 0) { return false; } bool flag = TryInputSystemKeyPressed(key) || TryLegacyInputKeyPressed(key); bool flag2 = TryInputSystemKeyCurrentlyPressed(key) || TryLegacyInputKeyCurrentlyPressed(key); bool flag3 = _trackedPressedVoteKeys.Contains(key); if (flag2) { _trackedPressedVoteKeys.Add(key); } else { _trackedPressedVoteKeys.Remove(key); } bool flag4 = flag || (flag2 && !flag3); if (flag4 && DebugOptionEnabled(_debugVoteInput)) { D($"[{NetRoleDebugName()}] Vote key edge detected. key={key}, pressedThisFrame={flag}, currentlyPressed={flag2}, wasTrackedDown={flag3}"); } return flag4; } private static bool TryInputSystemKeyPressed(KeyCode key) { //IL_0118: 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) try { Type type = Type.GetType("UnityEngine.InputSystem.Keyboard, Unity.InputSystem") ?? AccessTools.TypeByName("UnityEngine.InputSystem.Keyboard"); if (type == null) { return false; } object obj = type.GetProperty("current", BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null); if (obj == null) { return false; } string inputSystemKeyboardPropertyName = GetInputSystemKeyboardPropertyName(key); if (string.IsNullOrEmpty(inputSystemKeyboardPropertyName)) { return false; } object obj2 = type.GetProperty(inputSystemKeyboardPropertyName, BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj, null); if (obj2 == null) { return false; } PropertyInfo property = obj2.GetType().GetProperty("wasPressedThisFrame", BindingFlags.Instance | BindingFlags.Public); if (property == null) { return false; } object value = property.GetValue(obj2, null); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { if (!_inputSystemFailureLogged) { _inputSystemFailureLogged = true; D($"InputSystem vote key check failed for {key}. This will only be logged once: {ex.Message}"); } return false; } } private static bool TryInputSystemKeyCurrentlyPressed(KeyCode key) { //IL_01c3: 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) try { Type type = Type.GetType("UnityEngine.InputSystem.Keyboard, Unity.InputSystem") ?? AccessTools.TypeByName("UnityEngine.InputSystem.Keyboard"); if (type == null) { return false; } object obj = type.GetProperty("current", BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null); if (obj == null) { return false; } string inputSystemKeyboardPropertyName = GetInputSystemKeyboardPropertyName(key); if (string.IsNullOrEmpty(inputSystemKeyboardPropertyName)) { return false; } object obj2 = type.GetProperty(inputSystemKeyboardPropertyName, BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj, null); if (obj2 == null) { return false; } PropertyInfo property = obj2.GetType().GetProperty("isPressed", BindingFlags.Instance | BindingFlags.Public); if (property != null && property.GetValue(obj2, null) is bool result) { return result; } object obj3 = obj2.GetType().GetMethod("ReadValueAsObject", BindingFlags.Instance | BindingFlags.Public)?.Invoke(obj2, null); if (obj3 is float num) { return num > 0.5f; } if (obj3 is double num2) { return num2 > 0.5; } if (obj3 is bool) { bool result2 = (bool)obj3; if (true) { return result2; } } } catch (Exception ex) { if (!_inputSystemFailureLogged) { _inputSystemFailureLogged = true; D($"InputSystem current vote key check failed for {key}. This will only be logged once: {ex.Message}"); } } return false; } private static bool TryLegacyInputKeyPressed(KeyCode key) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) try { MethodInfo methodInfo = (Type.GetType("UnityEngine.Input, UnityEngine.InputLegacyModule") ?? AccessTools.TypeByName("UnityEngine.Input"))?.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(KeyCode) }, null); if (methodInfo == null) { return false; } object obj = methodInfo.Invoke(null, new object[1] { key }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { if (!_legacyInputFailureLogged) { _legacyInputFailureLogged = true; D($"Legacy input vote key check failed for {key}. This will only be logged once: {ex.Message}"); } return false; } } private static bool TryLegacyInputKeyCurrentlyPressed(KeyCode key) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) try { MethodInfo methodInfo = (Type.GetType("UnityEngine.Input, UnityEngine.InputLegacyModule") ?? AccessTools.TypeByName("UnityEngine.Input"))?.GetMethod("GetKey", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(KeyCode) }, null); if (methodInfo == null) { return false; } object obj = methodInfo.Invoke(null, new object[1] { key }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { if (!_legacyInputFailureLogged) { _legacyInputFailureLogged = true; D($"Legacy current vote key check failed for {key}. This will only be logged once: {ex.Message}"); } return false; } } private static string GetInputSystemKeyboardPropertyName(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Invalid comparison between Unknown and I4 //IL_004f: 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_0055: Expected I4, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_00ad: 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_00b0: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Invalid comparison between Unknown and I4 //IL_008d: 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_0096: Expected I4, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Invalid comparison between Unknown and I4 //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected I4, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected I4, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Invalid comparison between Unknown and I4 //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Invalid comparison between Unknown and I4 //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Invalid comparison between Unknown and I4 //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Invalid comparison between Unknown and I4 //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Invalid comparison between Unknown and I4 //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected I4, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Invalid comparison between Unknown and I4 //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Invalid comparison between Unknown and I4 if ((int)key >= 97 && (int)key <= 122) { return (char)(97 + (key - 97)) + "Key"; } if ((int)key >= 48 && (int)key <= 57) { return "digit" + (key - 48) + "Key"; } if ((int)key >= 256 && (int)key <= 265) { return "numpad" + (key - 256) + "Key"; } if ((int)key <= 32) { if ((int)key <= 9) { if ((int)key == 8) { return "backspaceKey"; } if ((int)key == 9) { return "tabKey"; } } else { if ((int)key == 13) { return "enterKey"; } if ((int)key == 27) { return "escapeKey"; } if ((int)key == 32) { return "spaceKey"; } } } else if ((int)key <= 61) { switch (key - 39) { default: if ((int)key != 59) { if ((int)key != 61) { break; } return "equalsKey"; } return "semicolonKey"; case 6: return "minusKey"; case 0: return "quoteKey"; case 5: return "commaKey"; case 7: return "periodKey"; case 8: return "slashKey"; case 1: case 2: case 3: case 4: break; } } else { switch (key - 91) { default: if ((int)key != 127) { switch (key - 271) { case 0: return "numpadEnterKey"; case 6: return "insertKey"; case 7: return "homeKey"; case 8: return "endKey"; case 9: return "pageUpKey"; case 10: return "pageDownKey"; case 2: return "upArrowKey"; case 3: return "downArrowKey"; case 5: return "leftArrowKey"; case 4: return "rightArrowKey"; case 33: return "leftShiftKey"; case 32: return "rightShiftKey"; case 35: return "leftCtrlKey"; case 34: return "rightCtrlKey"; case 37: return "leftAltKey"; case 36: return "rightAltKey"; case 30: return "capsLockKey"; case 11: return "f1Key"; case 12: return "f2Key"; case 13: return "f3Key"; case 14: return "f4Key"; case 15: return "f5Key"; case 16: return "f6Key"; case 17: return "f7Key"; case 18: return "f8Key"; case 19: return "f9Key"; case 20: return "f10Key"; case 21: return "f11Key"; case 22: return "f12Key"; } break; } return "deleteKey"; case 5: return "backquoteKey"; case 0: return "leftBracketKey"; case 2: return "rightBracketKey"; case 1: return "backslashKey"; case 3: case 4: break; } } return null; } private static bool LocalPlayerCanUseVoteInput() { PlayerControllerB val = StartOfRound.Instance?.localPlayerController; if ((Object)(object)val == (Object)null || val.isPlayerDead || !val.isPlayerControlled) { return false; } if (val.isTypingChat || val.inTerminalMenu) { return false; } if ((Object)(object)val.quickMenuManager != (Object)null && val.quickMenuManager.isMenuOpen) { return false; } return true; } private static void SubmitLocalEarlyExtractionVote() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { DebugLogVoteBlock("SubmitLocalEarlyExtractionVote aborted because StartOfRound is null", force: true); return; } int thisClientPlayerId = instance.thisClientPlayerId; _localEarlyVoteSubmitted = true; if (IsServer()) { ulong num = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.LocalClientId : 0); _debugEarlyVoteRequestSendCount++; D($"[{NetRoleDebugName()}] Host local vote path. voteRequestSendCount={_debugEarlyVoteRequestSendCount}, playerId={thisClientPlayerId}, clientId={num}"); HandleEarlyVoteRequestOnHost(num, thisClientPlayerId, clientSaysInside: true, 0); return; } NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.CustomMessagingManager : null) == null) { _localEarlyVoteSubmitted = false; D("[" + NetRoleDebugName() + "] Early extraction vote could not be sent because CustomMessagingManager was not ready. " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); return; } _earlyVoteRequestPendingAck = true; _earlyVoteRequestPendingPlayerId = thisClientPlayerId; _earlyVoteRequestStopTime = Time.realtimeSinceStartup + 20f; _earlyVoteRequestNextSendTime = Time.realtimeSinceStartup + 0.35f; _earlyVoteRequestTimeoutLogged = false; if (!SendEarlyVoteRequestToServer(thisClientPlayerId, clientSaysInside: true, "initial R press")) { _localEarlyVoteSubmitted = false; _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; } } private static bool SendEarlyVoteRequestToServer(int playerId, bool clientSaysInside, string reason) { NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.CustomMessagingManager : null) == null) { D("[" + NetRoleDebugName() + "] Early extraction vote request could not be sent because CustomMessagingManager was not ready. reason=" + reason + ". " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); return false; } bool flag = false; _earlyVoteRequestSequence++; int earlyVoteRequestSequence = _earlyVoteRequestSequence; flag |= TrySendEarlyVoteRequestToServer(playerId, earlyVoteRequestSequence, clientSaysInside, (NetworkDelivery)2, reason); return flag | TrySendEarlyVoteRequestToServer(playerId, earlyVoteRequestSequence, clientSaysInside, (NetworkDelivery)0, reason); } private static bool TrySendEarlyVoteRequestToServer(int playerId, int sequence, bool clientSaysInside, NetworkDelivery delivery, string reason) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0027: 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_003a: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(16, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref playerId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref sequence, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref clientSaysInside, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_EarlyVoteRequest_v1", 0uL, val, delivery); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } _debugEarlyVoteRequestSendCount++; D($"[{NetRoleDebugName()}] Sent early extraction vote request #{_debugEarlyVoteRequestSendCount} seq={sequence} delivery={delivery} from local playerId {playerId}, clientSaysInside={clientSaysInside}. reason={reason}. {VoteStateDebugLine()} | {CubeStateDebugLine()}"); return true; } catch (Exception ex) { Log.LogWarning((object)$"[Extraction] Failed sending early extraction vote request delivery={delivery}, reason={reason}: {ex.Message}"); return false; } } private static void UpdatePendingEarlyVoteRequestResend() { if (IsServer() || !_earlyVoteRequestPendingAck) { return; } int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)); if (num < 0 || _earlyVoteRequestPendingPlayerId != num) { D($"[{NetRoleDebugName()}] Clearing pending early vote resend because local player id changed. pending={_earlyVoteRequestPendingPlayerId}, local={num}"); _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _earlyVoteRequestTimeoutLogged = false; return; } if (!_hasCube || _cubeExtractionPassed || _earlyExtractionTriggered || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.shipIsLeaving) { D("[" + NetRoleDebugName() + "] Clearing pending early vote resend because cube/round is no longer voteable. " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _localEarlyVoteSubmitted = false; _earlyVoteRequestTimeoutLogged = false; return; } if (!_localPlayerInsideCube) { SendEarlyVoteRequestToServer(num, clientSaysInside: false, "pending vote cancelled because client HUD left cube"); D("[" + NetRoleDebugName() + "] Clearing pending early vote resend because local player left the Extraction Area before host confirmed it. Sent trusted outside/cancel report. " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _localEarlyVoteSubmitted = false; _earlyVoteRequestTimeoutLogged = false; return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup > _earlyVoteRequestStopTime) { if (!_earlyVoteRequestTimeoutLogged) { _earlyVoteRequestTimeoutLogged = true; D("[" + NetRoleDebugName() + "] Early vote request was not confirmed after retry window. Press the vote key again to retry. " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); } } else if (!(realtimeSinceStartup < _earlyVoteRequestNextSendTime)) { _earlyVoteRequestNextSendTime = realtimeSinceStartup + 0.35f; SendEarlyVoteRequestToServer(num, clientSaysInside: true, "pending ack retry"); } } private static void UpdateClientTrustedVoteLeaveCancel() { if (!IsServer() && (_localEarlyVoteSubmitted || _earlyVoteRequestPendingAck)) { StartOfRound instance = StartOfRound.Instance; int num = (((Object)(object)instance != (Object)null) ? instance.thisClientPlayerId : (-1)); if (num >= 0 && _hasCube && !_cubeExtractionPassed && !_earlyExtractionTriggered && (Object)(object)instance != (Object)null && !instance.shipIsLeaving && !_localPlayerInsideCube) { SendEarlyVoteRequestToServer(num, clientSaysInside: false, "client trusted leave cancel after HUD left cube"); _localEarlyVoteSubmitted = false; _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _earlyVoteRequestTimeoutLogged = false; D("[" + NetRoleDebugName() + "] Local submitted/pending vote cancelled because client HUD is outside cube. Sent trusted outside report. " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); } } } private static bool TryGetLivingPlayersForEarlyExtraction(out List livingPlayerIds, out string rosterKey) { livingPlayerIds = new List(); rosterKey = string.Empty; StartOfRound instance = StartOfRound.Instance; if (!_hasCube || instance?.allPlayerScripts == null || instance.allPlayersDead) { DebugLogHostVoteGate($"TryGetLivingPlayersForEarlyExtraction failed setup. hasCube={_hasCube}, sorNull={(Object)(object)instance == (Object)null}, playersNull={(Object)(object)instance == (Object)null || instance.allPlayerScripts == null}, allPlayersDead={(Object)(object)instance != (Object)null && instance.allPlayersDead}"); return false; } for (int i = 0; i < instance.allPlayerScripts.Length; i++) { PlayerControllerB player = instance.allPlayerScripts[i]; if (IsLivingControlledConnectedPlayer(player)) { livingPlayerIds.Add(i); } } if (livingPlayerIds.Count == 0) { DebugLogHostVoteGate("TryGetLivingPlayersForEarlyExtraction failed because no living controlled players were found.", force: true); return false; } livingPlayerIds.Sort(); rosterKey = string.Join(",", livingPlayerIds.Select((int id) => id.ToString()).ToArray()); return true; } private static void RemoveVotesForPlayersWhoLeftCube(List livingPlayerIds, string reason) { if (livingPlayerIds == null || livingPlayerIds.Count == 0 || _earlyExtractionVotes.Count == 0) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; float num = EarlyVoteLeaveGraceSeconds(); HashSet hashSet = new HashSet(livingPlayerIds); List list = new List(); foreach (int item in _earlyExtractionVotes.ToList()) { if (!hashSet.Contains(item)) { continue; } if (_clientTrustedEarlyVotePlayers.Contains(item)) { _earlyVoteLeftCubeSince.Remove(item); continue; } PlayerControllerB val = ((item >= 0 && item < instance.allPlayerScripts.Length) ? instance.allPlayerScripts[item] : null); float value; if ((Object)(object)val != (Object)null && PlayerBodyPositionInsideCubeForVoting(val)) { if (_earlyVoteLeftCubeSince.Remove(item)) { D($"Early extraction vote leave grace cleared for player {item}. reason={reason}. {PlayerInsideDebugLine(val, item)}"); } } else if (!_earlyVoteLeftCubeSince.TryGetValue(item, out value)) { _earlyVoteLeftCubeSince[item] = realtimeSinceStartup; D($"Early extraction voter {item} is outside the Extraction Area, starting leave grace {num:0.00}s. reason={reason}. {PlayerInsideDebugLine(val, item)}"); } else if (!(realtimeSinceStartup - value < num)) { _earlyExtractionVotes.Remove(item); _earlyVoteLeftCubeSince.Remove(item); list.Add(item); } } if (list.Count > 0) { D(string.Format("Removed early extraction vote(s) only for player(s) who stayed outside after grace. removed=[{0}], grace={1:0.00}s, reason={2}. Remaining voters=[{3}]", string.Join(",", list.Select((int id) => id.ToString()).ToArray()), num, reason, string.Join(",", (from id in _earlyExtractionVotes orderby id select id.ToString()).ToArray()))); } } private static void PruneVotesToLivingRoster(List livingPlayerIds) { if (livingPlayerIds == null || livingPlayerIds.Count == 0) { _earlyExtractionVotes.Clear(); _earlyVoteLeftCubeSince.Clear(); _clientTrustedEarlyVotePlayers.Clear(); return; } HashSet valid = new HashSet(livingPlayerIds); _earlyExtractionVotes.RemoveWhere((int id) => !valid.Contains(id)); _clientTrustedEarlyVotePlayers.RemoveWhere((int id) => !valid.Contains(id)); foreach (int item in _earlyVoteLeftCubeSince.Keys.ToList()) { if (!valid.Contains(item) || !_earlyExtractionVotes.Contains(item)) { _earlyVoteLeftCubeSince.Remove(item); } } } private static bool IsLocalPlayerVoteRecorded() { try { int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)); return num >= 0 && _earlyExtractionVotes.Contains(num); } catch { return false; } } private static void ResetEarlyExtractionVotesOnHost(string reason, bool forceSync) { bool flag = _earlyVoteEligible || _earlyVoteCount != 0 || _earlyVoteRequired != 0 || _earlyExtractionVotes.Count != 0 || !string.IsNullOrEmpty(_earlyVoteRosterKey) || _earlyExtractionCountdownActive; _earlyVoteEligible = false; _earlyVoteCount = 0; _earlyVoteRequired = 0; _localEarlyVoteSubmitted = false; _earlyVoteRosterKey = string.Empty; _earlyExtractionVotes.Clear(); _earlyVoteLeftCubeSince.Clear(); _clientTrustedEarlyVotePlayers.Clear(); _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _earlyVoteRequestNextSendTime = 0f; _earlyVoteRequestStopTime = 0f; _earlyVoteRequestTimeoutLogged = false; _earlyExtractionCountdownActive = false; _earlyExtractionCountdownEndTime = 0f; _earlyExtractionCountdownSecondsRemaining = 0; if (flag) { D("Early extraction vote reset: " + reason); } if (forceSync || flag) { BroadcastEarlyVoteSyncIfChanged(force: true); } } private static void HandleEarlyVoteRequestOnHost(ulong senderClientId, int claimedPlayerId, bool clientSaysInside, int sequence) { _debugEarlyVoteRequestReceiveCount++; D($"[{NetRoleDebugName()}] Host received early vote request #{_debugEarlyVoteRequestReceiveCount}. senderClientId={senderClientId}, claimedPlayerId={claimedPlayerId}, sequence={sequence}, clientSaysInside={clientSaysInside}. {VoteStateDebugLine()} | {CubeStateDebugLine()}"); if (!IsServer() || _enableEarlyExtractionVote == null || !_enableEarlyExtractionVote.Value) { D($"[{NetRoleDebugName()}] Ignored early vote request because server/vote enabled gate failed. isServer={IsServer()}, voteEnabled={_enableEarlyExtractionVote != null && _enableEarlyExtractionVote.Value}"); return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.shipIsLeaving || _cubeExtractionPassed || _earlyExtractionTriggered) { D($"[{NetRoleDebugName()}] Rejected early vote request during ship/closed/triggered state. sorNull={(Object)(object)instance == (Object)null}, shipLeaving={(Object)(object)instance != (Object)null && instance.shipIsLeaving}, cubeClosed={_cubeExtractionPassed}, triggered={_earlyExtractionTriggered}"); BroadcastEarlyVoteSyncIfChanged(force: true); return; } int num = FindPlayerIdByClientId(senderClientId); if (num < 0 && senderClientId == (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.LocalClientId : 0)) { num = claimedPlayerId; } if (num < 0 || instance.allPlayerScripts == null || num >= instance.allPlayerScripts.Length) { D($"Rejected early extraction vote. Could not resolve sender client {senderClientId} to a player. claimedPlayerId={claimedPlayerId}, realPlayerId={num}, playersNull={instance.allPlayerScripts == null}, playersLength={((instance.allPlayerScripts != null) ? instance.allPlayerScripts.Length : (-1))}"); BroadcastEarlyVoteSyncIfChanged(force: true); return; } if (!TryGetLivingPlayersForEarlyExtraction(out var livingPlayerIds, out var rosterKey)) { D($"[{NetRoleDebugName()}] Vote request rejected because no living controlled players were found. senderClientId={senderClientId}, claimedPlayerId={claimedPlayerId}, realPlayerId={num}"); DebugLogPlayersSnapshot("vote request rejected no living players", force: true); ResetEarlyExtractionVotesOnHost("vote request rejected because no living controlled players were found", forceSync: true); return; } if (!livingPlayerIds.Contains(num)) { D(string.Format("Rejected early extraction vote from player {0}. Player is not in alive roster [{1}]. {2}", num, string.Join(",", livingPlayerIds.Select((int id) => id.ToString()).ToArray()), PlayerInsideDebugLine((num >= 0 && instance.allPlayerScripts != null && num < instance.allPlayerScripts.Length) ? instance.allPlayerScripts[num] : null, num))); BroadcastEarlyVoteSyncIfChanged(force: true); return; } PlayerControllerB player = instance.allPlayerScripts[num]; if (!clientSaysInside) { bool flag = _earlyExtractionVotes.Remove(num); _clientTrustedEarlyVotePlayers.Remove(num); _earlyVoteLeftCubeSince.Remove(num); PruneVotesToLivingRoster(livingPlayerIds); _earlyVoteEligible = livingPlayerIds.Count > 0; _earlyVoteRequired = livingPlayerIds.Count; _earlyVoteCount = _earlyExtractionVotes.Count; _localEarlyVoteSubmitted = IsLocalPlayerVoteRecorded(); if (_earlyExtractionCountdownActive && _earlyVoteCount < _earlyVoteRequired) { CancelEarlyExtractionCountdownOnHost($"trusted client outside/cancel report from player {num}"); } D($"Trusted client outside/cancel report from player {num}. removedVote={flag}. Votes {_earlyVoteCount}/{_earlyVoteRequired}. {PlayerInsideDebugLine(player, num)}"); BroadcastEarlyVoteSyncIfChanged(force: true); return; } bool flag2 = senderClientId == (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.LocalClientId : 0); bool flag3 = clientSaysInside && !flag2; if (!flag3 && !PlayerBodyPositionInsideCubeForVoting(player)) { _earlyExtractionVotes.Remove(num); _clientTrustedEarlyVotePlayers.Remove(num); PruneVotesToLivingRoster(livingPlayerIds); _earlyVoteEligible = livingPlayerIds.Count > 0; _earlyVoteRequired = livingPlayerIds.Count; _earlyVoteCount = _earlyExtractionVotes.Count; _localEarlyVoteSubmitted = IsLocalPlayerVoteRecorded(); if (_earlyExtractionCountdownActive && _earlyVoteCount < _earlyVoteRequired) { CancelEarlyExtractionCountdownOnHost($"player {num} left before/while voting"); } D($"Rejected early extraction vote from player {num}. Host-local player is not inside the Extraction Area. Only their vote was removed. {PlayerInsideDebugLine(player, num)}"); BroadcastEarlyVoteSyncIfChanged(force: true); return; } if (flag3) { D($"Trusted client {senderClientId} HUD-inside vote for player {num}. Host position check skipped. {PlayerInsideDebugLine(player, num)}"); } if (_earlyVoteRosterKey != rosterKey) { D("Early extraction alive roster changed during vote request from [" + _earlyVoteRosterKey + "] to [" + rosterKey + "]. Keeping valid existing votes instead of resetting the whole vote."); _earlyVoteRosterKey = rosterKey; } PruneVotesToLivingRoster(livingPlayerIds); RemoveVotesForPlayersWhoLeftCube(livingPlayerIds, "host vote request"); bool flag4 = _earlyExtractionVotes.Add(num); if (flag3) { _clientTrustedEarlyVotePlayers.Add(num); } else { _clientTrustedEarlyVotePlayers.Remove(num); } _earlyVoteLeftCubeSince.Remove(num); _earlyVoteEligible = livingPlayerIds.Count > 0; _earlyVoteRequired = livingPlayerIds.Count; _earlyVoteCount = _earlyExtractionVotes.Count; _localEarlyVoteSubmitted = IsLocalPlayerVoteRecorded(); if (_earlyExtractionCountdownActive && _earlyVoteCount < _earlyVoteRequired) { CancelEarlyExtractionCountdownOnHost($"vote request updated votes to {_earlyVoteCount}/{_earlyVoteRequired}"); } D(flag4 ? string.Format("Early extraction vote accepted from player {0}. Votes {1}/{2}. aliveRoster=[{3}] voters=[{4}]", num, _earlyVoteCount, _earlyVoteRequired, rosterKey, string.Join(",", (from id in _earlyExtractionVotes orderby id select id.ToString()).ToArray())) : string.Format("Early extraction vote from player {0} was already recorded. Votes {1}/{2}. aliveRoster=[{3}] voters=[{4}]", num, _earlyVoteCount, _earlyVoteRequired, rosterKey, string.Join(",", (from id in _earlyExtractionVotes orderby id select id.ToString()).ToArray()))); DebugLogStateSnapshot("host accepted/processed early vote request", force: true); BroadcastEarlyVoteSyncIfChanged(force: true); if (!_earlyExtractionCountdownActive && _earlyVoteRequired > 0 && _earlyVoteCount >= _earlyVoteRequired) { StartEarlyExtractionCountdownOnHost($"votes reached {_earlyVoteCount}/{_earlyVoteRequired}"); } } private static int FindPlayerIdByClientId(ulong clientId) { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return -1; } for (int i = 0; i < array.Length; i++) { PlayerControllerB val = array[i]; if (IsControlledConnectedPlayer(val) && val.actualClientId == clientId) { return i; } } return -1; } private static void StartEarlyExtractionCountdownOnHost(string reason) { if (IsServer() && !_earlyExtractionCountdownActive && !_earlyExtractionTriggered && !((Object)(object)StartOfRound.Instance == (Object)null) && !StartOfRound.Instance.shipIsLeaving && !_cubeExtractionPassed) { float num = Mathf.Max(1f, (_earlyExtractionCountdownSeconds != null) ? _earlyExtractionCountdownSeconds.Value : 10f); _earlyExtractionCountdownActive = true; _earlyExtractionCountdownEndTime = Time.time + num; _earlyExtractionCountdownSecondsRemaining = Mathf.CeilToInt(num); D($"Early extraction countdown started for {_earlyExtractionCountdownSecondsRemaining} seconds. Reason: {reason}"); SendDebugChat($"[Extraction] Early extraction vote passed. Extracting in {_earlyExtractionCountdownSecondsRemaining} seconds."); BroadcastEarlyVoteSyncIfChanged(force: true); UpdateCubePulseVisual(force: true); } } private static void CancelEarlyExtractionCountdownOnHost(string reason) { if (_earlyExtractionCountdownActive) { _earlyExtractionCountdownActive = false; _earlyExtractionCountdownEndTime = 0f; _earlyExtractionCountdownSecondsRemaining = 0; D("Early extraction countdown cancelled but existing valid votes were kept. Reason: " + reason); UpdateCubePulseVisual(force: true); BroadcastEarlyVoteSyncIfChanged(force: true); } } private static void UpdateEarlyExtractionCountdownOnHost() { if (_earlyExtractionCountdownActive) { int earlyExtractionCountdownSecondsRemaining = _earlyExtractionCountdownSecondsRemaining; float num = Mathf.Max(0f, _earlyExtractionCountdownEndTime - Time.time); _earlyExtractionCountdownSecondsRemaining = Mathf.Max(0, Mathf.CeilToInt(num)); if (_earlyExtractionCountdownSecondsRemaining != earlyExtractionCountdownSecondsRemaining) { UpdateCubePulseVisual(force: true); } if (num <= 0.01f) { _earlyExtractionCountdownActive = false; _earlyExtractionCountdownSecondsRemaining = 0; TriggerEarlyExtractionOnHost("early extraction countdown finished with all living players still inside the Extraction Area"); } } } private static void TriggerEarlyExtractionOnHost(string reason) { if (!IsServer() || _earlyExtractionTriggered || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.shipIsLeaving || _cubeExtractionPassed) { return; } _earlyExtractionTriggered = true; D("Early extraction vote passed. Triggering ship leave. Reason: " + reason); SendDebugChat("[Extraction] Early extraction vote passed. Ship is leaving now."); BroadcastEarlyVoteSyncIfChanged(force: true); int num = ((_earlyExtractionVotes.Count > 0) ? _earlyExtractionVotes.First() : 0); if (StartOfRound.Instance.allPlayerScripts != null) { for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++) { PlayerControllerB player = StartOfRound.Instance.allPlayerScripts[i]; if (IsLivingControlledConnectedPlayer(player)) { num = i; break; } } } try { StartOfRound.Instance.EndGameServerRpc(num); } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Early extraction failed to call EndGameServerRpc: {arg}"); _earlyExtractionTriggered = false; } } private static void BroadcastEarlyVoteSyncIfChanged(bool force) { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return; } string text = BuildEarlyVoteSyncSignature(); if (!force && text == _lastEarlyVoteSyncSignature) { return; } _lastEarlyVoteSyncSignature = text; foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds) { if (connectedClientsId == NetworkManager.Singleton.LocalClientId) { ApplyEarlyVoteSyncLocal(_earlyVoteEligible, _earlyVoteCount, _earlyVoteRequired, _earlyExtractionCountdownActive, _earlyExtractionCountdownSecondsRemaining, _earlyExtractionVotes.ToList()); } else { SendEarlyVoteSync(connectedClientsId); } } } private static string BuildEarlyVoteSyncSignature() { string text = string.Join(",", (from id in _earlyExtractionVotes orderby id select id.ToString()).ToArray()); return $"{_earlyVoteEligible}|{_earlyVoteCount}|{_earlyVoteRequired}|{_earlyVoteRosterKey}|{text}|{_earlyExtractionTriggered}|{_cubeExtractionPassed}|{_earlyExtractionCountdownActive}|{_earlyExtractionCountdownSecondsRemaining}"; } private static void SendEarlyVoteSync(ulong clientId) { //IL_0067: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0099: 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_00af: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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) NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.CustomMessagingManager : null) == null) { return; } try { List list = _earlyExtractionVotes.OrderBy((int id) => id).ToList(); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref _earlyVoteEligible, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _earlyVoteCount, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _earlyVoteRequired, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _earlyExtractionCountdownActive, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _earlyExtractionCountdownSecondsRemaining, default(ForPrimitives)); int count = list.Count; ((FastBufferWriter)(ref val)).WriteValueSafe(ref count, default(ForPrimitives)); for (int i = 0; i < list.Count; i++) { count = list[i]; ((FastBufferWriter)(ref val)).WriteValueSafe(ref count, default(ForPrimitives)); } NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_EarlyVoteSync_v1", clientId, val, (NetworkDelivery)2); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } D(string.Format("[{0}] Sent early vote sync to client {1}. eligible={2}, votes={3}/{4}, countdown={5}, seconds={6}, voters=[{7}]", NetRoleDebugName(), clientId, _earlyVoteEligible, _earlyVoteCount, _earlyVoteRequired, _earlyExtractionCountdownActive, _earlyExtractionCountdownSecondsRemaining, string.Join(",", list.Select((int id) => id.ToString()).ToArray()))); } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed sending early vote sync to client {clientId}: {arg}"); } } private static void OnEarlyVoteSyncMessage(ulong senderClientId, FastBufferReader reader) { //IL_0037: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0079: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (!MessageFromServer(senderClientId)) { D($"[{NetRoleDebugName()}] Rejected early vote sync from non-server sender={senderClientId}."); return; } bool eligible = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref eligible, default(ForPrimitives)); int voteCount = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref voteCount, default(ForPrimitives)); int required = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref required, default(ForPrimitives)); bool countdownActive = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref countdownActive, default(ForPrimitives)); int countdownSeconds = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref countdownSeconds, default(ForPrimitives)); int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); List list = new List(); num = Mathf.Clamp(num, 0, 32); int item = default(int); for (int i = 0; i < num; i++) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref item, default(ForPrimitives)); list.Add(item); } ApplyEarlyVoteSyncLocal(eligible, voteCount, required, countdownActive, countdownSeconds, list); } private static void ApplyEarlyVoteSyncLocal(bool eligible, int voteCount, int required, bool countdownActive, int countdownSeconds, List voters) { _debugEarlyVoteSyncReceiveCount++; D(string.Format("[{0}] Applying early vote sync #{1}. eligible={2}, voteCount={3}, required={4}, countdown={5}, countdownSeconds={6}, voters=[{7}]", NetRoleDebugName(), _debugEarlyVoteSyncReceiveCount, eligible, voteCount, required, countdownActive, countdownSeconds, (voters != null) ? string.Join(",", voters.Select((int id) => id.ToString()).ToArray()) : "null")); _earlyVoteEligible = eligible && required > 0; _earlyVoteCount = Mathf.Max(0, voteCount); _earlyVoteRequired = Mathf.Max(0, required); _earlyExtractionCountdownActive = _earlyVoteEligible && countdownActive; _earlyExtractionCountdownSecondsRemaining = (_earlyExtractionCountdownActive ? Mathf.Max(0, countdownSeconds) : 0); int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)); _localEarlyVoteSubmitted = _earlyVoteEligible && num >= 0 && voters != null && voters.Contains(num); if (!_earlyVoteEligible) { _localEarlyVoteSubmitted = false; } if (_localEarlyVoteSubmitted) { _earlyVoteRequestPendingAck = false; _earlyVoteRequestPendingPlayerId = -1; _earlyVoteRequestTimeoutLogged = false; } D("[" + NetRoleDebugName() + "] Applied early vote sync local. " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); UpdateCubePulseVisual(force: true); } private static void OnEarlyVoteRequestMessage(ulong senderClientId, FastBufferReader reader) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!IsServer()) { D($"[{NetRoleDebugName()}] Ignored early vote request message on non-server. sender={senderClientId}"); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); int num2 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num2, default(ForPrimitives)); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); D($"[{NetRoleDebugName()}] OnEarlyVoteRequestMessage sender={senderClientId}, claimedPlayerId={num}, sequence={num2}, clientSaysInside={flag}"); HandleEarlyVoteRequestOnHost(senderClientId, num, flag, num2); } private static bool BaseGameSpectatorVoteToLeaveDisabled() { return _disableBaseGameSpectatorVoteToLeave != null && _disableBaseGameSpectatorVoteToLeave.Value; } private static void ClearBaseGameSpectatorVoteToLeaveState(string reason, bool resetVanillaTimeOfDayFields) { bool flag = _baseGameVoteToLeaveUrgencyActive || _baseGameVoteToLeaveObserved; float num = ((_normalShipLeaveAutomaticallyTimeCaptured && _normalShipLeaveAutomaticallyTime > 0.5f) ? _normalShipLeaveAutomaticallyTime : 1f); _baseGameVoteToLeaveUrgencyActive = false; _baseGameVoteToLeaveObserved = false; _normalShipLeaveAutomaticallyTimeCaptured = false; _normalShipLeaveAutomaticallyTime = -1f; if (resetVanillaTimeOfDayFields) { TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance != (Object)null) { float shipLeaveAutomaticallyTime = num; instance.votesForShipToLeaveEarly = 0; instance.votedShipToLeaveEarlyThisRound = false; instance.shipLeavingAlertCalled = false; if (instance.shipLeaveAutomaticallyTime > 0f && instance.shipLeaveAutomaticallyTime < 0.95f) { instance.shipLeaveAutomaticallyTime = shipLeaveAutomaticallyTime; } } } if (flag) { D("Cleared stale base-game spectator vote-to-leave state. reason=" + reason); } UpdateCubePulseVisual(force: true); } private static void CaptureNormalShipLeaveAutomaticallyTime(string reason) { if (_normalShipLeaveAutomaticallyTimeCaptured) { return; } TimeOfDay instance = TimeOfDay.Instance; if (!((Object)(object)instance == (Object)null)) { float shipLeaveAutomaticallyTime = instance.shipLeaveAutomaticallyTime; if (!(shipLeaveAutomaticallyTime <= 0.5f)) { _normalShipLeaveAutomaticallyTime = shipLeaveAutomaticallyTime; _normalShipLeaveAutomaticallyTimeCaptured = true; D($"Captured normal vanilla ship leave target={shipLeaveAutomaticallyTime:0.000}. reason={reason}"); } } } private static void ObserveBaseGameVoteToLeave(string reason) { if (!BaseGameSpectatorVoteToLeaveDisabled()) { _baseGameVoteToLeaveObserved = true; MarkBaseGameVoteToLeaveUrgency(reason); } } private static void MarkBaseGameVoteToLeaveUrgency(string reason) { if (!_cubeExtractionPassed) { if (!_baseGameVoteToLeaveUrgencyActive) { D("Base-game spectator vote-to-leave urgency started. Cube visual will flash pink. reason=" + reason); } _baseGameVoteToLeaveUrgencyActive = true; UpdateCubePulseVisual(force: true); } } private static void MarkCubeExtractionPassed(bool passed) { if (_cubeExtractionPassed == passed) { UpdateCubePulseVisual(force: true); return; } _cubeExtractionPassed = passed; if (passed) { _earlyVoteEligible = false; _earlyVoteCount = 0; _earlyVoteRequired = 0; _localEarlyVoteSubmitted = false; _earlyVoteRosterKey = string.Empty; _earlyExtractionVotes.Clear(); _clientTrustedEarlyVotePlayers.Clear(); _earlyExtractionCountdownActive = false; _earlyExtractionCountdownEndTime = 0f; _earlyExtractionCountdownSecondsRemaining = 0; _earlyExtractionTriggered = true; _lastEarlyVoteSyncSignature = string.Empty; } else { _earlyExtractionTriggered = false; } UpdateCubePulseVisual(force: true); } private static void UpdateBaseGameVoteToLeaveUrgencyState() { if (_cubeExtractionPassed) { return; } CaptureNormalShipLeaveAutomaticallyTime("base-game vote urgency update"); if (BaseGameSpectatorVoteToLeaveDisabled()) { _baseGameVoteToLeaveObserved = false; if (_baseGameVoteToLeaveUrgencyActive) { _baseGameVoteToLeaveUrgencyActive = false; UpdateCubePulseVisual(force: true); } } else { if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving) { return; } TimeOfDay instance = TimeOfDay.Instance; if (!((Object)(object)instance == (Object)null)) { bool baseGameVoteToLeaveObserved = _baseGameVoteToLeaveObserved; bool flag = HasVanillaShipDepartureMovedEarlier(); if ((baseGameVoteToLeaveObserved || flag) && !_baseGameVoteToLeaveUrgencyActive) { MarkBaseGameVoteToLeaveUrgency(flag ? "detected vanilla early ship departure target" : "detected vanilla spectator vote data"); } } } } private static bool HasVanillaShipDepartureMovedEarlier() { TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance == (Object)null) { return false; } CaptureNormalShipLeaveAutomaticallyTime("compare vanilla early ship target"); float num = ((_normalShipLeaveAutomaticallyTimeCaptured && _normalShipLeaveAutomaticallyTime > 0f) ? _normalShipLeaveAutomaticallyTime : 0.98f); float num2 = Mathf.Clamp01(instance.normalizedTimeOfDay); float shipLeaveAutomaticallyTime = instance.shipLeaveAutomaticallyTime; return shipLeaveAutomaticallyTime > num2 + 0.001f && shipLeaveAutomaticallyTime > 0f && shipLeaveAutomaticallyTime < num - 0.005f; } private static bool TryGetEarlyShipLeaveTargetTime(out float targetNormalizedTime, out float currentNormalizedTime) { targetNormalizedTime = 0f; currentNormalizedTime = 0f; TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance == (Object)null) { return false; } currentNormalizedTime = Mathf.Clamp01(instance.normalizedTimeOfDay); float shipLeaveAutomaticallyTime = instance.shipLeaveAutomaticallyTime; if (!HasVanillaShipDepartureMovedEarlier()) { return false; } targetNormalizedTime = Mathf.Clamp01(shipLeaveAutomaticallyTime); return targetNormalizedTime > currentNormalizedTime; } private static string GetShipTakeoffCountdownText() { try { if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving) { return "NOW"; } TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance == (Object)null) { return "--"; } bool flag = false; float num; if (TryGetEarlyShipLeaveTargetTime(out var targetNormalizedTime, out var currentNormalizedTime)) { num = Mathf.Max(0f, targetNormalizedTime - currentNormalizedTime); flag = true; } else { float num2 = Mathf.Max(0f, instance.currentDayTime); float num3 = Mathf.Max(0f, instance.totalTime); num = Mathf.Max(0f, num3 - num2); } if (num <= 0.001f) { return "NOW"; } int num5; if (flag) { int num4 = Mathf.Max(1, instance.numberOfHours); num5 = Mathf.CeilToInt(num * (float)num4 * 60f); } else { float num6 = Mathf.Max(1f, instance.lengthOfHours); num5 = Mathf.CeilToInt(num / num6 * 60f); } int num7 = num5 / 60; int num8 = num5 % 60; if (num7 > 0) { return $"{num7}h {num8:00}m"; } return $"{num8}m"; } catch { return "--"; } } internal static void LocalShipLeavePrefix() { //IL_0030: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (_hasCube) { MarkCubeExtractionPassed(passed: true); if (IsServer()) { BroadcastCubeClosedState(closed: true); } if (LocalPlayerShouldExtract()) { Vector3 shipSafePosition = GetShipSafePosition(); D($"Local player is in Extraction Area during ShipLeave. Teleporting to ship at {shipSafePosition}."); TeleportLocalPlayer(shipSafePosition, toShip: true); } if (IsServer()) { ProcessTakeoffOnHost(); } } } private static bool RoundStartTeleportEnabled() { return _teleportPlayersToCubeOnRoundStart == null || _teleportPlayersToCubeOnRoundStart.Value; } private static bool RoundStartTeleportUsesCube() { return _roundStartTeleportToCube == null || _roundStartTeleportToCube.Value; } private static void RequestRoundStartCubeTeleport(string reason) { if (IsServer() && _hasCube) { if (!RoundStartTeleportEnabled()) { D("Round-start facility teleport skipped because TeleportPlayersToCubeOnRoundStart is false."); } else if (!_cubeExtractionPassed && (!((Object)(object)StartOfRound.Instance != (Object)null) || !StartOfRound.Instance.shipIsLeaving)) { _roundStartTeleportRequested = true; _roundStartTeleportRequestTime = Time.realtimeSinceStartup; _roundStartTeleportRequestReason = reason ?? "round start"; D("Queued round-start facility teleport. Waiting for fully-ready floor callback. destination=" + (RoundStartTeleportUsesCube() ? "the Extraction Area" : "random facility spot") + ", reason=" + _roundStartTeleportRequestReason); TryStartQueuedRoundStartCubeTeleport("request"); } } } private static void RebuildAndBroadcastAuthoritativeCubeFootprintOnHost(string reason) { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) D($"[{NetRoleDebugName()}] RebuildAndBroadcastAuthoritativeCubeFootprintOnHost called. reason={reason}, isServer={IsServer()}, hasCube={_hasCube}, dynamicEnabled={CubeDynamicFootprintEnabled()} before={CubeStateDebugLine()}"); if (!IsServer() || !_hasCube) { D($"[{NetRoleDebugName()}] Authoritative footprint rebuild skipped. reason={reason}, isServer={IsServer()}, hasCube={_hasCube}"); return; } if (!CubeDynamicFootprintEnabled()) { _authoritativeCubeFootprintReadyForClients = false; D("[" + NetRoleDebugName() + "] Dynamic footprint disabled. Broadcasting box-only cube sync. reason=" + reason); BroadcastCubePosition(); DebugLogStateSnapshot("authoritative broadcast skipped dynamic disabled", force: true); return; } float cubeHorizontalSize = GetCubeHorizontalSize(); float cubeConfiguredHeight = GetCubeConfiguredHeight(); ResetDynamicAreaFootprint(); D($"[{NetRoleDebugName()}] Authoritative footprint reset. Now rebuilding. center={V3(_cubeCenter)}, horizontal={cubeHorizontalSize:0.00}, height={cubeConfiguredHeight:0.00}"); EnsureDynamicAreaFootprintBuilt(_cubeCenter, cubeHorizontalSize, cubeConfiguredHeight); _authoritativeCubeFootprintReadyForClients = _cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0; int num = (_authoritativeCubeFootprintReadyForClients ? GetDynamicFootprintCellHash() : 0); CreateOrMoveCubeVisual(_cubeCenter); BroadcastCubePosition(); D($"Authoritative host Extraction Area footprint rebuilt and broadcast after {reason}. ready={_authoritativeCubeFootprintReadyForClients}, cells={_cubeDynamicFootprintCells.Count}, cellHash={num}, bounds={CurrentCubeBounds()}"); DebugLogStateSnapshot("authoritative host footprint rebuilt and broadcast", force: true); } internal static void NotifyPlayersFinishedGeneratingNewLevel() { D("[" + NetRoleDebugName() + "] RoundManager.FinishGeneratingNewLevelClientRpc postfix fired. Floor is fully ready for round-start facility teleport. Before callback: " + RoundStateDebugLine() + " | " + CubeStateDebugLine()); FinalizeCubePlacementAfterLevelReady(); RebuildAndBroadcastAuthoritativeCubeFootprintOnHost("fully-ready level callback"); _roundStartTeleportFloorReady = true; TryStartQueuedRoundStartCubeTeleport("fully-ready level callback"); } private static void TryStartQueuedRoundStartCubeTeleport(string source) { if (IsServer() && _hasCube && _roundStartTeleportRequested && !_roundStartTeleportStarted && !_roundStartTeleportRoutineRunning && !_cubeExtractionPassed && (!((Object)(object)StartOfRound.Instance != (Object)null) || !StartOfRound.Instance.shipIsLeaving) && _roundStartTeleportFloorReady) { _roundStartTeleportStarted = true; _roundStartTeleportRequested = false; D("Starting queued round-start facility teleport from " + source + ". reason=" + _roundStartTeleportRequestReason); if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(RoundStartFacilityTeleportRoutine(_roundStartTeleportRequestReason)); } } } private static void UpdateLateJoinTeleportWindowTimeout() { if (IsServer() && _roundStartCubeTeleportWindowOpen && !_roundStartTeleportRoutineRunning && !(_roundStartCubeTeleportWindowEndTime <= 0f) && !(Time.realtimeSinceStartup <= _roundStartCubeTeleportWindowEndTime)) { _roundStartCubeTeleportWindowOpen = false; _roundStartCubeTeleportWindowEndTime = 0f; BroadcastCubePosition(); D($"[{NetRoleDebugName()}] Late-join/rehost teleport window closed by timeout. token={_roundStartCubeTeleportToken}"); } } private static void UpdateQueuedRoundStartCubeTeleportFallback() { if (IsServer() && _hasCube && _roundStartTeleportRequested && !_roundStartTeleportStarted && !_roundStartTeleportRoutineRunning && !_cubeExtractionPassed && (!((Object)(object)StartOfRound.Instance != (Object)null) || !StartOfRound.Instance.shipIsLeaving)) { float num = Mathf.Max(8f, (_roundStartTeleportMaxWaitForFloorReady != null) ? _roundStartTeleportMaxWaitForFloorReady.Value : 45f); if (_roundStartTeleportRequestTime > 0f && Time.realtimeSinceStartup - _roundStartTeleportRequestTime >= num) { RebuildAndBroadcastAuthoritativeCubeFootprintOnHost("fallback timer"); _roundStartTeleportFloorReady = true; D($"Fallback starting round-start facility teleport after waiting {num:0.0}s for fully-ready level callback."); TryStartQueuedRoundStartCubeTeleport("fallback timer"); } } } [IteratorStateMachine(typeof(d__434))] private static IEnumerator RoundStartFacilityTeleportRoutine(string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__434(0) { reason = reason }; } private static bool IsRoundStartFacilityTeleportMomentSafe() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (instance.shipIsLeaving || _cubeExtractionPassed) { return false; } if (TryGetBoolMember(instance, "shipHasLanded", out var value) && !value) { return false; } if (TryGetBoolMember(instance, "inShipPhase", out var value2) && value2) { return false; } return true; } private static bool TryGetBoolMember(object obj, string name, out bool value) { value = false; if (obj == null || string.IsNullOrEmpty(name)) { return false; } Type type = obj.GetType(); try { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(bool)) { value = (bool)field.GetValue(obj); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool) && property.GetIndexParameters().Length == 0) { value = (bool)property.GetValue(obj, null); return true; } } catch { } return false; } private static bool TrySetBoolMember(object obj, string name, bool value) { if (obj == null || string.IsNullOrEmpty(name)) { return false; } Type type = obj.GetType(); try { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(bool)) { field.SetValue(obj, value); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool) && property.CanWrite && property.GetIndexParameters().Length == 0) { property.SetValue(obj, value, null); return true; } } catch { } return false; } private static bool TryInvokeMethodFlexible(object obj, string methodName, params object[] args) { if (obj == null || string.IsNullOrEmpty(methodName)) { return false; } try { MethodInfo[] methods = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (methodInfo.Name != methodName) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != ((args != null) ? args.Length : 0)) { continue; } object[] array2 = new object[parameters.Length]; bool flag = true; for (int j = 0; j < parameters.Length; j++) { object obj2 = args[j]; Type parameterType = parameters[j].ParameterType; if (obj2 == null) { array2[j] = null; continue; } if (parameterType.IsInstanceOfType(obj2)) { array2[j] = obj2; continue; } try { array2[j] = Convert.ChangeType(obj2, parameterType); } catch { flag = false; break; } } if (flag) { methodInfo.Invoke(obj, array2); return true; } } } catch { } return false; } private static void TriggerInsideFactoryStateBestEffort(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } try { ulong actualClientId = player.actualClientId; float realtimeSinceStartup = Time.realtimeSinceStartup; if (!_lastInsideFactoryBestEffortTimeByClient.TryGetValue(actualClientId, out var value) || !(realtimeSinceStartup - value < 1f)) { _lastInsideFactoryBestEffortTimeByClient[actualClientId] = realtimeSinceStartup; int num = Mathf.Clamp((int)actualClientId, 0, 9999); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { TryInvokeMethodFlexible(instance, "SwitchIsInsideFactoryRpc", actualClientId, num, true); TryInvokeMethodFlexible(instance, "SwitchIsInsideFactoryRpc", num, true); } TryInvokeMethodFlexible(player, "UpdateCameraOutsideOrInside"); } } catch { } } private static int TeleportAllControlledPlayersIntoFacilityOnHost(int token, string reason, int pass) { //IL_0071: 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) //IL_00a5: 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) if (!IsServer() || !_hasCube || StartOfRound.Instance?.allPlayerScripts == null || (Object)(object)NetworkManager.Singleton == (Object)null) { return 0; } int num = 0; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; for (int i = 0; i < allPlayerScripts.Length; i++) { PlayerControllerB val = allPlayerScripts[i]; if (ShouldRoundStartMovePlayer(val)) { Vector3 roundStartTeleportTarget = GetRoundStartTeleportTarget(val, i, token); ApplyPlayerInsideFactoryState(val); if (val.actualClientId != NetworkManager.Singleton.LocalClientId) { SendRoundStartCubeTeleport(val.actualClientId, token, roundStartTeleportTarget, $"{reason} pass {pass}"); num++; } else if (token > _localCompletedRoundStartCubeTeleportToken) { TryApplyRoundStartCubeTeleportLocal(token, roundStartTeleportTarget, $"host local {reason} pass {pass}"); num++; } } } return num; } private static bool IsControlledConnectedPlayer(PlayerControllerB player) { if ((Object)(object)player == (Object)null || !player.isPlayerControlled) { return false; } return IsPlayerActuallyConnected(player); } private static bool IsLivingControlledConnectedPlayer(PlayerControllerB player) { return IsControlledConnectedPlayer(player) && !player.isPlayerDead; } private static bool IsPlayerActuallyConnected(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } if (!player.disconnectedMidGame) { return true; } try { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening) { return false; } ulong actualClientId = player.actualClientId; if (actualClientId == singleton.LocalClientId) { return true; } try { foreach (ulong connectedClientsId in singleton.ConnectedClientsIds) { if (connectedClientsId == actualClientId) { return true; } } } catch { } } catch { } return false; } private static bool ShouldRoundStartMovePlayer(PlayerControllerB player) { return IsLivingControlledConnectedPlayer(player); } private static Vector3 GetRoundStartTeleportTarget(PlayerControllerB player, int playerId, int token) { //IL_0023: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null && _roundStartTeleportTargetsByClient.TryGetValue(player.actualClientId, out var value)) { return value; } Vector3 val = (RoundStartTeleportUsesCube() ? GetCubeSafeTeleportPosition() : PickRandomFacilityPlayerSpawnPosition(playerId, token)); if ((Object)(object)player != (Object)null) { _roundStartTeleportTargetsByClient[player.actualClientId] = val; } return val; } private static Vector3 PickRandomFacilityPlayerSpawnPosition(int playerId, int token) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0282: 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) RoundManager instance = RoundManager.Instance; StartOfRound instance2 = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.insideAINodes == null || instance.insideAINodes.Length == 0) { return GetCubeSafeTeleportPosition(); } List list = instance.insideAINodes.Where((GameObject n) => (Object)(object)n != (Object)null && n.activeInHierarchy).ToList(); if (list.Count == 0) { return GetCubeSafeTeleportPosition(); } int seed = (((Object)(object)instance2 != (Object)null) ? instance2.randomMapSeed : Environment.TickCount) ^ (playerId * 397) ^ (token * 7919) ^ 0x51A7F11D; Random rng = new Random(seed); list = list.OrderBy((GameObject _) => rng.Next()).ToList(); Vector3 val = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.elevatorTransform != (Object)null) ? instance2.elevatorTransform.position : Vector3.zero); int num = Mathf.Max(0, (_minDistanceFromShip != null) ? _minDistanceFromShip.Value : 25); List source = BuildPlacementOffsets(1.25f); int num2 = 0; int num3 = Mathf.Max(100, (_cubePlacementMaxCandidates != null) ? _cubePlacementMaxCandidates.Value : 8000); string arg = string.Empty; foreach (GameObject item in list) { foreach (Vector3 item2 in source.OrderBy((Vector3 _) => rng.Next())) { if (num2 >= num3) { break; } num2++; if (!TrySnapPlayerTeleportPositionToFloorStrict(item.transform.position + item2, out var position, out var rejectReason)) { arg = rejectReason; continue; } float num4 = ((val == Vector3.zero) ? ((float)num + 1f) : Vector3.Distance(position, val)); if (num4 < (float)num) { arg = $"too close to ship ({num4:0.0}m < {num}m)"; continue; } if (IsPlayerTeleportPositionSafe(position, out var rejectReason2)) { D($"Picked random facility teleport position for player {playerId} after testing {num2}: {position}"); return position; } arg = rejectReason2; } if (num2 >= num3) { break; } } Vector3 cubeSafeTeleportPosition = GetCubeSafeTeleportPosition(); D($"No safe random facility teleport spot found for player {playerId}. Last reject: {arg}. Falling back to the Extraction Area position {cubeSafeTeleportPosition}"); return cubeSafeTeleportPosition; } private static bool TrySnapPlayerTeleportPositionToFloorStrict(Vector3 basePosition, out Vector3 position, out string rejectReason) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; rejectReason = string.Empty; Vector3 val = basePosition + Vector3.up * 6f; float num = Mathf.Clamp((_cubePlacementMaxFloorDrop != null) ? _cubePlacementMaxFloorDrop.Value : 1.25f, 0.25f, 6f); try { RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, 12f, -1, (QueryTriggerInteraction)1); if (array != null && array.Length != 0) { foreach (RaycastHit item in array.OrderByDescending((RaycastHit h) => ((RaycastHit)(ref h)).point.y)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ((RaycastHit)(ref current)).collider.isTrigger || ((RaycastHit)(ref current)).normal.y < 0.62f) { continue; } if (((RaycastHit)(ref current)).point.y > basePosition.y + 0.85f) { rejectReason = "player snap floor was too far above node"; continue; } float num2 = basePosition.y - ((RaycastHit)(ref current)).point.y; if (num2 > num) { rejectReason = $"player snap would drop into lower floor/pit; drop={num2:0.00}m > {num:0.00}m"; continue; } position = ((RaycastHit)(ref current)).point + Vector3.up * 0.85f; return true; } } } catch (Exception ex) { rejectReason = "player teleport floor snap failed: " + ex.Message; return false; } if (string.IsNullOrEmpty(rejectReason)) { rejectReason = "no strict player floor snap found"; } return false; } private static bool IsPlayerTeleportPositionSafe(Vector3 position, out string rejectReason) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) rejectReason = string.Empty; if (OverlapsDangerousTrigger(position + Vector3.up * 0.85f, new Vector3(0.6f, 1.9f, 0.6f), out rejectReason)) { return false; } Vector3 val = position + Vector3.up * 0.1f; Vector3 val2 = position + Vector3.up * 1.65f; try { Collider[] array = Physics.OverlapCapsule(val, val2, 0.38f, -1, (QueryTriggerInteraction)2); if (array != null) { Collider[] array2 = array; foreach (Collider c in array2) { if (!ShouldIgnorePlayerTeleportOverlap(c)) { rejectReason = "player capsule overlaps " + GetColliderPath(c); return false; } } } } catch (Exception ex) { D("Player teleport capsule check failed: " + ex.Message); } if (!TryFindFloorForPlayerTeleport(position, out var floorHit)) { rejectReason = "no floor under player teleport position"; return false; } if (Mathf.Abs(((RaycastHit)(ref floorHit)).point.y - (position.y - 0.85f)) > 0.45f) { rejectReason = $"floor height mismatch. playerY={position.y:0.00}, floorY={((RaycastHit)(ref floorHit)).point.y:0.00}"; return false; } if (CubePlacementRequiresNavMesh() && IsNavMeshReflectionAvailable() && !TrySampleNavMeshPosition(position, 2.25f, out var _)) { rejectReason = "player teleport position is not near navmesh"; return false; } if (!IsReachableFromInteriorEntrance(position, out rejectReason)) { rejectReason = "player teleport position is not reachable from an interior entrance: " + rejectReason; return false; } if (HasBackfaceGeometryNearPlayerSpot(position, out rejectReason)) { rejectReason = "player teleport position failed backface/out-of-bounds check: " + rejectReason; return false; } return true; } private static bool ShouldIgnorePlayerTeleportOverlap(Collider c) { //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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)c == (Object)null) { return true; } if ((Object)(object)_cubeVisual != (Object)null && (Object)(object)((Component)c).transform != (Object)null && ((Component)c).transform.IsChildOf(_cubeVisual.transform)) { return true; } if (c.isTrigger) { return !IsDangerousColliderName(c); } if ((Object)(object)((Component)c).GetComponentInParent() != (Object)null) { return true; } string text = GetColliderPath(c).ToLowerInvariant(); if (text.Contains("ainode") || text.Contains("navmesh") || text.Contains("scan") || text.Contains("audio") || text.Contains("sound")) { return true; } Bounds bounds = c.bounds; if (((Bounds)(ref bounds)).max.y < ((Component)c).transform.position.y - 50f) { return true; } return false; } private static bool TryFindFloorForPlayerTeleport(Vector3 position, out RaycastHit floorHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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) floorHit = default(RaycastHit); try { RaycastHit[] array = Physics.RaycastAll(position + Vector3.up * 1.25f, Vector3.down, 2.25f, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return false; } foreach (RaycastHit item in array.OrderByDescending((RaycastHit h) => ((RaycastHit)(ref h)).point.y)) { RaycastHit current = item; if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null || ((RaycastHit)(ref current)).collider.isTrigger || (Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent() != (Object)null || ((RaycastHit)(ref current)).normal.y < 0.62f || IsDangerousColliderName(((RaycastHit)(ref current)).collider)) { continue; } floorHit = current; return true; } } catch { return false; } return false; } private static Vector3 GetCubeSafeTeleportPosition() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) if (!_hasCube) { return Vector3.zero; } float num = (_cubeDynamicFootprintReady ? _cubeDynamicFootprintBottomY : (_cubeCenter.y - GetCubeConfiguredHeight() * 0.5f)); return new Vector3(_cubeCenter.x, num + 0.85f, _cubeCenter.z); } private void UpdateFacilityExitInteractionsLocked() { if (_disableFacilityExitInteractions != null && _disableFacilityExitInteractions.Value) { _exitInteractionClampTimer += Time.deltaTime; if (!(_exitInteractionClampTimer < 1f)) { _exitInteractionClampTimer = 0f; ForceFacilityExitInteractionsDisabled(); } } } private static void ForceFacilityExitInteractionsDisabled() { if (_disableFacilityExitInteractions != null && !_disableFacilityExitInteractions.Value) { return; } try { EntranceTeleport[] array = Object.FindObjectsOfType(); if (array == null) { return; } EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { if ((Object)(object)val == (Object)null) { continue; } DisableInteractTriggersOnObject(((Component)val).gameObject); try { if ((Object)(object)val.entrancePoint != (Object)null) { DisableInteractTriggersOnObject(((Component)val.entrancePoint).gameObject); } } catch { } } } catch (Exception ex) { D("Force facility exit interactions disabled failed: " + ex.Message); } } private static void DisableInteractTriggersOnObject(GameObject root) { SetInteractTriggersOnObject(root, interactable: false, blankTips: true); } private static void SetInteractTriggersOnObject(GameObject root, bool interactable, bool blankTips) { if ((Object)(object)root == (Object)null) { return; } try { Component[] componentsInChildren = root.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } Component[] array = componentsInChildren; foreach (Component val in array) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); string a = ((type != null) ? type.Name : string.Empty); if (string.Equals(a, "InteractTrigger", StringComparison.Ordinal)) { TrySetMemberValue(val, "interactable", interactable); if (blankTips) { TrySetMemberValue(val, "hoverTip", string.Empty); TrySetMemberValue(val, "disabledHoverTip", string.Empty); TrySetMemberValue(val, "holdTip", string.Empty); } } } } catch { } } private void UpdateShipDoorsLockedClosed() { if (_keepShipDoorsClosed == null || !_keepShipDoorsClosed.Value) { RestoreVanillaShipDoorVisualAndAudio(); SetClosedShipDoorOverlayActive(active: false); } else if (IsAtTheCompany()) { RestoreVanillaShipDoorVisualAndAudio(); SetClosedShipDoorOverlayActive(active: false); SetShipDoorButtonPromptsEnabled(enabled: true); } else { ForceShipDoorsClosedNow(); } } private static void ForceShipDoorsClosedNow() { if ((_keepShipDoorsClosed != null && !_keepShipDoorsClosed.Value) || IsAtTheCompany()) { return; } try { EnsureClosedShipDoorOverlay(); HideAndMuteVanillaShipDoorVisuals(); SetShipDoorButtonPromptsEnabled(enabled: false); } catch (Exception ex) { D("Ship door visual lock failed: " + ex.Message); } } private static bool IsAtTheCompany() { try { SelectableLevel val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.currentLevel : null); if ((Object)(object)val == (Object)null) { return false; } string empty = string.Empty; empty = empty + (GetMemberValue(val, "PlanetName") ?? string.Empty) + " "; empty = empty + (GetMemberValue(val, "planetName") ?? string.Empty) + " "; empty = empty + (GetMemberValue(val, "sceneName") ?? string.Empty) + " "; empty = empty + (GetMemberValue(val, "levelName") ?? string.Empty) + " "; empty = empty + (GetMemberValue(val, "LevelName") ?? string.Empty) + " "; if (empty.IndexOf("company", StringComparison.OrdinalIgnoreCase) >= 0 || empty.IndexOf("gordion", StringComparison.OrdinalIgnoreCase) >= 0 || empty.IndexOf("companybuilding", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } int memberValue = GetMemberValue(val, "levelID"); return memberValue == 71; } catch { return false; } } private static void SetClosedShipDoorOverlayActive(bool active) { try { if ((Object)(object)_shipDoorClosedOverlay != (Object)null) { _shipDoorClosedOverlay.SetActive(active); } if ((Object)(object)_shipDoorFallbackPanel != (Object)null) { _shipDoorFallbackPanel.SetActive(active); } } catch { } } private static void HideAndMuteVanillaShipDoorVisuals() { Component val = FindShipDoorAnimatorComponent(); if ((Object)(object)val == (Object)null || (Object)(object)val.gameObject == (Object)null) { return; } GameObject gameObject = val.gameObject; if (((Object)gameObject).name != null && ((Object)gameObject).name.StartsWith("Extraction_", StringComparison.OrdinalIgnoreCase)) { return; } Renderer[] componentsInChildren = gameObject.GetComponentsInChildren(true); if (componentsInChildren != null) { Renderer[] array = componentsInChildren; foreach (Renderer val2 in array) { if (!((Object)(object)val2 == (Object)null) && !(val2 is ParticleSystemRenderer)) { if (!_shipDoorOriginalRendererStates.ContainsKey(val2)) { _shipDoorOriginalRendererStates[val2] = val2.enabled; } val2.enabled = false; } } } Component[] componentsInChildren2 = gameObject.GetComponentsInChildren(true); if (componentsInChildren2 == null) { return; } Component[] array2 = componentsInChildren2; foreach (Component val3 in array2) { if (!((Object)(object)val3 == (Object)null) && !(((object)val3).GetType().Name != "AudioSource")) { if (!_shipDoorOriginalAudioStates.ContainsKey(val3)) { bool memberValue = GetMemberValue(val3, "mute"); float memberValue2 = GetMemberValue(val3, "volume"); _shipDoorOriginalAudioStates[val3] = new ShipDoorAudioState(memberValue, memberValue2); } TrySetMemberValue(val3, "mute", true); TrySetMemberValue(val3, "volume", 0f); } } } private static void RestoreVanillaShipDoorVisualAndAudio() { if (_shipDoorOriginalRendererStates.Count > 0) { foreach (KeyValuePair item in _shipDoorOriginalRendererStates.ToList()) { if ((Object)(object)item.Key != (Object)null) { item.Key.enabled = item.Value; } } _shipDoorOriginalRendererStates.Clear(); } if (_shipDoorOriginalAudioStates.Count <= 0) { return; } foreach (KeyValuePair item2 in _shipDoorOriginalAudioStates.ToList()) { if ((Object)(object)item2.Key != (Object)null) { TrySetMemberValue(item2.Key, "mute", item2.Value.Mute); TrySetMemberValue(item2.Key, "volume", item2.Value.Volume); } } _shipDoorOriginalAudioStates.Clear(); } private static void EnsureClosedShipDoorOverlay() { //IL_005e: 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_0097: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_shipDoorClosedOverlay != (Object)null) { _shipDoorClosedOverlay.SetActive(true); UpdateFallbackShipDoorPanel(active: false); return; } Component val = FindShipDoorAnimatorComponent(); if ((Object)(object)val != (Object)null && (Object)(object)val.gameObject != (Object)null) { GameObject val2 = null; try { val2 = Object.Instantiate(val.gameObject, val.transform.position, val.transform.rotation, val.transform.parent); ((Object)val2).name = "Extraction_ClosedShipDoorOverlay"; val2.transform.localScale = val.transform.localScale; StripDoorOverlayClone(val2); val2.SetActive(true); _shipDoorClosedOverlay = val2; UpdateFallbackShipDoorPanel(active: false); D("Created closed ship door visual overlay. Vanilla door coroutines are not blocked."); return; } catch (Exception ex) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } D("Failed to clone closed ship door overlay: " + ex.Message); } } if (!_shipDoorOverlaySourceMissingLogged) { _shipDoorOverlaySourceMissingLogged = true; D("Could not find ship door animator for overlay clone. Using fallback closed-door panel."); } UpdateFallbackShipDoorPanel(active: true); } private static Component FindShipDoorAnimatorComponent() { try { StartOfRound instance = StartOfRound.Instance; Component memberValue = GetMemberValue(instance, "shipDoorsAnimator"); if ((Object)(object)memberValue != (Object)null) { return memberValue; } HangarShipDoor[] array = Object.FindObjectsOfType(); if (array != null) { HangarShipDoor[] array2 = array; foreach (HangarShipDoor val in array2) { if (!((Object)(object)val == (Object)null)) { memberValue = GetMemberValue(val, "shipDoorsAnimator"); if ((Object)(object)memberValue != (Object)null) { return memberValue; } } } } } catch { } return null; } private static void StripDoorOverlayClone(GameObject clone) { if ((Object)(object)clone == (Object)null) { return; } try { HideShipDoorOverlayButtonPanels(clone); Component[] componentsInChildren = clone.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } Component[] array = componentsInChildren; foreach (Component val in array) { if (!((Object)(object)val == (Object)null) && !(val is Transform) && !(val is Renderer) && !(val is MeshFilter) && !(val is Collider)) { Object.Destroy((Object)(object)val); } } } catch { } } private static void HideShipDoorOverlayButtonPanels(GameObject clone) { if ((Object)(object)clone == (Object)null) { return; } try { Transform[] componentsInChildren = clone.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } Transform[] array = componentsInChildren; foreach (Transform val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)clone.transform) { continue; } string path = GetHierarchyPath(val).ToLowerInvariant(); if (!IsShipDoorOverlayButtonPanelPath(path)) { continue; } Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(true); if (componentsInChildren2 != null) { Renderer[] array2 = componentsInChildren2; foreach (Renderer val2 in array2) { if ((Object)(object)val2 != (Object)null) { val2.enabled = false; } } } Collider[] componentsInChildren3 = ((Component)val).GetComponentsInChildren(true); if (componentsInChildren3 == null) { continue; } Collider[] array3 = componentsInChildren3; foreach (Collider val3 in array3) { if ((Object)(object)val3 != (Object)null) { val3.enabled = false; } } } } catch { } } private static bool IsShipDoorOverlayButtonPanelPath(string path) { if (string.IsNullOrEmpty(path)) { return false; } return path.Contains("button") || path.Contains("control") || path.Contains("panel") || path.Contains("switch") || path.Contains("interact") || path.Contains("terminal") || path.Contains("lever"); } private static string GetHierarchyPath(Transform t) { if ((Object)(object)t == (Object)null) { return string.Empty; } try { List list = new List(); Transform val = t; while ((Object)(object)val != (Object)null) { list.Add(((Object)val).name ?? string.Empty); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } catch { return ((Object)t).name ?? string.Empty; } } private static void SetShipDoorButtonPromptsEnabled(bool enabled) { try { HangarShipDoor[] array = Object.FindObjectsOfType(); if (array == null) { return; } HangarShipDoor[] array2 = array; foreach (HangarShipDoor val in array2) { if (!((Object)(object)val == (Object)null)) { TrySetMemberValue(val, "buttonsEnabled", enabled); SetInteractTriggersOnObject(((Component)val).gameObject, enabled, blankTips: false); } } } catch { } } private static void DisableShipDoorButtonPromptsOnly() { SetShipDoorButtonPromptsEnabled(enabled: false); } private static void UpdateFallbackShipDoorPanel(bool active) { //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!active) { if ((Object)(object)_shipDoorFallbackPanel != (Object)null) { _shipDoorFallbackPanel.SetActive(false); } return; } Transform val = FindShipDoorPanelAnchor(); if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)_shipDoorFallbackPanel == (Object)null) { _shipDoorFallbackPanel = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)_shipDoorFallbackPanel).name = "Extraction_ClosedShipDoorFallbackPanel"; Object.DontDestroyOnLoad((Object)(object)_shipDoorFallbackPanel); if ((Object)(object)_shipDoorFallbackMaterial == (Object)null) { Shader val2 = Shader.Find("HDRP/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Sprites/Default"); _shipDoorFallbackMaterial = new Material(val2); _shipDoorFallbackMaterial.color = new Color(0.08f, 0.08f, 0.08f, 1f); } Renderer component = _shipDoorFallbackPanel.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)_shipDoorFallbackMaterial != (Object)null) { component.material = _shipDoorFallbackMaterial; } } _shipDoorFallbackPanel.SetActive(true); Vector3 forward = val.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.01f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); Vector3 position = val.position + Vector3.up * 2f; _shipDoorFallbackPanel.transform.position = position; _shipDoorFallbackPanel.transform.rotation = Quaternion.LookRotation(forward, Vector3.up); _shipDoorFallbackPanel.transform.localScale = new Vector3(7.5f, 4.5f, 0.55f); } private static Transform FindShipDoorPanelAnchor() { try { StartOfRound instance = StartOfRound.Instance; Transform transformFromMember = GetTransformFromMember(instance, "shipDoorNode"); if ((Object)(object)transformFromMember != (Object)null) { return transformFromMember; } transformFromMember = GetTransformFromMember(instance, "outsideDoorPosition"); if ((Object)(object)transformFromMember != (Object)null) { return transformFromMember; } HangarShipDoor[] array = Object.FindObjectsOfType(); if (array != null) { HangarShipDoor[] array2 = array; foreach (HangarShipDoor val in array2) { if (!((Object)(object)val == (Object)null)) { transformFromMember = GetTransformFromMember(val, "outsideDoorPoint"); if ((Object)(object)transformFromMember != (Object)null) { return transformFromMember; } return ((Component)val).transform; } } } } catch { } return null; } private static Transform GetTransformFromMember(object obj, string name) { object memberValue = GetMemberValue(obj, name); Transform val = (Transform)((memberValue is Transform) ? memberValue : null); if (val != null) { return val; } GameObject val2 = (GameObject)((memberValue is GameObject) ? memberValue : null); if (val2 != null) { return val2.transform; } Component val3 = (Component)((memberValue is Component) ? memberValue : null); if (val3 != null) { return val3.transform; } return null; } private static void ForceAnimatorDoorClosed(Component animator) { if ((Object)(object)animator == (Object)null) { return; } try { object memberValue = GetMemberValue(animator, "parameters"); if (memberValue is Array array) { foreach (object item in array) { if (item == null) { continue; } object memberValue2 = GetMemberValue(item, "type"); string a = ((memberValue2 != null) ? memberValue2.ToString() : string.Empty); if (string.Equals(a, "Bool", StringComparison.OrdinalIgnoreCase)) { string memberValue3 = GetMemberValue(item, "name"); if (!string.IsNullOrEmpty(memberValue3)) { ApplyDoorAnimatorBool(animator, memberValue3); } } } } string[] array2 = new string[16] { "open", "Open", "opened", "Opened", "isOpen", "IsOpen", "doorOpen", "DoorOpen", "doorsOpen", "DoorsOpen", "closed", "Closed", "isClosed", "IsClosed", "doorClosed", "DoorClosed" }; string[] array3 = array2; foreach (string name in array3) { ApplyDoorAnimatorBool(animator, name); } } catch { } } private static void ApplyDoorAnimatorBool(Component animator, string name) { if ((Object)(object)animator == (Object)null || string.IsNullOrEmpty(name)) { return; } string text = name.ToLowerInvariant(); bool flag; if (text.Contains("open")) { flag = false; } else { if (!text.Contains("closed") && !text.Contains("close")) { return; } flag = true; } TryInvokeMethodFlexible(animator, "SetBool", name, flag); } private static T GetMemberValue(object obj, string name) { if (obj == null || string.IsNullOrEmpty(name)) { return default(T); } try { Type type = obj.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.GetValue(obj) is T result) { return result; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { object value = property.GetValue(obj, null); if (value is T) { return (T)value; } } } catch { } return default(T); } private static bool TrySetMemberValue(object obj, string name, object value) { if (obj == null || string.IsNullOrEmpty(name)) { return false; } try { Type type = obj.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value2 = ConvertValueForMember(value, field.FieldType); field.SetValue(obj, value2); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite && property.GetIndexParameters().Length == 0) { object value3 = ConvertValueForMember(value, property.PropertyType); property.SetValue(obj, value3, null); return true; } } catch { } return false; } private static object ConvertValueForMember(object value, Type targetType) { if (targetType == null) { return value; } if (value == null) { return null; } if (targetType.IsInstanceOfType(value)) { return value; } try { return Convert.ChangeType(value, targetType); } catch { return value; } } [IteratorStateMachine(typeof(d__478))] private static IEnumerator EmptyCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__478(0); } [IteratorStateMachine(typeof(d__479))] private static IEnumerator KeepShipDoorsClosedWhileRunning(IEnumerator original, string source) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__479(0) { original = original, source = source }; } private static void ProcessTakeoffOnHost() { if (_processedThisTakeoff) { return; } _processedThisTakeoff = true; StartOfRound instance = StartOfRound.Instance; if (!((Object)(object)instance == (Object)null)) { D("Host processing Extraction Area takeoff logic."); if (!LivingRuleAllowsExtraction()) { D("Extraction ignored because living player rule failed. No Extraction Area scrap counted."); return; } ExtractPlayersInCubeOnHost(); CountAndRemoveScrapInCubeOnHost(); } } private static bool LivingRuleAllowsExtraction() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (instance.allPlayersDead) { D("StartOfRound.allPlayersDead is true."); return false; } PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; if (allPlayerScripts == null) { return false; } List list = allPlayerScripts.Where(IsControlledConnectedPlayer).ToList(); if (list.Count == 0) { return false; } int num = list.Count((PlayerControllerB p) => !p.isPlayerDead); D($"Controlled players: {list.Count}. Alive: {num}. Require all alive: {_requireAllControlledPlayersAlive.Value}"); if (_requireAllControlledPlayersAlive.Value) { return num == list.Count; } return num > 0; } private static void ExtractPlayersInCubeOnHost() { //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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if (instance?.allPlayerScripts == null) { return; } Vector3 shipSafePosition = GetShipSafePosition(); int num = 0; for (int i = 0; i < instance.allPlayerScripts.Length; i++) { PlayerControllerB val = instance.allPlayerScripts[i]; if (IsLivingControlledConnectedPlayer(val)) { if (!PlayerIntersectsCube(val)) { D($"Player {i} not in Extraction Area. playerPos={((Component)val).transform.position}, cubeBounds={CurrentCubeBounds()}"); continue; } num++; D($"Extracting player {i} / client {val.actualClientId} through cube."); val.isInsideFactory = false; val.isInElevator = true; val.isInHangarShipRoom = true; SendTeleportToPlayer(i, val.actualClientId, shipSafePosition, toShip: true); } } D($"Host extracted {num} player(s) through Extraction Area."); } private static Vector3 GetShipSafePosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00b8: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return Vector3.zero; } if ((Object)(object)instance.middleOfShipNode != (Object)null) { return instance.middleOfShipNode.position + Vector3.up * 0.25f; } if (instance.playerSpawnPositions != null && instance.playerSpawnPositions.Length != 0 && (Object)(object)instance.playerSpawnPositions[0] != (Object)null) { return instance.playerSpawnPositions[0].position; } if ((Object)(object)instance.elevatorTransform != (Object)null) { return instance.elevatorTransform.position + Vector3.up * 1f; } return Vector3.zero; } private static void CountAndRemoveScrapInCubeOnHost() { //IL_0151: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube) { return; } GrabbableObject[] array = Object.FindObjectsOfType(); List list = new List(); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && val.itemProperties.isScrap && !val.isHeld && !val.isPocketed && !((Object)(object)val.playerHeldBy != (Object)null) && ScrapIntersectsCube(val)) { list.Add(val); } } int num = list.Sum((GrabbableObject s) => Mathf.Max(0, s.scrapValue)); int num2 = num; if (_applyCompanyBuyingRate.Value && (Object)(object)StartOfRound.Instance != (Object)null) { num2 = Mathf.RoundToInt((float)num * Mathf.Clamp01(StartOfRound.Instance.companyBuyingRate)); } D($"Extraction Area scrap found: {list.Count}. Raw value: {num}. Quota value pending: {num2}. Cube bounds: {CurrentCubeBounds()}"); if (num2 > 0) { StorePendingQuotaValue(num2, num, list.Count); } _currentCubeScrapRawValue = num; _currentCubeScrapCount = list.Count; foreach (GrabbableObject item in list) { DespawnExtractedScrap(item); } } private static void StorePendingQuotaValue(int quotaValue, int rawValue, int itemCount) { _pendingQuotaValue += quotaValue; _pendingRawValue += rawValue; _pendingItemCount += itemCount; _pendingQuotaApplied = false; D($"Stored pending Extraction Area payout. pendingQuota={_pendingQuotaValue}, pendingRaw={_pendingRawValue}, pendingItems={_pendingItemCount}"); } internal static void ApplyPendingQuotaValueOnHost(string reason) { if (IsServer() && !_pendingQuotaApplied && _pendingQuotaValue > 0) { D($"Applying pending Extraction Area payout from {reason}. quota={_pendingQuotaValue}, raw={_pendingRawValue}, items={_pendingItemCount}"); _pendingQuotaApplied = true; ApplyQuotaValueOnHost(_pendingQuotaValue, _pendingRawValue, _pendingItemCount); } } private static void ApplyQuotaValueOnHost(int quotaValue, int rawValue, int itemCount) { TimeOfDay instance = TimeOfDay.Instance; StartOfRound instance2 = StartOfRound.Instance; RoundManager instance3 = RoundManager.Instance; if ((Object)(object)instance != (Object)null) { instance.quotaFulfilled += quotaValue; } if ((Object)(object)instance2 != (Object)null) { instance2.scrapCollectedLastRound += quotaValue; if (instance2.gameStats != null) { EndOfGameStats gameStats = instance2.gameStats; gameStats.scrapValueCollected += quotaValue; } } if ((Object)(object)instance3 != (Object)null) { instance3.scrapCollectedInLevel += quotaValue; instance3.valueOfFoundScrapItems += quotaValue; } int num = (((Object)(object)instance != (Object)null) ? instance.quotaFulfilled : quotaValue); int num2 = (((Object)(object)instance != (Object)null) ? instance.profitQuota : 0); int num3 = ApplyTerminalCreditsOnHost(quotaValue); D($"Quota updated. quotaFulfilled={num}, profitQuota={num2}, rawValue={rawValue}, items={itemCount}, terminalCreditsAfter={num3}"); SyncQuotaToAllClients(num, num2, quotaValue, itemCount, num3); } private static int ApplyTerminalCreditsOnHost(int amountAdded) { if (amountAdded <= 0) { return -1; } try { Terminal val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { D("Could not find Terminal. Cube payout changed quota but could not add group credits."); return -1; } int groupCredits = val.groupCredits; val.groupCredits = Mathf.Max(0, val.groupCredits + amountAdded); D($"Terminal credits updated like sold scrap. before={groupCredits}, added={amountAdded}, after={val.groupCredits}"); TryInvokeTerminalCreditsRpc(val); return val.groupCredits; } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed to add terminal group credits: {arg}"); return -1; } } private static void TryInvokeTerminalCreditsRpc(Terminal terminal) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)terminal == (Object)null) { return; } try { MethodInfo method = typeof(Terminal).GetMethod("SyncGroupCreditsClientRpc", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { method = typeof(Terminal).GetMethod("SyncGroupCreditsServerRpc", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (method == null) { return; } ParameterInfo[] parameters = method.GetParameters(); object[] parameters2; if (parameters.Length == 2) { parameters2 = new object[2] { terminal.groupCredits, terminal.numberOfItemsInDropship }; } else { if (parameters.Length != 3) { return; } parameters2 = new object[3] { terminal.groupCredits, terminal.numberOfItemsInDropship, (object)default(ClientRpcParams) }; } method.Invoke(terminal, parameters2); D("Invoked Terminal." + method.Name + " after Extraction Area payout."); } catch (Exception ex) { D("Terminal credit RPC reflection failed. Local field and Extraction sync will still update credits. " + ex.GetType().Name + ": " + ex.Message); } } private static void ApplyTerminalCreditsLocal(int terminalCreditsAfter) { if (terminalCreditsAfter < 0) { return; } try { Terminal val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { val.groupCredits = terminalCreditsAfter; } } catch { } } private static void DespawnExtractedScrap(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return; } try { D($"Removing extracted scrap: {((Object)item).name}, value {item.scrapValue}"); NetworkObject component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null && component.IsSpawned) { component.Despawn(true); } else { Object.Destroy((Object)(object)((Component)item).gameObject); } } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed to despawn extracted scrap {((Object)item).name}: {arg}"); } } private static void SyncQuotaToAllClients(int quotaFulfilled, int profitQuota, int amountAdded, int itemCount, int terminalCreditsAfter) { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return; } foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds) { if (connectedClientsId == NetworkManager.Singleton.LocalClientId) { ApplyQuotaSyncLocal(quotaFulfilled, profitQuota, amountAdded, itemCount, terminalCreditsAfter); } else { SendQuotaSync(connectedClientsId, quotaFulfilled, profitQuota, amountAdded, itemCount, terminalCreditsAfter); } } } private static void ApplyQuotaSyncLocal(int quotaFulfilled, int profitQuota, int amountAdded, int itemCount, int terminalCreditsAfter) { if ((Object)(object)TimeOfDay.Instance != (Object)null) { TimeOfDay.Instance.quotaFulfilled = quotaFulfilled; } ApplyTerminalCreditsLocal(terminalCreditsAfter); if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.SetQuota(quotaFulfilled, profitQuota); if (amountAdded > 0) { HUDManager.Instance.DisplayTip("Extraction", $"Cube extracted {itemCount} scrap item(s) for ${amountAdded} quota value.", false, false, "LC_ExtractionQuota"); } } } private static void SendQuotaSync(ulong clientId, int quotaFulfilled, int profitQuota, int amountAdded, int itemCount, int terminalCreditsAfter) { //IL_0014: 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_0027: 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_003a: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(20, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref quotaFulfilled, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref profitQuota, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref amountAdded, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref itemCount, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref terminalCreditsAfter, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_QuotaSync_v1", clientId, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed sending quota sync to client {clientId}: {arg}"); } } private static void OnQuotaSyncMessage(ulong senderClientId, FastBufferReader reader) { //IL_0037: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0079: 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_008d: Unknown result type (might be due to invalid IL or missing references) if (!MessageFromServer(senderClientId)) { D($"[{NetRoleDebugName()}] Rejected quota sync from non-server sender={senderClientId}."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); int num2 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num2, default(ForPrimitives)); int num3 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num3, default(ForPrimitives)); int num4 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num4, default(ForPrimitives)); int num5 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num5, default(ForPrimitives)); D($"Received quota sync. quotaFulfilled={num}, profitQuota={num2}, amountAdded={num3}, itemCount={num4}, terminalCreditsAfter={num5}"); ApplyQuotaSyncLocal(num, num2, num3, num4, num5); } private static List GetDynamicFootprintCellsForSync() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (!_cubeDynamicFootprintReady || _cubeDynamicFootprintCells.Count == 0) { return list; } foreach (int cubeDynamicFootprintCell in _cubeDynamicFootprintCells) { int num = cubeDynamicFootprintCell / 1000 - 128; int num2 = cubeDynamicFootprintCell % 1000 - 128; list.Add(new Vector2Int(num, num2)); } list.Sort(delegate(Vector2Int a, Vector2Int b) { int num3 = ((Vector2Int)(ref a)).y.CompareTo(((Vector2Int)(ref b)).y); return (num3 != 0) ? num3 : ((Vector2Int)(ref a)).x.CompareTo(((Vector2Int)(ref b)).x); }); return list; } private static int CalculateHostCellListHash(List cells) { //IL_0068: 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_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) if (cells == null || cells.Count == 0) { return 0; } List list = new List(cells); list.Sort(delegate(Vector2Int a, Vector2Int b) { int num4 = ((Vector2Int)(ref a)).y.CompareTo(((Vector2Int)(ref b)).y); return (num4 != 0) ? num4 : ((Vector2Int)(ref a)).x.CompareTo(((Vector2Int)(ref b)).x); }); int num = -2128831035; num = (num ^ list.Count) * 16777619; for (int i = 0; i < list.Count; i++) { int num2 = num; Vector2Int val = list[i]; num = (num2 ^ ((Vector2Int)(ref val)).x) * 16777619; int num3 = num; val = list[i]; num = (num3 ^ ((Vector2Int)(ref val)).y) * 16777619; } return num; } private static void ApplyHostDynamicFootprintSync(Vector3 center, float horizontalSize, float configuredHeight, float cellSize, float bottomY, float footprintHeight, List cells) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) int num = CalculateHostCellListHash(cells); D($"[{NetRoleDebugName()}] ApplyHostDynamicFootprintSync called. center={V3(center)}, horizontal={horizontalSize:0.00}, configuredHeight={configuredHeight:0.00}, cellSize={cellSize:0.00}, bottomY={bottomY:0.00}, footprintHeight={footprintHeight:0.00}, cells={cells?.Count ?? (-1)}, incomingHash={num}. BEFORE: {CubeStateDebugLine()}"); _cubeDynamicFootprintAuthoritativeFromHost = false; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _cubeDynamicFootprintCells.Clear(); _cubeDynamicFootprintReady = false; if (cells == null || cells.Count == 0) { D("[" + NetRoleDebugName() + "] ApplyHostDynamicFootprintSync aborted because host sent no cells."); return; } _cubeDynamicFootprintCellSize = Mathf.Clamp(cellSize, 0.1f, 2.5f); _cubeDynamicFootprintBottomY = bottomY; _cubeDynamicFootprintHorizontalSize = Mathf.Max(0.5f, horizontalSize); _cubeDynamicFootprintHeight = Mathf.Max(0.5f, footprintHeight); for (int i = 0; i < cells.Count; i++) { HashSet cubeDynamicFootprintCells = _cubeDynamicFootprintCells; Vector2Int val = cells[i]; int x = ((Vector2Int)(ref val)).x; val = cells[i]; cubeDynamicFootprintCells.Add(CubeCellKey(x, ((Vector2Int)(ref val)).y)); } CalculateDynamicAreaFootprintBounds(center, _cubeDynamicFootprintHorizontalSize, _cubeDynamicFootprintHeight); _cubeDynamicFootprintReady = true; _cubeDynamicFootprintAuthoritativeFromHost = true; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _cubeDynamicFootprintLocked = true; _cubeDynamicFootprintLockedCenter = center; _cubeDynamicFootprintLockedSize = _cubeDynamicFootprintHorizontalSize; _cubeDynamicFootprintLockedHeight = Mathf.Max(0.5f, configuredHeight); _cubeDynamicFootprintLockedCellSize = _cubeDynamicFootprintCellSize; InvalidateDynamicAreaMeshes(); D($"Applied host dynamic footprint sync: cells={_cubeDynamicFootprintCells.Count}, cell={_cubeDynamicFootprintCellSize:0.00}m, roofHeight={_cubeDynamicFootprintHeight:0.00}m/{configuredHeight:0.00}m, cellHash={GetDynamicFootprintCellHash()}, bounds={_cubeDynamicFootprintBounds}"); } private static void QueueClientCubeVisualRefresh(Vector3 center, int acceptedSyncSerial, int cubeRoundId) { //IL_00a4: 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) if (IsServer() || (Object)(object)Instance == (Object)null || _clientCubeVisualRefreshRunning) { if (DebugOptionEnabled(_debugCubeSyncPayloads)) { D($"[{NetRoleDebugName()}] QueueClientCubeVisualRefresh skipped. isServer={IsServer()}, instanceNull={(Object)(object)Instance == (Object)null}, running={_clientCubeVisualRefreshRunning}, capturedSerial={acceptedSyncSerial}, capturedRound={cubeRoundId}"); } } else { D($"[{NetRoleDebugName()}] QueueClientCubeVisualRefresh starting. center={V3(center)}, capturedSerial={acceptedSyncSerial}, capturedRound={cubeRoundId}, currentRound={_currentCubeNetworkRoundId}, {CubeStateDebugLine()}"); ((MonoBehaviour)Instance).StartCoroutine(ClientCubeVisualRefreshRoutine(center, acceptedSyncSerial, cubeRoundId)); } } [IteratorStateMachine(typeof(d__500))] private static IEnumerator ClientCubeVisualRefreshRoutine(Vector3 center, int acceptedSyncSerial, int cubeRoundId) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__500(0) { center = center, acceptedSyncSerial = acceptedSyncSerial, cubeRoundId = cubeRoundId }; } private static void BroadcastCubePosition() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube || (Object)(object)NetworkManager.Singleton == (Object)null) { if (DebugOptionEnabled(_debugCubeSyncPayloads)) { D($"[{NetRoleDebugName()}] BroadcastCubePosition skipped. hasCube={_hasCube}, networkNull={(Object)(object)NetworkManager.Singleton == (Object)null}"); } return; } if (DebugOptionEnabled(_debugCubeSyncPayloads)) { D($"[{NetRoleDebugName()}] BroadcastCubePosition to {NetworkManager.Singleton.ConnectedClientsIds.Count} connected clients. {CubeStateDebugLine()}"); } foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds) { if (connectedClientsId == NetworkManager.Singleton.LocalClientId) { CreateOrMoveCubeVisual(_cubeCenter); } else { SendCubePosition(connectedClientsId); } } } private static NetworkDelivery GetCubeSyncNetworkDelivery() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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) try { if (Enum.TryParse("ReliableFragmentedSequenced", out NetworkDelivery result)) { return result; } } catch { } return (NetworkDelivery)3; } private static void SendCubePosition(ulong clientId) { //IL_0025: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0119: 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_012d: 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_0144: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: 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_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) try { float cubeHorizontalSize = GetCubeHorizontalSize(); float cubeConfiguredHeight = GetCubeConfiguredHeight(); bool flag = CubeDynamicFootprintEnabled() && _authoritativeCubeFootprintReadyForClients; if (flag) { EnsureDynamicAreaFootprintBuilt(_cubeCenter, cubeHorizontalSize, cubeConfiguredHeight); } List list = (flag ? GetDynamicFootprintCellsForSync() : new List()); bool flag2 = flag && _cubeDynamicFootprintReady && list.Count > 0; bool flag3 = CubeDynamicFootprintEnabled(); bool authoritativeCubeFootprintReadyForClients = _authoritativeCubeFootprintReadyForClients; int num = (flag2 ? GetDynamicFootprintCellHash() : 0); int num2 = ((_currentCubeNetworkRoundId > 0) ? _currentCubeNetworkRoundId : _hostCubeNetworkRoundId); int num3 = 320 + Mathf.Clamp(list.Count, 0, 2048) * 4 * 2; NetworkDelivery cubeSyncNetworkDelivery = GetCubeSyncNetworkDelivery(); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num3, (Allocator)2, -1); try { bool flag4 = false; ((FastBufferWriter)(ref val)).WriteValueSafe(ref _cubeCenter.x, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _cubeCenter.y, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _cubeCenter.z, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref cubeHorizontalSize, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref flag4, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _roundStartCubeTeleportToken, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref cubeConfiguredHeight, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref flag2, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _cubeDynamicFootprintCellSize, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _cubeDynamicFootprintBottomY, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref _cubeDynamicFootprintHeight, default(ForPrimitives)); int count = list.Count; ((FastBufferWriter)(ref val)).WriteValueSafe(ref count, default(ForPrimitives)); for (int i = 0; i < list.Count; i++) { Vector2Int val2 = list[i]; count = ((Vector2Int)(ref val2)).x; ((FastBufferWriter)(ref val)).WriteValueSafe(ref count, default(ForPrimitives)); val2 = list[i]; count = ((Vector2Int)(ref val2)).y; ((FastBufferWriter)(ref val)).WriteValueSafe(ref count, default(ForPrimitives)); } ((FastBufferWriter)(ref val)).WriteValueSafe(ref num2, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref flag3, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref authoritativeCubeFootprintReadyForClients, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref num, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_CubeSync_v1", clientId, val, cubeSyncNetworkDelivery); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } _debugCubeSyncSendCount++; D($"Sent cube sync #{_debugCubeSyncSendCount} to client {clientId} delivery={cubeSyncNetworkDelivery}: center={V3(_cubeCenter)}, horizontal={cubeHorizontalSize:0.00}, height={cubeConfiguredHeight:0.00}, dynamicFootprint={flag2}, cells={list.Count}, cellHash={num}, hostDynamicEnabled={flag3}, authoritativeReady={authoritativeCubeFootprintReadyForClients}, cubeRoundId={num2}, roundStartTeleportActive=False, token={_roundStartCubeTeleportToken}, payloadCapacity={num3}, maySendAuthoritative={flag}, dynamicReady={_cubeDynamicFootprintReady}, localCellHash={((_cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) ? GetDynamicFootprintCellHash() : 0)}"); } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed sending cube sync to client {clientId}: {arg}"); } } private static void OnCubeSyncMessage(ulong senderClientId, FastBufferReader reader) { //IL_00a5: 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_00b9: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_064f: Unknown result type (might be due to invalid IL or missing references) if (!MessageFromServer(senderClientId)) { _debugCubeSyncRejectCount++; D($"[{NetRoleDebugName()}] Rejected cube sync from non-server sender={senderClientId}. rejectCount={_debugCubeSyncRejectCount}"); return; } _debugCubeSyncReceiveCount++; if (DebugOptionEnabled(_debugCubeSyncPayloads)) { D($"[{NetRoleDebugName()}] Cube sync message #{_debugCubeSyncReceiveCount} received from sender={senderClientId}. Pre-read state: {CubeStateDebugLine()}"); } float num = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); float num2 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num2, default(ForPrimitives)); float num3 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num3, default(ForPrimitives)); float num4 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num4, default(ForPrimitives)); bool flag = false; int num5 = 0; float num6 = Mathf.Max(1.5f, num4); bool flag2 = false; float cellSize = 0.75f; float bottomY = 0f; float footprintHeight = num6; List list = new List(); int num7 = 0; bool flag3 = false; bool flag4 = false; int num8 = 0; try { ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num5, default(ForPrimitives)); try { ((FastBufferReader)(ref reader)).ReadValueSafe(ref num6, default(ForPrimitives)); } catch { num6 = Mathf.Max(1.5f, num4); } try { ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag2, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref cellSize, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref bottomY, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref footprintHeight, default(ForPrimitives)); int num9 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num9, default(ForPrimitives)); num9 = Mathf.Clamp(num9, 0, 4096); int num10 = default(int); int num11 = default(int); for (int i = 0; i < num9; i++) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref num10, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num11, default(ForPrimitives)); list.Add(new Vector2Int(num10, num11)); } try { ((FastBufferReader)(ref reader)).ReadValueSafe(ref num7, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag3, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag4, default(ForPrimitives)); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num8, default(ForPrimitives)); } catch (Exception ex) { num7 = 0; flag3 = false; flag4 = flag2; num8 = 0; D("[" + NetRoleDebugName() + "] Cube sync v3 round guard payload missing or failed to read. Treating as legacy. error=" + ex.Message); } } catch (Exception ex2) { flag2 = false; list.Clear(); D("[" + NetRoleDebugName() + "] Cube sync v2 dynamic footprint payload missing or failed to read. Treating as box-only/legacy. error=" + ex2.Message); } } catch (Exception ex3) { D("[" + NetRoleDebugName() + "] Cube sync old payload after center/size only. error=" + ex3.Message); } if (num7 > 0) { bool flag5 = !_cubeNetworkRoundActive && num7 <= _lastAcceptedCubeNetworkRoundId; bool flag6 = _cubeNetworkRoundActive && num7 < _lastAcceptedCubeNetworkRoundId; if (flag5 || flag6) { _debugCubeSyncRejectCount++; D($"Ignored stale cube sync from old day. incomingRoundId={num7}, lastAcceptedRoundId={_lastAcceptedCubeNetworkRoundId}, currentRoundId={_currentCubeNetworkRoundId}, active={_cubeNetworkRoundActive}, staleClosed={flag5}, olderCurrent={flag6}, rejectCount={_debugCubeSyncRejectCount}"); DebugLogStateSnapshot("stale cube sync rejected", force: true); return; } if (num7 > _lastAcceptedCubeNetworkRoundId) { _lastAcceptedCubeNetworkRoundId = num7; } _currentCubeNetworkRoundId = num7; _cubeNetworkRoundActive = true; } else if (!_cubeNetworkRoundActive) { _cubeNetworkRoundActive = true; } _clientAcceptedCubeSyncSerial++; int clientAcceptedCubeSyncSerial = _clientAcceptedCubeSyncSerial; _cubeSize.Value = Mathf.Max(0.5f, num4); if (_cubeHeight != null) { _cubeHeight.Value = Mathf.Max(1.5f, num6); } _cubeEffectiveHeightOverride = Mathf.Max(1.5f, num6); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(num, num2, num3); int num12 = ((flag2 && list.Count > 0) ? CalculateHostCellListHash(list) : 0); bool flag7 = num8 == 0 || num8 == num12; D($"Received cube sync from host: center={V3(val)}, horizontal {_cubeSize.Value}, height {GetCubeConfiguredHeight()}, dynamicFootprint={flag2}, cells={list.Count}, hostDynamicEnabled={flag3}, authoritativeReady={flag4}, hostCellHash={num8}, calculatedCellHash={num12}, hashMatch={flag7}, cubeRoundId={num7}, syncSerial={clientAcceptedCubeSyncSerial}, roundStartTeleportActive={flag}, token={num5}"); if (!flag7) { D($"[{NetRoleDebugName()}] WARNING: host cube sync cell hash mismatch. Host hash={num8}, client calculated={num12}, cells={list.Count}. This means the payload was read differently than it was written."); } if (flag2 && list.Count > 0) { ApplyHostDynamicFootprintSync(val, _cubeSize.Value, GetCubeConfiguredHeight(), cellSize, bottomY, footprintHeight, list); CreateOrMoveCubeVisual(val); DebugLogStateSnapshot("client applied host dynamic footprint sync", force: true); QueueClientCubeVisualRefresh(val, clientAcceptedCubeSyncSerial, num7); } else if (flag3 && !flag4) { ResetDynamicAreaFootprint(); _cubeDynamicFootprintWaitingForAuthoritativeHostSync = true; _cubeCenter = val; _hasCube = false; DestroyCubeVisual(); _cubeDynamicFootprintWaitingForAuthoritativeHostSync = true; D($"Waiting for authoritative host footprint before showing Extraction Area. cubeRoundId={num7}, syncSerial={clientAcceptedCubeSyncSerial}, hostDynamicEnabled={flag3}, hostReady={flag4}, hostCells={list.Count}"); DebugLogStateSnapshot("client waiting for authoritative host footprint", force: true); } else { ResetDynamicAreaFootprint(); _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; CreateOrMoveCubeVisual(val); DebugLogStateSnapshot("client applied box-only cube sync", force: true); QueueClientCubeVisualRefresh(val, clientAcceptedCubeSyncSerial, num7); } } private static void BroadcastCubeClosedState(bool closed) { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return; } foreach (ulong connectedClientsId in NetworkManager.Singleton.ConnectedClientsIds) { if (connectedClientsId == NetworkManager.Singleton.LocalClientId) { MarkCubeExtractionPassed(closed); } else { SendCubeClosedState(connectedClientsId, closed); } } } private static void SendCubeClosedState(ulong clientId, bool closed) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)NetworkManager.Singleton == (Object)null) { return; } try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref closed, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_CubeClosed_v1", clientId, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed sending cube closed state to client {clientId}: {arg}"); } } private static void OnCubeClosedMessage(ulong senderClientId, FastBufferReader reader) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (!MessageFromServer(senderClientId)) { D($"[{NetRoleDebugName()}] Rejected cube closed state from non-server sender={senderClientId}."); return; } bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); D($"Received cube closed state from host: {flag}"); MarkCubeExtractionPassed(flag); } private static void SendRoundStartCubeTeleport(ulong clientId, int token, Vector3 position, string reason) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.CustomMessagingManager : null) == null) { return; } try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(32, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref token, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref position.x, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref position.y, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref position.z, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_RoundStartCubeTeleport_v1", clientId, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } D($"Sent round-start cube teleport token={token} to client {clientId}. reason={reason}, pos={position}"); } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed sending round-start cube teleport to client {clientId}: {arg}"); } } private static void OnRoundStartCubeTeleportMessage(ulong senderClientId, FastBufferReader reader) { //IL_0037: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00f1: Unknown result type (might be due to invalid IL or missing references) if (!MessageFromServer(senderClientId)) { D($"[{NetRoleDebugName()}] Rejected round-start cube teleport from non-server sender={senderClientId}."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); if (DebugOptionEnabled(_debugCubeSyncPayloads)) { D($"[{NetRoleDebugName()}] Round-start teleport message received from sender={senderClientId}, token={num}. Pre-state: {CubeStateDebugLine()}"); } float num2 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num2, default(ForPrimitives)); float num3 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num3, default(ForPrimitives)); float num4 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num4, default(ForPrimitives)); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(num2, num3, num4); D($"Received round-start cube teleport token={num} from host. pos={val}"); TryApplyRoundStartCubeTeleportLocal(num, val, "direct round-start message"); } private static bool RoundStartTeleportSucceededLocally(Vector3 targetFeetPosition) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = StartOfRound.Instance?.localPlayerController; if (!IsLivingControlledConnectedPlayer(val)) { return false; } try { if (_hasCube && PlayerBodyPositionInsideCube(val)) { return true; } return Vector3.Distance(((Component)val).transform.position, targetFeetPosition) <= 0.95f; } catch { return false; } } private static void TryApplyRoundStartCubeTeleportLocal(int token, Vector3 position, string source) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if ((_teleportPlayersToCubeOnRoundStart != null && !_teleportPlayersToCubeOnRoundStart.Value) || token <= 0 || token <= _localCompletedRoundStartCubeTeleportToken || token == _localPendingRoundStartCubeTeleportToken || token < _localAppliedRoundStartCubeTeleportToken) { return; } if (token == _localAppliedRoundStartCubeTeleportToken) { if (RoundStartTeleportSucceededLocally(position)) { _localCompletedRoundStartCubeTeleportToken = token; D($"[{NetRoleDebugName()}] Round-start teleport token already completed locally. Ignoring same-token resend. token={token}, source={source}"); return; } float num = Mathf.Max(0.1f, (_roundStartTeleportReapplyIntervalSeconds != null) ? _roundStartTeleportReapplyIntervalSeconds.Value : 0.65f); if (Time.realtimeSinceStartup - _lastLocalRoundStartCubeTeleportApplyTime < num) { return; } } if (!_cubeExtractionPassed && (!((Object)(object)StartOfRound.Instance != (Object)null) || !StartOfRound.Instance.shipIsLeaving) && !((Object)(object)Instance == (Object)null)) { if (!_hasCube) { D($"[{NetRoleDebugName()}] Round-start teleport will not create cube visual because no authoritative cube sync is active yet. token={token}, teleportFeetTarget={position}, source={source}, state={CubeStateDebugLine()}"); } _localPendingRoundStartCubeTeleportToken = token; ((MonoBehaviour)Instance).StartCoroutine(ApplyRoundStartCubeTeleportLocalCoroutine(token, position, source)); } } [IteratorStateMachine(typeof(d__512))] private static IEnumerator ApplyRoundStartCubeTeleportLocalCoroutine(int token, Vector3 position, string source) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__512(0) { token = token, position = position, source = source }; } private static void SendTeleportToPlayer(int playerId, ulong clientId, Vector3 position, bool toShip) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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) if ((Object)(object)NetworkManager.Singleton == (Object)null) { return; } if (clientId == NetworkManager.Singleton.LocalClientId) { TeleportLocalPlayer(position, toShip); return; } try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(64, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref playerId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref position.x, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref position.y, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref position.z, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref toShip, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Extraction_Teleport_v1", clientId, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } D($"Sent teleport to playerId={playerId}, client={clientId}, pos={position}, toShip={toShip}"); } catch (Exception arg) { Log.LogWarning((object)$"[Extraction] Failed sending teleport to client {clientId}: {arg}"); } } private static void OnTeleportMessage(ulong senderClientId, FastBufferReader reader) { //IL_0037: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if (!MessageFromServer(senderClientId)) { D($"[{NetRoleDebugName()}] Rejected teleport message from non-server sender={senderClientId}."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); if (DebugOptionEnabled(_debugCubeSyncPayloads)) { D($"[{NetRoleDebugName()}] Teleport message received from sender={senderClientId}, playerId={num}. Pre-state: {CubeStateDebugLine()}"); } float num2 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num2, default(ForPrimitives)); float num3 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num3, default(ForPrimitives)); float num4 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num4, default(ForPrimitives)); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); if (!((Object)(object)StartOfRound.Instance == (Object)null) && StartOfRound.Instance.thisClientPlayerId == num) { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(num2, num3, num4); D($"Received teleport for local player. pos={val}, toShip={flag}"); TeleportLocalPlayer(val, flag); } } private static void TeleportLocalPlayer(Vector3 position, bool toShip) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = StartOfRound.Instance?.localPlayerController; if ((Object)(object)val == (Object)null || val.isPlayerDead) { return; } if (toShip) { ApplyPlayerShipState(val); FacilityStartStyleTeleportPlayer(val, position, 0f); ApplyPlayerShipState(val); return; } SetPlayerInsideFactoryFieldsFacilityStyle(val); FacilityStartStyleTeleportPlayer(val, position, 0f); SetPlayerInsideFactoryFieldsFacilityStyle(val); TriggerGameInsideFactoryStateOnceFacilityStyle(val); ApplyLocalInsideVisualStateFacilityStyle(val); if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(MaintainLocalInsideFactoryStateCoroutine((_roundStartTeleportMaintainInsideSeconds != null) ? _roundStartTeleportMaintainInsideSeconds.Value : 8f)); } } private static bool FacilityStartStyleTeleportPlayer(PlayerControllerB player, Vector3 position, float yRot) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) if ((Object)(object)player == (Object)null) { return false; } if (CallTeleportPlayerMethodFacilityStyle(player, position, yRot)) { return true; } CharacterController val = null; bool enabled = false; try { val = ((Component)player).GetComponent(); enabled = (Object)(object)val != (Object)null && ((Collider)val).enabled; if ((Object)(object)val != (Object)null) { ((Collider)val).enabled = false; } ((Component)player).transform.position = position; ((Component)player).transform.rotation = Quaternion.Euler(0f, yRot, 0f); return true; } catch (Exception ex) { D("FacilityStartTeleport style transform fallback failed: " + ex.Message); return false; } finally { if ((Object)(object)val != (Object)null) { ((Collider)val).enabled = enabled; } } } private static bool CallTeleportPlayerMethodFacilityStyle(PlayerControllerB player, Vector3 position, float yRot) { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } try { MethodInfo[] methods = typeof(PlayerControllerB).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (methodInfo.Name != "TeleportPlayer") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (!parameters.Any((ParameterInfo p) => p.ParameterType == typeof(Vector3))) { continue; } object[] array2 = new object[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; string text = (parameters[j].Name ?? string.Empty).ToLowerInvariant(); if (parameterType == typeof(Vector3)) { array2[j] = position; } else if (parameterType == typeof(float)) { array2[j] = yRot; } else if (parameterType == typeof(bool)) { if (text.Contains("rotation") || text.Contains("rot")) { array2[j] = true; } else if (text.Contains("enable")) { array2[j] = true; } else { array2[j] = false; } } else { array2[j] = GetDefaultValue(parameterType); } } methodInfo.Invoke(player, array2); return true; } } catch (Exception ex) { D("TeleportPlayer reflection failed, using transform fallback: " + ex.Message); } return false; } private static object GetDefaultValue(Type type) { if (type == null || type == typeof(void)) { return null; } return type.IsValueType ? Activator.CreateInstance(type) : null; } private static void ApplyPlayerInsideFactoryState(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { SetPlayerInsideFactoryFieldsFacilityStyle(player); TriggerGameInsideFactoryStateOnceFacilityStyle(player); ApplyLocalInsideVisualStateFacilityStyle(player); } } private static void SetPlayerInsideFactoryFieldsFacilityStyle(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { player.isInsideFactory = true; TrySetBoolMember(player, "isInFactory", value: true); player.isInHangarShipRoom = false; player.isInElevator = false; TrySetBoolMember(player, "isPlayerAlone", value: false); TrySetBoolMember(player, "isInShipRoom", value: false); } } private static void TriggerGameInsideFactoryStateOnceFacilityStyle(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } try { ulong playerClientIdSafeUlongFacilityStyle = GetPlayerClientIdSafeUlongFacilityStyle(player); float realtimeSinceStartup = Time.realtimeSinceStartup; if (_lastInsideFactoryBestEffortTimeByClient.TryGetValue(playerClientIdSafeUlongFacilityStyle, out var value) && realtimeSinceStartup - value < 1f) { ApplyLocalInsideVisualStateFacilityStyle(player); return; } _lastInsideFactoryBestEffortTimeByClient[playerClientIdSafeUlongFacilityStyle] = realtimeSinceStartup; int num = Mathf.Clamp((int)playerClientIdSafeUlongFacilityStyle, 0, 9999); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { TryInvokeMethodFlexible(instance, "SwitchIsInsideFactoryRpc", playerClientIdSafeUlongFacilityStyle, num, true); } ApplyLocalInsideVisualStateFacilityStyle(player); } catch (Exception ex) { D("FacilityStartTeleport style inside RPC failed: " + ex.Message); } } private static ulong GetPlayerClientIdSafeUlongFacilityStyle(PlayerControllerB player) { ulong num = 0uL; if (TryGetULongMember(player, "playerClientId", out var value)) { num = value; } if (num == 0L && TryGetULongMember(player, "actualClientId", out var value2)) { num = value2; } if (num == 0L && (Object)(object)player != (Object)null) { num = player.actualClientId; } return num; } private static bool TryGetULongMember(object obj, string name, out ulong value) { value = 0uL; if (obj == null || string.IsNullOrEmpty(name)) { return false; } try { Type type = obj.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value2 = field.GetValue(obj); if (value2 is ulong num) { value = num; return true; } if (value2 is int num2) { value = (ulong)Mathf.Max(0, num2); return true; } } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanRead && property.GetIndexParameters().Length == 0) { object value3 = property.GetValue(obj, null); if (value3 is ulong num3) { value = num3; return true; } if (value3 is int) { int num4 = (int)value3; if (true) { value = (ulong)Mathf.Max(0, num4); return true; } } } } catch { } return false; } private static void ApplyLocalInsideVisualStateFacilityStyle(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { PlayerControllerB val = StartOfRound.Instance?.localPlayerController; if (!((Object)(object)val != (Object)null) || !((Object)(object)player != (Object)(object)val)) { SetPlayerInsideFactoryFieldsFacilityStyle(player); ApplyDynamicInsideAudioAndLightingFacilityStyle(player); TryInvokeMethodFlexible(player, "UpdateCameraOutsideOrInside"); RefreshInsideTimeAndLightingFacilityStyle(); TrySetClockVisibleFacilityStyle(visible: false); } } } private static void ApplyDynamicInsideAudioAndLightingFacilityStyle(PlayerControllerB player) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } try { object obj = FindBestInsideAudioTriggerFacilityStyle(((Component)player).transform.position); if (obj == null) { D("FacilityStartTeleport style inside audio trigger was not found. Weather/audio may stay outside."); SetPlayerInsideFactoryFieldsFacilityStyle(player); RefreshInsideTimeAndLightingFacilityStyle(); return; } bool flag = false; try { flag = TryInvokeMethodFlexible(obj, "ChangeAudioReverbForPlayer", player); } catch { flag = false; } TrySetObjectMember(player, "currentAudioTrigger", obj); TrySetObjectMember(player, "currentAudioTriggerB", null); if (TryGetObjectMember(obj, "reverbPreset", out var value) && value != null) { TrySetObjectMember(player, "reverbPreset", value); } SetPlayerInsideFactoryFieldsFacilityStyle(player); RefreshInsideTimeAndLightingFacilityStyle(); Component val = (Component)((obj is Component) ? obj : null); D($"Applied FacilityStartTeleport style inside audio trigger: {(((Object)(object)val != (Object)null) ? GetHierarchyPath(val.transform) : obj.ToString())}, ChangeAudioReverbForPlayer={flag}"); } catch (Exception ex) { D("FacilityStartTeleport style inside audio/lighting failed: " + ex.Message); } } private static void RefreshInsideTimeAndLightingFacilityStyle() { try { TimeOfDay instance = TimeOfDay.Instance; if (!((Object)(object)instance == (Object)null)) { TrySetBoolMember(instance, "insideLighting", value: true); TryInvokeMethodFlexible(instance, "SetInsideLightingDimness", true, 1f, 0f); } } catch (Exception ex) { D("FacilityStartTeleport style inside lighting refresh failed: " + ex.Message); } } private static object FindBestInsideAudioTriggerFacilityStyle(Vector3 playerPosition) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) Type audioReverbTriggerType = GetAudioReverbTriggerType(); if (audioReverbTriggerType == null) { return null; } try { Object[] array = Object.FindObjectsOfType(audioReverbTriggerType); if (array == null || array.Length == 0) { return null; } object result = null; float num = float.NegativeInfinity; float radius = 60f; Object[] array2 = array; foreach (Object val in array2) { if (val == (Object)null) { continue; } Component val2 = (Component)(object)((val is Component) ? val : null); if (!((Object)(object)val2 == (Object)null)) { float num2 = ScoreInsideAudioTriggerFacilityStyle(val2, playerPosition, radius); if (num2 > num) { num = num2; result = val; } } } if (num < 10f) { return null; } return result; } catch (Exception ex) { D("FacilityStartTeleport style FindBestInsideAudioTrigger failed: " + ex.Message); return null; } } private static float ScoreInsideAudioTriggerFacilityStyle(Component trigger, Vector3 playerPosition, float radius) { //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)trigger == (Object)null) { return float.NegativeInfinity; } string text = GetHierarchyPath(trigger.transform).ToLowerInvariant(); string text2 = (((Object)(object)trigger.gameObject != (Object)null) ? ((Object)trigger.gameObject).name.ToLowerInvariant() : string.Empty); float num = 0f; bool value; bool flag = TryGetBoolMember(trigger, "isShipRoom", out value) && value; bool value2; bool flag2 = TryGetBoolMember(trigger, "setInsideAtmosphere", out value2) && value2; bool value3; bool flag3 = TryGetBoolMember(trigger, "insideLighting", out value3) && value3; bool value4; bool flag4 = TryGetBoolMember(trigger, "disableAllWeather", out value4) && value4; bool value5; bool flag5 = TryGetBoolMember(trigger, "enableCurrentLevelWeather", out value5) && value5; bool value6; bool flag6 = TryGetBoolMember(trigger, "setInElevatorTrigger", out value6) && value6; object value7; bool flag7 = TryGetObjectMember(trigger, "reverbPreset", out value7) && value7 != null; object value8; bool flag8 = TryGetObjectMember(trigger, "audioChanges", out value8) && CountEnumerableFacilityStyle(value8) > 0; if (flag) { num -= 150f; } if (flag6) { num -= 80f; } if (flag5) { num -= 80f; } if (flag2) { num += 80f; } if (flag3) { num += 80f; } if (flag4) { num += 80f; } if (flag7) { num += 25f; } if (flag8) { num += 15f; } if (text.Contains("inside") || text2.Contains("inside")) { num += 80f; } if (text.Contains("interior") || text.Contains("factory") || text.Contains("dungeon") || text.Contains("facility")) { num += 35f; } if (text.Contains("ambience") || text2.Contains("ambience")) { num += 35f; } if (text.Contains("outside") || text2.Contains("outside")) { num -= 120f; } if (text.Contains("hangar") || text2.Contains("hangar") || text.Contains("ship") || text2.Contains("ship")) { num -= 120f; } if (text.Contains("wind") || text2.Contains("wind") || text.Contains("weather") || text2.Contains("weather")) { num -= 60f; } if (text.Contains("elevator") || text2.Contains("elevator")) { num -= 45f; } if ((Object)(object)trigger.gameObject != (Object)null && trigger.gameObject.activeInHierarchy) { num += 15f; } float num2 = Vector3.Distance(trigger.transform.position, playerPosition); if (num2 < radius) { num += Mathf.Clamp(10f - num2 * 0.15f, 0f, 10f); } return num; } private static int CountEnumerableFacilityStyle(object value) { if (value == null) { return 0; } try { if (!(value is IEnumerable enumerable) || value is string) { return 0; } int num = 0; foreach (object item in enumerable) { num++; } return num; } catch { return 0; } } private static void TrySetClockVisibleFacilityStyle(bool visible) { try { object instance = HUDManager.Instance; if (instance != null) { TryInvokeMethodFlexible(instance, "SetClockVisible", visible); } } catch { } } private static Type GetAudioReverbTriggerType() { if (_audioReverbTriggerTypeSearched) { return _audioReverbTriggerType; } _audioReverbTriggerTypeSearched = true; _audioReverbTriggerType = FindLoadedTypeByName("AudioReverbTrigger"); return _audioReverbTriggerType; } private static Type FindLoadedTypeByName(string typeName) { if (string.IsNullOrEmpty(typeName)) { return null; } try { Type type = Type.GetType(typeName + ", Assembly-CSharp", throwOnError: false); if (type != null) { return type; } } catch { } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type2 = assembly.GetType(typeName, throwOnError: false); if (type2 != null) { return type2; } Type[] types = assembly.GetTypes(); type2 = types.FirstOrDefault((Type t) => t != null && t.Name == typeName); if (type2 != null) { return type2; } } catch { } } return null; } private static bool TrySetObjectMember(object obj, string name, object value) { if (obj == null || string.IsNullOrEmpty(name)) { return false; } Type type = obj.GetType(); try { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && (value == null || field.FieldType.IsInstanceOfType(value))) { field.SetValue(obj, value); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite && property.GetIndexParameters().Length == 0 && (value == null || property.PropertyType.IsInstanceOfType(value))) { property.SetValue(obj, value, null); return true; } } catch { } return false; } private static bool TryGetObjectMember(object obj, string name, out object value) { value = null; if (obj == null || string.IsNullOrEmpty(name)) { return false; } Type type = obj.GetType(); try { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { value = field.GetValue(obj); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanRead && property.GetIndexParameters().Length == 0) { value = property.GetValue(obj, null); return true; } } catch { } return false; } private static void ApplyPlayerShipState(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { player.isInsideFactory = false; player.isInElevator = true; player.isInHangarShipRoom = true; TrySetBoolMember(player, "isInFactory", value: false); TrySetBoolMember(player, "isInShipRoom", value: true); } } [IteratorStateMachine(typeof(d__536))] private static IEnumerator MaintainLocalInsideFactoryStateCoroutine(float seconds) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__536(0) { seconds = seconds }; } internal static bool HandleChatCommand(string chatMessage, int playerId) { //IL_027f: Unknown result type (might be due to invalid IL or missing references) if (!_enableDebugCommands.Value || string.IsNullOrWhiteSpace(chatMessage)) { return false; } string text = chatMessage.Trim().ToLowerInvariant(); if (text.StartsWith("/")) { text = text.Substring(1); } if (text != "tpcube" && text != "endday" && text != "cubepos" && text != "countcube" && text != "extractionhelp" && text != "extractionstate" && text != "extractionplayers" && text != "extractionvotes") { return false; } D($"Chat command received from playerId {playerId}: {text}"); if (_hostOnlyDebugCommands.Value && !IsCommandSenderHost(playerId)) { SendDebugChat("[Extraction] Debug command '" + text + "' is host only."); D($"Blocked non-host debug command from playerId {playerId}: {text}"); return true; } switch (text) { case "tpcube": DebugTeleportPlayerToCube(playerId); break; case "endday": DebugEndDay(playerId); break; case "cubepos": SendDebugChat(_hasCube ? $"[Extraction] Extraction Area center: {_cubeCenter}" : "[Extraction] No Extraction Area has been placed yet."); break; case "countcube": DebugCountCubeScrap(); break; case "extractionstate": DebugChatStateSnapshot(playerId); break; case "extractionplayers": DebugChatPlayersSnapshot(playerId); break; case "extractionvotes": DebugChatVoteSnapshot(playerId); break; case "extractionhelp": SendDebugChat("[Extraction] Commands: tpcube, endday, cubepos, countcube, extractionstate, extractionplayers, extractionvotes, extractionhelp"); break; } return true; } private static bool IsCommandSenderHost(int playerId) { if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost || StartOfRound.Instance?.allPlayerScripts == null) { return false; } if (playerId < 0 || playerId >= StartOfRound.Instance.allPlayerScripts.Length) { return false; } PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId]; return (Object)(object)val != (Object)null && val.actualClientId == NetworkManager.Singleton.LocalClientId; } private static void DebugTeleportPlayerToCube(int playerId) { //IL_0046: 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_0053: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube) { SendDebugChat("[Extraction] No Extraction Area exists yet. Start a round first."); return; } PlayerControllerB playerById = GetPlayerById(playerId); if ((Object)(object)playerById == (Object)null) { SendDebugChat($"[Extraction] Could not find playerId {playerId}."); return; } Vector3 cubeSafeTeleportPosition = GetCubeSafeTeleportPosition(); SendTeleportToPlayer(playerId, playerById.actualClientId, cubeSafeTeleportPosition, toShip: false); SendDebugChat($"[Extraction] Teleported player {playerId} to Extraction Area."); } private static void DebugEndDay(int playerId) { if (!IsServer() || (Object)(object)StartOfRound.Instance == (Object)null) { SendDebugChat("[Extraction] endday can only run on the host during a round."); return; } if (StartOfRound.Instance.shipIsLeaving) { SendDebugChat("[Extraction] Ship is already leaving."); return; } D($"Debug command endday called by playerId {playerId}. Calling EndGameServerRpc."); SendDebugChat("[Extraction] Forcing ship to leave now."); StartOfRound.Instance.EndGameServerRpc(playerId); } private static void DebugCountCubeScrap() { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube) { SendDebugChat("[Extraction] No Extraction Area exists yet."); return; } int num = 0; int num2 = 0; GrabbableObject[] array = Object.FindObjectsOfType(); foreach (GrabbableObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && val.itemProperties.isScrap && !val.isHeld && !val.isPocketed && !((Object)(object)val.playerHeldBy != (Object)null) && ScrapIntersectsCube(val)) { num++; num2 += Mathf.Max(0, val.scrapValue); } } SendDebugChat($"[Extraction] Extraction Area contains {num} loose scrap item(s), raw value ${num2}. Bounds are 1:1 with the visual Extraction Area."); D($"Debug countcube: count={num}, value={num2}, cubeBounds={CurrentCubeBounds()}"); } private static void DebugChatStateSnapshot(int playerId) { string message = $"[Extraction] STATE {NetRoleDebugName()} | roundId={_currentCubeNetworkRoundId} active={_cubeNetworkRoundActive} hasCube={_hasCube} dynReady={_cubeDynamicFootprintReady} cells={_cubeDynamicFootprintCells.Count} hash={((_cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) ? GetDynamicFootprintCellHash() : 0)} hostReady={_authoritativeCubeFootprintReadyForClients} waitingHost={_cubeDynamicFootprintWaitingForAuthoritativeHostSync} eligible={_earlyVoteEligible} votes={_earlyVoteCount}/{_earlyVoteRequired}"; SendDebugChat(message); DebugLogStateSnapshot($"chat extractionstate by player {playerId}", force: true); } private static void DebugChatPlayersSnapshot(int playerId) { SendDebugChat("[Extraction] Player cube diagnostics were written to the BepInEx log."); DebugLogPlayersSnapshot($"chat extractionplayers by player {playerId}", force: true); } private static void DebugChatVoteSnapshot(int playerId) { string localVoteInputBlockReason = GetLocalVoteInputBlockReason(); SendDebugChat(string.Format("[Extraction] VOTE {0} eligible={1} votes={2}/{3} localInside={4} localSubmitted={5} block={6}", NetRoleDebugName(), _earlyVoteEligible, _earlyVoteCount, _earlyVoteRequired, _localPlayerInsideCube, _localEarlyVoteSubmitted, string.IsNullOrEmpty(localVoteInputBlockReason) ? "none" : localVoteInputBlockReason)); DebugLogStateSnapshot($"chat extractionvotes by player {playerId}", force: true); } private static PlayerControllerB GetPlayerById(int playerId) { if (StartOfRound.Instance?.allPlayerScripts == null) { return null; } if (playerId < 0 || playerId >= StartOfRound.Instance.allPlayerScripts.Length) { return null; } return StartOfRound.Instance.allPlayerScripts[playerId]; } private static void UpdateCubeScrapGlowLoop() { if (_enableCubeScrapGlow == null || !_enableCubeScrapGlow.Value || !_hasCube) { if (_glowingCubeScrap.Count > 0) { ClearAllCubeScrapGlow(); } return; } float num = Mathf.Max(0.03f, (_cubeScrapGlowRefreshInterval != null) ? _cubeScrapGlowRefreshInterval.Value : 0.15f); _cubeScrapGlowTimer += Time.deltaTime; if (_cubeScrapGlowTimer < num) { return; } _cubeScrapGlowTimer = 0f; HashSet hashSet = new HashSet(); GrabbableObject[] array = Object.FindObjectsOfType(); GrabbableObject[] array2 = array; foreach (GrabbableObject item in array2) { if (ShouldScrapGlowRedInCube(item)) { hashSet.Add(item); } } List list = new List(_glowingCubeScrap.Keys); foreach (GrabbableObject item2 in list) { if ((Object)(object)item2 == (Object)null) { if (_glowingCubeScrap.TryGetValue(item2, out var value)) { value?.Restore(); } _glowingCubeScrap.Remove(item2); } else if (!hashSet.Contains(item2)) { RemoveCubeScrapGlow(item2); } } foreach (GrabbableObject item3 in hashSet) { ApplyCubeScrapGlow(item3); } } private static bool ShouldScrapGlowRedInCube(GrabbableObject item) { if ((Object)(object)item == (Object)null || (Object)(object)item.itemProperties == (Object)null || !item.itemProperties.isScrap) { return false; } if (item.isHeld || item.isPocketed || (Object)(object)item.playerHeldBy != (Object)null) { return false; } if ((Object)(object)((Component)item).gameObject == (Object)null || !((Component)item).gameObject.activeInHierarchy) { return false; } return ScrapIntersectsCube(item); } private static void ApplyCubeScrapGlow(GrabbableObject item) { if (!((Object)(object)item == (Object)null) && !_glowingCubeScrap.ContainsKey(item)) { ScrapGlowState scrapGlowState = new ScrapGlowState(item); scrapGlowState.Apply(); _glowingCubeScrap[item] = scrapGlowState; D($"Cube scrap glow ON: {((Object)item).name}, value={item.scrapValue}"); } } private static void RemoveCubeScrapGlow(GrabbableObject item) { if (!((Object)(object)item == (Object)null) && _glowingCubeScrap.TryGetValue(item, out var value)) { value.Restore(); _glowingCubeScrap.Remove(item); D("Cube scrap glow OFF: " + ((Object)item).name); } } private static void ClearAllCubeScrapGlow() { if (_glowingCubeScrap.Count == 0) { return; } foreach (ScrapGlowState item in new List(_glowingCubeScrap.Values)) { item?.Restore(); } _glowingCubeScrap.Clear(); } private static void UpdateScrapVisibilityLoop() { if (_enableScrapVisibility == null || !_enableScrapVisibility.Value) { ClearAllScrapVisibilityHighlighters(); return; } float num = Mathf.Max(0.05f, (_scrapVisibilityRefreshInterval != null) ? _scrapVisibilityRefreshInterval.Value : 0.35f); _scrapVisibilityAttachTimer += Time.deltaTime; if (!(_scrapVisibilityAttachTimer < num)) { _scrapVisibilityAttachTimer = 0f; AttachScrapVisibilityHighlighters(); } } private static void AttachScrapVisibilityHighlighters() { GrabbableObject[] array = Object.FindObjectsOfType(); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { ScrapValueHighlighter scrapValueHighlighter = ((Component)val).GetComponent(); if ((Object)(object)scrapValueHighlighter == (Object)null) { scrapValueHighlighter = ((Component)val).gameObject.AddComponent(); } scrapValueHighlighter.Init(val); } } } private static void ClearAllScrapVisibilityHighlighters() { ScrapValueHighlighter[] array = Object.FindObjectsOfType(); ScrapValueHighlighter[] array2 = array; foreach (ScrapValueHighlighter scrapValueHighlighter in array2) { if ((Object)(object)scrapValueHighlighter != (Object)null) { scrapValueHighlighter.DestroySelf(); } } if ((Object)(object)_scrapTextRoot != (Object)null) { Object.Destroy((Object)(object)((Component)_scrapTextRoot).gameObject); _scrapTextRoot = null; } } private static Transform GetScrapTextRoot() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if ((Object)(object)_scrapTextRoot != (Object)null) { return _scrapTextRoot; } GameObject val = new GameObject("Extraction_ScrapValueTextRoot"); Object.DontDestroyOnLoad((Object)(object)val); _scrapTextRoot = val.transform; return _scrapTextRoot; } internal static bool ShouldBlockManualScanner() { return _disableManualRightClickScan != null && _disableManualRightClickScan.Value; } internal static bool ScrapIsRegisteredInsideCubeForVisuals(GrabbableObject item) { return ShouldScrapGlowRedInCube(item); } internal static Color GetScrapDisplayColor(bool isScrap, int value) { //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_004b: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (!isScrap) { return new Color(0.2f, 0.55f, 1f, 1f); } if (value >= 300) { return new Color(1f, 0.78f, 0.05f, 1f); } if (value >= 150) { return new Color(0.72f, 0.25f, 1f, 1f); } if (value >= 100) { return new Color(0.15f, 1f, 0.25f, 1f); } if (value >= 50) { return new Color(1f, 1f, 0.15f, 1f); } return new Color(1f, 0.45f, 0.05f, 1f); } private static bool ItemIsHeldByAnyone(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return true; } return item.isHeld || item.isPocketed || (Object)(object)item.playerHeldBy != (Object)null || item.isHeldByEnemy; } private static void SendDebugChat(string message) { D(message); if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.AddTextToChatOnServer(message, -1); } } private static bool DebugOptionEnabled(ConfigEntry option) { return _debugLogging != null && _debugLogging.Value && (option?.Value ?? true); } private static string NetRoleDebugName() { try { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { return "NO-NETWORK"; } if (singleton.IsHost) { return $"HOST localClient={singleton.LocalClientId}"; } if (singleton.IsServer) { return $"SERVER localClient={singleton.LocalClientId}"; } if (singleton.IsClient) { return $"CLIENT localClient={singleton.LocalClientId}"; } return $"NETWORK-UNKNOWN localClient={singleton.LocalClientId}"; } catch { return "ROLE-ERROR"; } } private static string V3(Vector3 v) { //IL_0006: 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_001c: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:0.00},{v.y:0.00},{v.z:0.00})"; } private static string B3(Bounds b) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) return "center=" + V3(((Bounds)(ref b)).center) + " size=" + V3(((Bounds)(ref b)).size) + " min=" + V3(((Bounds)(ref b)).min) + " max=" + V3(((Bounds)(ref b)).max); } private static string CubeStateDebugLine() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) int num = ((_cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) ? GetDynamicFootprintCellHash() : 0); return $"cube has={_hasCube} center={V3(_cubeCenter)} size={GetCubeHorizontalSize():0.00} height={GetCubeConfiguredHeight():0.00} " + $"dynamicEnabled={CubeDynamicFootprintEnabled()} dynamicReady={_cubeDynamicFootprintReady} cells={_cubeDynamicFootprintCells.Count} cellHash={num} " + $"cellSize={_cubeDynamicFootprintCellSize:0.00} bottomY={_cubeDynamicFootprintBottomY:0.00} dynHeight={_cubeDynamicFootprintHeight:0.00} " + $"fromHost={_cubeDynamicFootprintAuthoritativeFromHost} waitingHost={_cubeDynamicFootprintWaitingForAuthoritativeHostSync} hostReady={_authoritativeCubeFootprintReadyForClients} " + $"roundId host={_hostCubeNetworkRoundId} current={_currentCubeNetworkRoundId} lastAccepted={_lastAcceptedCubeNetworkRoundId} active={_cubeNetworkRoundActive} syncSerial={_clientAcceptedCubeSyncSerial} " + string.Format("visual={0} visualActive={1} bounds={2}", (Object)(object)_cubeVisual != (Object)null, (Object)(object)_cubeVisual != (Object)null && _cubeVisual.activeSelf, _hasCube ? B3(CurrentCubeBounds()) : ""); } private static string VoteStateDebugLine() { PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null); int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)); return $"vote enabled={_enableEarlyExtractionVote != null && _enableEarlyExtractionVote.Value} eligible={_earlyVoteEligible} count={_earlyVoteCount}/{_earlyVoteRequired} " + $"localSubmitted={_localEarlyVoteSubmitted} countdown={_earlyExtractionCountdownActive} countdownSeconds={_earlyExtractionCountdownSecondsRemaining} triggered={_earlyExtractionTriggered} " + $"closed={_cubeExtractionPassed} localInside={_localPlayerInsideCube} localId={num} localCanInput={LocalPlayerCanUseVoteInput()} " + $"localDead={(Object)(object)val != (Object)null && val.isPlayerDead} localControlled={(Object)(object)val != (Object)null && val.isPlayerControlled} localTyping={(Object)(object)val != (Object)null && val.isTypingChat} localTerminal={(Object)(object)val != (Object)null && val.inTerminalMenu} " + $"pendingAck={_earlyVoteRequestPendingAck} sentVoteReq={_debugEarlyVoteRequestSendCount} recvVoteReq={_debugEarlyVoteRequestReceiveCount} recvVoteSync={_debugEarlyVoteSyncReceiveCount}"; } private static string RoundStateDebugLine() { StartOfRound instance = StartOfRound.Instance; TimeOfDay instance2 = TimeOfDay.Instance; bool value = false; if ((Object)(object)instance != (Object)null) { TryGetBoolMember(instance, "shipHasLanded", out value); } return $"round shipLeaving={(Object)(object)instance != (Object)null && instance.shipIsLeaving} allPlayersDead={(Object)(object)instance != (Object)null && instance.allPlayersDead} inShipPhase={(Object)(object)instance != (Object)null && instance.inShipPhase} " + string.Format("shipHasLanded={0} todNorm={1} ", value, ((Object)(object)instance2 != (Object)null) ? instance2.normalizedTimeOfDay.ToString("0.000") : "null") + $"resetCount={_debugRoundResetCount} shipHasLeftCount={_debugShipHasLeftCount} cubeSyncSent={_debugCubeSyncSendCount} cubeSyncRecv={_debugCubeSyncReceiveCount} cubeSyncReject={_debugCubeSyncRejectCount} " + $"netInit={_networkSessionStateInitialized} handlers={_messagesRegistered} registeredNm={(Object)(object)_registeredNetworkManager != (Object)null} lastClient={_lastObservedLocalClientId} lastPlayer={_lastObservedThisClientPlayerId} " + $"roundStartTeleport requested={_roundStartTeleportRequested} floorReady={_roundStartTeleportFloorReady} started={_roundStartTeleportStarted} routine={_roundStartTeleportRoutineRunning} window={_roundStartCubeTeleportWindowOpen} token={_roundStartCubeTeleportToken} appliedToken={_localAppliedRoundStartCubeTeleportToken} completedToken={_localCompletedRoundStartCubeTeleportToken}"; } private static string ExplainPositionAgainstCube(Vector3 position) { //IL_0012: 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_0147: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_012e: Unknown result type (might be due to invalid IL or missing references) if (!_hasCube) { return "noCube pos=" + V3(position); } if (_cubeDynamicFootprintReady && _cubeDynamicFootprintCells.Count > 0) { float num = Mathf.Max(0.1f, _cubeDynamicFootprintCellSize); float num2 = _cubeDynamicFootprintBottomY - 0.5f; float num3 = _cubeDynamicFootprintBottomY + _cubeDynamicFootprintHeight + 0.85f; Vector3 val = position - _cubeCenter; int num4 = Mathf.FloorToInt(val.x / num + 0.5f); int num5 = Mathf.FloorToInt(val.z / num + 0.5f); bool flag = CubeFootprintHasCell(num4, num5); return $"dynamic pos={V3(position)} local={V3(val)} cell=({num4},{num5}) hasCell={flag} yRange={num2:0.00}-{num3:0.00} yOk={position.y >= num2 && position.y <= num3} contains={PositionIsInsideDynamicAreaFootprint(position)}"; } Bounds b = CurrentCubeBounds(); return $"box pos={V3(position)} contains={((Bounds)(ref b)).Contains(position)} bounds={B3(b)}"; } private static string PlayerInsideDebugLine(PlayerControllerB player, int playerId) { //IL_00b8: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_003e: 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) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return $"player[{playerId}]=null"; } Vector3 val = (((Object)(object)((Component)player).transform != (Object)null) ? ((Component)player).transform.position : Vector3.zero); bool flag = false; bool flag2 = false; try { flag = PlayerBodyPositionInsideCube(player); } catch { } try { flag2 = PlayerBodyPositionInsideCubeForVoting(player); } catch { } return $"player[{playerId}] client={player.actualClientId} controlled={player.isPlayerControlled} dead={player.isPlayerDead} disconnected={player.disconnectedMidGame} pos={V3(val)} inside={flag} voteInside={flag2} voteTol={EarlyVoteInsideTolerance():0.00} explainFeet={ExplainPositionAgainstCube(val)} explainChest={ExplainPositionAgainstCube(val + Vector3.up * 1.45f)}"; } private static void DebugLogPlayersSnapshot(string reason, bool force) { if (!force && !DebugOptionEnabled(_debugInsideCubeChecks)) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { D("[" + NetRoleDebugName() + "] PLAYER SNAPSHOT " + reason + ": no StartOfRound/allPlayerScripts"); return; } for (int i = 0; i < instance.allPlayerScripts.Length; i++) { PlayerControllerB val = instance.allPlayerScripts[i]; if (!((Object)(object)val == (Object)null) && (val.isPlayerControlled || force)) { D("[" + NetRoleDebugName() + "] PLAYER SNAPSHOT " + reason + ": " + PlayerInsideDebugLine(val, i)); } } } private static void DebugLogStateSnapshot(string reason, bool force = false) { if (force || DebugOptionEnabled(_debugStateSnapshots)) { D("[" + NetRoleDebugName() + "] STATE SNAPSHOT " + reason + ": " + RoundStateDebugLine() + " | " + CubeStateDebugLine() + " | " + VoteStateDebugLine()); if (force) { DebugLogPlayersSnapshot(reason, force: true); } } } private static void UpdateExtractionDiagnosticSnapshotLoop() { if (DebugOptionEnabled(_debugStateSnapshots) && (_hasCube || _cubeNetworkRoundActive || _roundStartTeleportRequested || _earlyVoteEligible || _localPlayerInsideCube)) { float num = Mathf.Max(1f, (_debugStateSnapshotInterval != null) ? _debugStateSnapshotInterval.Value : 5f); _debugStateSnapshotTimer += Time.deltaTime; if (!(_debugStateSnapshotTimer < num)) { _debugStateSnapshotTimer = 0f; DebugLogStateSnapshot("periodic"); DebugLogPlayersSnapshot("periodic", force: false); } } } private static void DebugLogVoteBlock(string reason, bool force = false) { if (force || DebugOptionEnabled(_debugVoteInput)) { bool flag = reason != _lastDebugVoteBlockReason; _debugVoteBlockLogTimer += Time.deltaTime; if (force || flag || !(_debugVoteBlockLogTimer < 1f)) { _debugVoteBlockLogTimer = 0f; _lastDebugVoteBlockReason = reason; D("[" + NetRoleDebugName() + "] VOTE INPUT GATE: " + reason + " | " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); } } } private static void DebugLogHostVoteGate(string reason, bool force = false) { if (force || DebugOptionEnabled(_debugVoteInput)) { bool flag = reason != _lastDebugHostVoteGateReason; _debugHostVoteGateLogTimer += Time.deltaTime; if (force || flag || !(_debugHostVoteGateLogTimer < 1f)) { _debugHostVoteGateLogTimer = 0f; _lastDebugHostVoteGateReason = reason; D("[" + NetRoleDebugName() + "] HOST VOTE GATE: " + reason + " | " + VoteStateDebugLine() + " | " + CubeStateDebugLine()); } } } private static void DebugLogInsideCubeResult(bool inside, string reason, bool force = false) { if (force || DebugOptionEnabled(_debugInsideCubeChecks)) { _debugInsideCubeLogTimer += Time.deltaTime; if (force || inside != _lastDebugInsideCubeState || !(_debugInsideCubeLogTimer < 1.25f)) { _debugInsideCubeLogTimer = 0f; _lastDebugInsideCubeState = inside; PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null); string text = (((Object)(object)val != (Object)null) ? PlayerInsideDebugLine(val, ((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.thisClientPlayerId : (-1)) : "no local player"); D($"[{NetRoleDebugName()}] LOCAL INSIDE CHECK {reason}: inside={inside} {text}"); } } } private static string GetLocalVoteInputBlockReason() { if (_enableEarlyExtractionVote == null || !_enableEarlyExtractionVote.Value) { return "EnableEarlyExtractionVote=false"; } if (!_hasCube) { return "no local cube state"; } if (!_localPlayerInsideCube) { return "local player not inside cube"; } if (!_earlyVoteEligible) { return "host says earlyVoteEligible=false"; } if (_earlyVoteRequestPendingAck) { return "local vote request pending host voter-list ack"; } if (_localEarlyVoteSubmitted) { return "local vote already submitted"; } if (_earlyExtractionCountdownActive) { return "countdown already active"; } if (_cubeExtractionPassed) { return "cube extraction already closed"; } if (_earlyExtractionTriggered) { return "early extraction already triggered"; } if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving) { return "ship is leaving"; } if (!LocalPlayerCanUseVoteInput()) { return "player input blocked by chat/terminal/quick menu/dead/uncontrolled"; } return string.Empty; } private static bool IsServer() { return (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer; } private static bool MessageFromServer(ulong senderClientId) { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return senderClientId == 0L || senderClientId == NetworkManager.Singleton.LocalClientId; } internal static void ResetRoundState() { _debugRoundResetCount++; D($"[{NetRoleDebugName()}] Resetting round extraction state. resetCount={_debugRoundResetCount}. BEFORE: {RoundStateDebugLine()} | {CubeStateDebugLine()} | {VoteStateDebugLine()}"); DebugLogPlayersSnapshot("before ResetRoundState", force: true); _pendingQuotaValue = 0; _pendingRawValue = 0; _pendingItemCount = 0; _pendingQuotaApplied = false; _cubeEffectiveHeightOverride = -1f; _cubeExtractionPassed = false; _earlyExtractionCountdownActive = false; _earlyExtractionCountdownEndTime = 0f; _earlyExtractionCountdownSecondsRemaining = 0; _earlyExtractionTriggered = false; ClearBaseGameSpectatorVoteToLeaveState("round state reset", resetVanillaTimeOfDayFields: true); _earlyVoteEligible = false; _earlyVoteCount = 0; _earlyVoteRequired = 0; _localEarlyVoteSubmitted = false; _earlyVoteRosterKey = string.Empty; _earlyExtractionVotes.Clear(); _clientTrustedEarlyVotePlayers.Clear(); _lastEarlyVoteSyncSignature = string.Empty; _currentCubeScrapRawValue = 0; _currentCubeScrapCount = 0; _localPlayerInsideCube = false; _roundStartCubeTeleportWindowOpen = false; _roundStartTeleportRequested = false; _roundStartTeleportFloorReady = false; _roundStartTeleportStarted = false; _roundStartTeleportRoutineRunning = false; _cubePostReadyPlacementFinalized = false; _authoritativeCubeFootprintReadyForClients = false; _cubeDynamicFootprintAuthoritativeFromHost = false; _cubeDynamicFootprintWaitingForAuthoritativeHostSync = false; _cubeNetworkRoundActive = false; _currentCubeNetworkRoundId = -1; _clientAcceptedCubeSyncSerial++; _trackedPressedVoteKeys.Clear(); _roundStartTeleportRequestTime = 0f; _roundStartTeleportRequestReason = string.Empty; _roundStartTeleportTargetsByClient.Clear(); _lastInsideFactoryBestEffortTimeByClient.Clear(); _lastInsideAudioLightingBestEffortTimeByClient.Clear(); _cachedInteriorEntranceReachabilityAnchors.Clear(); _cachedInteriorEntranceReachabilityAnchorsFrame = -1; _localPendingRoundStartCubeTeleportToken = -1; _localAppliedRoundStartCubeTeleportToken = -1; _localCompletedRoundStartCubeTeleportToken = -1; _lastLocalRoundStartCubeTeleportApplyTime = 0f; _earlyVoteLeftCubeSince.Clear(); ClearAllScrapVisibilityHighlighters(); DestroyCubeVisual(); D("[" + NetRoleDebugName() + "] ResetRoundState finished. AFTER: " + RoundStateDebugLine() + " | " + CubeStateDebugLine() + " | " + VoteStateDebugLine()); } internal static void D(string msg) { if (_debugLogging != null && _debugLogging.Value) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[Extraction] " + msg)); } } } }