Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ExitLineFromEnteredDoor v1.0.1
ExitLineFromEnteredDoor.dll
Decompiled an hour agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.AI; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExitLineFromEnteredDoor { internal class ExitLineController : MonoBehaviour { private sealed class DotLine { public GameObject Container; public readonly List<Transform> Dots = new List<Transform>(); public NavMeshPath Path; public bool HasPath; public float RecomputeIn; public Vector3 LastDestination; public Vector3[] Corners; public float[] CumLen; public float TotalLen; public readonly List<float> BaseArcs = new List<float>(); public float OverflowArc; public float Phase; public bool IsFireExit; public int AppliedColorKind = -1; } private static readonly FieldInfo PingScanField = AccessTools.Field(typeof(HUDManager), "playerPingingScan"); private static readonly FieldInfo IsScreenOnField = AccessTools.Field(typeof(ManualCameraRenderer), "isScreenOn"); private const int MaxDotsPerLine = 400; private readonly List<DotLine> _lines = new List<DotLine>(); private readonly List<EntranceTeleport> _insideDoors = new List<EntranceTeleport>(); private readonly List<Vector3> _destinations = new List<Vector3>(); private readonly List<bool> _destinationIsFireExit = new List<bool>(); private bool _wasInside; private bool _wasVisible; private float _lastPing; private float _pulseTimer; private float _lastScanTime = -9999f; private MineshaftElevatorController _elevator; private bool _searchedElevator; private int _worldLayer; private bool _worldLayerResolved; private float _doorRescanCooldown; private float _errorLogCooldown; private static Mesh _dotMesh; private static Material _dotMatMain; private static Material _dotMatFire; private static readonly List<float> ArcScratch = new List<float>(); private Color _mainColor = new Color(0.38f, 1f, 0.44f, 1f); private Color _fireColor = new Color(1f, 0.3f, 0.3f, 1f); private string _parsedMainText; private string _parsedFireText; private int _dotBudget; private bool _loggedArcFallback; private bool _snapshotDirty; private void Update() { try { UpdateInternal(); } catch (Exception ex) { if (Time.unscaledTime >= _errorLogCooldown) { _errorLogCooldown = Time.unscaledTime + 10f; ExitLinePlugin.Log.LogWarning((object)("ExitLineController error: " + ex)); } HideAll(); } } private void UpdateInternal() { //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) GameNetworkManager instance = GameNetworkManager.Instance; PlayerControllerB val = (((Object)(object)instance != (Object)null) ? instance.localPlayerController : null); StartOfRound instance2 = StartOfRound.Instance; if ((Object)(object)val == (Object)null || (Object)(object)instance2 == (Object)null) { HideAll(); return; } DetectScan(); bool isInsideFactory = val.isInsideFactory; if (!isInsideFactory) { ExitLinePlugin.LastEnteredEntranceId = -1; } if (isInsideFactory && !_wasInside) { OnEnteredInterior(); } _wasInside = isInsideFactory; _doorRescanCooldown -= Time.deltaTime; if (!IsLineVisible(val, instance2, isInsideFactory)) { _wasVisible = false; HideAll(); return; } if (!_wasVisible) { _snapshotDirty = true; for (int i = 0; i < _lines.Count; i++) { _lines[i].RecomputeIn = 0f; } } _wasVisible = true; if (!EnsureDotAssets()) { HideAll(); return; } EnsureWorldLayer(val); bool value = ExitLinePlugin.OnlyShowAfterScan.Value; if (!value || _snapshotDirty) { _destinations.Clear(); _destinationIsFireExit.Clear(); ResolveDestinations(val); if (value && _destinations.Count > 0) { for (int j = 0; j < _lines.Count; j++) { _lines[j].HasPath = false; _lines[j].RecomputeIn = 0f; } _snapshotDirty = false; } } if (_destinations.Count == 0) { HideAll(); return; } EnsurePool(_destinations.Count); _dotBudget = 80; float deltaTime = Time.deltaTime; bool num = _pulseTimer > 0f && ExitLinePlugin.PulseOnScan.Value; _pulseTimer = Mathf.Max(0f, _pulseTimer - deltaTime); float num2 = (num ? (_pulseTimer / Mathf.Max(0.5f, ExitLinePlugin.PulseDuration.Value)) : 0f); float num3 = ExitLinePlugin.FlowSpeed.Value * Mathf.Pow(num2, 1.5f); float value2 = ExitLinePlugin.BreatheStrength.Value; float num4 = Mathf.Max(0.25f, ExitLinePlugin.BreathePeriod.Value); float num5 = 1f + value2 * 0.5f * Mathf.Sin(Time.time * 2f * (float)Math.PI / num4); num5 += ExitLinePlugin.PulseBrightness.Value * num2; if (ExitLinePlugin.OnlyShowAfterScan.Value) { float num6 = ExitLinePlugin.ShowDurationAfterScan.Value - (Time.time - _lastScanTime); num5 *= Mathf.Clamp01(num6 / 1.2f); } ApplyBrightness(num5); Vector3 position = ((Component)val).transform.position; for (int k = 0; k < _lines.Count; k++) { DotLine dotLine = _lines[k]; if (k >= _destinations.Count) { dotLine.RecomputeIn = 0f; SetLineActive(dotLine, on: false); continue; } dotLine.IsFireExit = k < _destinationIsFireExit.Count && _destinationIsFireExit[k]; ApplyLineMaterial(dotLine); if (value) { if (!dotLine.HasPath) { dotLine.RecomputeIn -= deltaTime; if (dotLine.RecomputeIn <= 0f) { ComputePath(dotLine, position, _destinations[k]); } } } else { dotLine.RecomputeIn -= deltaTime; if (dotLine.RecomputeIn <= 0f) { goto IL_03d7; } if (dotLine.HasPath) { Vector3 val2 = _destinations[k] - dotLine.LastDestination; if (((Vector3)(ref val2)).sqrMagnitude > 1f) { goto IL_03d7; } } } goto IL_03ee; IL_03d7: ComputePath(dotLine, position, _destinations[k]); goto IL_03ee; IL_03ee: if (!dotLine.HasPath) { SetLineActive(dotLine, on: false); continue; } if (num3 > 0f) { dotLine.Phase = Mathf.Repeat(dotLine.Phase + deltaTime * num3, 1f); RepositionDots(dotLine); } else if (dotLine.Dots.Count < dotLine.BaseArcs.Count + 1) { RepositionDots(dotLine); } SetLineActive(dotLine, on: true); } BillboardDots(val); } private void BillboardDots(PlayerControllerB localPlayer) { //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_0071: Unknown result type (might be due to invalid IL or missing references) Camera gameplayCamera = localPlayer.gameplayCamera; if ((Object)(object)gameplayCamera == (Object)null) { return; } Quaternion rotation = ((Component)gameplayCamera).transform.rotation; for (int i = 0; i < _lines.Count; i++) { DotLine dotLine = _lines[i]; if ((Object)(object)dotLine.Container == (Object)null || !dotLine.Container.activeSelf) { continue; } List<Transform> dots = dotLine.Dots; for (int j = 0; j < dots.Count; j++) { Transform val = dots[j]; if (((Component)val).gameObject.activeSelf) { val.rotation = rotation; } } } } private bool IsLineVisible(PlayerControllerB localPlayer, StartOfRound sor, bool inside) { if (!ExitLinePlugin.Enabled.Value) { return false; } if (!inside || localPlayer.isPlayerDead || !localPlayer.isPlayerControlled) { return false; } if (sor.inShipPhase) { return false; } if (ExitLinePlugin.RequirePlayerInShip.Value && !AnyPlayerInShip(sor)) { return false; } if (ExitLinePlugin.RequireShipCameraOnYou.Value && !ShipCameraOnLocal(sor, localPlayer)) { return false; } if (ExitLinePlugin.OnlyShowAfterScan.Value && Time.time - _lastScanTime > ExitLinePlugin.ShowDurationAfterScan.Value) { return false; } return true; } private static bool AnyPlayerInShip(StartOfRound sor) { PlayerControllerB[] allPlayerScripts = sor.allPlayerScripts; if (allPlayerScripts == null) { return false; } foreach (PlayerControllerB val in allPlayerScripts) { if ((Object)(object)val != (Object)null && val.isPlayerControlled && !val.isPlayerDead && val.isInHangarShipRoom) { return true; } } return false; } private static bool ShipCameraOnLocal(StartOfRound sor, PlayerControllerB localPlayer) { ManualCameraRenderer mapScreen = sor.mapScreen; if ((Object)(object)mapScreen == (Object)null || (Object)(object)mapScreen.targetedPlayer != (Object)(object)localPlayer) { return false; } if (IsScreenOnField != null && !(bool)IsScreenOnField.GetValue(mapScreen)) { return false; } return true; } private void DetectScan() { HUDManager instance = HUDManager.Instance; if (!((Object)(object)instance == (Object)null) && !(PingScanField == null)) { float num = (float)PingScanField.GetValue(instance); if (num > 0f && _lastPing <= 0f) { _lastScanTime = Time.time; _pulseTimer = ExitLinePlugin.PulseDuration.Value; _snapshotDirty = true; } _lastPing = num; } } private void OnEnteredInterior() { RescanDoors(); _elevator = null; _searchedElevator = false; foreach (DotLine line in _lines) { line.HasPath = false; line.RecomputeIn = 0f; } } private void RescanDoors() { _insideDoors.Clear(); EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(); foreach (EntranceTeleport val in array) { if ((Object)(object)val != (Object)null && !val.isEntranceToBuilding) { _insideDoors.Add(val); } } _doorRescanCooldown = 5f; } private void ResolveDestinations(PlayerControllerB localPlayer) { //IL_019f: 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_0108: 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_013e: Unknown result type (might be due to invalid IL or missing references) bool flag = _insideDoors.Count == 0; for (int num = _insideDoors.Count - 1; num >= 0; num--) { if ((Object)(object)_insideDoors[num] == (Object)null) { _insideDoors.RemoveAt(num); flag = true; } } if (flag && _doorRescanCooldown <= 0f) { RescanDoors(); } if (_insideDoors.Count == 0) { return; } RoundManager instance = RoundManager.Instance; if ((Object)(object)instance != (Object)null && instance.currentDungeonType == 4) { if (!_searchedElevator || (Object)(object)_elevator == (Object)null) { _elevator = Object.FindObjectOfType<MineshaftElevatorController>(); _searchedElevator = true; } if ((Object)(object)_elevator != (Object)null && (Object)(object)_elevator.elevatorTopPoint != (Object)null && (Object)(object)_elevator.elevatorBottomPoint != (Object)null && _elevator.elevatorTopPoint.position.y - ((Component)localPlayer).transform.position.y > 10f) { EntranceTeleport val = ResolveModeDoor(_elevator.elevatorTopPoint.position); AddDestination(_elevator.elevatorBottomPoint.position, (Object)(object)val != (Object)null && IsFireExitDoor(val)); return; } } if (ExitLinePlugin.Mode.Value == DoorMode.AllDoors) { for (int i = 0; i < _insideDoors.Count; i++) { AddDoorDestination(_insideDoors[i]); } return; } EntranceTeleport val2 = ResolveModeDoor(((Component)localPlayer).transform.position); if ((Object)(object)val2 != (Object)null) { AddDoorDestination(val2); } } private EntranceTeleport ResolveModeDoor(Vector3 from) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (ExitLinePlugin.Mode.Value == DoorMode.EnteredDoor) { int lastEnteredEntranceId = ExitLinePlugin.LastEnteredEntranceId; if (lastEnteredEntranceId >= 0) { for (int i = 0; i < _insideDoors.Count; i++) { if ((Object)(object)_insideDoors[i] != (Object)null && _insideDoors[i].entranceId == lastEnteredEntranceId) { return _insideDoors[i]; } } } } return ClosestDoorTo(from); } private EntranceTeleport ClosestDoorTo(Vector3 from) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport result = null; float num = float.MaxValue; for (int i = 0; i < _insideDoors.Count; i++) { EntranceTeleport val = _insideDoors[i]; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = DoorPosition(val) - from; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } } return result; } private void AddDoorDestination(EntranceTeleport door) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) AddDestination(DoorPosition(door), IsFireExitDoor(door)); } private void AddDestination(Vector3 pos, bool isFireExit) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _destinations.Add(pos); _destinationIsFireExit.Add(isFireExit); } private static bool IsFireExitDoor(EntranceTeleport door) { return door.entranceId != 0; } private static Vector3 DoorPosition(EntranceTeleport door) { //IL_0020: 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) if (!((Object)(object)door.entrancePoint != (Object)null)) { return ((Component)door).transform.position; } return door.entrancePoint.position; } private void ComputePath(DotLine line, Vector3 start, Vector3 destination) { //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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0046: 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_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_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_00b1: 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_00bb: 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_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_00f3: 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_0111: 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_015e: Unknown result type (might be due to invalid IL or missing references) line.HasPath = false; line.RecomputeIn = 1f; Vector3 val = start; NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(start, ref val2, 4f, -1)) { val = ((NavMeshHit)(ref val2)).position; } Vector3 val3 = destination; if (NavMesh.SamplePosition(destination, ref val2, 4f, -1)) { val3 = ((NavMeshHit)(ref val2)).position; } if (!NavMesh.CalculatePath(val, val3, -1, line.Path)) { return; } Vector3[] corners = line.Path.corners; if (corners.Length >= 2) { float value = ExitLinePlugin.LineHeight.Value; int num = corners.Length; line.Corners = (Vector3[])(object)new Vector3[num]; line.CumLen = new float[num]; float num2 = 0f; line.Corners[0] = corners[0] + Vector3.up * value; line.CumLen[0] = 0f; for (int i = 1; i < num; i++) { line.Corners[i] = corners[i] + Vector3.up * value; num2 += Vector3.Distance(line.Corners[i - 1], line.Corners[i]); line.CumLen[i] = num2; } line.TotalLen = num2; if (!(num2 < 0.5f)) { GenerateBaseArcs(line); RepositionDots(line); line.HasPath = true; line.LastDestination = destination; line.RecomputeIn = ((num > 50) ? 2f : ((num < 36) ? 0.4f : 1f)); } } } private void GenerateBaseArcs(DotLine line) { float value = ExitLinePlugin.DotSpacingNear.Value; float far = Mathf.Max(value, ExitLinePlugin.DotSpacingFar.Value); float value2 = ExitLinePlugin.DotSpacingFarDistance.Value; float num = 1f; for (int i = 0; i < 4; i++) { float num2 = FillArcs(line.BaseArcs, line.TotalLen, value, far, value2, num, 400); if (num2 >= line.TotalLen) { line.OverflowArc = num2; return; } num *= 1.6f; } float num3 = FillArcs(ArcScratch, line.TotalLen, value, far, value2, num, 1600); if (num3 < line.TotalLen) { ArcScratch.Clear(); float num4 = line.TotalLen / 400f; for (int j = 0; j < 400; j++) { ArcScratch.Add(0.3f + (float)j * num4); } num3 = 0.3f + 400f * num4; } line.BaseArcs.Clear(); if (ArcScratch.Count <= 400) { line.BaseArcs.AddRange(ArcScratch); } else { for (int k = 0; k < 400; k++) { line.BaseArcs.Add(ArcScratch[Mathf.RoundToInt((float)(k * (ArcScratch.Count - 1)) / 399f)]); } } line.OverflowArc = num3; if (!_loggedArcFallback) { _loggedArcFallback = true; ExitLinePlugin.Log.LogInfo((object)("Very long path (" + line.TotalLen.ToString("F0") + "m) - dot trail thinned to stay under the dot cap.")); } } private static float FillArcs(List<float> arcs, float totalLen, float near, float far, float farDist, float scale, int cap) { arcs.Clear(); float num; for (num = 0.3f; num < totalLen; num += Mathf.Lerp(near, far, Mathf.Clamp01(num / farDist)) * scale) { if (arcs.Count >= cap) { break; } arcs.Add(num); } return num; } private void RepositionDots(DotLine line) { //IL_014d: 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) int num = line.BaseArcs.Count + 1; while (line.Dots.Count < num && _dotBudget > 0) { line.Dots.Add(CreateDot(line.Container.transform, LineMaterial(line))); _dotBudget--; } float value = ExitLinePlugin.DotSize.Value; Vector3 localScale = default(Vector3); ((Vector3)(ref localScale))..ctor(value, value, value); int segCursor = line.CumLen.Length - 1; for (int i = 0; i < line.Dots.Count; i++) { Transform val = line.Dots[i]; if (i >= num) { if (((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } continue; } float num2 = ((i < line.BaseArcs.Count) ? line.BaseArcs[i] : line.OverflowArc); float num3 = ((i == 0) ? 0f : line.BaseArcs[i - 1]); float num4 = num2 - line.Phase * (num2 - num3); if (num4 < 0.05f || num4 > line.TotalLen - 0.05f) { if (((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } continue; } val.position = SampleAlongPath(line, line.TotalLen - num4, ref segCursor); val.localScale = localScale; if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } } } private static Vector3 SampleAlongPath(DotLine line, float arcFromStart, ref int segCursor) { //IL_001b: 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_007c: 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) float[] cumLen = line.CumLen; if (arcFromStart >= line.TotalLen) { return line.Corners[cumLen.Length - 1]; } if (segCursor < 1) { segCursor = 1; } while (segCursor > 1 && arcFromStart <= cumLen[segCursor - 1]) { segCursor--; } float num = cumLen[segCursor] - cumLen[segCursor - 1]; float num2 = ((num > 0.0001f) ? ((arcFromStart - cumLen[segCursor - 1]) / num) : 0f); return Vector3.Lerp(line.Corners[segCursor - 1], line.Corners[segCursor], Mathf.Clamp01(num2)); } private bool EnsureDotAssets() { //IL_00c4: 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_00d3: 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_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) if ((Object)(object)_dotMesh == (Object)null) { GameObject obj = GameObject.CreatePrimitive((PrimitiveType)5); obj.SetActive(false); _dotMesh = obj.GetComponent<MeshFilter>().sharedMesh; Object.Destroy((Object)(object)obj); } if ((Object)(object)_dotMatMain == (Object)null || (Object)(object)_dotMatFire == (Object)null) { Shader val = Shader.Find("HDRP/Unlit"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Sprites/Default"); } if ((Object)(object)val == (Object)null) { ExitLinePlugin.Log.LogWarning((object)"No usable shader found for the exit dots."); return false; } if ((Object)(object)_dotMatMain == (Object)null) { _dotMatMain = MakeDotMaterial(val); } if ((Object)(object)_dotMatFire == (Object)null) { _dotMatFire = MakeDotMaterial(val); } } _mainColor = ParseColor(ExitLinePlugin.DotColorMainEntrance.Value, ref _parsedMainText, _mainColor, "DotColorMainEntrance"); _fireColor = ParseColor(ExitLinePlugin.DotColorFireExit.Value, ref _parsedFireText, _fireColor, "DotColorFireExit"); return true; } private static Material MakeDotMaterial(Shader shader) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Material val = new Material(shader); if (val.HasProperty("_DoubleSidedEnable")) { val.SetFloat("_DoubleSidedEnable", 1f); val.EnableKeyword("_DOUBLESIDED_ON"); } if (val.HasProperty("_CullMode")) { val.SetFloat("_CullMode", 0f); } return val; } private static Color ParseColor(string text, ref string cached, Color current, string settingName) { //IL_000a: 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_0033: Unknown result type (might be due to invalid IL or missing references) if (text == cached) { return current; } cached = text; Color result = default(Color); if (ColorUtility.TryParseHtmlString(text.StartsWith("#") ? text : ("#" + text), ref result)) { return result; } ExitLinePlugin.Log.LogWarning((object)("Could not parse " + settingName + " '" + text + "', keeping previous color.")); return current; } private void ApplyBrightness(float brightness) { //IL_0006: 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) ApplyColor(_dotMatMain, _mainColor, brightness); ApplyColor(_dotMatFire, _fireColor, brightness); } private static void ApplyColor(Material mat, Color baseColor, float brightness) { //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_0012: 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_0040: 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) Color val = default(Color); ((Color)(ref val))..ctor(baseColor.r * brightness, baseColor.g * brightness, baseColor.b * brightness, baseColor.a); if (mat.HasProperty("_UnlitColor")) { mat.SetColor("_UnlitColor", val); } else { mat.color = val; } } private Transform CreateDot(Transform parent, Material mat) { //IL_0005: 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_0016: 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_0033: 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) GameObject val = new GameObject("Dot") { layer = _worldLayer }; val.transform.SetParent(parent, false); val.AddComponent<MeshFilter>().sharedMesh = _dotMesh; MeshRenderer obj = val.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterial = mat; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; val.SetActive(false); return val.transform; } private static Material LineMaterial(DotLine line) { if (!line.IsFireExit) { return _dotMatMain; } return _dotMatFire; } private void ApplyLineMaterial(DotLine line) { int num = (line.IsFireExit ? 1 : 0); if (line.AppliedColorKind == num) { return; } line.AppliedColorKind = num; Material sharedMaterial = LineMaterial(line); for (int i = 0; i < line.Dots.Count; i++) { Transform val = line.Dots[i]; if (!((Object)(object)val == (Object)null)) { MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sharedMaterial = sharedMaterial; } } } } private void EnsureWorldLayer(PlayerControllerB localPlayer) { if (_worldLayerResolved) { return; } Camera gameplayCamera = localPlayer.gameplayCamera; if ((Object)(object)gameplayCamera == (Object)null) { return; } int cullingMask = gameplayCamera.cullingMask; if ((cullingMask & 1) != 0) { _worldLayer = 0; } else { for (int i = 0; i < 32; i++) { if ((cullingMask & (1 << i)) != 0 && i != 5) { _worldLayer = i; break; } } } _worldLayerResolved = true; foreach (DotLine line in _lines) { if ((Object)(object)line.Container != (Object)null) { line.Container.layer = _worldLayer; } foreach (Transform dot in line.Dots) { if ((Object)(object)dot != (Object)null) { ((Component)dot).gameObject.layer = _worldLayer; } } } } private void EnsurePool(int needed) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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 while (_lines.Count < needed) { GameObject val = new GameObject("ExitLineFromEnteredDoor_Dots"); val.transform.SetParent(((Component)this).transform, false); val.layer = _worldLayer; val.SetActive(false); _lines.Add(new DotLine { Container = val, Path = new NavMeshPath() }); } } private static void SetLineActive(DotLine line, bool on) { if ((Object)(object)line.Container != (Object)null && line.Container.activeSelf != on) { line.Container.SetActive(on); } } private void HideAll() { for (int i = 0; i < _lines.Count; i++) { SetLineActive(_lines[i], on: false); } } } public enum DoorMode { EnteredDoor, ClosestDoor, AllDoors } [BepInPlugin("Haaylo.ExitLineFromEnteredDoor", "ExitLineFromEnteredDoor", "1.0.1")] public class ExitLinePlugin : BaseUnityPlugin { public const string Guid = "Haaylo.ExitLineFromEnteredDoor"; public const string Name = "ExitLineFromEnteredDoor"; public const string Version = "1.0.1"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<DoorMode> Mode; internal static ConfigEntry<bool> RequirePlayerInShip; internal static ConfigEntry<bool> RequireShipCameraOnYou; internal static ConfigEntry<float> LineHeight; internal static ConfigEntry<float> DotSize; internal static ConfigEntry<string> DotColorMainEntrance; internal static ConfigEntry<string> DotColorFireExit; internal static ConfigEntry<float> DotSpacingNear; internal static ConfigEntry<float> DotSpacingFar; internal static ConfigEntry<float> DotSpacingFarDistance; internal static ConfigEntry<float> BreathePeriod; internal static ConfigEntry<float> BreatheStrength; internal static ConfigEntry<bool> PulseOnScan; internal static ConfigEntry<float> PulseDuration; internal static ConfigEntry<float> FlowSpeed; internal static ConfigEntry<float> PulseBrightness; internal static ConfigEntry<bool> OnlyShowAfterScan; internal static ConfigEntry<float> ShowDurationAfterScan; internal static int LastEnteredEntranceId = -1; private void Awake() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Expected O, but got Unknown //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Expected O, but got Unknown //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Expected O, but got Unknown //IL_03db: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for the exit line."); Mode = ((BaseUnityPlugin)this).Config.Bind<DoorMode>("General", "DoorMode", DoorMode.EnteredDoor, "Which exit the line leads to. EnteredDoor = the door you came in through (falls back to closest if unknown, e.g. after a teleport). ClosestDoor = nearest exit by distance. AllDoors = one line per exit."); RequirePlayerInShip = ((BaseUnityPlugin)this).Config.Bind<bool>("Conditions", "RequirePlayerInShip", false, "Only show the line while at least one living player is inside the ship."); RequireShipCameraOnYou = ((BaseUnityPlugin)this).Config.Bind<bool>("Conditions", "RequireShipCameraOnYou", false, "Only show the line while the ship's map screen is on and its radar is targeting you."); LineHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "LineHeight", 0.1f, new ConfigDescription("How high above the floor the dots sit, in meters. 0.1 hugs the ground.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); DotSize = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "DotSize", 0.04f, new ConfigDescription("Diameter of each dot, in meters. Keep it tiny for a subtle pixel-like trail.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.005f, 0.5f), Array.Empty<object>())); DotColorMainEntrance = ((BaseUnityPlugin)this).Config.Bind<string>("Visuals", "DotColorMainEntrance", "62FF71", "Dot color when the trail leads to the main entrance, as an RGB hex value (radar green by default)."); DotColorFireExit = ((BaseUnityPlugin)this).Config.Bind<string>("Visuals", "DotColorFireExit", "FF4D4D", "Dot color when the trail leads to a fire exit, as an RGB hex value (red by default), so you can tell at a glance which way out you're being pointed."); DotSpacingNear = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "DotSpacingNear", 0.4f, new ConfigDescription("Distance between dots right next to the exit door, in meters (dense end).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); DotSpacingFar = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "DotSpacingFar", 2f, new ConfigDescription("Distance between dots far away from the exit door, in meters (sparse end). The trail getting denser tells you which way the door is.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); DotSpacingFarDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "DotSpacingFarDistance", 40f, new ConfigDescription("How many meters from the door the spacing reaches its sparsest.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>())); BreathePeriod = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "BreathePeriod", 2.5f, new ConfigDescription("Seconds per breathing cycle.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>())); BreatheStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "BreatheStrength", 0.35f, new ConfigDescription("How strongly the dots breathe (brightness swing). 0 disables breathing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); PulseOnScan = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "PulseOnScan", true, "Make the dots flow toward the exit right after a scan, slowing back down to a static trail."); PulseDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "PulseDuration", 3f, new ConfigDescription("How long the scan flow takes to settle back to static, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>())); FlowSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "FlowSpeed", 4f, new ConfigDescription("How fast dots travel toward the exit at the peak of the scan flow (dots per second).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>())); PulseBrightness = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "PulseBrightness", 1f, new ConfigDescription("Extra brightness at the start of the scan flow.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); OnlyShowAfterScan = ((BaseUnityPlugin)this).Config.Bind<bool>("Scan", "OnlyShowAfterScan", true, "Hide the trail by default and only reveal it for a few seconds after each scan. The trail is a snapshot: it runs from where you scanned to the door and stays put. Turning this off keeps an always-on trail that follows you instead."); ShowDurationAfterScan = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "ShowDurationAfterScan", 5f, new ConfigDescription("How long the trail stays visible after a scan when OnlyShowAfterScan is on (fades out at the end).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); new Harmony("Haaylo.ExitLineFromEnteredDoor").PatchAll(typeof(EntranceTeleportPatch)); GameObject val = new GameObject("ExitLineFromEnteredDoorController"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<ExitLineController>(); Log.LogInfo((object)"ExitLineFromEnteredDoor 1.0.1 loaded."); } } [HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayer")] internal static class EntranceTeleportPatch { private static void Postfix(EntranceTeleport __instance) { try { if (!((Object)(object)__instance.exitScript == (Object)null)) { ExitLinePlugin.LastEnteredEntranceId = (__instance.isEntranceToBuilding ? __instance.entranceId : (-1)); } } catch { } } } }