Decompiled source of LC BetterMonitors v2.1.0
BepInEx/plugins/GoAwayModList.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using LC_API; using LC_API.GameInterfaceAPI.Features; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Go Away ModList")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Go Away ModList")] [assembly: AssemblyCopyright("Copyright © RTPoogle 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6e7bde11-075e-4589-8140-a0065ee617f8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace FacilityMeltdownPatch { [BepInPlugin("xyz.poogle.goml", "Go Away ModList", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class GOMLPlugin : BaseUnityPlugin { public const string GUID = "xyz.poogle.goml"; public const string NAME = "Go Away ModList"; public const string VER = "1.0.1"; public readonly Harmony harmony = new Harmony("xyz.poogle.goml"); public ManualLogSource LogSrc; public static GOMLPlugin Instance; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } LogSrc = Logger.CreateLogSource("xyz.poogle.goml"); Patches.InitPatches(); LogSrc.LogInfo((object)"Initialized!"); } } internal class Patches { [HarmonyPatch] public static class CheatDatabase_OtherPlayerCheatDetector_Patch { private static readonly MethodInfo QueueTip = AccessTools.Method(typeof(Player), "QueueTip", (Type[])null, (Type[])null); private static readonly MethodInfo LocalPlayer = AccessTools.PropertyGetter(typeof(Player), "LocalPlayer"); private static readonly MethodInfo Nop_With_Params = CreateDynamicNop(); private static readonly int LookAhead = ((MethodBase)QueueTip).GetParameterTypes().Length + 1; private static MethodInfo CreateDynamicNop() { DynamicMethod dynamicMethod = new DynamicMethod("Nop", null, ((MethodBase)QueueTip).GetParameterTypes(), typeof(Player)); dynamicMethod.GetILGenerator().Emit(OpCodes.Ret); return dynamicMethod; } public static IEnumerable<MethodBase> TargetMethods() { return AccessTools.GetDeclaredMethods(typeof(CheatDatabase)).Cast<MethodBase>(); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown GOMLPlugin.Instance.LogSrc.LogInfo((object)("Patching " + original.Name)); List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count - LookAhead; i++) { if (CodeInstructionExtensions.Calls(list[i], LocalPlayer) && CodeInstructionExtensions.Calls(list[i + LookAhead], QueueTip)) { list[i] = new CodeInstruction(OpCodes.Nop, (object)null); list[i + LookAhead] = new CodeInstruction(OpCodes.Callvirt, (object)Nop_With_Params); } } GOMLPlugin.Instance.LogSrc.LogInfo((object)("Patched " + original.Name)); return list; } } internal static void InitPatches() { GOMLPlugin.Instance.harmony.PatchAll(); } } }
BepInEx/plugins/MeteoMultiplier.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MeteoMultiplier")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Multiplies loot value according to meteorigical conditions. An improved version of the other mod with a similar name")] [assembly: AssemblyFileVersion("1.1.3.0")] [assembly: AssemblyInformationalVersion("1.1.3+9ac6c74c13fd163aad4e01cf6c11e4dd7c3de1d8")] [assembly: AssemblyProduct("MeteoMultiplier")] [assembly: AssemblyTitle("MeteoMultiplier")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 MeteoMultiplier { [BepInPlugin("com.github.fredolx.meteomultiplier", "MeteoMultiplier", "1.1.3")] public class Plugin : BaseUnityPlugin { public static Dictionary<LevelWeatherType, ConfigEntry<float>> Multipliers = new Dictionary<LevelWeatherType, ConfigEntry<float>>(); public static Dictionary<LevelWeatherType, ConfigEntry<float>> SpawnMultipliers = new Dictionary<LevelWeatherType, ConfigEntry<float>>(); public static ConfigEntry<bool> MultipliersEnabled; public static ConfigEntry<bool> SpawnMultipliersEnabled; public static ConfigEntry<bool> MultiplyApparatusEnabled; public const LevelWeatherType DEFAULT_WEATHER = -1; private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin MeteoMultiplier is loaded!"); Harmony val = new Harmony("MeteoMultiplier"); SetConfig(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"MultipliersEnabled: {MultipliersEnabled.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"MultiplyApparatusEnabled: {MultiplyApparatusEnabled.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Multipliers:\n" + string.Join("\n", Multipliers.Select((KeyValuePair<LevelWeatherType, ConfigEntry<float>> x) => $"{x.Key}:{x.Value.Value}")))); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"SpawnMultipliersEnabled: {SpawnMultipliersEnabled.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("SpawnMultipliers:\n" + string.Join("\n", SpawnMultipliers.Select((KeyValuePair<LevelWeatherType, ConfigEntry<float>> x) => $"{x.Key}:{x.Value.Value}")))); val.PatchAll(); } private void SetConfig() { MultipliersEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Multipliers", "Enabled", true, "Enables multipliers (scrap value according to meteo)"); MultiplyApparatusEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Multipliers", "MultiplyApparatusEnabled", true, "Also multiply the value of the apparatus (power module) according to meteo"); SetMultipliers(); SpawnMultipliersEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn Multipliers", "Enabled", false, "Enables spawn multipliers (amount of scrap in the map)"); SetSpawnMultipliers(); } private void SetMultipliers() { Multipliers.Add((LevelWeatherType)(-1), ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "None", 0.4f, "No weather event")); Multipliers.Add((LevelWeatherType)0, ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "DustClouds", 0.44f, "Dust Clouds")); Multipliers.Add((LevelWeatherType)3, ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "Foggy", 0.44f, "Foggy")); Multipliers.Add((LevelWeatherType)1, ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "Rainy", 0.44f, "Rainy")); Multipliers.Add((LevelWeatherType)2, ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "Stormy", 0.52f, "Stormy")); Multipliers.Add((LevelWeatherType)4, ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "Flooded", 0.56f, "Flooded")); Multipliers.Add((LevelWeatherType)5, ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "Eclipsed", 0.6f, "Eclipsed")); } private void SetSpawnMultipliers() { SpawnMultipliers.Add((LevelWeatherType)(-1), ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "None", 1f, "No weather event")); SpawnMultipliers.Add((LevelWeatherType)0, ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "DustClouds", 1.25f, "Dust Clouds")); SpawnMultipliers.Add((LevelWeatherType)3, ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "Foggy", 1.25f, "Foggy")); SpawnMultipliers.Add((LevelWeatherType)1, ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "Rainy", 1.25f, "Rainy")); SpawnMultipliers.Add((LevelWeatherType)2, ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "Stormy", 1.5f, "Stormy")); SpawnMultipliers.Add((LevelWeatherType)4, ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "Flooded", 1.5f, "Flooded")); SpawnMultipliers.Add((LevelWeatherType)5, ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Multipliers", "Eclipsed", 1.5f, "Eclipsed")); } } public static class PluginInfo { public const string PLUGIN_GUID = "MeteoMultiplier"; public const string PLUGIN_NAME = "MeteoMultiplier"; public const string PLUGIN_VERSION = "1.1.3"; } } namespace MeteoMultiplier.Patches { [HarmonyPatch(typeof(LungProp), "DisconnectFromMachinery")] public class MultiplyApparatus { private static void Prefix(LungProp __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) LevelWeatherType currentWeather = __instance.roundManager.currentLevel.currentWeather; if (Plugin.MultiplyApparatusEnabled.Value && Plugin.Multipliers.ContainsKey(currentWeather)) { ((GrabbableObject)__instance).SetScrapValue((int)((float)((GrabbableObject)__instance).scrapValue * (Plugin.Multipliers[currentWeather].Value + 1f))); } } } [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] public class SpawnScrapInLevelPatches { private static void Prefix(RoundManager __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) LevelWeatherType currentWeather = __instance.currentLevel.currentWeather; if (Plugin.MultipliersEnabled.Value) { if (Plugin.Multipliers.ContainsKey(currentWeather)) { __instance.scrapValueMultiplier = Plugin.Multipliers[currentWeather].Value; } else { __instance.scrapValueMultiplier = Plugin.Multipliers[(LevelWeatherType)(-1)].Value; } } if (Plugin.SpawnMultipliersEnabled.Value) { if (Plugin.SpawnMultipliers.ContainsKey(currentWeather)) { __instance.scrapAmountMultiplier = Plugin.SpawnMultipliers[currentWeather].Value; } else { __instance.scrapAmountMultiplier = Plugin.SpawnMultipliers[(LevelWeatherType)(-1)].Value; } } } } }
BepInEx/plugins/OpenBodyCams.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AdvancedCompany.Game; using AdvancedCompany.Objects; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalVRM; using Microsoft.CodeAnalysis; using ModelReplacement; using MoreCompany; using MoreCompany.Cosmetics; using OpenBodyCams.Compatibility; using OpenBodyCams.Patches; using Unity.Netcode; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("OpenBodyCams")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OpenBodyCams")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3d49e5ff-443d-44f6-90aa-a870ecfeb2d5")] [assembly: AssemblyFileVersion("1.3.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 OpenBodyCams { public class BodyCamComponent : MonoBehaviour { [Flags] private enum TargetDirtyStatus { None = 0, Immediate = 1, UntilRender = 2 } private enum Perspective { FirstPerson, ThirdPerson } public const int DEFAULT_LAYER = 0; public const int ENEMIES_LAYER = 19; public const int ENEMIES_NOT_RENDERED_LAYER = 23; private const float RADAR_BOOSTER_INITIAL_PAN = 270f; private static readonly Vector3 BODY_CAM_OFFSET = new Vector3(0.07f, 0f, 0.15f); private static readonly Vector3 CAMERA_CONTAINER_OFFSET = new Vector3(0.07f, 0f, 0.125f); private static BodyCamComponent[] AllBodyCams = Array.Empty<BodyCamComponent>(); private static BodyCamComponent lastBodyCamRendered; private static int bodyCamCullingMask; private static FrameSettings mainCameraCustomFrameSettings; private static FrameSettingsOverrideMask mainCameraCustomFrameSettingsMask; private static Material fogShaderMaterial; private static GameObject nightVisionPrefab; private static bool hasFinishedStaticSetup = false; private static bool disableCameraWhileTargetIsOnShip = false; private static Color screenEmissiveColor; private static float radarBoosterPanSpeed; private static bool bruteForcePreventNullModels; internal GameObject CameraObject; internal Camera Camera; internal Renderer MonitorRenderer; internal int MonitorMaterialIndex = -1; internal Material MonitorOnMaterial; internal Material MonitorOffMaterial; internal bool MonitorIsOn = true; private bool keepCameraOn; private bool enableCamera = true; private bool wasBlanked; private GameObject[] localPlayerCosmetics = Array.Empty<GameObject>(); private PlayerModelState localPlayerModelState; private PlayerControllerB currentPlayer; private GameObject[] currentPlayerCosmetics = Array.Empty<GameObject>(); private PlayerModelState currentPlayerModelState; private Transform currentActualTarget; internal Renderer[] currentlyViewedMeshes = Array.Empty<Renderer>(); private TargetDirtyStatus targetDirtyStatus; private float elapsedSinceLastFrame; private float timePerFrame; private bool panCamera; private float panAngle = 270f; private Light nightVisionLight; private MeshRenderer greenFlashRenderer; private Animator greenFlashAnimator; private MeshRenderer fogShaderPlaneRenderer; public bool ForceEnableCamera { get { return keepCameraOn; } set { keepCameraOn = value; } } public bool IsBlanked => wasBlanked; public event Action<Camera> OnCameraCreated; public event Action<RenderTexture> OnRenderTextureCreated; public event Action<bool> OnBlankedSet; public static BodyCamComponent[] GetAllBodyCams() { BodyCamComponent[] allBodyCams = AllBodyCams; int num = 0; BodyCamComponent[] array = new BodyCamComponent[allBodyCams.Length]; BodyCamComponent[] array2 = allBodyCams; foreach (BodyCamComponent bodyCamComponent in array2) { array[num] = bodyCamComponent; num++; } return array; } public Camera GetCamera() { return Camera; } internal static void InitializeStatic() { RenderPipelineManager.beginCameraRendering += BeginAnyCameraRendering; RenderPipelineManager.endCameraRendering += EndAnyCameraRendering; } internal static void InitializeAtStartOfGame() { //IL_00f3: 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_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) PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[0]; bodyCamCullingMask = val.gameplayCamera.cullingMask & ~LayerMask.GetMask(new string[3] { "Ignore Raycast", "UI", "HelmetVisor" }); HDAdditionalCameraData component = ((Component)val.gameplayCamera).GetComponent<HDAdditionalCameraData>(); if (component.customRenderingSettings) { Plugin.Instance.Logger.LogInfo((object)("Using custom camera settings from " + ((Object)component).name + ".")); mainCameraCustomFrameSettings = component.renderingPathCustomFrameSettings; mainCameraCustomFrameSettingsMask = component.renderingPathCustomFrameSettingsOverrideMask; } fogShaderMaterial = ((Renderer)((Component)((Component)val.localVisor).transform.Find("ScavengerHelmet/Plane")).GetComponent<MeshRenderer>()).sharedMaterial; nightVisionPrefab = Object.Instantiate<GameObject>(((Component)val.nightVision).gameObject); ((Object)nightVisionPrefab).hideFlags = (HideFlags)61; ((Object)nightVisionPrefab).name = "NightVision"; nightVisionPrefab.transform.localPosition = Vector3.zero; nightVisionPrefab.SetActive(false); Light mapCameraLight = StartOfRound.Instance.mapScreen.mapCameraLight; mapCameraLight.cullingMask = 1 << ((Component)mapCameraLight).gameObject.layer; UpdateAllCameraSettings(); hasFinishedStaticSetup = true; } public static void UpdateAllCameraSettings() { UpdateStaticSettings(); BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { allBodyCams[i].UpdateSettings(); } } private static Color ParseColor(string str) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) float[] array = (from x in str.Split(new char[2] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) select float.Parse(x.Trim(), CultureInfo.InvariantCulture)).ToArray(); if (array.Length < 0 || array.Length > 4) { throw new ArgumentException("Too many color components"); } return new Color(array[0], array[1], array[2], (array.Length == 4) ? array[3] : 0f); } private static Color GetEmissiveColor() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) try { return ParseColor(Plugin.MonitorEmissiveColor.Value); } catch (Exception arg) { Plugin.Instance.Logger.LogWarning((object)$"Failed to parse emissive color: {arg}"); return ParseColor((string)((ConfigEntryBase)Plugin.MonitorEmissiveColor).DefaultValue); } } internal static void UpdateStaticSettings() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) screenEmissiveColor = GetEmissiveColor(); disableCameraWhileTargetIsOnShip = Plugin.DisableCameraWhileTargetIsOnShip.Value; radarBoosterPanSpeed = Plugin.RadarBoosterPanRPM.Value * 360f / 60f; bruteForcePreventNullModels = Plugin.BruteForcePreventFreezes.Value; } public static void MarkTargetDirtyUntilRenderForAllBodyCams(Transform target) { BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { allBodyCams[i].MarkTargetDirtyUntilRender(target); } } public static void MarkTargetDirtyUntilRenderForAllBodyCams() { BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { allBodyCams[i].MarkTargetDirtyUntilRender(); } } public static void MarkTargetStatusChangedForAllBodyCams(Transform target) { BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { allBodyCams[i].MarkTargetStatusChanged(target); } } public static void MarkTargetStatusChangedForAllBodyCams() { BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { allBodyCams[i].MarkTargetStatusChanged(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void ResetLastRenderedBodyCam() { if ((Object)(object)lastBodyCamRendered != (Object)null) { lastBodyCamRendered.ResetCameraRendering(); lastBodyCamRendered = null; } } private static void BeginAnyCameraRendering(ScriptableRenderContext context, Camera camera) { ResetLastRenderedBodyCam(); int num = AllBodyCams.Length; for (int i = 0; i < num; i++) { BodyCamComponent bodyCamComponent = AllBodyCams[i]; if (bodyCamComponent.Camera == camera) { lastBodyCamRendered = bodyCamComponent; bodyCamComponent.BeginCameraRendering(); break; } } } private static void EndAnyCameraRendering(ScriptableRenderContext context, Camera camera) { ResetLastRenderedBodyCam(); } private void Awake() { if (!hasFinishedStaticSetup) { Plugin.Instance.Logger.LogError((object)"Attempted to create a body cam before static initialization has been completed."); Plugin.Instance.Logger.LogError((object)"This may occur if the save is corrupted, or if a mod caused an error during the start of the game."); Object.Destroy((Object)(object)this); return; } BodyCamComponent[] allBodyCams = AllBodyCams; int num = 0; BodyCamComponent[] array = new BodyCamComponent[1 + allBodyCams.Length]; BodyCamComponent[] array2 = allBodyCams; foreach (BodyCamComponent bodyCamComponent in array2) { array[num] = bodyCamComponent; num++; } array[num] = this; num++; AllBodyCams = array; ((Behaviour)nightVisionPrefab.GetComponent<Light>()).enabled = false; } private void Start() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if ((Object)(object)MonitorRenderer != (Object)null) { MonitorOnMaterial = new Material(Shader.Find("HDRP/Unlit")) { name = "BodyCamMaterial" }; MonitorOnMaterial.SetFloat("_AlbedoAffectEmissive", 1f); MonitorOffMaterial = ShipObjects.blackScreenMaterial; SetMaterial(MonitorRenderer, MonitorMaterialIndex, MonitorOnMaterial); } EnsureCameraExists(); SyncBodyCamToRadarMap.UpdateBodyCamTarget(this); } private static void SetMaterial(Renderer renderer, int index, Material material) { Material[] sharedMaterials = renderer.sharedMaterials; sharedMaterials[index] = material; renderer.sharedMaterials = sharedMaterials; } public void EnsureCameraExists() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)CameraObject != (Object)null)) { Plugin.Instance.Logger.LogInfo((object)"Camera has been destroyed, recreating it."); CameraObject = new GameObject("BodyCam"); Camera = CameraObject.AddComponent<Camera>(); Camera.nearClipPlane = 0.05f; Camera.cullingMask = bodyCamCullingMask; HDAdditionalCameraData val = CameraObject.AddComponent<HDAdditionalCameraData>(); val.volumeLayerMask = LayerMask.op_Implicit(1); _ = mainCameraCustomFrameSettings; val.customRenderingSettings = true; val.renderingPathCustomFrameSettings = mainCameraCustomFrameSettings; val.renderingPathCustomFrameSettingsOverrideMask = mainCameraCustomFrameSettingsMask; GameObject val2 = Object.Instantiate<GameObject>(nightVisionPrefab); val2.transform.SetParent(CameraObject.transform, false); val2.SetActive(true); nightVisionLight = val2.GetComponent<Light>(); UpdateSettings(); GameObject val3 = new GameObject("CameraGreenTransitionScaler"); val3.transform.SetParent(CameraObject.transform, false); val3.transform.localScale = new Vector3(1f, 0.004f, 1f); GameObject val4 = Object.Instantiate<GameObject>(((Component)StartOfRound.Instance.mapScreen.mapCameraAnimator).gameObject); val4.transform.SetParent(val3.transform, false); val4.transform.localPosition = new Vector3(0f, 0f, 0.1f); val4.layer = 0; greenFlashRenderer = val4.GetComponent<MeshRenderer>(); ((Renderer)greenFlashRenderer).forceRenderingOff = true; greenFlashAnimator = val4.GetComponent<Animator>() ?? throw new Exception("Green flash object copied from the map screen has no Animator."); greenFlashAnimator.Play("MapTransitionGreen", 0, 1f); greenFlashAnimator.WriteDefaultValues(); GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)5); Object.Destroy((Object)(object)val5.GetComponent<MeshCollider>()); val5.transform.SetParent(CameraObject.transform, false); val5.transform.localPosition = new Vector3(0f, 0f, Camera.nearClipPlane * 2f); val5.transform.localRotation = Quaternion.Euler(0f, 0f, 0f); fogShaderPlaneRenderer = val5.GetComponent<MeshRenderer>(); ((Renderer)fogShaderPlaneRenderer).sharedMaterial = fogShaderMaterial; ((Renderer)fogShaderPlaneRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)fogShaderPlaneRenderer).receiveShadows = false; ((Renderer)fogShaderPlaneRenderer).forceRenderingOff = true; this.OnCameraCreated?.Invoke(Camera); } } public void UpdateSettings() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) Camera.targetTexture = new RenderTexture(Plugin.HorizontalResolution.Value, Plugin.HorizontalResolution.Value * 3 / 4, 32) { name = ((Object)this).name + ".RenderTexture", filterMode = Plugin.MonitorTextureFiltering.Value }; Camera.fieldOfView = Plugin.FieldOfView.Value; if ((Object)(object)MonitorOnMaterial != (Object)null) { MonitorOnMaterial.mainTexture = (Texture)(object)Camera.targetTexture; MonitorOnMaterial.SetColor("_EmissiveColor", screenEmissiveColor); } Camera.farClipPlane = Plugin.RenderDistance.Value; if (Plugin.Framerate.Value != 0f) { timePerFrame = 1f / Plugin.Framerate.Value; ((Behaviour)Camera).enabled = false; } else { timePerFrame = 0f; ((Behaviour)Camera).enabled = false; } nightVisionLight.intensity = 367f * Plugin.NightVisionBrightness.Value; nightVisionLight.range = 12f * Plugin.NightVisionBrightness.Value; enableCamera = Plugin.EnableCamera.Value; this.OnRenderTextureCreated?.Invoke(Camera.targetTexture); } public void StartTargetTransition() { if (Plugin.UseTargetTransitionAnimation.Value) { Animator obj = greenFlashAnimator; if (obj != null) { obj.SetTrigger("Transition"); } } } private static void SetCosmeticHidden(GameObject cosmetic, bool hidden) { cosmetic.layer = (hidden ? 23 : 0); } public void SetScreenPowered(bool powered) { if (!((Object)(object)MonitorRenderer == (Object)null) && powered != MonitorIsOn) { if (powered) { StartTargetTransition(); SetMaterial(MonitorRenderer, MonitorMaterialIndex, MonitorOnMaterial); MonitorIsOn = true; } else { SetMaterial(MonitorRenderer, MonitorMaterialIndex, MonitorOffMaterial); MonitorIsOn = false; } } } public bool IsScreenPowered() { return MonitorIsOn; } private void SetScreenBlanked(bool blanked) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (blanked != wasBlanked) { if ((Object)(object)MonitorOnMaterial != (Object)null) { MonitorOnMaterial.color = (blanked ? Color.black : Color.white); } this.OnBlankedSet?.Invoke(blanked); } wasBlanked = blanked; } private bool ShouldHideOutput() { if (!enableCamera) { return true; } if ((Object)(object)currentActualTarget == (Object)null) { return true; } if (currentPlayer != null) { if (currentPlayer.isPlayerControlled) { if (disableCameraWhileTargetIsOnShip) { return currentPlayer.isInHangarShipRoom; } return false; } if (!currentPlayer.isPlayerDead) { return false; } if ((Object)(object)currentPlayer.redirectToEnemy != (Object)null) { if (disableCameraWhileTargetIsOnShip) { return currentPlayer.redirectToEnemy.isInsidePlayerShip; } return false; } if ((Object)(object)currentPlayer.deadBody != (Object)null) { if (disableCameraWhileTargetIsOnShip) { return currentPlayer.deadBody.isInShip; } return false; } } RadarBoosterItem component = ((Component)currentActualTarget).GetComponent<RadarBoosterItem>(); if (component != null) { if (disableCameraWhileTargetIsOnShip) { return ((GrabbableObject)component).isInShipRoom; } return false; } return true; } private static void CollectDescendentModelsToHide(Transform parent, List<Renderer> list) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown BodyCamComponent[] allBodyCams = AllBodyCams; foreach (BodyCamComponent bodyCamComponent in allBodyCams) { if ((Object)(object)parent == (Object)(object)bodyCamComponent.CameraObject.transform) { return; } } Renderer component = ((Component)parent).GetComponent<Renderer>(); if ((Object)(object)component != (Object)null && ((1 << ((Component)component).gameObject.layer) & bodyCamCullingMask) != 0) { list.Add(component); } foreach (Transform item in parent) { CollectDescendentModelsToHide(item, list); } } private static Renderer[] CollectModelsToHide(Transform parent) { List<Renderer> list = new List<Renderer>(20); CollectDescendentModelsToHide(parent, list); int num = 0; Renderer[] array = (Renderer[])(object)new Renderer[list.Count]; foreach (Renderer item in list) { array[num] = item; num++; } return array; } private bool TargetWouldRequireUpdate(Transform target) { if (target == null) { return true; } if (currentActualTarget == target) { return true; } if (((Component)StartOfRound.Instance.localPlayerController).transform == target) { return true; } return false; } public void MarkTargetStatusChanged(Transform transform) { if (!targetDirtyStatus.HasFlag(TargetDirtyStatus.Immediate) && TargetWouldRequireUpdate(transform)) { targetDirtyStatus |= TargetDirtyStatus.Immediate; } } public void MarkTargetStatusChanged() { MarkTargetStatusChanged(null); } public void MarkTargetDirtyUntilRender(Transform transform) { if (!targetDirtyStatus.HasFlag(TargetDirtyStatus.UntilRender) && TargetWouldRequireUpdate(transform)) { targetDirtyStatus |= TargetDirtyStatus.UntilRender; } } public void MarkTargetDirtyUntilRender() { MarkTargetDirtyUntilRender(null); } private void ClearTargetDirtyImmediate() { targetDirtyStatus &= ~TargetDirtyStatus.Immediate; } public void SetTargetToNone() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) ClearTargetDirtyImmediate(); currentPlayer = null; currentActualTarget = null; currentlyViewedMeshes = Array.Empty<Renderer>(); if (!((Object)(object)CameraObject == (Object)null)) { CameraObject.transform.SetParent((Transform)null, false); CameraObject.transform.localPosition = Vector3.zero; CameraObject.transform.localRotation = Quaternion.identity; } } public void SetTargetToPlayer(PlayerControllerB player) { //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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { SetTargetToNone(); return; } EnsureCameraExists(); ClearTargetDirtyImmediate(); currentPlayer = player; UpdateModelReferences(); panCamera = false; Vector3 localPosition = Vector3.zero; currentActualTarget = null; Transform val = null; if (!currentPlayer.isPlayerDead) { if (Plugin.CameraMode.Value == CameraModeOptions.Head) { val = ((Component)currentPlayer.gameplayCamera).transform; localPosition = CAMERA_CONTAINER_OFFSET; } else { val = ((Component)currentPlayer.playerGlobalHead).transform.parent; localPosition = BODY_CAM_OFFSET; } currentActualTarget = ((Component)currentPlayer).transform; currentlyViewedMeshes = Array.Empty<Renderer>(); } else if ((Object)(object)currentPlayer.redirectToEnemy != (Object)null) { EnemyAI redirectToEnemy = currentPlayer.redirectToEnemy; MaskedPlayerEnemy val2 = (MaskedPlayerEnemy)(object)((redirectToEnemy is MaskedPlayerEnemy) ? redirectToEnemy : null); if (val2 != null) { if (Plugin.CameraMode.Value == CameraModeOptions.Head) { val = val2.headTiltTarget; localPosition = CAMERA_CONTAINER_OFFSET; } else { val = val2.animationContainer.Find("metarig/spine/spine.001/spine.002/spine.003"); localPosition = BODY_CAM_OFFSET; } } else { val = currentPlayer.redirectToEnemy.eye; } currentActualTarget = ((Component)currentPlayer.redirectToEnemy).transform; currentlyViewedMeshes = CollectModelsToHide(currentActualTarget); } else if ((Object)(object)currentPlayer.deadBody != (Object)null) { Transform parent; if (Plugin.CameraMode.Value == CameraModeOptions.Head) { val = ((Component)currentPlayer.deadBody).transform.Find("spine.001/spine.002/spine.003/spine.004/spine.004_end"); parent = val.parent; localPosition = CAMERA_CONTAINER_OFFSET - new Vector3(0f, 0.15f, 0f); } else { val = ((Component)currentPlayer.deadBody).transform.Find("spine.001/spine.002/spine.003"); parent = val; localPosition = BODY_CAM_OFFSET; } currentActualTarget = ((Component)currentPlayer.deadBody).transform; currentlyViewedMeshes = CollectModelsToHide(parent); } if ((Object)(object)val == (Object)null) { SetTargetToNone(); return; } CameraObject.transform.SetParent(val, false); CameraObject.transform.localPosition = localPosition; CameraObject.transform.localRotation = Quaternion.identity; } public void SetTargetToTransform(Transform transform) { //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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null || (Object)(object)((Component)transform).gameObject == (Object)null) { SetTargetToNone(); return; } EnsureCameraExists(); ClearTargetDirtyImmediate(); currentPlayer = null; currentActualTarget = transform; UpdateModelReferences(); panCamera = false; Vector3 zero = Vector3.zero; if ((Object)(object)((Component)currentActualTarget).GetComponent<RadarBoosterItem>() != (Object)null) { currentlyViewedMeshes = (Renderer[])(object)new Renderer[1] { ((Component)((Component)currentActualTarget).transform.Find("AnimContainer/Rod")).GetComponent<Renderer>() }; ((Vector3)(ref zero))..ctor(0f, 1.5f, 0f); panCamera = true; } CameraObject.transform.SetParent(((Component)currentActualTarget).transform, false); CameraObject.transform.localPosition = zero; CameraObject.transform.localRotation = Quaternion.identity; } private void UpdateTargetStatus() { if ((Object)(object)currentPlayer != (Object)null) { SetTargetToPlayer(currentPlayer); } else { SetTargetToTransform(currentActualTarget); } } private void UpdateModelReferences() { currentPlayerCosmetics = CosmeticsCompatibility.CollectCosmetics(currentPlayer); currentPlayerModelState.cosmeticsLayers = new int[currentPlayerCosmetics.Length]; if ((Object)(object)currentPlayer != (Object)(object)StartOfRound.Instance.localPlayerController) { localPlayerCosmetics = CosmeticsCompatibility.CollectCosmetics(StartOfRound.Instance.localPlayerController); localPlayerModelState.cosmeticsLayers = new int[localPlayerCosmetics.Length]; } else { localPlayerCosmetics = Array.Empty<GameObject>(); localPlayerModelState.cosmeticsLayers = Array.Empty<int>(); } } private static void SaveStateAndApplyPerspective(PlayerControllerB player, ref GameObject[] cosmetics, ref PlayerModelState state, Perspective perspective) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (player == null) { return; } state.bodyShadowMode = ((Renderer)player.thisPlayerModel).shadowCastingMode; state.bodyLayer = ((Component)player.thisPlayerModel).gameObject.layer; state.armsEnabled = ((Renderer)player.thisPlayerModelArms).enabled; state.armsLayer = ((Component)player.thisPlayerModelArms).gameObject.layer; if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { state.heldItemPosition = ((Component)player.currentlyHeldObjectServer).transform.position; state.heldItemRotation = ((Component)player.currentlyHeldObjectServer).transform.rotation; } for (int i = 0; i < cosmetics.Length; i++) { state.cosmeticsLayers[i] = cosmetics[i].layer; } switch (perspective) { case Perspective.FirstPerson: { ((Renderer)player.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)3; ((Component)player.thisPlayerModel).gameObject.layer = 23; ((Renderer)player.thisPlayerModelArms).enabled = true; ((Component)player.thisPlayerModelArms).gameObject.layer = 0; if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { AttachItem(player.currentlyHeldObjectServer, player.localItemHolder); } GameObject[] array = cosmetics; for (int j = 0; j < array.Length; j++) { SetCosmeticHidden(array[j], hidden: true); } break; } case Perspective.ThirdPerson: { ((Renderer)player.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1; ((Component)player.thisPlayerModel).gameObject.layer = 0; ((Renderer)player.thisPlayerModelArms).enabled = false; ((Component)player.thisPlayerModelArms).gameObject.layer = 23; if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { AttachItem(player.currentlyHeldObjectServer, player.serverItemHolder); } GameObject[] array = cosmetics; for (int j = 0; j < array.Length; j++) { SetCosmeticHidden(array[j], hidden: false); } break; } } static void AttachItem(GrabbableObject item, Transform holder) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) ((Component)item).transform.rotation = holder.rotation; ((Component)item).transform.Rotate(item.itemProperties.rotationOffset); ((Component)item).transform.position = holder.position + holder.rotation * item.itemProperties.positionOffset; } } private static void RestoreState(PlayerControllerB player, GameObject[] cosmetics, PlayerModelState state) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (player != null) { ((Renderer)player.thisPlayerModel).shadowCastingMode = state.bodyShadowMode; ((Component)player.thisPlayerModel).gameObject.layer = state.bodyLayer; ((Renderer)player.thisPlayerModelArms).enabled = state.armsEnabled; ((Component)player.thisPlayerModelArms).gameObject.layer = state.armsLayer; for (int i = 0; i < cosmetics.Length; i++) { cosmetics[i].layer = state.cosmeticsLayers[i]; } if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { ((Component)player.currentlyHeldObjectServer).transform.position = state.heldItemPosition; ((Component)player.currentlyHeldObjectServer).transform.rotation = state.heldItemRotation; } } } private void UpdateTargetStatusBeforeRender() { if (targetDirtyStatus.HasFlag(TargetDirtyStatus.UntilRender)) { UpdateTargetStatus(); targetDirtyStatus ^= TargetDirtyStatus.UntilRender; } } private void BeginCameraRendering() { UpdateTargetStatusBeforeRender(); ((Behaviour)nightVisionLight).enabled = true; ((Renderer)greenFlashRenderer).forceRenderingOff = false; ((Renderer)fogShaderPlaneRenderer).forceRenderingOff = false; PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; SaveStateAndApplyPerspective(currentPlayer, ref currentPlayerCosmetics, ref currentPlayerModelState, Perspective.FirstPerson); if (currentPlayer != localPlayerController) { SaveStateAndApplyPerspective(localPlayerController, ref localPlayerCosmetics, ref localPlayerModelState, Perspective.ThirdPerson); } Renderer[] array = currentlyViewedMeshes; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { val.forceRenderingOff = true; } } } private void ResetCameraRendering() { ((Behaviour)nightVisionLight).enabled = false; ((Renderer)greenFlashRenderer).forceRenderingOff = true; ((Renderer)fogShaderPlaneRenderer).forceRenderingOff = true; PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; RestoreState(currentPlayer, currentPlayerCosmetics, currentPlayerModelState); if (currentPlayer != localPlayerController) { RestoreState(localPlayerController, localPlayerCosmetics, localPlayerModelState); } if (currentlyViewedMeshes.Length == 0 || !((Object)(object)currentlyViewedMeshes[0] == (Object)null)) { Renderer[] array = currentlyViewedMeshes; for (int i = 0; i < array.Length; i++) { array[i].forceRenderingOff = false; } } } private bool AllCosmeticsExist(PlayerControllerB player, GameObject[] cosmetics) { for (int i = 0; i < cosmetics.Length; i++) { if ((Object)(object)cosmetics[i] == (Object)null) { Plugin.Instance.Logger.LogError((object)("A cosmetic attached to " + player.playerUsername + " has been destroyed, re-collecting cosmetics.")); return false; } } return true; } private void UpdateTargetStatusDuringUpdate() { if (targetDirtyStatus.HasFlag(TargetDirtyStatus.Immediate)) { UpdateTargetStatus(); } } private void LateUpdate() { //IL_01ba: Unknown result type (might be due to invalid IL or missing references) EnsureCameraExists(); UpdateTargetStatusDuringUpdate(); PlayerControllerB val = StartOfRound.Instance.localPlayerController; if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)val.spectatedPlayerScript != (Object)null) { val = val.spectatedPlayerScript; } bool flag = keepCameraOn || ((Object)(object)MonitorRenderer != (Object)null && MonitorRenderer.isVisible && val.isInHangarShipRoom && IsScreenPowered()); if (flag) { bool flag2 = ShouldHideOutput(); flag = !flag2; if (flag2 != wasBlanked) { SetScreenBlanked(flag2); wasBlanked = flag2; } } if (flag && bruteForcePreventNullModels) { bool flag3 = false; if ((Object)(object)currentPlayer != (Object)null && !AllCosmeticsExist(currentPlayer, currentPlayerCosmetics)) { flag3 = true; } PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if (currentPlayer != localPlayerController && !AllCosmeticsExist(localPlayerController, localPlayerCosmetics)) { flag3 = true; } Renderer[] array = currentlyViewedMeshes; for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] == (Object)null) { Plugin.Instance.Logger.LogError((object)("A mesh attached to non-player target " + ((Object)currentActualTarget).name + " is null, marking dirty.")); flag3 = true; break; } } if (flag3) { UpdateTargetStatus(); } } if (!flag) { ((Behaviour)Camera).enabled = false; return; } if (radarBoosterPanSpeed != 0f) { panAngle = (panAngle + Time.deltaTime * radarBoosterPanSpeed) % 360f; } else { panAngle = 270f; } if (panCamera) { CameraObject.transform.localRotation = Quaternion.Euler(0f, panAngle, 0f); } if (timePerFrame > 0f) { elapsedSinceLastFrame += Time.deltaTime; if (elapsedSinceLastFrame >= timePerFrame) { Camera.Render(); elapsedSinceLastFrame %= timePerFrame; } } else { ((Behaviour)Camera).enabled = true; } } private void OnDestroy() { AllBodyCams = AllBodyCams.Where((BodyCamComponent bodyCam) => bodyCam != this).ToArray(); SyncBodyCamToRadarMap.OnBodyCamDestroyed(this); } private static bool PlayerContainsRenderer(PlayerControllerB player, Renderer renderer) { if ((Object)(object)player == (Object)null) { return false; } if ((Object)(object)player.thisPlayerModelArms == (Object)(object)renderer) { return true; } if ((Object)(object)player.thisPlayerModel == (Object)(object)renderer) { return true; } return false; } public bool HasReference(Renderer renderer) { if (targetDirtyStatus.HasFlag(TargetDirtyStatus.UntilRender)) { return false; } if (targetDirtyStatus.HasFlag(TargetDirtyStatus.Immediate)) { UpdateTargetStatus(); } if (PlayerContainsRenderer(currentPlayer, renderer)) { return true; } if (PlayerContainsRenderer(StartOfRound.Instance?.localPlayerController, renderer)) { return true; } if (Array.IndexOf(currentlyViewedMeshes, renderer) != -1) { return true; } return false; } public bool HasReference(GameObject gameObject) { if (targetDirtyStatus.HasFlag(TargetDirtyStatus.UntilRender)) { return false; } if (targetDirtyStatus.HasFlag(TargetDirtyStatus.Immediate)) { UpdateTargetStatus(); } if (Array.IndexOf(currentPlayerCosmetics, gameObject) != -1) { return true; } return Array.IndexOf(localPlayerCosmetics, gameObject) != -1; } public static bool AnyBodyCamHasReference(Renderer renderer) { BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { if (allBodyCams[i].HasReference(renderer)) { return true; } } return false; } public static bool AnyBodyCamHasReference(GameObject gameObject) { BodyCamComponent[] allBodyCams = AllBodyCams; for (int i = 0; i < allBodyCams.Length; i++) { if (allBodyCams[i].HasReference(gameObject)) { return true; } } return false; } } internal struct PlayerModelState { public ShadowCastingMode bodyShadowMode; public int bodyLayer; public bool armsEnabled; public int armsLayer; public int[] cosmeticsLayers; public Vector3 heldItemPosition; public Quaternion heldItemRotation; } internal static class CosmeticsCompatibility { [Flags] private enum CompatibilityMode { None = 0, MoreCompany = 1, AdvancedCompany = 2, ModelReplacementAPI = 4, LethalVRM = 8 } internal static bool PrintDebugInfo; private static CompatibilityMode compatibilityMode; public static void Initialize(Harmony harmony) { bool flag = Chainloader.PluginInfos.ContainsKey("com.potatoepet.AdvancedCompany"); if (Plugin.EnableAdvancedCompanyCosmeticsCompatibility.Value && flag) { if (AdvancedCompanyCompatibility.Initialize(harmony)) { compatibilityMode |= CompatibilityMode.AdvancedCompany; Plugin.Instance.Logger.LogInfo((object)"AdvancedCompany compatibility mode is enabled."); } else { Plugin.Instance.Logger.LogWarning((object)"AdvancedCompany is installed, but the compatibility feature failed to initialize."); } } if (Plugin.EnableMoreCompanyCosmeticsCompatibility.Value && !flag && Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany")) { if (MoreCompanyCompatibility.Initialize(harmony)) { compatibilityMode |= CompatibilityMode.MoreCompany; Plugin.Instance.Logger.LogInfo((object)"MoreCompany compatibility mode is enabled."); } else { Plugin.Instance.Logger.LogWarning((object)"MoreCompany is installed, but the compatibility feature failed to initialize."); } } if (Plugin.EnableModelReplacementAPICompatibility.Value && Chainloader.PluginInfos.ContainsKey("meow.ModelReplacementAPI")) { if (ModelReplacementAPICompatibility.Initialize(harmony)) { compatibilityMode |= CompatibilityMode.ModelReplacementAPI; Plugin.Instance.Logger.LogInfo((object)"ModelReplacementAPI compatibility mode is enabled."); } else { Plugin.Instance.Logger.LogWarning((object)"ModelReplacementAPI is installed, but the compatibility feature failed to initialize."); } } if (Plugin.EnableLethalVRMCompatibility.Value && Chainloader.PluginInfos.ContainsKey("Ooseykins.LethalVRM")) { if (LethalVRMCompatibility.Initialize(harmony)) { compatibilityMode |= CompatibilityMode.LethalVRM; Plugin.Instance.Logger.LogInfo((object)"LethalVRM compatibility mode is enabled."); } else { Plugin.Instance.Logger.LogWarning((object)"LethalVRM is installed, but the compatibility feature failed to initialize."); } } } private static void DebugLog(object data) { if (PrintDebugInfo) { Plugin.Instance.Logger.LogInfo(data); } } private static GameObject[] DoCollectCosmetics(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return (GameObject[])(object)new GameObject[0]; } List<GameObject> list = new List<GameObject>(); DebugLog("Collecting cosmetics for " + player.playerUsername + "."); if (compatibilityMode.HasFlag(CompatibilityMode.MoreCompany)) { GameObject[] array = MoreCompanyCompatibility.CollectCosmetics(player); list.AddRange(array); DebugLog($"Collected {array.Length} MoreCompany cosmetics objects."); } if (compatibilityMode.HasFlag(CompatibilityMode.AdvancedCompany)) { GameObject[] array2 = AdvancedCompanyCompatibility.CollectCosmetics(player); list.AddRange(array2); DebugLog($"Collected {array2.Length} AdvancedCompany cosmetics objects."); } if (compatibilityMode.HasFlag(CompatibilityMode.ModelReplacementAPI)) { GameObject[] array3 = ModelReplacementAPICompatibility.CollectCosmetics(player); list.AddRange(array3); DebugLog($"Collected {array3.Length} ModelReplacementAPI cosmetics objects."); } if (compatibilityMode.HasFlag(CompatibilityMode.LethalVRM)) { GameObject[] array4 = LethalVRMCompatibility.CollectCosmetics(player); list.AddRange(array4); DebugLog($"Collected {array4.Length} LethalVRM cosmetics objects."); } Plugin.Instance.Logger.LogInfo((object)$"Collected {list.Count} cosmetics objects for {player.playerUsername}."); if (PrintDebugInfo) { Plugin.Instance.Logger.LogInfo((object)"Called from:"); StackFrame[] frames = new StackTrace().GetFrames(); for (int i = 1; i < frames.Length; i++) { StackFrame stackFrame = frames[i]; Plugin.Instance.Logger.LogInfo((object)(" " + stackFrame.GetMethod().DeclaringType.Name + "." + stackFrame.GetMethod().Name + "()")); } } int num = 0; GameObject[] array5 = (GameObject[])(object)new GameObject[list.Count]; foreach (GameObject item in list) { array5[num] = item; num++; } return array5; } public static GameObject[] CollectCosmetics(PlayerControllerB player) { try { return DoCollectCosmetics(player); } catch (Exception ex) { Plugin.Instance.Logger.LogError((object)("Failed to get cosmetics for player " + player.playerUsername + ":")); Plugin.Instance.Logger.LogError((object)ex); return Array.Empty<GameObject>(); } } } public enum CameraModeOptions { Body, Head } [BepInPlugin("Zaggy1024.OpenBodyCams", "OpenBodyCams", "1.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string MOD_NAME = "OpenBodyCams"; public const string MOD_UNIQUE_NAME = "Zaggy1024.OpenBodyCams"; public const string MOD_VERSION = "1.3.0"; private readonly Harmony harmony = new Harmony("Zaggy1024.OpenBodyCams"); public static ConfigEntry<CameraModeOptions> CameraMode; public static ConfigEntry<int> HorizontalResolution; public static ConfigEntry<float> FieldOfView; public static ConfigEntry<float> RenderDistance; public static ConfigEntry<float> Framerate; public const float NightVisionIntensityBase = 367f; public const float NightVisionRangeBase = 12f; public static ConfigEntry<float> NightVisionBrightness; public static ConfigEntry<string> MonitorEmissiveColor; public static ConfigEntry<FilterMode> MonitorTextureFiltering; public static ConfigEntry<float> RadarBoosterPanRPM; public static ConfigEntry<bool> UseTargetTransitionAnimation; public static ConfigEntry<bool> DisableCameraWhileTargetIsOnShip; public static ConfigEntry<bool> EnableCamera; public static ConfigEntry<bool> TerminalPiPBodyCamEnabled; public static ConfigEntry<PiPPosition> TerminalPiPPosition; public static ConfigEntry<int> TerminalPiPWidth; public static ConfigEntry<int> GeneralImprovementsBetterMonitorIndex; public static ConfigEntry<bool> EnableMoreCompanyCosmeticsCompatibility; public static ConfigEntry<bool> EnableAdvancedCompanyCosmeticsCompatibility; public static ConfigEntry<bool> EnableModelReplacementAPICompatibility; public static ConfigEntry<bool> EnableLethalVRMCompatibility; public static ConfigEntry<bool> DisableInternalShipCamera; public static ConfigEntry<bool> FixDroppedItemRotation; public static ConfigEntry<bool> PrintCosmeticsDebugInfo; public static ConfigEntry<bool> BruteForcePreventFreezes; public static ConfigEntry<bool> ReferencedObjectDestructionDetectionEnabled; private static readonly Harmony DestructionDetectionPatch = new Harmony("Zaggy1024.OpenBodyCams.DestructionDetectionPatch"); public static Plugin Instance { get; private set; } public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; private void Awake() { //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04ef: Expected O, but got Unknown Instance = this; harmony.PatchAll(typeof(PatchStartOfRound)); harmony.PatchAll(typeof(PatchManualCameraRenderer)); harmony.PatchAll(typeof(PatchPlayerControllerB)); harmony.PatchAll(typeof(PatchHauntedMaskItem)); harmony.PatchAll(typeof(PatchMaskedPlayerEnemy)); CameraMode = ((BaseUnityPlugin)this).Config.Bind<CameraModeOptions>("Camera", "Mode", CameraModeOptions.Head, "Choose where to attach the camera. 'Head' will attach the camera to the right side of the head, 'Body' will attach it to the chest."); HorizontalResolution = ((BaseUnityPlugin)this).Config.Bind<int>("Camera", "HorizontalResolution", 160, "The horizontal resolution of the rendering. The vertical resolution is calculated based on the aspect ratio of the monitor."); FieldOfView = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "FieldOfView", 65f, "The vertical FOV of the camera in degrees."); RenderDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "RenderDistance", 25f, "The far clip plane for the body cam. Lowering may improve framerates."); Framerate = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Framerate", 0f, "The number of frames to render per second. A value of 0 will render at the game's framerate and results in best performance. Higher framerates will negatively affect performance, values between 0 and 30 are recommended."); NightVisionBrightness = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "NightVisionBrightness", 1f, "A multiplier for the intensity of the area light used to brighten dark areas. A value of 1 is identical to the player's actual vision."); MonitorEmissiveColor = ((BaseUnityPlugin)this).Config.Bind<string>("Camera", "MonitorEmissiveColor", "0.05, 0.13, 0.05", "Adjust the color that is emitted from the body cam monitor."); MonitorTextureFiltering = ((BaseUnityPlugin)this).Config.Bind<FilterMode>("Camera", "MonitorTextureFiltering", (FilterMode)1, "The texture filtering to use for the body cam on the monitor. Bilinear and Trilinear will result in a smooth image, while Point will result in sharp square edges. If Point is used, a fairly high resolution is recommended."); RadarBoosterPanRPM = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "RadarBoosterPanRPM", 9f, "The rotations per minute to turn the camera when a radar booster is selected. If the value is set to 0, the radar booster camera will face in the direction player faces when it is placed."); UseTargetTransitionAnimation = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "UseTargetTransitionAnimation", true, "Enables a green flash animation on the body cam screen mirroring the one that the radar map shows when switching targets."); DisableCameraWhileTargetIsOnShip = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "DisableCameraWhileTargetIsOnShip", false, "With this option enabled, the camera will stop rendering when the target is onboard the ship to reduce the performance hit of rendering a large number of items on the ship twice."); EnableCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableCamera", true, "Enables/disables rendering of the body cam, and can be enabled/disabled during a game with LethalConfig."); CameraMode.SettingChanged += delegate { BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(); }; HorizontalResolution.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; FieldOfView.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; RenderDistance.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; Framerate.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; NightVisionBrightness.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; MonitorEmissiveColor.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; MonitorTextureFiltering.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; RadarBoosterPanRPM.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; DisableCameraWhileTargetIsOnShip.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; EnableCamera.SettingChanged += delegate { BodyCamComponent.UpdateAllCameraSettings(); }; TerminalPiPBodyCamEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Terminal", "EnablePiPBodyCam", false, "Adds a 'view bodycam' command to the terminal that places a picture-in-picture view of the bodycam in front of the radar map."); TerminalPiPPosition = ((BaseUnityPlugin)this).Config.Bind<PiPPosition>("Terminal", "PiPPosition", PiPPosition.BottomRight, "The corner inside the terminal's radar map to align the body cam to."); TerminalPiPWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Terminal", "PiPWidth", 150, "The width of the picture-in-picture in pixels."); TerminalPiPBodyCamEnabled.SettingChanged += delegate { TerminalCommands.Initialize(); }; TerminalPiPPosition.SettingChanged += delegate { TerminalCommands.Initialize(); }; TerminalPiPWidth.SettingChanged += delegate { TerminalCommands.Initialize(); }; harmony.PatchAll(typeof(TerminalCommands)); GeneralImprovementsBetterMonitorIndex = ((BaseUnityPlugin)this).Config.Bind<int>("Compatibility", "GeneralImprovementsBetterMonitorIndex", 0, new ConfigDescription("Choose which of GeneralImprovements' extended monitor set to display the body cam on. A value of 0 will place it on the large monitor on the right, 1-14 goes left to right, top to bottom, skipping the large center monitor.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 14), Array.Empty<object>())); EnableMoreCompanyCosmeticsCompatibility = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "EnableMoreCompanyCosmeticsCompatibility", true, "If this is enabled, a patch will be applied to MoreCompany to spawn cosmetics for the local player, and all cosmetics will be shown and hidden based on the camera's perspective."); EnableAdvancedCompanyCosmeticsCompatibility = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "EnableAdvancedCompanyCosmeticsCompatibility", true, "When this is enabled and AdvancedCompany is installed, all cosmetics will be shown and hidden based on the camera's perspective."); EnableModelReplacementAPICompatibility = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "EnableModelReplacementAPICompatibility", true, "When enabled, this will get the third person model replacement and hide/show it based on the camera's perspective."); EnableLethalVRMCompatibility = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "EnableLethalVRMCompatibility", true, "When enabled, any VRM model will be hidden/shown based on the camera's perspective."); DisableInternalShipCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "DisableInternalShipCamera", false, "Whether to disable the internal ship camera displayed above the bodycam monitor."); FixDroppedItemRotation = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "FixDroppedItemRotation", true, "If enabled, the mod will patch a bug that causes the rotation of dropped items to be desynced between clients."); PrintCosmeticsDebugInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "PrintCosmeticsDebugInfo", false, "Prints extra information about the cosmetics being collected for each player, as well as the code that is causing the collection."); BruteForcePreventFreezes = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "BruteForcePreventFreezes", false, "Enable a brute force approach to preventing errors in the camera setup callback that can cause the screen to freeze."); ReferencedObjectDestructionDetectionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ModelDestructionDebuggingPatchEnabled", false, "Enable this option when reproducing a camera freeze. This will cause a debug message to be printed when a model that a body cam is tracking is destroyed."); PrintCosmeticsDebugInfo.SettingChanged += delegate { CosmeticsCompatibility.PrintDebugInfo = PrintCosmeticsDebugInfo.Value; }; CosmeticsCompatibility.PrintDebugInfo = PrintCosmeticsDebugInfo.Value; BruteForcePreventFreezes.SettingChanged += delegate { BodyCamComponent.UpdateStaticSettings(); }; ReferencedObjectDestructionDetectionEnabled.SettingChanged += delegate { UpdateReferencedObjectDestructionDetectionEnabled(); }; UpdateReferencedObjectDestructionDetectionEnabled(); CosmeticsCompatibility.Initialize(harmony); harmony.PatchAll(typeof(PatchFixItemDropping)); BodyCamComponent.InitializeStatic(); } private void UpdateReferencedObjectDestructionDetectionEnabled() { if (ReferencedObjectDestructionDetectionEnabled.Value) { DestructionDetectionPatch.PatchAll(typeof(PatchModelDestructionDebugging)); } else { DestructionDetectionPatch.UnpatchSelf(); } } } public static class ShipObjects { public static Material blackScreenMaterial; public static ManualCameraRenderer ShipCameraRenderer; public static Terminal TerminalScript; public static bool TwoRadarCamsPresent; public static BodyCamComponent MainBodyCam; public static ManualCameraRenderer ExternalCameraRenderer; public static MeshRenderer DoorScreenRenderer; public static bool DoorScreenUsesExternalCamera; public static void EarlyInitialization() { blackScreenMaterial = StartOfRound.Instance.mapScreen.offScreenMat; GameObject obj = GameObject.Find("Environment/HangarShip/Cameras/FrontDoorSecurityCam/SecurityCamera"); ExternalCameraRenderer = ((obj != null) ? obj.GetComponent<ManualCameraRenderer>() : null); GameObject obj2 = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/SingleScreen"); DoorScreenRenderer = ((obj2 != null) ? obj2.GetComponent<MeshRenderer>() : null); GetAndMaybeDisableShipCamera(); BodyCamComponent.InitializeAtStartOfGame(); } private static void GetAndMaybeDisableShipCamera() { GameObject val = GameObject.Find("Environment/HangarShip/Cameras/ShipCamera"); if ((Object)(object)val == (Object)null) { Plugin.Instance.Logger.LogError((object)"Could not find the internal ship camera object."); return; } ShipCameraRenderer = val.GetComponent<ManualCameraRenderer>(); if ((Object)(object)ShipCameraRenderer?.mesh == (Object)null) { Plugin.Instance.Logger.LogError((object)"Internal ship camera does not have a camera renderer."); } else if (Plugin.DisableInternalShipCamera.Value) { int num = Array.FindIndex(((Renderer)ShipCameraRenderer.mesh).sharedMaterials, (Material material) => ((Object)material).name.StartsWith("ShipScreen1Mat")); if ((Object)(object)blackScreenMaterial == (Object)null || num == -1) { Plugin.Instance.Logger.LogError((object)"Internal ship camera monitor does not have the expected materials."); return; } val.SetActive(false); Material[] sharedMaterials = ((Renderer)ShipCameraRenderer.mesh).sharedMaterials; sharedMaterials[num] = blackScreenMaterial; ((Renderer)ShipCameraRenderer.mesh).sharedMaterials = sharedMaterials; } } public static void LateInitialization() { TerminalScript = Object.FindObjectOfType<Terminal>(); TwoRadarCamsPresent = (Object)(object)((Component)TerminalScript).GetComponent<ManualCameraRenderer>() != (Object)null; if ((Object)(object)DoorScreenRenderer != (Object)null) { DoorScreenUsesExternalCamera = ((Renderer)DoorScreenRenderer).sharedMaterials.Any((Material mat) => (Object)(object)mat.mainTexture == (Object)(object)ExternalCameraRenderer.cam.targetTexture); } InitializeBodyCam(); TerminalCommands.Initialize(); if (!TwoRadarCamsPresent && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { ManualCameraRenderer mapScreen = StartOfRound.Instance.mapScreen; mapScreen.SwitchRadarTargetAndSync(Math.Min(mapScreen.targetTransformIndex, mapScreen.radarTargets.Count - 1)); } } private static void InitializeBodyCam() { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001"); if ((Object)(object)val == (Object)null) { Plugin.Instance.Logger.LogError((object)"Could not find the bottom monitors' game object."); } else if ((Object)(object)val.GetComponent<BodyCamComponent>() == (Object)null) { MainBodyCam = val.AddComponent<BodyCamComponent>(); val.AddComponent<SyncBodyCamToRadarMap>(); MeshRenderer val2 = val.GetComponent<MeshRenderer>(); int monitorMaterialIndex = 2; int num = Plugin.GeneralImprovementsBetterMonitorIndex.Value - 1; if (num < 0) { num = 13; } MeshRenderer monitorForID = GeneralImprovementsCompatibility.GetMonitorForID(num); if (monitorForID != null) { val2 = monitorForID; monitorMaterialIndex = 0; } if ((Object)(object)val2 == (Object)null) { Plugin.Instance.Logger.LogError((object)"Failed to find the monitor renderer."); return; } MainBodyCam.MonitorRenderer = (Renderer)(object)val2; MainBodyCam.MonitorMaterialIndex = monitorMaterialIndex; } } } public class SyncBodyCamToRadarMap : MonoBehaviour { private static SyncBodyCamToRadarMap[] AllSynchronizedCams = new SyncBodyCamToRadarMap[0]; public static readonly FieldInfo f_ManualCameraRenderer_isScreenOn = AccessTools.Field(typeof(ManualCameraRenderer), "isScreenOn"); internal ManualCameraRenderer MapRenderer; internal BodyCamComponent BodyCam; public static SyncBodyCamToRadarMap[] GetAllSynchronizedCams() { return AllSynchronizedCams; } public ManualCameraRenderer GetMapRenderer() { return MapRenderer; } public BodyCamComponent GetBodyCam() { return BodyCam; } private static void DoForMap(ManualCameraRenderer mapRenderer, Action<SyncBodyCamToRadarMap> action) { SyncBodyCamToRadarMap[] allSynchronizedCams = AllSynchronizedCams; foreach (SyncBodyCamToRadarMap syncBodyCamToRadarMap in allSynchronizedCams) { if (syncBodyCamToRadarMap.MapRenderer == mapRenderer) { action(syncBodyCamToRadarMap); } } } public static void UpdateBodyCamTargetForMap(ManualCameraRenderer mapRenderer) { DoForMap(mapRenderer, delegate(SyncBodyCamToRadarMap syncedCam) { syncedCam.UpdateBodyCamTarget(); }); } public static void StartTargetTransitionForMap(ManualCameraRenderer mapRenderer) { DoForMap(mapRenderer, delegate(SyncBodyCamToRadarMap syncedCam) { syncedCam.StartTargetTransition(); }); } private static void DoForCam(BodyCamComponent bodyCam, Action<SyncBodyCamToRadarMap> action) { SyncBodyCamToRadarMap[] allSynchronizedCams = AllSynchronizedCams; foreach (SyncBodyCamToRadarMap syncBodyCamToRadarMap in allSynchronizedCams) { if (syncBodyCamToRadarMap.BodyCam == bodyCam) { action(syncBodyCamToRadarMap); } } } public static void UpdateBodyCamTarget(BodyCamComponent bodyCam) { DoForCam(bodyCam, delegate(SyncBodyCamToRadarMap syncedCam) { syncedCam.UpdateBodyCamTarget(); }); } private void Awake() { AllSynchronizedCams = AllSynchronizedCams.Append(this).ToArray(); if ((Object)(object)MapRenderer == (Object)null) { MapRenderer = ((Component)this).GetComponentsInChildren<ManualCameraRenderer>()?.FirstOrDefault((Func<ManualCameraRenderer, bool>)((ManualCameraRenderer renderer) => (Object)(object)renderer.cam == (Object)(object)renderer.mapCamera)); } if ((Object)(object)BodyCam == (Object)null) { BodyCam = ((Component)this).GetComponent<BodyCamComponent>(); } } private void Start() { UpdateBodyCamTarget(); } public void UpdateBodyCamTarget() { if ((Object)(object)MapRenderer.targetedPlayer != (Object)null) { BodyCam.SetTargetToPlayer(MapRenderer.targetedPlayer); } else { BodyCam.SetTargetToTransform(MapRenderer.radarTargets[MapRenderer.targetTransformIndex].transform); } BodyCam.SetScreenPowered((bool)f_ManualCameraRenderer_isScreenOn.GetValue(MapRenderer)); } public void StartTargetTransition() { BodyCam.StartTargetTransition(); } internal static void OnBodyCamDestroyed(BodyCamComponent bodyCam) { DoForCam(bodyCam, (Action<SyncBodyCamToRadarMap>)Object.Destroy); } private void OnDestroy() { AllSynchronizedCams = AllSynchronizedCams.Where((SyncBodyCamToRadarMap syncedCam) => syncedCam != this).ToArray(); } } public static class TerminalCommands { public static TerminalNode ViewMonitorNode; public static TerminalNode ViewBodyCamNode; public static TerminalKeyword BodyCamKeyword; public static RawImage PiPImage; private static readonly List<TerminalKeyword> newTerminalKeywords = new List<TerminalKeyword>(); private static readonly List<TerminalKeyword> modifiedTerminalKeywords = new List<TerminalKeyword>(); public static void Initialize() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ShipObjects.TerminalScript == (Object)null || (Object)(object)ShipObjects.MainBodyCam == (Object)null) { return; } if ((Object)(object)PiPImage != (Object)null) { Object.Destroy((Object)(object)((Component)PiPImage).gameObject); } PiPImage = null; ShipObjects.MainBodyCam.OnRenderTextureCreated -= SetRenderTexture; if (Plugin.TerminalPiPBodyCamEnabled.Value) { GameObject val = new GameObject("PictureInPictureImage"); val.transform.SetParent(((Component)ShipObjects.TerminalScript.terminalImageMask).transform, false); PiPImage = val.AddComponent<RawImage>(); val.AddComponent<TerminalBodyCamVisibilityTracker>().BodyCamToActivate = ShipObjects.MainBodyCam; RectTransform rectTransform = ((Graphic)ShipObjects.TerminalScript.terminalImage).rectTransform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 0f); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 1f); int value = (int)Plugin.TerminalPiPPosition.Value; ref float x = ref val2.x; ref float x2 = ref val3.x; (float, int) tuple = ((((uint)value & (true ? 1u : 0u)) != 0) ? (rectTransform.offsetMax.x, -1) : (rectTransform.offsetMin.x, 1)); (float, int) tuple2 = tuple; float num = tuple2.Item2; x = tuple2.Item1; x2 = num; ref float y = ref val2.y; x2 = ref val3.y; (float, int) tuple3 = ((((uint)value & 2u) != 0) ? (rectTransform.offsetMax.y, -1) : (rectTransform.offsetMin.y, 1)); (float, int) tuple4 = tuple3; num = tuple4.Item2; y = tuple4.Item1; x2 = num; Vector2 val4 = val2 + new Vector2(1f, 0.75f) * val3 * (float)Plugin.TerminalPiPWidth.Value; ((Graphic)PiPImage).rectTransform.offsetMin = Vector2.Min(val2, val4); ((Graphic)PiPImage).rectTransform.offsetMax = Vector2.Max(val2, val4); if ((Object)(object)ShipObjects.MainBodyCam.Camera != (Object)null) { PiPImage.texture = (Texture)(object)ShipObjects.MainBodyCam.Camera.targetTexture; } ShipObjects.MainBodyCam.OnRenderTextureCreated += SetRenderTexture; ShipObjects.MainBodyCam.OnBlankedSet += SetBodyCamBlanked; val.SetActive(false); } InitializeCommands(); } public static void SetRenderTexture(RenderTexture texture) { PiPImage.texture = (Texture)(object)texture; } public static void SetBodyCamBlanked(bool blanked) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) ((Graphic)PiPImage).color = (blanked ? Color.black : Color.white); } private static void InitializeCommands() { //IL_007c: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown RemoveAddedKeywords(); ViewBodyCamNode = null; BodyCamKeyword = null; if (Plugin.TerminalPiPBodyCamEnabled.Value) { ViewBodyCamNode = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)ViewBodyCamNode).name = "ViewBodyCam"; ViewBodyCamNode.displayText = "Toggling body cam\n\n"; ViewBodyCamNode.clearPreviousText = true; BodyCamKeyword = FindOrCreateKeyword("BodyCam", "bodycam", verb: false); ViewMonitorNode = FindOrCreateKeyword("View", "view", verb: true, (CompatibleNoun[])(object)new CompatibleNoun[1] { new CompatibleNoun { noun = BodyCamKeyword, result = ViewBodyCamNode } }).FindCompatibleNoun("monitor").result; } AddNewlyCreatedCommands(); } private static bool TerminalIsDisplayingMap() { return (Object)(object)ShipObjects.TerminalScript.displayingPersistentImage == (Object)(object)ViewMonitorNode.displayTexture; } [HarmonyPrefix] [HarmonyPatch(typeof(Terminal), "RunTerminalEvents")] private static bool RunTerminalEventsPrefix(TerminalNode node) { if ((Object)(object)node == (Object)(object)ViewBodyCamNode) { if (((Component)PiPImage).gameObject.activeSelf) { ((Component)PiPImage).gameObject.SetActive(false); return false; } if (!TerminalIsDisplayingMap()) { ShipObjects.TerminalScript.LoadTerminalImage(ViewMonitorNode); } if (TerminalIsDisplayingMap()) { ((Component)PiPImage).gameObject.SetActive(true); } return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(Terminal), "LoadNewNode")] private static void LoadNewNodePostfix(TerminalNode node) { if (!((Object)(object)PiPImage == (Object)null) && !((Object)(object)node != (Object)(object)ViewMonitorNode) && !TerminalIsDisplayingMap()) { ((Component)PiPImage).gameObject.SetActive(false); } } private static void RemoveAddedKeywords() { foreach (TerminalKeyword modifiedTerminalKeyword in modifiedTerminalKeywords) { if (modifiedTerminalKeyword.compatibleNouns == null) { continue; } TerminalKeyword val = modifiedTerminalKeyword; List<CompatibleNoun> list = new List<CompatibleNoun>(); foreach (CompatibleNoun item in modifiedTerminalKeyword.compatibleNouns.Where((CompatibleNoun compatible) => !newTerminalKeywords.Contains(compatible.noun))) { list.Add(item); } val.compatibleNouns = list.ToArray(); } modifiedTerminalKeywords.Clear(); foreach (TerminalKeyword newTerminalKeyword in newTerminalKeywords) { Object.Destroy((Object)(object)newTerminalKeyword); } TerminalNodesList terminalNodes; TerminalNodesList obj = (terminalNodes = ShipObjects.TerminalScript.terminalNodes); List<TerminalKeyword> list2 = new List<TerminalKeyword>(); foreach (TerminalKeyword item2 in obj.allKeywords.Where((TerminalKeyword keyword) => !newTerminalKeywords.Contains(keyword))) { list2.Add(item2); } terminalNodes.allKeywords = list2.ToArray(); newTerminalKeywords.Clear(); } private static TerminalKeyword FindKeyword(string word, bool verb) { return ((IEnumerable<TerminalKeyword>)ShipObjects.TerminalScript.terminalNodes.allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword keyword) => keyword.word == word && keyword.isVerb == verb)); } private static CompatibleNoun FindCompatibleNoun(this TerminalKeyword keyword, string noun) { return ((IEnumerable<CompatibleNoun>)keyword.compatibleNouns).FirstOrDefault((Func<CompatibleNoun, bool>)((CompatibleNoun compatible) => compatible.noun.word == noun)); } private static TerminalKeyword FindOrCreateKeyword(string name, string word, bool verb, CompatibleNoun[] compatibleNouns = null) { Plugin.Instance.Logger.LogInfo((object)("Creating terminal " + (verb ? "verb" : "noun") + " '" + word + "' (" + name + ").")); TerminalKeyword val = FindKeyword(word, verb); if ((Object)(object)val == (Object)null) { val = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val).name = name; val.isVerb = verb; val.word = word; val.compatibleNouns = compatibleNouns; newTerminalKeywords.Add(val); Plugin.Instance.Logger.LogInfo((object)" Keyword was not found, created a new one."); } else { TerminalKeyword val2 = val; CompatibleNoun[] obj = val.compatibleNouns ?? Array.Empty<CompatibleNoun>(); CompatibleNoun[] array = compatibleNouns ?? Array.Empty<CompatibleNoun>(); int num = 0; CompatibleNoun[] array2 = (CompatibleNoun[])(object)new CompatibleNoun[obj.Length + array.Length]; CompatibleNoun[] array3 = obj; foreach (CompatibleNoun val3 in array3) { array2[num] = val3; num++; } array3 = array; foreach (CompatibleNoun val3 in array3) { array2[num] = val3; num++; } val2.compatibleNouns = array2; Plugin.Instance.Logger.LogInfo((object)" Keyword existed, appended nouns."); } modifiedTerminalKeywords.Add(val); return val; } private static void AddNewlyCreatedCommands() { TerminalNodesList terminalNodes; TerminalKeyword[] allKeywords = (terminalNodes = ShipObjects.TerminalScript.terminalNodes).allKeywords; List<TerminalKeyword> list = newTerminalKeywords; int num = 0; TerminalKeyword[] array = (TerminalKeyword[])(object)new TerminalKeyword[allKeywords.Length + list.Count]; TerminalKeyword[] array2 = allKeywords; foreach (TerminalKeyword val in array2) { array[num] = val; num++; } foreach (TerminalKeyword item in list) { array[num] = item; num++; } terminalNodes.allKeywords = array; } } public enum PiPPosition : uint { BottomLeft, BottomRight, TopLeft, TopRight } public class TerminalBodyCamVisibilityTracker : MonoBehaviour { public BodyCamComponent BodyCamToActivate; private void OnEnable() { if ((Object)(object)BodyCamToActivate != (Object)null) { BodyCamToActivate.ForceEnableCamera = true; } } private void OnDisable() { if ((Object)(object)BodyCamToActivate != (Object)null) { BodyCamToActivate.ForceEnableCamera = false; } } } public static class Utilities { private static Camera[] allCameras = Array.Empty<Camera>(); private static readonly Plane[] frustumPlanes = (Plane[])(object)new Plane[6]; public static bool IsVisibleToAnyCameraExcept(this Renderer renderer, Camera cameraToSkip, bool debug = false) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (allCameras.Length != Camera.allCamerasCount) { allCameras = (Camera[])(object)new Camera[Camera.allCamerasCount]; } Camera.GetAllCameras(allCameras); Bounds bounds = renderer.bounds; int layer = ((Component)renderer).gameObject.layer; Camera[] array = allCameras; foreach (Camera val in array) { if ((val == null || val != cameraToSkip) && (val.cullingMask & (1 << layer)) != 0) { GeometryUtility.CalculateFrustumPlanes(val, frustumPlanes); if (GeometryUtility.TestPlanesAABB(frustumPlanes, bounds)) { return true; } } } return false; } } } namespace OpenBodyCams.Patches { public class SequenceMatch { public int Start; public int End; public int Size => End - Start; public SequenceMatch(int start, int end) { Start = start; End = end; base..ctor(); } } public static class Common { public static IEnumerable<T> IndexRangeView<T>(this List<T> list, int start, int end) { for (int i = start; i < end; i++) { yield return list[i]; } } public static IEnumerable<T> IndexRangeView<T>(this List<T> list, SequenceMatch range) { return list.IndexRangeView(range.Start, range.End); } public static SequenceMatch FindIndexOfSequence<T>(this List<T> list, int startIndex, IEnumerable<Predicate<T>> predicates) { int num; for (num = startIndex; num < list.Count(); num++) { IEnumerator<Predicate<T>> enumerator = predicates.GetEnumerator(); if (!enumerator.MoveNext()) { return null; } num = list.FindIndex(num, enumerator.Current); if (num < 0) { break; } bool flag = true; int num2 = 1; while (enumerator.MoveNext()) { if (num2 >= list.Count() - num || !enumerator.Current(list[num + num2])) { flag = false; break; } num2++; } if (flag) { return new SequenceMatch(num, num + predicates.Count()); } } return null; } public static SequenceMatch FindIndexOfSequence<T>(this List<T> list, IEnumerable<Predicate<T>> predicates) { return list.FindIndexOfSequence(0, predicates); } public static int PopCount(this CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) { MethodInfo obj = (MethodInfo)instruction.operand; int num = obj.GetParameters().Length; if (!obj.IsStatic) { num++; } return num; } if (instruction.opcode == OpCodes.Ret) { return 1; } return instruction.opcode.StackBehaviourPop switch { StackBehaviour.Pop0 => 0, StackBehaviour.Pop1 => 1, StackBehaviour.Pop1_pop1 => 2, StackBehaviour.Popi => 1, StackBehaviour.Popi_pop1 => 2, StackBehaviour.Popi_popi => 2, StackBehaviour.Popi_popi8 => 2, StackBehaviour.Popi_popi_popi => 3, StackBehaviour.Popi_popr4 => 2, StackBehaviour.Popi_popr8 => 2, StackBehaviour.Popref => 1, StackBehaviour.Popref_pop1 => 2, StackBehaviour.Popref_popi => 2, StackBehaviour.Popref_popi_popi => 3, StackBehaviour.Popref_popi_popi8 => 3, StackBehaviour.Popref_popi_popr4 => 3, StackBehaviour.Popref_popi_popr8 => 3, StackBehaviour.Popref_popi_popref => 3, StackBehaviour.Varpop => throw new NotImplementedException("Variable pop on non-call instruction"), StackBehaviour.Popref_popi_pop1 => 3, _ => throw new NotSupportedException($"StackBehaviourPop of {instruction.opcode.StackBehaviourPop} was not a pop for instruction '{instruction}'"), }; } public static int PushCount(this CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) { if (((MethodInfo)instruction.operand).ReturnType == typeof(void)) { return 0; } return 1; } return instruction.opcode.StackBehaviourPush switch { StackBehaviour.Push0 => 0, StackBehaviour.Push1 => 1, StackBehaviour.Push1_push1 => 2, StackBehaviour.Pushi => 1, StackBehaviour.Pushi8 => 1, StackBehaviour.Pushr4 => 1, StackBehaviour.Pushr8 => 1, StackBehaviour.Pushref => 1, StackBehaviour.Varpush => throw new NotImplementedException("Variable push on non-call instruction"), _ => throw new NotSupportedException($"StackBehaviourPush of {instruction.opcode.StackBehaviourPush} was not a push for instruction '{instruction}'"), }; } public static SequenceMatch InstructionRangeForStackItems(this List<CodeInstruction> instructions, int instructionIndex, int startIndex, int endIndex) { int num = -1; int num2 = -1; instructionIndex--; int num3 = 0; while (instructionIndex >= 0) { CodeInstruction instruction = instructions[instructionIndex]; int num4 = instruction.PushCount(); if (num2 == -1 && num3 == startIndex && num4 > 0) { num2 = instructionIndex + 1; } num3 += instruction.PushCount(); num3 -= instruction.PopCount(); if (num3 > endIndex) { num = instructionIndex; break; } instructionIndex--; } if (num == -1 || num2 == -1) { return null; } return new SequenceMatch(num, num2); } } internal class PatchFixItemDropping { private static readonly MethodInfo m_PlayerControllerB_SetObjectAsNoLongerHeld = typeof(PlayerControllerB).GetMethod("SetObjectAsNoLongerHeld", new Type[5] { typeof(bool), typeof(bool), typeof(Vector3), typeof(GrabbableObject), typeof(int) }); [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "ThrowObjectClientRpc")] private static IEnumerable<CodeInstruction> ThrowObjectClientRpcTranspiler(IEnumerable<CodeInstruction> instructions, MethodBase method) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown if (!Plugin.FixDroppedItemRotation.Value) { return instructions; } List<CodeInstruction> list = instructions.ToList(); int num = Array.FindIndex(method.GetParameters(), (ParameterInfo p) => p.Name == "floorYRot") + 1; if (num < 1) { Plugin.Instance.Logger.LogWarning((object)"Dropped item patch transpiler failed to find the floorYRot argument."); return instructions; } int num2 = list.FindIndex((CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_PlayerControllerB_SetObjectAsNoLongerHeld)); if (num2 == -1) { Plugin.Instance.Logger.LogWarning((object)"Dropped item patch transpiler failed to find the call to SetObjectAsNoLongerHeld()."); return instructions; } SequenceMatch sequenceMatch = list.InstructionRangeForStackItems(num2, 0, 0); if (sequenceMatch == null) { Plugin.Instance.Logger.LogWarning((object)"Dropped item patch transpiler failed to get the instructions pushing the floorYRot value."); return instructions; } list.RemoveRange(sequenceMatch.Start, sequenceMatch.Size); list.Insert(sequenceMatch.Start, new CodeInstruction(OpCodes.Ldarg, (object)num)); return list; } } [HarmonyPatch(typeof(ManualCameraRenderer))] internal class PatchManualCameraRenderer { [HarmonyPostfix] [HarmonyPatch("updateMapTarget")] private static IEnumerator updateMapTargetPostfix(IEnumerator result, ManualCameraRenderer __instance) { SyncBodyCamToRadarMap.StartTargetTransitionForMap(__instance); while (result.MoveNext()) { yield return result.Current; } SyncBodyCamToRadarMap.UpdateBodyCamTargetForMap(__instance); } [HarmonyPostfix] [HarmonyPatch("SwitchScreenOn")] [HarmonyAfter(new string[] { "ShaosilGaming.GeneralImprovements" })] private static void SwitchScreenOnPostfix(ManualCameraRenderer __instance) { SyncBodyCamToRadarMap.UpdateBodyCamTargetForMap(__instance); } [HarmonyPostfix] [HarmonyPatch("MeetsCameraEnabledConditions")] private static void MeetsCameraEnabledConditionsPostfix(ManualCameraRenderer __instance, ref bool __result, PlayerControllerB player) { if (__instance == StartOfRound.Instance.mapScreen) { if (!__result && !ShipObjects.TwoRadarCamsPresent && ((Behaviour)ShipObjects.TerminalScript.terminalUIScreen).isActiveAndEnabled) { __result = true; } } else if (__instance == ShipObjects.ShipCameraRenderer) { if (__result) { __result = ((Renderer)(object)__instance.mesh).IsVisibleToAnyCameraExcept(__instance.cam); } } else if (__instance == ShipObjects.ExternalCameraRenderer && ShipObjects.DoorScreenUsesExternalCamera && !__result && (player.isInHangarShipRoom || !StartOfRound.Instance.shipDoorsEnabled)) { __result = ((Renderer)(object)ShipObjects.DoorScreenRenderer).IsVisibleToAnyCameraExcept(__instance.cam, debug: true); } } [HarmonyTranspiler] [HarmonyPatch("RemoveTargetFromRadar")] private static IEnumerable<CodeInstruction> RemoveTargetFromRadarTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown MethodInfo m_ManualCameraRenderer_SwitchRadarTargetForward = typeof(ManualCameraRenderer).GetMethod("SwitchRadarTargetForward", new Type[1] { typeof(bool) }); MethodInfo method = typeof(NetworkBehaviour).GetMethod("get_IsOwner"); List<CodeInstruction> list = instructions.ToList(); SequenceMatch sequenceMatch = list.FindIndexOfSequence(new <>z__ReadOnlyArray<Predicate<CodeInstruction>>(new Predicate<CodeInstruction>[3] { (CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)0), (CodeInstruction insn) => CodeInstructionExtensions.LoadsConstant(insn, 0L), (CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_ManualCameraRenderer_SwitchRadarTargetForward) })); list[sequenceMatch.Start + 1] = new CodeInstruction(OpCodes.Ldc_I4_1, (object)null); Label label = generator.DefineLabel(); list[sequenceMatch.End].labels.Add(label); list.InsertRange(sequenceMatch.Start, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Call, (object)method), new CodeInstruction(OpCodes.Brfalse_S, (object)label) })); return list; } } [HarmonyPatch(typeof(HauntedMaskItem))] internal class PatchHauntedMaskItem { [HarmonyPostfix] [HarmonyPatch("CreateMimicServerRpc")] private static void CreateMimicServerRpcPostfix() { BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(); } [HarmonyPostfix] [HarmonyPatch("waitForMimicEnemySpawn")] private static IEnumerator waitForMimicEnemySpawnPostfix(IEnumerator __result) { while (__result.MoveNext()) { yield return __result.Current; } BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(); } } [HarmonyPatch(typeof(MaskedPlayerEnemy))] internal class PatchMaskedPlayerEnemy { [HarmonyPrefix] [HarmonyPatch("FinishKillAnimation")] private static void FinishKillAnimationPrefix(bool __0) { if (__0) { BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(); } } [HarmonyPostfix] [HarmonyPatch("waitForMimicEnemySpawn")] private static IEnumerator waitForMimicEnemySpawnPostfix(IEnumerator __result) { while (__result.MoveNext()) { yield return __result.Current; } BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(); } } internal static class PatchModelDestructionDebugging { private static bool IsChildReferenced(GameObject obj) { Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (BodyCamComponent.AnyBodyCamHasReference(((Component)componentsInChildren[i]).gameObject)) { return true; } } Renderer[] componentsInChildren2 = obj.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { if (BodyCamComponent.AnyBodyCamHasReference(componentsInChildren2[i])) { return true; } } return false; } private static bool IsReferencedObject(Object obj) { if (obj == (Object)null) { return false; } Renderer val = (Renderer)(object)((obj is Renderer) ? obj : null); if (val != null) { return BodyCamComponent.AnyBodyCamHasReference(val); } GameObject val2 = (GameObject)(object)((obj is GameObject) ? obj : null); if (val2 != null) { return IsChildReferenced(val2); } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object), typeof(float) })] private static void DestroyingObject(Object obj, float t) { if (IsReferencedObject(obj)) { Plugin.Instance.Logger.LogWarning((object)$"In {t} seconds, {obj.name} will be destroyed while it is referenced by a body cam."); Plugin.Instance.Logger.LogWarning((object)new StackTrace()); } } [HarmonyPrefix] [HarmonyPatch(typeof(Object), "DestroyImmediate", new Type[] { typeof(Object), typeof(bool) })] private static void DestroyingObjectImmediately(Object obj) { if (IsReferencedObject(obj)) { Plugin.Instance.Logger.LogWarning((object)("Immediately destroying " + obj.name + " which is referenced by a body cam.")); Plugin.Instance.Logger.LogWarning((object)new StackTrace()); } } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PatchPlayerControllerB { [HarmonyFinalizer] [HarmonyPatch("ConnectClientToPlayerObject")] [HarmonyAfter(new string[] { "ShaosilGaming.GeneralImprovements" })] private static void ConnectClientToPlayerObjectFinalizer() { ShipObjects.LateInitialization(); } [HarmonyPostfix] [HarmonyPatch("KillPlayer")] private static void KillPlayerPostfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(((Component)__instance).transform); } } [HarmonyPostfix] [HarmonyPatch("KillPlayerClientRpc")] private static void KillPlayerClientRpcPostfix(PlayerControllerB __instance) { if (!((NetworkBehaviour)__instance).IsOwner) { BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(((Component)__instance).transform); } } } [HarmonyPatch(typeof(StartOfRound))] internal class PatchStartOfRound { [HarmonyPostfix] [HarmonyPatch("Start")] [HarmonyPriority(700)] private static void StartPostfix() { ShipObjects.EarlyInitialization(); } [HarmonyPostfix] [HarmonyPatch("ReviveDeadPlayers")] private static void ReviveDeadPlayersPostfix() { BodyCamComponent.MarkTargetStatusChangedForAllBodyCams(); } } public static class Reflection { public static readonly MethodInfo m_StartOfRound_get_Instance = typeof(StartOfRound).GetMethod("get_Instance", Array.Empty<Type>()); public static readonly FieldInfo f_StartOfRound_thisClientPlayerId = typeof(StartOfRound).GetField("thisClientPlayerId"); } } namespace OpenBodyCams.Compatibility { public static class AdvancedCompanyCompatibility { private static int cosmeticChangesInProgress; public static bool Initialize(Harmony harmony) { Type typeFromHandle = typeof(Player); (string, Type[])[] obj = new(string, Type[])[6] { ("SetCosmetics", new Type[2] { typeof(string[]), typeof(bool) }), ("AddCosmetic", new Type[1] { typeof(string) }), ("ReequipHead", Array.Empty<Type>()), ("ReequipBody", Array.Empty<Type>()), ("ReequipFeet", Array.Empty<Type>()), ("UnequipAll", Array.Empty<Type>()) }; MethodInfo method = typeof(AdvancedCompanyCompatibility).GetMethod("AfterEquipmentChange", BindingFlags.Static | BindingFlags.NonPublic); (string, Type[])[] array = obj; for (int i = 0; i < array.Length; i++) { (string, Type[]) tuple = array[i]; string item = tuple.Item1; Type[] item2 = tuple.Item2; MethodInfo method2 = typeFromHandle.GetMethod(item, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, item2, null); if ((object)method2 == null) { Plugin.Instance.Logger.LogWarning((object)("Failed to find " + typeFromHandle.Name + "." + item + " to apply postfix.")); return false; } harmony.CreateProcessor((MethodBase)method2).AddPostfix(method).Patch(); } harmony.CreateProcessor((MethodBase)typeof(LightShoeRGB).GetMethod("LiftCurse", BindingFlags.Instance | BindingFlags.NonPublic)).AddPostfix(typeof(AdvancedCompanyCompatibility).GetMethod("UpdateCosmeticsAfterCoroutine", BindingFlags.Static | BindingFlags.NonPublic)).Patch(); return true; } [MethodImpl(MethodImplOptions.NoInlining)] public static GameObject[] CollectCosmetics(PlayerControllerB player) { Player player2 = Player.GetPlayer(player); IEnumerable<GameObject> enumerable = player2.AppliedCosmetics.Values; GameObject[] equipmentItemsHead = player2.EquipmentItemsHead; if (equipmentItemsHead != null) { enumerable = enumerable.Concat(equipmentItemsHead); } GameObject[] equipmentItemsBody = player2.EquipmentItemsBody; if (equipmentItemsBody != null) { enumerable = enumerable.Concat(equipmentItemsBody); } GameObject[] equipmentItemsFeet = player2.EquipmentItemsFeet; if (equipmentItemsFeet != null) { enumerable = enumerable.Concat(equipmentItemsFeet); } IEnumerable<GameObject> first = from transform in enumerable.Where((GameObject cosmetic) => (Object)(object)cosmetic != (Object)null).SelectMany((GameObject cosmetic) => cosmetic.GetComponentsInChildren<Transform>()) select ((Component)transform).gameObject; IEnumerable<GameObject> second; if (!((Object)(object)player2.HeadMount == (Object)null)) { IEnumerable<GameObject> enumerable2 = new <>z__ReadOnlyArray<GameObject>((GameObject[])(object)new GameObject[1] { player2.HeadMount }); second = enumerable2; } else { IEnumerable<GameObject> enumerable2 = Array.Empty<GameObject>(); second = enumerable2; } return first.Concat(second).ToArray(); } private static void AfterEquipmentChange() { BodyCamComponent.MarkTargetDirtyUntilRenderForAllBodyCams(); } private static IEnumerator UpdateCosmeticsAfterCoroutine(IEnumerator __result) { while (true) { try { if (!__result.MoveNext()) { break; } } catch (Exception ex) { Plugin.Instance.Logger.LogError((object)"AdvancedCompany encountered an error in a coroutine:"); Plugin.Instance.Logger.LogError((object)ex); break; } yield return __result.Current; } BodyCamComponent.MarkTargetDirtyUntilRenderForAllBodyCams(); } } public static class GeneralImprovementsCompatibility { private static string getMonitorPath(int id) { return id switch { 0 => "Monitors/TopGroupL/Screen1", 1 => "Monitors/TopGroupL/Screen2", 2 => "Monitors/TopGroupM/Screen3", 3 => "Monitors/TopGroupM/Screen4", 4 => "Monitors/TopGroupR/Screen5", 5 => "Monitors/TopGroupR/Screen6", 6 => "Monitors/TopGroupL/Screen7", 7 => "Monitors/TopGroupL/Screen8", 8 => "Monitors/TopGroupM/Screen9", 9 => "Monitors/TopGroupM/Screen10", 10 => "Monitors/TopGroupR/Screen11", 11 => "Monitors/TopGroupR/Screen12", 12 => "Monitors/BigLeft/LScreen", 13 => "Monitors/BigRight/RScreen", _ => null, }; } public static MeshRenderer GetMonitorForID(int id) { GameObject obj = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/MonitorGroup(Clone)/" + getMonitorPath(id)); if (obj == null) { return null; } return obj.GetComponent<MeshRenderer>(); } } public static class LethalVRMCompatibility { private static IEnumerable vrmInstances; [MethodImpl(MethodImplOptions.NoInlining)] public static bool Initialize(Harmony harmony) { GameObject obj = GameObject.Find("LethalVRM Manager"); LethalVRMManager val = ((obj != null) ? obj.GetComponent<LethalVRMManager>() : null); if (val == null) { Plugin.Instance.Logger.LogWarning((object)"Failed to find the LethalVRMManager instance."); return false; } vrmInstances = val.instances; if (vrmInstances == null) { Plugin.Instance.Logger.LogWarning((object)"Failed to get the value of the LethalVRMManager.instances field."); return false; } MethodInfo method = typeof(LethalVRMManager).GetMethod("LoadModelToPlayer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetCustomAttribute<AsyncStateMachineAttribute>().StateMachineType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic); harmony.CreateProcessor((MethodBase)method).AddTranspiler(typeof(LethalVRMCompatibility).GetMethod("LoadModelToPlayerTranspiler", BindingFlags.Static | BindingFlags.NonPublic)).Patch(); return true; } private static IEnumerable<CodeInstruction> LoadModelToPlayerTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); MethodInfo method = typeof(BodyCamComponent).GetMethod("MarkTargetDirtyUntilRenderForAllBodyCams", Array.Empty<Type>()); list.Insert(list.Count() - 2, new CodeInstruction(OpCodes.Call, (object)method)); return list; } [MethodImpl(MethodImplOptions.NoInlining)] public static GameObject[] CollectCosmetics(PlayerControllerB player) { foreach (LethalVRMInstance item in (ICollection<LethalVRMInstance>)vrmInstances) { if (item != null && item.PlayerControllerB == player) { return item.renderers.Select((Renderer renderer) => ((Component)renderer).gameObject).ToArray(); } } return (GameObject[])(object)new GameObject[0]; } } public static class ModelReplacementAPICompatibility { public static MethodInfo m_UpdateModelReplacement; public static bool Initialize(Harmony harmony) { MethodInfo method = typeof(ViewStateManager).GetMethod("ReportBodyReplacementAddition", new Type[1] { typeof(BodyReplacementBase) }); if ((object)method == null) { Plugin.Instance.Logger.LogInfo((object)"ModelReplacementAPI is installed, but the `ViewStateManager.ReportBodyReplacementAddition()` method was not found."); return false; } MethodInfo method2 = typeof(ModelReplacementAPI).GetMethod("RemovePlayerModelReplacement", new Type[1] { typeof(PlayerControllerB) }); if ((object)method2 == null) { Plugin.Instance.Logger.LogInfo((object)"ModelReplacementAPI is installed, but the `ModelReplacementAPI.RemovePlayerModelReplacement()` method was not found."); return false; } m_UpdateModelReplacement = typeof(ModelReplacementAPICompatibility).GetMethod("UpdateModelReplacement", new Type[1] { typeof(ViewStateManager) }); harmony.CreateProcessor((MethodBase)method).AddPostfix(m_UpdateModelReplacement).Patch(); MethodInfo method3 = typeof(ModelReplacementAPICompatibility).GetMethod("RemoveModelReplacementTranspiler"); harmony.CreateProcessor((MethodBase)method2).AddTranspiler(method3).Patch(); m_UpdateModelReplacement = null; return true; } [MethodImpl(MethodImplOptions.NoInlining)] public static GameObject[] CollectCosmetics(PlayerControllerB player) { BodyReplacementBase val = ((Component)player).GetComponent<ViewStateManager>()?.bodyReplacement; if ((Object)(object)val?.replacementModel == (Object)null) { return Array.Empty<GameObject>(); } return (from cosmeticObject in val.replacementModel.GetComponentsInChildren<Transform>() select ((Component)cosmeticObject).gameObject).ToArray(); } public static void UpdateModelReplacement(ViewStateManager __instance) { BodyCamComponent.MarkTargetDirtyUntilRenderForAllBodyCams(((Com
BepInEx/plugins/OpenMonitors.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using OpenMonitors.Monitors; using TMPro; using Unity.Netcode; 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("OpenMonitors")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OpenMonitors")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1203C15A-FDA7-419A-9D8B-0312A7C308AC")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 OpenMonitors { public static class ModInfo { public const string Name = "OpenMonitors"; public const string Guid = "xxxstoner420bongmasterxxx.open_monitors"; public const string Version = "1.1.1"; } [BepInPlugin("xxxstoner420bongmasterxxx.open_monitors", "OpenMonitors", "1.1.1")] public class Plugin : BaseUnityPlugin { public static ConfigFile ModConfig; private static Plugin? _instance; public static ManualLogSource ModLogger; private readonly Harmony _harmony = new Harmony("xxxstoner420bongmasterxxx.open_monitors"); private void Awake() { ModLogger = ((BaseUnityPlugin)this).Logger; if (!Object.op_Implicit((Object)(object)_instance)) { ModLogger.LogInfo((object)"OpenMonitors -> loading"); _instance = this; ModConfig = ((BaseUnityPlugin)this).Config; Config.Initialize(); _harmony.PatchAll(Assembly.GetExecutingAssembly()); ModLogger.LogInfo((object)"OpenMonitors -> complete"); } } } public static class PluginInfo { public const string PLUGIN_GUID = "OpenMonitors"; public const string PLUGIN_NAME = "OpenMonitors"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace OpenMonitors.Patch { [HarmonyPatch(typeof(DepositItemsDesk))] public class DepositItemsDesk { [HarmonyPostfix] [HarmonyPatch("SellAndDisplayItemProfits")] private static void UpdateCreditsAfterSellingLoot() { Plugin.ModLogger.LogDebug((object)"DepositItemsDesk.UpdateCreditsAfterSellingLoot"); CreditsMonitor.Instance.UpdateMonitor(); } } [HarmonyPatch(typeof(HUDManager))] public class HUDManager { [HarmonyPostfix] [HarmonyPatch("ApplyPenalty")] private static void UpdateCreditsAfterDeadPlayersPenalty() { Plugin.ModLogger.LogDebug((object)"HUDManager.UpdateCreditsAfterDeadPlayersPenalty"); CreditsMonitor.Instance.UpdateMonitor(); } } [HarmonyPatch(typeof(PlayerControllerB))] public class PlayerControllerB { [HarmonyPostfix] [HarmonyPatch("ConnectClientToPlayerObject")] private static void OnPlayerConnect() { ((MonoBehaviour)CoroutineHelper.Instance).StartCoroutine(WaitOnPlayerConnectForMonitorsToBeCreated()); } private static IEnumerator WaitOnPlayerConnectForMonitorsToBeCreated() { Plugin.ModLogger.LogDebug((object)"WaitOnPlayerConnectForMonitorsToBeCreated"); yield return (object)new WaitUntil((Func<bool>)(() => Object.op_Implicit((Object)(object)CreditsMonitor.Instance) && Object.op_Implicit((Object)(object)LifeSupportMonitor.Instance))); CreditsMonitor.Instance.UpdateMonitor(); LifeSupportMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("GrabObjectClientRpc")] private static void RefreshLootOnPickupClient(bool grabValidated, ref NetworkObjectReference grabbedObject) { NetworkObject val = default(NetworkObject); if (((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null)) { GrabbableObject componentInChildren = ((Component)val).gameObject.GetComponentInChildren<GrabbableObject>(); if (componentInChildren.isInShipRoom || componentInChildren.isInElevator) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.RefreshLootOnPickupClient"); LootMonitor.Instance.UpdateMonitor(); } } } [HarmonyPostfix] [HarmonyPatch("ThrowObjectClientRpc")] private static void RefreshLootOnThrowClient(bool droppedInElevator, bool droppedInShipRoom, Vector3 targetFloorPosition, NetworkObjectReference grabbedObject) { if (droppedInShipRoom || droppedInElevator) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.RefreshLootOnThrowClient"); LootMonitor.Instance.UpdateMonitor(); } } [HarmonyPostfix] [HarmonyPatch("KillPlayer")] private static void UpdateLifeSupportMonitorOnPlayerDeath(Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.UpdateLifeSupportMonitorOnPlayerDeath"); LifeSupportMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("KillPlayerClientRpc")] private static void UpdateLifeSupportMonitorOnPlayerDeathClientRpc(int playerId, bool spawnBody, Vector3 bodyVelocity, int causeOfDeath, int deathAnimation) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.UpdateLifeSupportMonitorOnPlayerDeathClientRpc"); LifeSupportMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("DamagePlayer")] private static void UpdateLifeSupportMonitorOnPlayerDamage(int damageNumber, bool hasDamageSFX, bool callRPC, CauseOfDeath causeOfDeath, int deathAnimation, bool fallDamage, Vector3 force) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.UpdateLifeSupportMonitorOnPlayerDamage"); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("DamageOnOtherClients")] private static void UpdateLifeSupportMonitorForPlayerDamageOnOtherClients(int damageNumber, int newHealthAmount) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.UpdateLifeSupportMonitorForPlayerDamageOnOtherClients"); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("DamagePlayerClientRpc")] private static void UpdateLifeSupportMonitorOnPlayerDamageClientRpc(int damageNumber, int newHealthAmount) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.UpdateLifeSupportMonitorOnPlayerDamageClientRpc"); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("DamagePlayerFromOtherClientClientRpc")] private static void UpdateLifeSupportMonitorOnOtherClientPlayerDamageClientRpc(int damageAmount, Vector3 hitDirection, int playerWhoHit, int newHealthAmount) { Plugin.ModLogger.LogDebug((object)"PlayerControllerB.UpdateLifeSupportMonitorOnOtherClientPlayerDamageClientRpc"); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } } [HarmonyPatch(typeof(StartOfRound))] public class StartOfRound { [HarmonyPostfix] [HarmonyPatch("Start")] private static void Initialize() { Plugin.ModLogger.LogDebug((object)"StartOfRound.Initialize"); Setup.Initialize(); } [HarmonyPostfix] [HarmonyPatch("ReviveDeadPlayers")] private static void RefreshMonitorsWhenPlayerRevives() { Plugin.ModLogger.LogDebug((object)"StartOfRound.RefreshMonitorsWhenPlayerRevives"); CreditsMonitor.Instance.UpdateMonitor(); DayMonitor.Instance.UpdateMonitor(); LifeSupportMonitor.Instance.UpdateMonitor(); LootMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("SyncShipUnlockablesClientRpc")] private static void RefreshLootForClientOnStart() { Plugin.ModLogger.LogDebug((object)"StartOfRound.RefreshLootForClientOnStart"); LootMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("ChangeLevelClientRpc")] private static void UpdateCreditsWhenSwitchingMoons() { Plugin.ModLogger.LogDebug((object)"StartOfRound.UpdateCreditsWhenSwitchingMoons"); CreditsMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("EndOfGameClientRpc")] private static void RefreshDayWhenShipHasLeft() { Plugin.ModLogger.LogDebug((object)"StartOfRound.RefreshDayWhenShipHasLeft"); DayMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("StartGame")] private static void UpdateDayAtStartOfGame() { Plugin.ModLogger.LogDebug((object)"StartOfRound.UpdateDayAtStartOfGame"); DayMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("OnClientConnect")] private static void UpdateMonitorsWhenPlayerConnectsClient(ulong clientId) { Plugin.ModLogger.LogDebug((object)"StartOfRound.UpdateMonitorsWhenPlayerConnectsClient"); CreditsMonitor.Instance.UpdateMonitor(); LifeSupportMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); LootMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("OnPlayerConnectedClientRpc")] private static void UpdateMonitorsWhenPlayerConnectsClientRpc(ulong clientId, int connectedPlayers, ulong[] connectedPlayerIdsOrdered, int assignedPlayerObjectId, int serverMoneyAmount, int levelID, int profitQuota, int timeUntilDeadline, int quotaFulfilled, int randomSeed) { Plugin.ModLogger.LogDebug((object)"StartOfRound.UpdateMonitorsWhenPlayerConnectsClientRpc"); CreditsMonitor.Instance.UpdateMonitor(); LifeSupportMonitor.Instance.UpdateMonitor(); LootMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("OnPlayerDC")] private static void UpdateMonitorsWhenPlayerDisconnects(int playerObjectNumber, ulong clientId) { Plugin.ModLogger.LogDebug((object)"StartOfRound.UpdateMonitorsWhenPlayerDisconnects"); CreditsMonitor.Instance.UpdateMonitor(); LifeSupportMonitor.Instance.UpdateMonitor(); LootMonitor.Instance.UpdateMonitor(); PlayersLifeSupportMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("SetMapScreenInfoToCurrentLevel")] private static void ColorWeather(ref TextMeshProUGUI ___screenLevelDescription, ref SelectableLevel ___currentLevel) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder("Orbiting: ").AppendLine(___currentLevel.PlanetName); if (!Config.HideWeather.Value) { stringBuilder.Append("Weather: ").AppendLine(FormatWeather(___currentLevel.currentWeather)); } stringBuilder.Append(___currentLevel.LevelDescription ?? string.Empty); ((TMP_Text)___screenLevelDescription).text = stringBuilder.ToString(); } private static string FormatWeather(LevelWeatherType currentWeather) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected I4, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) Plugin.ModLogger.LogDebug((object)$"Weather: {currentWeather}"); if (1 == 0) { } string text = (currentWeather - -1) switch { 1 => ParseColorInput(Config.DustCloudsWeatherColor), 6 => ParseColorInput(Config.EclipsedWeatherColor), 5 => ParseColorInput(Config.FloodedWeatherColor), 4 => ParseColorInput(Config.FoggyWeatherColor), 0 => ParseColorInput(Config.NoneWeatherColor), 2 => ParseColorInput(Config.RainyWeatherColor), 3 => ParseColorInput(Config.StormyWeatherColor), _ => ((ConfigEntryBase)Config.NoneWeatherColor).DefaultValue.ToString(), }; if (1 == 0) { } string arg = text; return $"<color=#{arg}>{currentWeather}</color>"; } private static string ParseColorInput(ConfigEntry<string> entry) { string text = entry.Value.Replace("#", ""); Regex regex = new Regex("(?i)[0-9a-f]{6}"); return regex.IsMatch(text) ? text : ((ConfigEntryBase)entry).DefaultValue.ToString(); } } [HarmonyPatch(typeof(Terminal))] public class Terminal { [HarmonyPostfix] [HarmonyPatch("SyncGroupCreditsClientRpc")] private static void RefreshMoney() { Plugin.ModLogger.LogDebug((object)"Terminal.RefreshMoney"); CreditsMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("TextPostProcess")] private static string WeatherConditions(string __result) { if (Config.HideWeather.Value) { __result = Enum.GetValues(typeof(LevelWeatherType)).Cast<LevelWeatherType>().Aggregate(__result, (string current, LevelWeatherType value) => current.Replace($"({value})", string.Empty)); } return __result; } } [HarmonyPatch(typeof(TimeOfDay))] public class TimeOfDay { [HarmonyPostfix] [HarmonyPatch("SyncNewProfitQuotaClientRpc")] private static void UpdateCreditsAfterReachingQuota() { Plugin.ModLogger.LogDebug((object)"TimeOfDay.UpdateCreditsAfterReachingQuota"); CreditsMonitor.Instance.UpdateMonitor(); } [HarmonyPostfix] [HarmonyPatch("MoveTimeOfDay")] private static void UpdateClockTime() { TimeMonitor.Instance.UpdateMonitor(); } } } namespace OpenMonitors.Monitors { public static class Config { private const string MonitorSection = "Monitors"; private const string MonitorWeatherColors = "MonitorWeatherColors"; private const string AllowableSlotValues = "Possible Slots: 1, 2, 4, 5, 6, 7, 8"; public static ConfigEntry<bool> HideWeather { get; private set; } public static ConfigEntry<int> ProfitQuotaMonitorSlot { get; private set; } public static ConfigEntry<int> DeadlineMonitorSlot { get; private set; } public static ConfigEntry<bool> HideLifeSupport { get; private set; } public static ConfigEntry<int> LifeSupportMonitorSlot { get; private set; } public static ConfigEntry<bool> HidePlayersLifeSupport { get; private set; } public static ConfigEntry<bool> HideLoot { get; private set; } public static ConfigEntry<int> LootMonitorSlot { get; private set; } public static ConfigEntry<bool> HideCredits { get; private set; } public static ConfigEntry<int> CreditsMonitorSlot { get; private set; } public static ConfigEntry<bool> HideDay { get; private set; } public static ConfigEntry<int> DayMonitorSlot { get; private set; } public static ConfigEntry<bool> HideTime { get; private set; } public static ConfigEntry<int> TimeMonitorSlot { get; private set; } public static ConfigEntry<bool> KeepBlueBackground1 { get; private set; } public static ConfigEntry<bool> KeepBlueBackground2 { get; private set; } public static ConfigEntry<string> NoneWeatherColor { get; private set; } public static ConfigEntry<string> RainyWeatherColor { get; private set; } public static ConfigEntry<string> FoggyWeatherColor { get; private set; } public static ConfigEntry<string> StormyWeatherColor { get; private set; } public static ConfigEntry<string> FloodedWeatherColor { get; private set; } public static ConfigEntry<string> EclipsedWeatherColor { get; private set; } public static ConfigEntry<string> DustCloudsWeatherColor { get; private set; } public static void Initialize() { HideWeather = Plugin.ModConfig.Bind<bool>("General", "HideWeather", false, "Disables Weather from the navigation screen, and Terminal"); ProfitQuotaMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "ProfitQuotaMonitorSlot", 1, "Slot for the Profit Quota Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); DeadlineMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "DeadlineMonitorSlot", 2, "Slot for the Deadline Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); HideLifeSupport = Plugin.ModConfig.Bind<bool>("Monitors", "HideLifeSupport", false, "Disables the Life Support Monitor."); LifeSupportMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "LifeSupportMonitorSlot", 4, "Slot for the Life Support Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); HidePlayersLifeSupport = Plugin.ModConfig.Bind<bool>("Monitors", "HidePlayersLifeSupport", true, "Disables the Players Life Support Monitor."); HideLoot = Plugin.ModConfig.Bind<bool>("Monitors", "HideLoot", false, "Disables the Loot Monitor"); LootMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "LootMonitorSlot", 5, "Slot for the Loot Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); HideCredits = Plugin.ModConfig.Bind<bool>("Monitors", "HideCredits", false, "Disables the Credits Monitor"); TimeMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "TimeMonitorSlot", 6, "Slot for the Time Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); HideDay = Plugin.ModConfig.Bind<bool>("Monitors", "HideDay", false, "Disables the Day Monitor"); DayMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "DayMonitorSlot", 7, "Slot for the Day Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); HideTime = Plugin.ModConfig.Bind<bool>("Monitors", "HideTime", false, "Disables the Time Monitor"); CreditsMonitorSlot = Plugin.ModConfig.Bind<int>("Monitors", "CreditsMonitorSlot", 8, "Slot for the Credits Monitor. Possible Slots: 1, 2, 4, 5, 6, 7, 8"); KeepBlueBackground1 = Plugin.ModConfig.Bind<bool>("Monitors", "KeepBlueBackground - Monitor 1", false, "Keeps the blue background on Monitor 1 (Quota)"); KeepBlueBackground2 = Plugin.ModConfig.Bind<bool>("Monitors", "KeepBlueBackground - Monitor 2", false, "Keeps the blue background on Monitor 2 (Deadline)"); NoneWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "No weather:", "69FF69", "Input 6 character hex code for weather coloring"); RainyWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "Rainy:", "FFF01C", "Input 6 character hex code for weather coloring"); FoggyWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "Foggy:", "FFF01C", "Input 6 character hex code for weather coloring"); StormyWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "Stormy:", "FF9B00", "Input 6 character hex code for weather coloring"); FloodedWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "Flooded:", "FF9B00", "Input 6 character hex code for weather coloring"); EclipsedWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "Eclipsed:", "FF0000", "Input 6 character hex code for weather coloring"); DustCloudsWeatherColor = Plugin.ModConfig.Bind<string>("MonitorWeatherColors", "Dust Clouds:", "69FF69", "Input 6 character color hex code for weather coloring"); if (ProfitQuotaMonitorSlot.Value == 3) { ProfitQuotaMonitorSlot.Value = (int)((ConfigEntryBase)ProfitQuotaMonitorSlot).DefaultValue; } if (DeadlineMonitorSlot.Value == 3) { DeadlineMonitorSlot.Value = (int)((ConfigEntryBase)DeadlineMonitorSlot).DefaultValue; } if (LifeSupportMonitorSlot.Value == 3) { LifeSupportMonitorSlot.Value = (int)((ConfigEntryBase)LifeSupportMonitorSlot).DefaultValue; } if (LootMonitorSlot.Value == 3) { LootMonitorSlot.Value = (int)((ConfigEntryBase)LootMonitorSlot).DefaultValue; } if (TimeMonitorSlot.Value == 3) { TimeMonitorSlot.Value = (int)((ConfigEntryBase)TimeMonitorSlot).DefaultValue; } if (DayMonitorSlot.Value == 3) { DayMonitorSlot.Value = (int)((ConfigEntryBase)DayMonitorSlot).DefaultValue; } } } public class CreditsMonitor : MonoBehaviour { public static CreditsMonitor Instance; private Terminal _terminal = null; private TextMeshProUGUI _textMesh = null; public void Start() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start()")); if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; } _textMesh = ((Component)this).GetComponent<TextMeshProUGUI>(); _terminal = Object.FindObjectOfType<Terminal>(); Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() -> UpdateMonitor()")); UpdateMonitor(); } public void UpdateMonitor() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> UpdateMonitor()")); ((TMP_Text)_textMesh).text = (Config.HideCredits.Value ? string.Empty : $"CREDITS:\n${_terminal.groupCredits}"); } } public class DayMonitor : MonoBehaviour { public static DayMonitor Instance; public TextMeshProUGUI textMesh = null; public void Start() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start()")); if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; } textMesh = ((Component)this).GetComponent<TextMeshProUGUI>(); ((TMP_Text)textMesh).text = (Config.HideDay.Value ? string.Empty : "DAY:\n?"); if (((NetworkBehaviour)StartOfRound.Instance).IsHost) { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() -> IsHost")); UpdateMonitor(); } else { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() -> NOT IsHost")); } } public void UpdateMonitor() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> UpdateMonitor()")); ((TMP_Text)textMesh).text = (Config.HideDay.Value ? string.Empty : $"DAY:\n{StartOfRound.Instance.gameStats.daysSpent}"); } } public class LifeSupportMonitor : MonoBehaviour { public static LifeSupportMonitor Instance; private TextMeshProUGUI _textMesh = null; public void Start() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start()")); if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; } _textMesh = ((Component)this).GetComponent<TextMeshProUGUI>(); Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() -> UpdateMonitor()")); UpdateMonitor(); } public void UpdateMonitor() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> UpdateMonitor()")); ((TMP_Text)_textMesh).text = (Config.HideLifeSupport.Value ? string.Empty : $"ALIVE:\n{StartOfRound.Instance.livingPlayers} / {StartOfRound.Instance.connectedPlayersAmount + 1}"); } } public class LootMonitor : MonoBehaviour { public static LootMonitor Instance; public TextMeshProUGUI textMesh = null; private GameObject _ship = null; public void Start() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start()")); if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; } textMesh = ((Component)this).GetComponent<TextMeshProUGUI>(); ((TMP_Text)textMesh).text = "LOOT:\n$NaN"; _ship = GameObject.Find("/Environment/HangarShip"); Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() -> UpdateMonitor()")); UpdateMonitor(); } public void UpdateMonitor() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> UpdateMonitor()")); ((TMP_Text)textMesh).text = (Config.HideLoot.Value ? string.Empty : $"LOOT:\n${Calculate()}"); } private float Calculate() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Calculate()")); return (from grabbable in _ship.GetComponentsInChildren<GrabbableObject>() where CheckIfItemIsScrapAndOnShipFloor(grabbable) select grabbable).Sum((GrabbableObject x) => x.scrapValue); static bool CheckIfItemIsScrapAndOnShipFloor(GrabbableObject item) { return item.itemProperties.isScrap && item != null && !item.isPocketed && !item.isHeld; } } } public class PlayersLifeSupportMonitor : MonoBehaviour { public static PlayersLifeSupportMonitor Instance; public TextMeshProUGUI textMesh = null; public void Start() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start()")); if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; } textMesh = ((Component)this).GetComponent<TextMeshProUGUI>(); ((TMP_Text)textMesh).fontSize = 42f; ((TMP_Text)textMesh).enableWordWrapping = false; ((TMP_Text)textMesh).text = (Config.HidePlayersLifeSupport.Value ? string.Empty : "LIFE SUPPORT:\n?"); Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() end")); } public void UpdateMonitor() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> UpdateMonitor()")); if (!Config.HidePlayersLifeSupport.Value) { ((MonoBehaviour)CoroutineHelper.Instance).StartCoroutine(UpdateMonitorCoroutine()); } } private IEnumerator UpdateMonitorCoroutine() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> UpdateCoroutine(), waiting 2 seconds before updating due to slow player loading")); yield return (object)new WaitForSeconds(2f); StringBuilder builder = new StringBuilder().AppendLine("LIFE SUPPORT:").AppendLine(); foreach (PlayerControllerB player in StartOfRound.Instance.ClientPlayerList.Keys.Select((ulong playerId) => StartOfRound.Instance.allPlayerScripts[playerId])) { builder.Append((player.playerUsername.Length > 15) ? ("- " + player.playerUsername.Substring(0, 15) + "... ") : ("- " + player.playerUsername + " ")); if (player.isPlayerDead) { Plugin.ModLogger.LogDebug((object)("-> " + player.playerUsername + " is dead")); builder.AppendLine("<color=#FF0000>(DEAD)</color>"); } else if (player.health <= 50) { Plugin.ModLogger.LogDebug((object)$"-> {player.playerUsername} is injured! {player.health}"); builder.AppendLine("<color=#FFF01C>(HURT)</color>"); } else { Plugin.ModLogger.LogDebug((object)("-> " + player.playerUsername + " is still alive!")); builder.AppendLine(); } } ((TMP_Text)textMesh).text = builder.ToString(); } } internal static class Setup { private const string MonitorContainerPath = "Environment/HangarShip/ShipModels2b/MonitorWall/Cube/Canvas (1)/MainContainer"; private static GameObject _mainContainer = null; private static GameObject _quotaMonitorText = null; private static GameObject _deadlineMonitorText = null; private static readonly Vector3 TopRowLocalRotation = new Vector3(351.5f, 0f); private static readonly Vector3 LeftMonitorGroupBottomRowLocalRotation = new Vector3(9.5577f, 0f); private static readonly Vector3 RightMonitorGroupLocalRotation = new Vector3(0f, 24.9f, 5.4f); private static readonly Dictionary<int, Tuple<Vector3, Vector3>> MonitorPositionsBySlots = new Dictionary<int, Tuple<Vector3, Vector3>> { { 1, new Tuple<Vector3, Vector3>(new Vector3(-233f, 24f, 21f), LeftMonitorGroupBottomRowLocalRotation) }, { 2, new Tuple<Vector3, Vector3>(new Vector3(240f, 24f, 21f), LeftMonitorGroupBottomRowLocalRotation) }, { 3, new Tuple<Vector3, Vector3>(new Vector3(797f, 29f, -101f), new Vector3(8.4566f, 26.5f, RightMonitorGroupLocalRotation.z)) }, { 4, new Tuple<Vector3, Vector3>(new Vector3(1220f, 80f, -304f), new Vector3(8.4566f, RightMonitorGroupLocalRotation.y, RightMonitorGroupLocalRotation.z)) }, { 5, new Tuple<Vector3, Vector3>(new Vector3(-233f, 480f), TopRowLocalRotation) }, { 6, new Tuple<Vector3, Vector3>(new Vector3(240f, 480f), TopRowLocalRotation) }, { 7, new Tuple<Vector3, Vector3>(new Vector3(748f, 500f, -110f), TopRowLocalRotation + RightMonitorGroupLocalRotation) }, { 8, new Tuple<Vector3, Vector3>(new Vector3(1170f, 540f, -310.3f), TopRowLocalRotation + RightMonitorGroupLocalRotation) }, { 9, new Tuple<Vector3, Vector3>(new Vector3(905f, -545f, -235f), new Vector3(10.5f, 26.2f, 5.2f)) } }; public static void Initialize() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) _mainContainer = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube/Canvas (1)/MainContainer"); _quotaMonitorText = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube/Canvas (1)/MainContainer/HeaderText"); MonitorPositionsBySlots[Config.ProfitQuotaMonitorSlot.Value].Deconstruct(out var item, out var item2); Vector3 localPosition = item; Vector3 val = item2; _quotaMonitorText.transform.localPosition = localPosition; _quotaMonitorText.transform.localRotation = Quaternion.Euler(val); if (!Config.KeepBlueBackground1.Value) { Plugin.ModLogger.LogDebug((object)"Destroying Quota BG"); Object.Destroy((Object)(object)GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube/Canvas (1)/MainContainer/BG")); } if (!Config.KeepBlueBackground2.Value) { Plugin.ModLogger.LogDebug((object)"Destroying Deadline BG"); Object.Destroy((Object)(object)GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube/Canvas (1)/MainContainer/BG (1)")); } _deadlineMonitorText = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube/Canvas (1)/MainContainer/HeaderText (1)"); MonitorPositionsBySlots[Config.DeadlineMonitorSlot.Value].Deconstruct(out item2, out item); Vector3 localPosition2 = item2; Vector3 val2 = item; _deadlineMonitorText.transform.localPosition = localPosition2; _deadlineMonitorText.transform.localRotation = Quaternion.Euler(val2); LifeSupportMonitor.Instance = CreateMonitor<LifeSupportMonitor>(Config.LifeSupportMonitorSlot.Value); LootMonitor.Instance = CreateMonitor<LootMonitor>(Config.LootMonitorSlot.Value); TimeMonitor.Instance = CreateMonitor<TimeMonitor>(Config.TimeMonitorSlot.Value); CreditsMonitor.Instance = CreateMonitor<CreditsMonitor>(Config.CreditsMonitorSlot.Value); DayMonitor.Instance = CreateMonitor<DayMonitor>(Config.DayMonitorSlot.Value); PlayersLifeSupportMonitor.Instance = CreateMonitor<PlayersLifeSupportMonitor>(9); } private static T CreateMonitor<T>(int targetSlot) where T : MonoBehaviour { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) string text = typeof(T).Name.Replace("Monitor", ""); Plugin.ModLogger.LogDebug((object)("Creating Monitor " + text)); GameObject val = Object.Instantiate<GameObject>(_quotaMonitorText, _mainContainer.transform); ((Object)val).name = text; TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); var (localPosition, val4) = MonitorPositionsBySlots[targetSlot]; ((TMP_Text)component).transform.localPosition = localPosition; ((TMP_Text)component).transform.localRotation = Quaternion.Euler(val4); Plugin.ModLogger.LogDebug((object)("Monitor " + text + " created")); return val.AddComponent<T>(); } } public class TimeMonitor : MonoBehaviour { public static TimeMonitor Instance; public TextMeshProUGUI textMesh = null; public void Start() { Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start()")); if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; } textMesh = ((Component)this).GetComponent<TextMeshProUGUI>(); ((TMP_Text)textMesh).text = (Config.HideTime.Value ? string.Empty : "TIME:\n7:30\nAM"); Plugin.ModLogger.LogDebug((object)(((Object)this).name + " -> Start() end")); } public void UpdateMonitor() { ((TMP_Text)textMesh).text = (Config.HideTime.Value ? string.Empty : ("TIME:\n" + ((TMP_Text)HUDManager.Instance.clockNumber).text)); } } }