using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 UnityEngine; [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 FacilityStartTeleport; [BepInPlugin("YourFurnace.FacilityStartTeleport", "FacilityStartTeleport", "1.2.5")] public class FacilityStartTeleport : BaseUnityPlugin { [CompilerGenerated] private sealed class d__84 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PlayerControllerB player; public GrabbableObject grabbable; public FacilityStartTeleport <>4__this; private bool 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__84(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)player == (Object)null || (Object)(object)grabbable == (Object)null) { return false; } ReflectionUtil.SetFieldObject(player, "currentlyGrabbingObject", grabbable); 5__1 = ReflectionUtil.CallNoArgMethod(player, "BeginGrabObject"); if (!5__1) { <>4__this.TryCallGrabObjectServerRpc(player, ((Component)grabbable).gameObject); } <>2__current = (object)new WaitForSeconds(0.35f); <>1__state = 2; return true; case 2: <>1__state = -1; if (!<>4__this.IsItemInPlayerInventory(player, grabbable)) { <>4__this.SetupStartingItemAsRealDroppedItem(((Component)grabbable).gameObject, grabbable, grabbable.itemProperties, player); if (DebugLogging != null && DebugLogging.Value && Log != null) { Log.LogInfo((object)"Starting flashlight stayed as a normal pickup because vanilla auto-pickup did not claim it."); } } 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(); } } private const string modGUID = "YourFurnace.FacilityStartTeleport"; private const string modName = "FacilityStartTeleport"; private const string modVersion = "1.2.5"; internal static FacilityStartTeleport Instance; internal static ManualLogSource Log; internal static ConfigEntry EnableMod; internal static ConfigEntry SkipCompanyMoon; internal static ConfigEntry TeleportAllActivePlayers; internal static ConfigEntry DebugLogging; internal static ConfigEntry TeleportDelayAfterLanding; internal static ConfigEntry SpawnRadiusFromNode; internal static ConfigEntry FloorRaycastHeight; internal static ConfigEntry FloorRaycastDistance; internal static ConfigEntry PlayerHeightOffset; internal static ConfigEntry MaintainInsideStateSeconds; internal static ConfigEntry ApplyDynamicInsideAudioState; internal static ConfigEntry InsideAudioSearchRadius; internal static ConfigEntry HideClockDuringInsideSpawn; internal static ConfigEntry RequireDungeonFinished; internal static ConfigEntry PreferInverseTeleporterLogic; internal static ConfigEntry MaxSpawnAttempts; internal static ConfigEntry CapsuleRadius; internal static ConfigEntry CapsuleHeight; internal static ConfigEntry MinimumWallClearance; internal static ConfigEntry NavmeshSearchRadius; internal static ConfigEntry MinimumCeilingClearance; internal static ConfigEntry MaximumHeightDifferenceFromNearestNode; internal static ConfigEntry RejectPipeAndPropFloors; internal static ConfigEntry MinimumDistanceFromEntrance; internal static ConfigEntry GiveFlashlightIfInventoryEmpty; internal static ConfigEntry FlashlightGiveChance; internal static ConfigEntry ProFlashlightChance; internal static ConfigEntry NormalFlashlightNames; internal static ConfigEntry ProFlashlightNames; internal static ConfigEntry EquipGivenFlashlight; private bool teleportedThisDay = false; private int lastRoundKey = int.MinValue; private float nextCheckTime = 0f; private float readyToTeleportTime = -1f; private float maintainInsideStateUntil = -1f; private readonly List cachedInsideNodes = new List(); private float nextNodeRefreshTime = 0f; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; EnableMod = ((BaseUnityPlugin)this).Config.Bind("General", "Enable mod", true, "If true, players are moved into a random facility position at the start of a new day."); SkipCompanyMoon = ((BaseUnityPlugin)this).Config.Bind("General", "Skip Company moon", true, "If true, the mod will not run at The Company / Gordion."); TeleportAllActivePlayers = ((BaseUnityPlugin)this).Config.Bind("General", "Teleport all active players", true, "If true, attempts to teleport every active controlled player object. If false, only the local player is teleported. For multiplayer, all clients should have the mod installed."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "Debug logging", true, "Logs when the mod finds nodes, validates spawn points, teleports players, and gives flashlights."); TeleportDelayAfterLanding = ((BaseUnityPlugin)this).Config.Bind("Timing", "Teleport delay after landing", 6f, "Seconds to wait after the moon loads before teleporting players. This gives the facility and nodes time to spawn."); SpawnRadiusFromNode = ((BaseUnityPlugin)this).Config.Bind("Spawning", "Spawn radius from inside node", 1.25f, "Random horizontal offset around the selected inside AI node. Lower is safer."); FloorRaycastHeight = ((BaseUnityPlugin)this).Config.Bind("Spawning", "Floor raycast height", 1.35f, "How far above the candidate point the floor raycast starts. Keep this low so it does not hit ceiling pipes above the real floor."); FloorRaycastDistance = ((BaseUnityPlugin)this).Config.Bind("Spawning", "Floor raycast distance", 4f, "How far down the mod searches for a floor under the candidate point."); PlayerHeightOffset = ((BaseUnityPlugin)this).Config.Bind("Spawning", "Player height offset", 0.75f, "How far above the detected floor the player is placed."); MaintainInsideStateSeconds = ((BaseUnityPlugin)this).Config.Bind("Indoor State", "Maintain inside state seconds", 30f, "After teleporting, the mod briefly stabilizes isInsideFactory true. This is clamped to 3 seconds so exiting the facility does not break outside lighting."); ApplyDynamicInsideAudioState = ((BaseUnityPlugin)this).Config.Bind("Indoor State", "Apply dynamic inside audio state", true, "If true, the mod finds the map's active inside ambience AudioReverbTrigger and applies it to the local player after teleporting."); InsideAudioSearchRadius = ((BaseUnityPlugin)this).Config.Bind("Indoor State", "Inside audio search radius", 60f, "Used only as a tie breaker when choosing between multiple inside audio triggers. The mod does not rely on hardcoded map names."); HideClockDuringInsideSpawn = ((BaseUnityPlugin)this).Config.Bind("Indoor State", "Hide clock during inside spawn", true, "If true, asks HUDManager to hide the outside clock after the forced inside spawn. The actual fix is still the player inside state plus inside ambience trigger."); RequireDungeonFinished = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Require dungeon finished", true, "If true, the mod waits until the facility reports that dungeon generation finished before teleporting."); PreferInverseTeleporterLogic = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Prefer inverse teleporter logic", false, "If true, the mod tries to use the game's inverse teleporter position function first when an inverse teleporter exists. Default is false because some maps can return ceiling/pipe positions."); MaxSpawnAttempts = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Max spawn attempts", 250, "How many random inside positions the mod tests before giving up for that player."); CapsuleRadius = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Player capsule radius", 0.34f, "Radius used when checking if the spawn point has enough space for the player."); CapsuleHeight = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Player capsule height", 1.75f, "Height used when checking if the spawn point has enough space for the player."); MinimumWallClearance = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Minimum wall clearance", 0.75f, "Horizontal clearance required around the player's chest. Raise this to avoid corners. Lower it if too many spawns fail."); NavmeshSearchRadius = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Navmesh search radius", 5f, "Radius used when asking RoundManager for a navmesh position around an inside AI node."); MinimumCeilingClearance = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Minimum ceiling clearance", 2.15f, "Minimum clear vertical space above the spawn. This helps prevent spawning on pipes or ceiling props."); MaximumHeightDifferenceFromNearestNode = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Maximum height difference from nearest node", 2.5f, "Rejects spawn points much higher or lower than the nearest inside AI node. This helps avoid ceiling pipes and out of bounds ledges."); RejectPipeAndPropFloors = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Reject pipe and prop floors", true, "Rejects floor hits on pipes, rails, sockets, props, vents, and similar non-floor objects."); MinimumDistanceFromEntrance = ((BaseUnityPlugin)this).Config.Bind("Safe Spawning", "Minimum distance from entrances", 8f, "Rejects spawn points too close to main/fire exits. This helps prevent entrance triggers from repeatedly firing after the forced indoor spawn."); GiveFlashlightIfInventoryEmpty = ((BaseUnityPlugin)this).Config.Bind("Starting Flashlight", "Give flashlight if inventory empty", true, "If true, a player with no items has a chance to start with a normal flashlight or pro flashlight after being moved inside."); FlashlightGiveChance = ((BaseUnityPlugin)this).Config.Bind("Starting Flashlight", "Chance to give flashlight", 1f, "Chance to give any flashlight when the player's inventory is empty. 1.0 means 100%."); ProFlashlightChance = ((BaseUnityPlugin)this).Config.Bind("Starting Flashlight", "Chance flashlight is pro", 0.35f, "If a flashlight is given, this is the chance it is a pro flashlight. Normal flashlight is used if this roll fails."); NormalFlashlightNames = ((BaseUnityPlugin)this).Config.Bind("Starting Flashlight", "Normal flashlight item names", "Flashlight", "Comma separated item names to search for normal flashlights."); ProFlashlightNames = ((BaseUnityPlugin)this).Config.Bind("Starting Flashlight", "Pro flashlight item names", "Pro-flashlight,Pro flashlight,ProFlashlight", "Comma separated item names to search for pro flashlights."); EquipGivenFlashlight = ((BaseUnityPlugin)this).Config.Bind("Starting Flashlight", "Attempt vanilla pickup after spawn", false, "If true, the mod spawns the flashlight as a real network item and then tries to make vanilla pickup it. If false, it leaves the real flashlight at the player's feet. Safer default is false."); Log.LogInfo((object)"FacilityStartTeleport 1.2.5 loaded. Server-authoritative flashlight spawns, dynamic inside ambience state, and entrance-safe spawns enabled."); } private void Update() { if (EnableMod == null || !EnableMod.Value) { return; } if (Time.time < nextCheckTime) { MaintainInsideStateIfNeeded(); return; } nextCheckTime = Time.time + 0.5f; MaintainInsideStateIfNeeded(); if (!IsOnPlayableMoon()) { teleportedThisDay = false; readyToTeleportTime = -1f; cachedInsideNodes.Clear(); return; } int currentRoundKey = GetCurrentRoundKey(); if (currentRoundKey != lastRoundKey) { lastRoundKey = currentRoundKey; teleportedThisDay = false; readyToTeleportTime = Time.time + Mathf.Max(0f, TeleportDelayAfterLanding.Value); cachedInsideNodes.Clear(); nextNodeRefreshTime = 0f; if (DebugLogging.Value) { Log.LogInfo((object)("FacilityStartTeleport detected a new day/round. Waiting " + TeleportDelayAfterLanding.Value.ToString("0.0") + " seconds before teleporting.")); } } if (teleportedThisDay) { return; } if (readyToTeleportTime < 0f) { readyToTeleportTime = Time.time + Mathf.Max(0f, TeleportDelayAfterLanding.Value); } else { if (Time.time < readyToTeleportTime) { return; } if (RequireDungeonFinished.Value && !DungeonFinishedGenerating()) { if (DebugLogging.Value) { Log.LogInfo((object)"FacilityStartTeleport waiting for dungeon generation to finish before teleporting."); } readyToTeleportTime = Time.time + 1f; } else if (RefreshInsideNodesIfNeeded()) { TeleportPlayersIntoFacility(); } } } private bool IsOnPlayableMoon() { try { if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)RoundManager.Instance == (Object)null) { return false; } if (ReflectionUtil.GetBoolField(StartOfRound.Instance, "inShipPhase")) { return false; } if (ReflectionUtil.GetBoolField(StartOfRound.Instance, "travellingToNewLevel")) { return false; } if (!ReflectionUtil.GetBoolField(StartOfRound.Instance, "shipHasLanded") && Time.timeSinceLevelLoad < 10f) { return false; } if (SkipCompanyMoon != null && SkipCompanyMoon.Value && IsCompanyMoon()) { return false; } return true; } catch { return false; } } private bool IsCompanyMoon() { try { object fieldObject = ReflectionUtil.GetFieldObject(StartOfRound.Instance, "currentLevel"); if (fieldObject == null) { return false; } string text = ReflectionUtil.GetStringField(fieldObject, "PlanetName").ToLowerInvariant(); string text2 = ReflectionUtil.GetStringField(fieldObject, "levelName").ToLowerInvariant(); return text.Contains("gordion") || text.Contains("company") || text2.Contains("gordion") || text2.Contains("company"); } catch { return false; } } private bool DungeonFinishedGenerating() { if ((Object)(object)RoundManager.Instance == (Object)null) { return false; } if (ReflectionUtil.GetBoolField(RoundManager.Instance, "dungeonFinishedGeneratingForAllPlayers")) { return true; } if (ReflectionUtil.GetBoolField(RoundManager.Instance, "playersFinishedGeneratingFloor")) { return true; } bool boolField = ReflectionUtil.GetBoolField(RoundManager.Instance, "dungeonIsGenerating"); return ReflectionUtil.GetBoolField(RoundManager.Instance, "dungeonCompletedGenerating") && !boolField; } private int GetCurrentRoundKey() { int num = ReflectionUtil.GetIntField(StartOfRound.Instance, "randomMapSeed"); if (num == 0 && (Object)(object)RoundManager.Instance != (Object)null) { num = ReflectionUtil.GetIntField(RoundManager.Instance, "randomMapSeed"); } int intField = ReflectionUtil.GetIntField(StartOfRound.Instance, "currentLevelID"); if (num == 0) { num = Mathf.RoundToInt(Time.timeSinceLevelLoad * 1000f); } return num ^ (intField << 16); } private bool RefreshInsideNodesIfNeeded() { if (cachedInsideNodes.Count > 0 && Time.time < nextNodeRefreshTime) { return true; } nextNodeRefreshTime = Time.time + 2f; cachedInsideNodes.Clear(); AddInsideNodesFromRoundManager(cachedInsideNodes); if (cachedInsideNodes.Count == 0) { AddInsideNodesFromScene(cachedInsideNodes); } if (cachedInsideNodes.Count == 0) { AddEntranceFallbackNodes(cachedInsideNodes); } if (DebugLogging.Value) { Log.LogInfo((object)("FacilityStartTeleport inside spawn nodes found: " + cachedInsideNodes.Count)); } return cachedInsideNodes.Count > 0; } private void AddInsideNodesFromRoundManager(List list) { if (!((Object)(object)RoundManager.Instance == (Object)null)) { object fieldObject = ReflectionUtil.GetFieldObject(RoundManager.Instance, "insideAINodes"); AddTransformsFromObject(fieldObject, list); object fieldObject2 = ReflectionUtil.GetFieldObject(RoundManager.Instance, "allInsideAINodes"); AddTransformsFromObject(fieldObject2, list); } } private void AddInsideNodesFromScene(List list) { try { GameObject[] array = GameObject.FindGameObjectsWithTag("AINode"); GameObject[] array2 = array; foreach (GameObject val in array2) { if (!((Object)(object)val == (Object)null)) { string text = GetTransformPath(val.transform).ToLowerInvariant(); if (!text.Contains("outside") && !text.Contains("ship") && !text.Contains("hangar") && (text.Contains("inside") || text.Contains("levelgeneration") || text.Contains("dungeon") || text.Contains("factory"))) { AddUniqueTransform(val.transform, list); } } } } catch { } } private void AddEntranceFallbackNodes(List list) { try { EntranceTeleport[] array = Object.FindObjectsOfType(); EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { if (!((Object)(object)val == (Object)null) && !ReflectionUtil.GetBoolField(val, "isEntranceToBuilding")) { AddUniqueTransform(((Component)val).transform, list); } } } catch { } } private void AddTransformsFromObject(object value, List list) { if (value == null) { return; } Transform val = (Transform)((value is Transform) ? value : null); if ((Object)(object)val != (Object)null) { AddUniqueTransform(val, list); return; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val2 != (Object)null) { AddUniqueTransform(val2.transform, list); return; } Component val3 = (Component)((value is Component) ? value : null); if ((Object)(object)val3 != (Object)null) { AddUniqueTransform(val3.transform, list); } else { if (!(value is IEnumerable enumerable)) { return; } foreach (object item in enumerable) { if (item == null) { continue; } Transform val4 = (Transform)((item is Transform) ? item : null); if ((Object)(object)val4 != (Object)null) { AddUniqueTransform(val4, list); continue; } GameObject val5 = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val5 != (Object)null) { AddUniqueTransform(val5.transform, list); continue; } Component val6 = (Component)((item is Component) ? item : null); if ((Object)(object)val6 != (Object)null) { AddUniqueTransform(val6.transform, list); } } } } private void AddUniqueTransform(Transform transform, List list) { if (!((Object)(object)transform == (Object)null) && !list.Contains(transform)) { list.Add(transform); } } private void TeleportPlayersIntoFacility() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] playersToMove = GetPlayersToMove(); if (playersToMove == null || playersToMove.Length == 0) { return; } int num = 0; int num2 = 0; int currentRoundKey = GetCurrentRoundKey(); for (int i = 0; i < playersToMove.Length; i++) { PlayerControllerB val = playersToMove[i]; if (!ShouldMovePlayer(val)) { continue; } int num3 = currentRoundKey ^ ((i + 1) * 92821) ^ GetPlayerClientIdSafe(val); if (!TryGetRandomFacilityPosition(num3, out var position, out var yRot)) { if (DebugLogging.Value) { Log.LogWarning((object)("Could not find a safe facility spawn for player " + ((Object)val).name + ".")); } continue; } SetPlayerInsideFactoryFields(val); TeleportPlayer(val, position, yRot); SetPlayerInsideFactoryFields(val); TriggerGameInsideFactoryStateOnce(val); if (MaybeGiveStartingFlashlight(val, num3 ^ 0x6A2B1C)) { num2++; } num++; if (DebugLogging.Value) { Log.LogInfo((object)("Teleported player " + ((Object)val).name + " into facility at " + ((Vector3)(ref position)).ToString("F2"))); } } if (num > 0) { teleportedThisDay = true; maintainInsideStateUntil = Time.time + Mathf.Clamp(MaintainInsideStateSeconds.Value, 0f, 3f); if (num2 > 0) { DoorTip("Facility Drop", "You wake up somewhere inside the facility with a flashlight.", warning: false); } else { DoorTip("Facility Drop", "You wake up somewhere inside the facility.", warning: false); } } } private PlayerControllerB[] GetPlayersToMove() { try { if (!TeleportAllActivePlayers.Value) { PlayerControllerB localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer == (Object)null) { return (PlayerControllerB[])(object)new PlayerControllerB[0]; } return (PlayerControllerB[])(object)new PlayerControllerB[1] { localPlayer }; } object fieldObject = ReflectionUtil.GetFieldObject(StartOfRound.Instance, "allPlayerScripts"); if (fieldObject is PlayerControllerB[] array && array.Length != 0) { return array; } } catch { } return Object.FindObjectsOfType(); } private PlayerControllerB GetLocalPlayer() { try { if ((Object)(object)GameNetworkManager.Instance == (Object)null) { return null; } return GameNetworkManager.Instance.localPlayerController; } catch { return null; } } private bool ShouldMovePlayer(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } if (!player.isPlayerControlled || player.isPlayerDead) { return false; } return true; } private bool TryGetRandomFacilityPosition(int seed, out Vector3 position, out float yRot) { //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_009a: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_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_0176: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; yRot = 0f; Random random = new Random(seed); if (cachedInsideNodes.Count == 0) { return false; } int num = Mathf.Max(10, MaxSpawnAttempts.Value); float num2 = Mathf.Max(0f, SpawnRadiusFromNode.Value); Vector3 val2 = default(Vector3); for (int i = 0; i < num; i++) { Transform val = cachedInsideNodes[random.Next(cachedInsideNodes.Count)]; if (!((Object)(object)val == (Object)null)) { if (!TryGetRoundManagerNavmeshPosition(val.position, seed ^ i, out var position2)) { float num3 = (float)(random.NextDouble() * Math.PI * 2.0); float num4 = (float)random.NextDouble() * num2; ((Vector3)(ref val2))..ctor(Mathf.Cos(num3) * num4, 0f, Mathf.Sin(num3) * num4); position2 = val.position + val2; } if (TryValidateAndAdjustSpawn(position2, out position)) { yRot = (float)(random.NextDouble() * 360.0); return true; } } } for (int j = 0; j < cachedInsideNodes.Count; j++) { Transform val3 = cachedInsideNodes[j]; if (!((Object)(object)val3 == (Object)null) && TryValidateAndAdjustSpawn(val3.position, out position)) { yRot = (float)(random.NextDouble() * 360.0); return true; } } return false; } private bool TryGetInverseTeleporterPosition(int seed, out Vector3 position) { //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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; try { ShipTeleporter[] array = Object.FindObjectsOfType(); ShipTeleporter[] array2 = array; foreach (ShipTeleporter val in array2) { if (!((Object)(object)val == (Object)null) && val.isInverseTeleporter) { ReflectionUtil.SetIntField(val, "shipTeleporterSeed", seed); ReflectionUtil.CallNoArgMethod(val, "SetRandomSeed"); object obj = ReflectionUtil.CallNoArgMethodReturn(val, "GetInverseTelePosition"); if (obj is Vector3) { position = (Vector3)obj; return true; } } } } catch { } return false; } private bool TryGetRoundManagerNavmeshPosition(Vector3 center, int seed, out Vector3 position) { //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_0088: 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_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_00fd: 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_0111: 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) position = Vector3.zero; if ((Object)(object)RoundManager.Instance == (Object)null) { return false; } string[] array = new string[2] { "GetRandomNavMeshPositionInRadius", "GetRandomNavMeshPositionInRadiusSpherical" }; for (int i = 0; i < array.Length; i++) { MethodInfo[] methods = ((object)RoundManager.Instance).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { if (methodInfo.Name != array[i] || !BuildNavmeshMethodArgs(methodInfo, center, seed, out var args)) { continue; } try { object obj = methodInfo.Invoke(RoundManager.Instance, args); if (obj is Vector3) { position = (Vector3)obj; return true; } for (int k = 0; k < args.Length; k++) { if (args[k] is Vector3) { Vector3 val = (Vector3)args[k]; if (val != Vector3.zero) { position = val; return true; } } } } catch { } } } return false; } private bool BuildNavmeshMethodArgs(MethodInfo method, Vector3 center, int seed, out object[] args) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) args = null; try { ParameterInfo[] parameters = method.GetParameters(); args = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; Type type = (parameterType.IsByRef ? parameterType.GetElementType() : parameterType); string text = ((parameters[i].Name == null) ? "" : parameters[i].Name.ToLowerInvariant()); if (type == typeof(Vector3)) { args[i] = center; } else if (type == typeof(float)) { if (text.Contains("radius")) { args[i] = Mathf.Max(0.5f, NavmeshSearchRadius.Value); } else { args[i] = 0f; } } else if (type == typeof(int)) { if (text.Contains("seed")) { args[i] = seed; } else { args[i] = -1; } } else if (type == typeof(bool)) { args[i] = false; } else if (type == typeof(Random)) { args[i] = new Random(seed); } else { args[i] = GetDefaultValue(type); } } return true; } catch { return false; } } private bool TryValidateAndAdjustSpawn(Vector3 candidate, out Vector3 adjustedPosition) { //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_002f: 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_002b: 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_0061: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_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_00aa: 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_00e0: 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_0116: Unknown result type (might be due to invalid IL or missing references) adjustedPosition = candidate; if (TrySampleNavMeshReflective(candidate, Mathf.Max(0.5f, NavmeshSearchRadius.Value), out var position)) { candidate = position; } if (!IsHeightNearInsideNode(candidate)) { return false; } if (!TryFindFloor(candidate, out var floorPosition)) { return false; } adjustedPosition = floorPosition + Vector3.up * Mathf.Max(0.1f, PlayerHeightOffset.Value); if (!LooksInsideFacility(adjustedPosition)) { return false; } if (!IsHeightNearInsideNode(adjustedPosition)) { return false; } if (!IsFarEnoughFromEntrances(adjustedPosition)) { return false; } if (!CapsuleHasRoom(adjustedPosition)) { return false; } if (!HasCeilingClearance(adjustedPosition)) { return false; } if (!HasWallClearance(adjustedPosition)) { return false; } return true; } private bool TryFindFloor(Vector3 candidate, out Vector3 floorPosition) { //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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0050: 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_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_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_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) floorPosition = candidate; float num = Mathf.Clamp(FloorRaycastHeight.Value, 0.25f, 2f); float num2 = Mathf.Clamp(FloorRaycastDistance.Value, 1f, 6f); Vector3 val = candidate + Vector3.up * num; float num3 = num2; RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, num3, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return false; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !ShouldIgnoreColliderForSafety(((RaycastHit)(ref val2)).collider) && !(Vector3.Dot(((RaycastHit)(ref val2)).normal, Vector3.up) < 0.55f) && !ShouldRejectFloorCollider(((RaycastHit)(ref val2)).collider)) { floorPosition = ((RaycastHit)(ref val2)).point; return true; } } return false; } private bool TrySampleNavMeshReflective(Vector3 center, float radius, out Vector3 position) { //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_00ac: 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_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) position = center; try { Type type = Type.GetType("UnityEngine.AI.NavMesh, UnityEngine.AIModule"); Type type2 = Type.GetType("UnityEngine.AI.NavMeshHit, UnityEngine.AIModule"); if (type == null || type2 == null) { return false; } MethodInfo method = type.GetMethod("SamplePosition", BindingFlags.Static | BindingFlags.Public, null, new Type[4] { typeof(Vector3), type2.MakeByRefType(), typeof(float), typeof(int) }, null); if (method == null) { return false; } object obj = Activator.CreateInstance(type2); object[] array = new object[4] { center, obj, radius, -1 }; object obj2 = method.Invoke(null, array); if (!(obj2 is bool) || !(bool)obj2) { return false; } object obj3 = array[1]; PropertyInfo property = type2.GetProperty("position", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object value = property.GetValue(obj3, null); if (value is Vector3) { position = (Vector3)value; return true; } } FieldInfo field = type2.GetField("m_Position", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value2 = field.GetValue(obj3); if (value2 is Vector3) { position = (Vector3)value2; return true; } } } catch { } return false; } private bool IsHeightNearInsideNode(Vector3 position) { //IL_0037: 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_006b: 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_0088: 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_0099: 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_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_00be: Unknown result type (might be due to invalid IL or missing references) if (cachedInsideNodes.Count == 0) { return true; } float num = Mathf.Max(0.5f, MaximumHeightDifferenceFromNearestNode.Value); float num2 = float.MaxValue; float y = position.y; Vector2 val2 = default(Vector2); Vector2 val3 = default(Vector2); for (int i = 0; i < cachedInsideNodes.Count; i++) { Transform val = cachedInsideNodes[i]; if (!((Object)(object)val == (Object)null)) { ((Vector2)(ref val2))..ctor(val.position.x, val.position.z); ((Vector2)(ref val3))..ctor(position.x, position.z); Vector2 val4 = val2 - val3; float sqrMagnitude = ((Vector2)(ref val4)).sqrMagnitude; if (sqrMagnitude < num2) { num2 = sqrMagnitude; y = val.position.y; } } } return Mathf.Abs(position.y - y) <= num; } private bool ShouldRejectFloorCollider(Collider collider) { if ((Object)(object)collider == (Object)null) { return true; } if (RejectPipeAndPropFloors != null && !RejectPipeAndPropFloors.Value) { return false; } string text = GetTransformPath(((Component)collider).transform).ToLowerInvariant(); string text2 = ((Object)((Component)collider).gameObject).name.ToLowerInvariant(); if (text.Contains("pipe") || text.Contains("socket") || text.Contains("steam") || text.Contains("valve") || text.Contains("vent") || text.Contains("rail") || text.Contains("ceiling") || text.Contains("roof") || text.Contains("wire") || text.Contains("cable") || text.Contains("prop") || text.Contains("lung") || text2.Contains("pipe") || text2.Contains("socket") || text2.Contains("steam") || text2.Contains("valve") || text2.Contains("vent") || text2.Contains("rail") || text2.Contains("ceiling") || text2.Contains("roof") || text2.Contains("wire") || text2.Contains("cable")) { return true; } return false; } private bool CapsuleHasRoom(Vector3 position) { //IL_0035: 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_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_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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_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_005e: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(CapsuleRadius.Value, 0.1f, 1f); float num2 = Mathf.Clamp(CapsuleHeight.Value, 1f, 3f); Vector3 val = position + Vector3.up * 0.35f; Vector3 val2 = position + Vector3.up * num2; Collider[] array = Physics.OverlapCapsule(val, val2, num, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return true; } foreach (Collider val3 in array) { if (!((Object)(object)val3 == (Object)null) && !ShouldIgnoreColliderForSafety(val3)) { return false; } } return true; } private bool HasCeilingClearance(Vector3 position) { //IL_0016: 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_0021: 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_002b: 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_0047: 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) float num = Mathf.Max(1.25f, MinimumCeilingClearance.Value); Vector3 val = position + Vector3.up * 0.35f; RaycastHit[] array = Physics.SphereCastAll(val, Mathf.Max(0.1f, CapsuleRadius.Value * 0.75f), Vector3.up, num, -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)); for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !ShouldIgnoreColliderForSafety(((RaycastHit)(ref val2)).collider)) { return false; } } return true; } private bool HasWallClearance(Vector3 position) { //IL_0033: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_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_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_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_0081: 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_0090: 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_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_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_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_00bf: 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_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_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_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_00f1: 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_0105: 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) float num = Mathf.Clamp(MinimumWallClearance.Value, 0f, 2f); if (num <= 0.01f) { return true; } Vector3 val = position + Vector3.up * 1.05f; Vector3[] obj = new Vector3[8] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val2 = Vector3.forward + Vector3.left; obj[4] = ((Vector3)(ref val2)).normalized; val2 = Vector3.forward + Vector3.right; obj[5] = ((Vector3)(ref val2)).normalized; val2 = Vector3.back + Vector3.left; obj[6] = ((Vector3)(ref val2)).normalized; val2 = Vector3.back + Vector3.right; obj[7] = ((Vector3)(ref val2)).normalized; Vector3[] array = (Vector3[])(object)obj; for (int i = 0; i < array.Length; i++) { RaycastHit[] array2 = Physics.RaycastAll(val, array[i], num, -1, (QueryTriggerInteraction)1); if (array2 == null || array2.Length == 0) { continue; } Array.Sort(array2, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); for (int j = 0; j < array2.Length; j++) { if (!((Object)(object)((RaycastHit)(ref array2[j])).collider == (Object)null) && !ShouldIgnoreColliderForSafety(((RaycastHit)(ref array2[j])).collider)) { return false; } } } return true; } private bool IsFarEnoughFromEntrances(Vector3 position) { //IL_0062: 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_0081: 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_00a6: 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) float num = ((MinimumDistanceFromEntrance == null) ? 8f : Mathf.Max(0f, MinimumDistanceFromEntrance.Value)); if (num <= 0.01f) { return true; } try { EntranceTeleport[] array = Object.FindObjectsOfType(); Vector3 val2 = default(Vector3); Vector3 val3 = default(Vector3); foreach (EntranceTeleport val in array) { if (!((Object)(object)val == (Object)null)) { ((Vector3)(ref val2))..ctor(position.x, 0f, position.z); ((Vector3)(ref val3))..ctor(((Component)val).transform.position.x, 0f, ((Component)val).transform.position.z); if (Vector3.Distance(val2, val3) < num) { return false; } } } } catch { } return true; } private bool LooksInsideFacility(Vector3 position) { //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_0036: Unknown result type (might be due to invalid IL or missing references) string text = ""; float num = float.MaxValue; for (int i = 0; i < cachedInsideNodes.Count; i++) { Transform val = cachedInsideNodes[i]; if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.SqrMagnitude(val.position - position); if (num2 < num) { num = num2; text = GetTransformPath(val).ToLowerInvariant(); } } } if (text.Contains("outside") || text.Contains("hangar") || text.Contains("ship")) { return false; } return true; } private bool ShouldIgnoreColliderForSafety(Collider collider) { if ((Object)(object)collider == (Object)null) { return true; } if (collider.isTrigger) { return true; } string text = GetTransformPath(((Component)collider).transform).ToLowerInvariant(); string text2 = ((Object)((Component)collider).gameObject).name.ToLowerInvariant(); if (text.Contains("player") || text.Contains("enemy") || text.Contains("trigger") || text.Contains("scan") || text.Contains("item") || text.Contains("grabbable") || text.Contains("ainode") || text.Contains("audio") || text.Contains("interact") || text2.Contains("player") || text2.Contains("trigger") || text2.Contains("scan") || text2.Contains("ainode") || text2.Contains("interact")) { return true; } return false; } private void TeleportPlayer(PlayerControllerB player, Vector3 position, float yRot) { //IL_0014: 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_0071: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !CallTeleportPlayerMethod(player, position, yRot)) { CharacterController component = ((Component)player).GetComponent(); bool enabled = (Object)(object)component != (Object)null && ((Collider)component).enabled; if ((Object)(object)component != (Object)null) { ((Collider)component).enabled = false; } ((Component)player).transform.position = position; ((Component)player).transform.rotation = Quaternion.Euler(0f, yRot, 0f); if ((Object)(object)component != (Object)null) { ((Collider)component).enabled = enabled; } } } private bool CallTeleportPlayerMethod(PlayerControllerB player, Vector3 position, float yRot) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) 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(); bool flag = false; for (int j = 0; j < parameters.Length; j++) { if (parameters[j].ParameterType == typeof(Vector3)) { flag = true; break; } } if (!flag) { continue; } object[] array2 = new object[parameters.Length]; for (int k = 0; k < parameters.Length; k++) { Type parameterType = parameters[k].ParameterType; string text = ((parameters[k].Name == null) ? "" : parameters[k].Name.ToLowerInvariant()); if (parameterType == typeof(Vector3)) { array2[k] = position; } else if (parameterType == typeof(float)) { array2[k] = yRot; } else if (parameterType == typeof(bool)) { if (text.Contains("rotation") || text.Contains("rot")) { array2[k] = true; } else if (text.Contains("enable")) { array2[k] = true; } else { array2[k] = false; } } else { array2[k] = GetDefaultValue(parameterType); } } methodInfo.Invoke(player, array2); return true; } } catch (Exception ex) { if (DebugLogging != null && DebugLogging.Value && Log != null) { Log.LogWarning((object)("TeleportPlayer reflection failed, using transform fallback: " + ex.Message)); } } return false; } private bool MaybeGiveStartingFlashlight(PlayerControllerB player, int seed) { if ((Object)(object)player == (Object)null) { return false; } if (!IsHostOrServer()) { return false; } if (GiveFlashlightIfInventoryEmpty == null || !GiveFlashlightIfInventoryEmpty.Value) { return false; } if (PlayerHasAnyInventoryItem(player)) { return false; } Random random = new Random(seed); if (random.NextDouble() > (double)Mathf.Clamp01(FlashlightGiveChance.Value)) { return false; } bool flag = random.NextDouble() <= (double)Mathf.Clamp01(ProFlashlightChance.Value); Item val = null; if (flag) { val = FindItemByConfigNames(ProFlashlightNames.Value); } if ((Object)(object)val == (Object)null) { val = FindItemByConfigNames(NormalFlashlightNames.Value); } if ((Object)(object)val == (Object)null && !flag) { val = FindItemByConfigNames(ProFlashlightNames.Value); } if ((Object)(object)val == (Object)null) { if (DebugLogging.Value) { Log.LogWarning((object)"Could not find normal or pro flashlight Item in allItemsList."); } return false; } bool flag2 = GiveItemToPlayer(player, val); if (flag2 && DebugLogging.Value) { Log.LogInfo((object)("Gave starting item to " + ((Object)player).name + ": " + val.itemName)); } return flag2; } private bool PlayerHasAnyInventoryItem(PlayerControllerB player) { try { GrabbableObject[] itemSlots = player.ItemSlots; if (itemSlots != null) { for (int i = 0; i < itemSlots.Length; i++) { if ((Object)(object)itemSlots[i] != (Object)null) { return true; } } } object fieldObject = ReflectionUtil.GetFieldObject(player, "currentlyHeldObjectServer"); object fieldObject2 = ReflectionUtil.GetFieldObject(player, "currentlyHeldObject"); if (fieldObject != null || fieldObject2 != null) { return true; } } catch { } return false; } private Item FindItemByConfigNames(string namesCsv) { List allGameItems = GetAllGameItems(); if (allGameItems.Count == 0) { return null; } string[] array = SplitCsv(namesCsv); for (int i = 0; i < array.Length; i++) { string text = NormalizeName(array[i]); if (string.IsNullOrEmpty(text)) { continue; } for (int j = 0; j < allGameItems.Count; j++) { Item val = allGameItems[j]; if (!((Object)(object)val == (Object)null) && NormalizeName(val.itemName) == text) { return val; } } } for (int k = 0; k < array.Length; k++) { string text2 = NormalizeName(array[k]); if (string.IsNullOrEmpty(text2)) { continue; } for (int l = 0; l < allGameItems.Count; l++) { Item val2 = allGameItems[l]; if (!((Object)(object)val2 == (Object)null)) { string text3 = NormalizeName(val2.itemName); if (text3.Contains(text2) || text2.Contains(text3)) { return val2; } } } } return null; } private List GetAllGameItems() { List list = new List(); try { object fieldObject = ReflectionUtil.GetFieldObject(StartOfRound.Instance, "allItemsList"); object fieldObject2 = ReflectionUtil.GetFieldObject(fieldObject, "itemsList"); if (fieldObject2 is IEnumerable enumerable) { foreach (object item in enumerable) { Item val = (Item)((item is Item) ? item : null); if ((Object)(object)val != (Object)null && !list.Contains(val)) { list.Add(val); } } } } catch { } return list; } private string[] SplitCsv(string value) { if (string.IsNullOrEmpty(value)) { return new string[0]; } return value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); } private string NormalizeName(string value) { if (string.IsNullOrEmpty(value)) { return ""; } return value.ToLowerInvariant().Replace(" ", "").Replace("-", "") .Replace("_", "") .Trim(); } private bool GiveItemToPlayer(PlayerControllerB player, Item itemDef) { //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_006f: 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) try { if (!IsHostOrServer()) { return false; } if ((Object)(object)player == (Object)null || (Object)(object)itemDef == (Object)null || (Object)(object)itemDef.spawnPrefab == (Object)null) { return false; } if (GetFirstEmptyItemSlot(player) < 0) { return false; } Vector3 val = FindStartingItemDropPosition(player); GameObject val2 = Object.Instantiate(itemDef.spawnPrefab, val, Quaternion.identity); if ((Object)(object)val2 == (Object)null) { return false; } GrabbableObject component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return false; } SetupStartingItemAsRealDroppedItem(val2, component, itemDef, player); TryFillBattery(component); TrySpawnNetworkObject(val2); if (EquipGivenFlashlight != null && EquipGivenFlashlight.Value) { ((MonoBehaviour)this).StartCoroutine(TryVanillaPickupAfterSpawn(player, component)); } return true; } catch (Exception ex) { if (DebugLogging.Value) { Log.LogWarning((object)("Failed to spawn starting flashlight: " + ex.Message)); } } return false; } private Vector3 FindStartingItemDropPosition(PlayerControllerB player) { //IL_001e: 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_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_003d: 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_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) //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_0067: 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_0012: 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_00a0: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return Vector3.zero; } Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * 0.65f + Vector3.up * 0.75f; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val + Vector3.up * 1f, Vector3.down, ref val2, 4f, -1, (QueryTriggerInteraction)1)) { return ((RaycastHit)(ref val2)).point + Vector3.up * 0.25f; } return val; } private void SetupStartingItemAsRealDroppedItem(GameObject itemObject, GrabbableObject grabbable, Item itemDef, PlayerControllerB player) { if (!((Object)(object)itemObject == (Object)null) && !((Object)(object)grabbable == (Object)null)) { itemObject.transform.SetParent((Transform)null, true); grabbable.itemProperties = itemDef; grabbable.grabbable = true; grabbable.grabbableToEnemies = true; grabbable.hasHitGround = true; grabbable.fallTime = 0f; grabbable.playerHeldBy = null; grabbable.isHeld = false; grabbable.isPocketed = false; grabbable.isInElevator = false; grabbable.isInShipRoom = false; ReflectionUtil.SetBoolField(grabbable, "heldByPlayerOnServer", value: false); ReflectionUtil.SetBoolField(grabbable, "isInFactory", value: true); ReflectionUtil.SetBoolField(grabbable, "isInShipRoom", value: false); ReflectionUtil.SetBoolField(grabbable, "isInElevator", value: false); ReflectionUtil.SetBoolField(grabbable, "wasOwnerLastFrame", value: false); ReflectionUtil.SetBoolField(grabbable, "deactivated", value: false); ReflectionUtil.SetFieldObject(grabbable, "playerHeldBy", null); ReflectionUtil.SetFieldObject(grabbable, "parentObject", null); ReflectionUtil.CallFlexibleMethod(grabbable, "EnableItemMeshes", new object[1] { true }); ReflectionUtil.CallFlexibleMethod(grabbable, "EnablePhysics", new object[1] { true }); ReflectionUtil.CallNoArgMethod(grabbable, "FallToGround"); } } [IteratorStateMachine(typeof(d__84))] private IEnumerator TryVanillaPickupAfterSpawn(PlayerControllerB player, GrabbableObject grabbable) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__84(0) { <>4__this = this, player = player, grabbable = grabbable }; } private bool IsItemInPlayerInventory(PlayerControllerB player, GrabbableObject item) { try { if ((Object)(object)player == (Object)null || (Object)(object)item == (Object)null || player.ItemSlots == null) { return false; } for (int i = 0; i < player.ItemSlots.Length; i++) { if ((Object)(object)player.ItemSlots[i] == (Object)(object)item) { return true; } } } catch { } return false; } private bool TryCallGrabObjectServerRpc(PlayerControllerB player, GameObject itemObject) { try { if ((Object)(object)player == (Object)null || (Object)(object)itemObject == (Object)null) { return false; } Component networkObjectComponent = GetNetworkObjectComponent(itemObject); if ((Object)(object)networkObjectComponent == (Object)null) { return false; } MethodInfo[] methods = ((object)player).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (methodInfo.Name != "GrabObjectServerRpc") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array2 = new object[parameters.Length]; bool flag = true; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; Type type = (parameterType.IsByRef ? parameterType.GetElementType() : parameterType); if (type.Name == "NetworkObjectReference") { object obj = CreateNetworkObjectReference(type, networkObjectComponent); if (obj == null) { flag = false; break; } array2[j] = obj; } else if (type == typeof(bool)) { array2[j] = false; } else if (type == typeof(int)) { array2[j] = 0; } else { array2[j] = GetDefaultValue(type); } } if (flag) { methodInfo.Invoke(player, array2); return true; } } } catch { } return false; } private Component GetNetworkObjectComponent(GameObject itemObject) { if ((Object)(object)itemObject == (Object)null) { return null; } Component[] components = itemObject.GetComponents(); foreach (Component val in components) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "NetworkObject") { return val; } } return null; } private object CreateNetworkObjectReference(Type referenceType, Component networkObject) { try { if (referenceType == null || (Object)(object)networkObject == (Object)null) { return null; } ConstructorInfo[] constructors = referenceType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ConstructorInfo[] array = constructors; foreach (ConstructorInfo constructorInfo in array) { ParameterInfo[] parameters = constructorInfo.GetParameters(); if (parameters.Length == 1) { Type parameterType = parameters[0].ParameterType; if (parameterType.IsAssignableFrom(((object)networkObject).GetType())) { return constructorInfo.Invoke(new object[1] { networkObject }); } } } } catch { } return null; } private int GetFirstEmptyItemSlot(PlayerControllerB player) { try { if ((Object)(object)player == (Object)null) { return -1; } GrabbableObject[] itemSlots = player.ItemSlots; if (itemSlots != null) { for (int i = 0; i < itemSlots.Length; i++) { if ((Object)(object)itemSlots[i] == (Object)null) { return i; } } } } catch { } return -1; } private void ForceItemIntoPlayerSlot(PlayerControllerB player, GrabbableObject grabbable, int slot) { //IL_00b2: 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_00de: 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)player == (Object)null) && !((Object)(object)grabbable == (Object)null)) { GrabbableObject[] itemSlots = player.ItemSlots; if (itemSlots != null && slot >= 0 && slot < itemSlots.Length) { itemSlots[slot] = grabbable; } Transform val = ReflectionUtil.GetTransformField(player, "localItemHolder"); if ((Object)(object)val == (Object)null) { val = ReflectionUtil.GetTransformField(player, "serverItemHolder"); } if ((Object)(object)val == (Object)null) { val = ((Component)player).transform; } grabbable.parentObject = val; ((Component)grabbable).transform.SetParent(val, false); ((Component)grabbable).transform.localPosition = (((Object)(object)grabbable.itemProperties != (Object)null) ? grabbable.itemProperties.positionOffset : Vector3.zero); ((Component)grabbable).transform.localEulerAngles = (((Object)(object)grabbable.itemProperties != (Object)null) ? grabbable.itemProperties.rotationOffset : Vector3.zero); ReflectionUtil.SetIntField(player, "currentItemSlot", slot); ReflectionUtil.SetBoolField(player, "isHoldingObject", value: true); ReflectionUtil.SetBoolField(player, "twoHanded", (Object)(object)grabbable.itemProperties != (Object)null && grabbable.itemProperties.twoHanded); ReflectionUtil.SetFieldObject(player, "currentlyHeldObjectServer", grabbable); ReflectionUtil.SetFieldObject(player, "currentlyHeldObject", grabbable); ReflectionUtil.CallNoArgMethod(grabbable, "GrabItemOnClient"); ReflectionUtil.CallNoArgMethod(grabbable, "GrabItem"); if (EquipGivenFlashlight == null || EquipGivenFlashlight.Value) { ReflectionUtil.CallFlexibleMethod(player, "SwitchToItemSlot", new object[2] { slot, grabbable }); ReflectionUtil.CallNoArgMethod(grabbable, "EquipItem"); } else { ReflectionUtil.CallNoArgMethod(grabbable, "PocketItem"); } ReflectionUtil.CallFlexibleMethod(grabbable, "EnableItemMeshes", new object[1] { true }); } } private void TrySpawnNetworkObject(GameObject itemObject) { if ((Object)(object)itemObject == (Object)null) { return; } if (!IsHostOrServer()) { if (DebugLogging != null && DebugLogging.Value && Log != null) { Log.LogWarning((object)"Blocked a non-host client from spawning a starting flashlight NetworkObject."); } Object.Destroy((Object)(object)itemObject); return; } try { Component[] components = itemObject.GetComponents(); foreach (Component val in components) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); if (type.Name != "NetworkObject") { continue; } MethodInfo method = type.GetMethod("Spawn", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method != null) { method.Invoke(val, null); break; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (methodInfo.Name != "Spawn") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array2 = new object[parameters.Length]; for (int k = 0; k < parameters.Length; k++) { if (parameters[k].ParameterType == typeof(bool)) { array2[k] = true; } else { array2[k] = GetDefaultValue(parameters[k].ParameterType); } } methodInfo.Invoke(val, array2); return; } } } catch { } } private void TryFillBattery(GrabbableObject grabbable) { try { if ((Object)(object)grabbable == (Object)null) { return; } FieldInfo field = typeof(GrabbableObject).GetField("insertedBattery", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object boxedStruct = field.GetValue(grabbable); if (boxedStruct == null) { boxedStruct = Activator.CreateInstance(field.FieldType); } ReflectionUtil.SetFieldOnBoxedStruct(ref boxedStruct, "empty", false); ReflectionUtil.SetFieldOnBoxedStruct(ref boxedStruct, "charge", 1f); field.SetValue(grabbable, boxedStruct); } } catch { } } private bool IsHostOrServer() { try { PlayerControllerB localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer != (Object)null && localPlayer.isHostPlayerObject) { return true; } Type type = FindTypeByName("Unity.Netcode.NetworkManager"); if (type != null) { object obj = null; PropertyInfo property = type.GetProperty("Singleton", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { obj = property.GetValue(null, null); } if (obj == null) { FieldInfo field = type.GetField("Singleton", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { obj = field.GetValue(null); } } if (obj != null && (GetBoolPropertyOrField(obj, "IsServer") || GetBoolPropertyOrField(obj, "IsHost"))) { return true; } } if ((Object)(object)StartOfRound.Instance != (Object)null) { object instance = StartOfRound.Instance; if (GetBoolPropertyOrField(instance, "IsServer") || GetBoolPropertyOrField(instance, "IsHost")) { return true; } } } catch { } return false; } private Type FindTypeByName(string fullName) { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } } catch { } return null; } private bool GetBoolPropertyOrField(object instance, string name) { if (instance == null || string.IsNullOrEmpty(name)) { return false; } try { Type type = instance.GetType(); PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool)) { return (bool)property.GetValue(instance, null); } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(bool)) { return (bool)field.GetValue(instance); } } catch { } return false; } private object GetDefaultValue(Type type) { if (type == null) { return null; } if (type.IsByRef) { type = type.GetElementType(); } if (type.IsValueType) { return Activator.CreateInstance(type); } return null; } private void SetPlayerInsideFactoryFields(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { ReflectionUtil.SetBoolField(player, "isInsideFactory", value: true); ReflectionUtil.SetBoolField(player, "isInFactory", value: true); ReflectionUtil.SetBoolField(player, "isInHangarShipRoom", value: false); ReflectionUtil.SetBoolField(player, "isInElevator", value: false); ReflectionUtil.SetBoolField(player, "isPlayerAlone", value: false); } } private void TriggerGameInsideFactoryStateOnce(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { ulong playerClientIdSafeUlong = GetPlayerClientIdSafeUlong(player); int num = (int)Mathf.Clamp((float)playerClientIdSafeUlong, 0f, 9999f); ReflectionUtil.CallFlexibleMethod(StartOfRound.Instance, "SwitchIsInsideFactoryRpc", new object[3] { playerClientIdSafeUlong, num, true }); ApplyLocalInsideVisualState(player); } } private void ApplyLocalInsideVisualState(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } PlayerControllerB localPlayer = GetLocalPlayer(); if (!((Object)(object)localPlayer != (Object)null) || !((Object)(object)player != (Object)(object)localPlayer)) { SetPlayerInsideFactoryFields(player); if (ApplyDynamicInsideAudioState == null || ApplyDynamicInsideAudioState.Value) { ApplyDynamicInsideAudioAndLighting(player); } ReflectionUtil.CallNoArgMethod(player, "UpdateCameraOutsideOrInside"); RefreshInsideTimeAndLighting(); if (HideClockDuringInsideSpawn == null || HideClockDuringInsideSpawn.Value) { TrySetClockVisible(visible: false); } } } private void ApplyDynamicInsideAudioAndLighting(PlayerControllerB player) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } AudioReverbTrigger val = FindBestInsideAudioTrigger(((Component)player).transform.position); if ((Object)(object)val == (Object)null) { if (DebugLogging != null && DebugLogging.Value && Log != null) { Log.LogWarning((object)"FacilityStartTeleport could not find an inside AudioReverbTrigger. Falling back to player flags only."); } return; } bool flag = false; try { flag = ReflectionUtil.CallFlexibleMethod(val, "ChangeAudioReverbForPlayer", new object[1] { player }); } catch { flag = false; } ReflectionUtil.SetFieldObject(player, "currentAudioTrigger", val); ReflectionUtil.SetFieldObject(player, "currentAudioTriggerB", null); object fieldObject = ReflectionUtil.GetFieldObject(val, "reverbPreset"); if (fieldObject != null) { ReflectionUtil.SetFieldObject(player, "reverbPreset", fieldObject); } SetPlayerInsideFactoryFields(player); RefreshInsideTimeAndLighting(); if (DebugLogging != null && DebugLogging.Value && Log != null) { string text = ((fieldObject == null) ? "null" : fieldObject.ToString()); Log.LogInfo((object)("Applied dynamic inside audio trigger: " + GetTransformPath(((Component)val).transform) + " preset=" + text + " calledChangeAudio=" + flag)); } } private AudioReverbTrigger FindBestInsideAudioTrigger(Vector3 playerPosition) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) AudioReverbTrigger[] array = null; try { array = Object.FindObjectsOfType(); } catch { return null; } if (array == null || array.Length == 0) { return null; } AudioReverbTrigger result = null; float num = float.MinValue; float tieRadius = ((InsideAudioSearchRadius == null) ? 60f : Mathf.Max(1f, InsideAudioSearchRadius.Value)); foreach (AudioReverbTrigger val in array) { if (!((Object)(object)val == (Object)null)) { float num2 = ScoreInsideAudioTrigger(val, playerPosition, tieRadius); if (num2 > num) { num = num2; result = val; } } } if (num < 10f) { return null; } return result; } private float ScoreInsideAudioTrigger(AudioReverbTrigger trigger, Vector3 playerPosition, float tieRadius) { //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)trigger == (Object)null) { return float.MinValue; } string text = GetTransformPath(((Component)trigger).transform).ToLowerInvariant(); string text2 = (((Object)(object)((Component)trigger).gameObject == (Object)null) ? "" : ((Object)((Component)trigger).gameObject).name.ToLowerInvariant()); float num = 0f; bool boolField = ReflectionUtil.GetBoolField(trigger, "isShipRoom"); bool boolField2 = ReflectionUtil.GetBoolField(trigger, "setInsideAtmosphere"); bool boolField3 = ReflectionUtil.GetBoolField(trigger, "insideLighting"); bool boolField4 = ReflectionUtil.GetBoolField(trigger, "disableAllWeather"); bool boolField5 = ReflectionUtil.GetBoolField(trigger, "enableCurrentLevelWeather"); bool boolField6 = ReflectionUtil.GetBoolField(trigger, "setInElevatorTrigger"); object fieldObject = ReflectionUtil.GetFieldObject(trigger, "reverbPreset"); object fieldObject2 = ReflectionUtil.GetFieldObject(trigger, "audioChanges"); int num2 = CountEnumerable(fieldObject2); if (boolField) { num -= 150f; } if (boolField6) { num -= 80f; } if (boolField5) { num -= 80f; } if (boolField2) { num += 80f; } if (boolField3) { num += 80f; } if (boolField4) { num += 80f; } if (fieldObject != null) { num += 25f; } if (num2 > 0) { 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)((Component)trigger).gameObject != (Object)null && ((Component)trigger).gameObject.activeInHierarchy) { num += 15f; } float num3 = Vector3.Distance(((Component)trigger).transform.position, playerPosition); if (num3 < tieRadius) { num += Mathf.Clamp(10f - num3 * 0.15f, 0f, 10f); } return num; } private int CountEnumerable(object value) { if (value == null) { return 0; } if (value is Array array) { return array.Length; } if (value is ICollection collection) { return collection.Count; } if (!(value is IEnumerable enumerable)) { return 0; } int num = 0; foreach (object item in enumerable) { num++; if (num > 999) { break; } } return num; } private void RefreshInsideTimeAndLighting() { try { if ((Object)(object)TimeOfDay.Instance != (Object)null) { ReflectionUtil.SetBoolField(TimeOfDay.Instance, "insideLighting", value: true); ReflectionUtil.CallFlexibleMethod(TimeOfDay.Instance, "SetInsideLightingDimness", new object[3] { true, 1f, 0f }); } } catch { } } private void TrySetClockVisible(bool visible) { try { HUDManager val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { ReflectionUtil.CallFlexibleMethod(val, "SetClockVisible", new object[1] { visible }); } } catch { } } private void MaintainInsideStateIfNeeded() { if (Time.time > maintainInsideStateUntil) { return; } PlayerControllerB[] playersToMove = GetPlayersToMove(); PlayerControllerB[] array = playersToMove; foreach (PlayerControllerB val in array) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead) { SetPlayerInsideFactoryFields(val); ApplyLocalInsideVisualState(val); } } } private ulong GetPlayerClientIdSafeUlong(PlayerControllerB player) { ulong uLongField = ReflectionUtil.GetULongField(player, "playerClientId"); if (uLongField == 0) { uLongField = ReflectionUtil.GetULongField(player, "actualClientId"); } return uLongField; } private int GetPlayerClientIdSafe(PlayerControllerB player) { int intField = ReflectionUtil.GetIntField(player, "playerClientId"); if (intField == 0) { intField = ReflectionUtil.GetIntField(player, "actualClientId"); } return intField; } private void DoorTip(string header, string body, bool warning) { try { HUDManager val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return; } MethodInfo method = typeof(HUDManager).GetMethod("DisplayTip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { return; } ParameterInfo[] parameters = method.GetParameters(); object[] array = new object[parameters.Length]; int num = 0; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType == typeof(string)) { array[i] = num switch { 1 => body, 0 => header, _ => "FacilityStartTeleport", }; num++; } else if (parameterType == typeof(bool)) { array[i] = warning; } else { array[i] = GetDefaultValue(parameterType); } } method.Invoke(val, array); } catch { } } private string GetTransformPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal static class ReflectionUtil { public static object GetFieldObject(object instance, string fieldName) { try { if (instance == null) { return null; } FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return null; } return field.GetValue(instance); } catch { return null; } } public static Transform GetTransformField(object instance, string fieldName) { object fieldObject = GetFieldObject(instance, fieldName); return (Transform)((fieldObject is Transform) ? fieldObject : null); } public static void SetFieldObject(object instance, string fieldName, object value) { try { if (instance != null) { FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && (value == null || field.FieldType.IsAssignableFrom(value.GetType()))) { field.SetValue(instance, value); } } } catch { } } public static bool GetBoolField(object instance, string fieldName) { try { object fieldObject = GetFieldObject(instance, fieldName); if (fieldObject is bool) { return (bool)fieldObject; } } catch { } return false; } public static void SetBoolField(object instance, string fieldName, bool value) { try { if (instance != null) { FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !(field.FieldType != typeof(bool))) { field.SetValue(instance, value); } } } catch { } } public static void SetIntField(object instance, string fieldName, int value) { try { if (instance == null) { return; } FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { if (field.FieldType == typeof(int)) { field.SetValue(instance, value); } else if (field.FieldType == typeof(uint)) { field.SetValue(instance, (uint)value); } } } catch { } } public static int GetIntField(object instance, string fieldName) { try { object fieldObject = GetFieldObject(instance, fieldName); if (fieldObject is int result) { return result; } if (fieldObject is long) { return (int)(long)fieldObject; } if (fieldObject is ulong) { return (int)(ulong)fieldObject; } if (fieldObject is uint) { return (int)(uint)fieldObject; } } catch { } return 0; } public static ulong GetULongField(object instance, string fieldName) { try { object fieldObject = GetFieldObject(instance, fieldName); if (fieldObject is ulong result) { return result; } if (fieldObject is ulong result2) { return result2; } if (fieldObject is uint) { return (uint)fieldObject; } if (fieldObject is int) { return (ulong)(int)fieldObject; } } catch { } return 0uL; } public static string GetStringField(object instance, string fieldName) { try { object fieldObject = GetFieldObject(instance, fieldName); if (fieldObject is string) { return (string)fieldObject; } } catch { } return ""; } public static bool CallNoArgMethod(object instance, string methodName) { object obj = CallNoArgMethodReturn(instance, methodName); return obj != null; } public static object CallNoArgMethodReturn(object instance, string methodName) { try { if (instance == null) { return null; } MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method == null) { return null; } return method.Invoke(instance, null); } catch { return null; } } public static bool CallFlexibleMethod(object instance, string methodName, object[] preferredArgs) { try { if (instance == null) { return false; } MethodInfo[] methods = instance.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(); object[] array2 = new object[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; object obj = null; bool flag = false; if (preferredArgs != null) { foreach (object obj2 in preferredArgs) { if (obj2 != null) { if (parameterType.IsAssignableFrom(obj2.GetType())) { obj = obj2; flag = true; break; } if (parameterType == typeof(int) && obj2 is int) { obj = obj2; flag = true; break; } if (parameterType == typeof(ulong) && obj2 is ulong) { obj = obj2; flag = true; break; } if (parameterType == typeof(ulong) && obj2 is int) { obj = (ulong)(int)obj2; flag = true; break; } if (parameterType == typeof(uint) && obj2 is int) { obj = (uint)(int)obj2; flag = true; break; } if (parameterType == typeof(bool) && obj2 is bool) { obj = obj2; flag = true; break; } } } } array2[j] = (flag ? obj : GetDefaultValue(parameterType)); } methodInfo.Invoke(instance, array2); return true; } } catch { } return false; } private static object GetDefaultValue(Type type) { if (type == null) { return null; } if (type.IsByRef) { type = type.GetElementType(); } if (type.IsValueType) { return Activator.CreateInstance(type); } return null; } public static void SetFieldOnBoxedStruct(ref object boxedStruct, string fieldName, object value) { try { if (boxedStruct != null) { FieldInfo field = boxedStruct.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { field.SetValue(boxedStruct, value); } } } catch { } } }