using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ClearanceIndicator")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ClearanceIndicator")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("456179b8-30db-47a6-b45c-14ef72d22386")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace ClearanceIndicator; [BepInPlugin("Swaggies.ClearanceIndicator", "ClearanceIndicator", "1.0.0")] public class Plugin : BaseUnityPlugin { private enum AlignmentOptions { BOTTOM_RIGHT, BOTTOM_LEFT, TOP_LEFT, TOP_RIGHT } private const string _guid = "Swaggies.ClearanceIndicator"; private const string _name = "ClearanceIndicator"; private const string _ver = "1.0.0"; private readonly Harmony harmony = new Harmony("Swaggies.ClearanceIndicator"); private static Plugin Instance; private static ManualLogSource loggr; private static ConfigEntry AllCaps; private static ConfigEntry SingleLined; private static ConfigEntry ShowTotal; private static ConfigEntry ShowProfitQuota; private static ConfigEntry ShowDollarSign; private static ConfigEntry ShowWhileDead; private static ConfigEntry CountSpeed; private static ConfigEntry ProfitQuotaCountSpeed; private static ConfigEntry CatchUpThreshold; private static ConfigEntry CatchUpSpeed; private static ConfigEntry UpdateRate; private static ConfigEntry PlaySFX; private static ConfigEntry LabelTextSize; private static ConfigEntry CurrentTextSize; private static ConfigEntry TotalTextSize; private static ConfigEntry TextFontSize; private static ConfigEntry XOffset; private static ConfigEntry YOffset; private static ConfigEntry Alignment; private static float currentTextAlpha = 0f; private static float targetTextAlpha = 0f; public static float updateTime = 0f; public static bool displayValue = false; public static int currentValue = 0; public static int totalValue = 0; private static readonly float CONST_X = 350f; private static readonly float CONST_Y = 250f; public static TextMeshProUGUI _text; public static TextMeshProUGUI _deadText; public static Transform ingamePlayerHud; public static Transform spectateUI; private static bool curParent = true; private static bool tarParent = true; private static float displayText = 0f; private static float displayUpdateTimer = 0f; private void Awake() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Expected O, but got Unknown //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Expected O, but got Unknown //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Expected O, but got Unknown //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Expected O, but got Unknown //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Expected O, but got Unknown //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Expected O, but got Unknown //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } loggr = Logger.CreateLogSource("Swaggies.ClearanceIndicator"); harmony.PatchAll(typeof(Plugin)); loggr.LogInfo((object)"ClearanceIndicator up and running."); ShowWhileDead = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Show While Dead", true, new ConfigDescription("Whether to display the Clearance Indicator while dead.", (AcceptableValueBase)null, Array.Empty())); ShowTotal = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Show Total Value", true, new ConfigDescription("Whether to show the total scrap value on the current moon. Disabling will show only how much you've collected.", (AcceptableValueBase)null, Array.Empty())); ShowProfitQuota = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Show Profit Quota", true, new ConfigDescription("Whether to show the current profit quota when on the Company Building.", (AcceptableValueBase)null, Array.Empty())); CountSpeed = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Counting Speed", 3.2f, new ConfigDescription("How quickly the displayed collected scrap value increments to the actual collected scrap value. Higher value = quicker counting.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f), Array.Empty())); ProfitQuotaCountSpeed = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Profit Quota Counting Speed", 24.3f, new ConfigDescription("How quickly the displayed profit quota value increments to the actual profit quota value. Higher value = quicker counting.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 100f), Array.Empty())); CatchUpThreshold = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Catch-up State Threshold", 1000, new ConfigDescription("If the counter falls too far behind the actual value, it will attempt to catch-up by increasing how much the counter counts by. This determines how far behind the counter needs to be in order to initiate the catch-up state.", (AcceptableValueBase)(object)new AcceptableValueRange(100, 5000), Array.Empty())); CatchUpSpeed = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Catch-up State Divisor", 12f, new ConfigDescription("Determines how quickly to catch back up to the actual value when in the catch-up state. Lower value = quicker counting.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 32f), Array.Empty())); UpdateRate = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Update Time (ms)", 33, new ConfigDescription("How often in milliseconds to update the counter. This affects the counting speed and how often the count-up SFX is played. A higher update time means slower counting, as there is a longer period between each update.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100), Array.Empty())); PlaySFX = ((BaseUnityPlugin)this).Config.Bind("Clearance Indicator", "Play Counting SFX", true, new ConfigDescription("Whether to play the scanned scrap total SFX when counting up.", (AcceptableValueBase)null, Array.Empty())); AllCaps = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Uppercase Text", false, new ConfigDescription("Whether text should be capitalized.", (AcceptableValueBase)null, Array.Empty())); SingleLined = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Single Lined", false, new ConfigDescription("Whether the \"Collected\" text label and number value should be on a single line rather than split into two lines.", (AcceptableValueBase)null, Array.Empty())); ShowDollarSign = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Show Dollar Sign", false, new ConfigDescription("Whether to prefix the value with a dollar sign ($).", (AcceptableValueBase)null, Array.Empty())); LabelTextSize = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Label Text Size", 65, new ConfigDescription("(%) Text size of the \"Collected\" text label. Recommended to use 100 if Single Lined is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange(10, 100), Array.Empty())); CurrentTextSize = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Current Value Text Size", 100, new ConfigDescription("(%) Text size of the current value (the 'a' in 'a/b'). Recommended to use 100 if Single Lined is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange(10, 100), Array.Empty())); TotalTextSize = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Total Value Text Size", 100, new ConfigDescription("(%) Text size of the total scrap value (the '/b' in 'a/b'). Recommended to use 100 if Single Lined is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange(10, 100), Array.Empty())); TextFontSize = ((BaseUnityPlugin)this).Config.Bind("Text Options", "Clearance Indicator Font Size", 32, new ConfigDescription("Text size of the entire text element.", (AcceptableValueBase)(object)new AcceptableValueRange(18, 72), Array.Empty())); Alignment = ((BaseUnityPlugin)this).Config.Bind("Visual Alignment", "Position Alignment", AlignmentOptions.BOTTOM_RIGHT, new ConfigDescription("Which corner of the screen to anchor Clearance Indicator to.", (AcceptableValueBase)null, Array.Empty())); XOffset = ((BaseUnityPlugin)this).Config.Bind("Visual Alignment", "X Offset", 35f, new ConfigDescription("Horizontal distance from the screen corner.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 400f), Array.Empty())); YOffset = ((BaseUnityPlugin)this).Config.Bind("Visual Alignment", "Y Offset", 25f, new ConfigDescription("Vertical distance from the screen corner.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 250f), Array.Empty())); } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")] [HarmonyPostfix] private static void UpdateDisplayValue() { if (!RoundManager.Instance.currentLevel.planetHasTime) { UpdateDisplayValue(TimeOfDay.Instance.quotaFulfilled); } } [HarmonyPatch(typeof(RoundManager), "SyncScrapValuesClientRpc")] [HarmonyPostfix] private static void UpdateDisplayValueNonProfitQuota() { if (RoundManager.Instance.currentLevel.planetHasTime) { UpdateDisplayValue(0); } } private static void UpdateDisplayValue(int startingAmount) { currentValue = startingAmount; displayText = currentValue; if (RoundManager.Instance.currentLevel.planetHasTime || ShowProfitQuota.Value) { displayValue = true; SetTotalValue(); UpdateText(); } } [HarmonyPatch(typeof(RoundManager), "CollectNewScrapForThisRound")] [HarmonyPrefix] private static void CollectScrap(GrabbableObject scrapObject) { if (scrapObject.itemProperties.isScrap && !RoundManager.Instance.scrapCollectedThisRound.Contains(scrapObject) && !scrapObject.scrapPersistedThroughRounds && RoundManager.Instance.currentLevel.planetHasTime) { currentValue += scrapObject.scrapValue; } } [HarmonyPatch(typeof(HUDManager), "Update")] [HarmonyPostfix] private static void HUDUpdate() { if (displayValue) { SetTotalValue(); } targetTextAlpha = ((totalValue > 0 && displayValue && !StartOfRound.Instance.inShipPhase) ? 1f : 0f); if (!ShowProfitQuota.Value && !RoundManager.Instance.currentLevel.planetHasTime) { targetTextAlpha = 0f; } UpdateUI(); } private static void SetTotalValue() { totalValue = (RoundManager.Instance.currentLevel.planetHasTime ? ((int)RoundManager.Instance.totalScrapValueInLevel) : TimeOfDay.Instance.profitQuota); } private static void UpdateText() { //IL_007a: 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_007f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_text)) { string arg = (RoundManager.Instance.currentLevel.planetHasTime ? "Collected" : "Profit Quota"); ((Graphic)_text).color = Color32.op_Implicit(RoundManager.Instance.currentLevel.planetHasTime ? new Color32(byte.MaxValue, byte.MaxValue, (byte)150, byte.MaxValue) : new Color32((byte)150, byte.MaxValue, byte.MaxValue, byte.MaxValue)); string text = $"{arg}"; text += (SingleLined.Value ? ": " : "\n"); string arg2 = (ShowDollarSign.Value ? "$" : ""); text += $"{arg2}{(int)displayText}"; if (ShowTotal.Value) { text += $"/{totalValue}"; } ((TMP_Text)_text).text = text; } } private static void CreateTextObject() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_text)) { ingamePlayerHud = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD").transform; spectateUI = GameObject.Find("Systems/UI/Canvas/DeathScreen/SpectateUI").transform; _text = Object.Instantiate(GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/TopRightCorner/ControlTip1").GetComponent()); ((Object)_text).name = "CIDisplay"; ((TMP_Text)_text).transform.SetParent(ingamePlayerHud, false); ((TMP_Text)_text).transform.localScale = new Vector3(1f, 1f, 1f); ((TMP_Text)_text).transform.rotation = new Quaternion(0f, 0f, 0f, 0f); ((Behaviour)_text).enabled = true; curParent = (tarParent = true); } } private static void UpdateDisplay() { if ((RoundManager.Instance.currentLevel.planetHasTime || ShowProfitQuota.Value) && !(Time.realtimeSinceStartup - displayUpdateTimer < (float)UpdateRate.Value / 1000f)) { ChangeDisplayValue(); displayUpdateTimer = Time.realtimeSinceStartup; } } private static void ChangeDisplayValue() { float num = (float)currentValue - displayText; if (Math.Abs(num) >= (float)CatchUpThreshold.Value) { num /= CatchUpSpeed.Value; } else { if (num < 0f) { num = Math.Max(num, RoundManager.Instance.currentLevel.planetHasTime ? (0f - CountSpeed.Value) : (0f - ProfitQuotaCountSpeed.Value)); } if (num > 0f) { num = Math.Min(num, RoundManager.Instance.currentLevel.planetHasTime ? CountSpeed.Value : ProfitQuotaCountSpeed.Value); } } displayText += num; if (num < 0f && displayText <= (float)currentValue) { displayText = currentValue; } if (num > 0f && displayText >= (float)currentValue) { displayText = currentValue; } if (StartOfRound.Instance.inShipPhase) { displayText = currentValue; } else if (PlaySFX.Value) { if (displayText == (float)currentValue) { HUDManager.Instance.UIAudio.PlayOneShot(HUDManager.Instance.finishAddingToTotalSFX); } else { HUDManager.Instance.UIAudio.PlayOneShot(HUDManager.Instance.addToScrapTotalSFX); } } } private static void UpdateUI() { CreateTextObject(); UpdateTextObjectSettings(); if (!RoundManager.Instance.currentLevel.planetHasTime) { currentValue = TimeOfDay.Instance.quotaFulfilled; } if ((float)currentValue != displayText) { UpdateDisplay(); } UpdateText(); currentTextAlpha = Mathf.MoveTowards(currentTextAlpha, targetTextAlpha, Time.deltaTime * 1.25f); ((TMP_Text)_text).alpha = currentTextAlpha; } private static void UpdateTextObjectSettings() { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_text)) { tarParent = !GameNetworkManager.Instance.localPlayerController.isPlayerDead || !ShowWhileDead.Value; if (curParent != tarParent) { ((TMP_Text)_text).transform.SetParent(tarParent ? ingamePlayerHud : spectateUI, false); curParent = tarParent; } ((TMP_Text)_text).fontSize = TextFontSize.Value; ((TMP_Text)_text).fontStyle = (FontStyles)(AllCaps.Value ? 16 : 0); switch (Alignment.Value) { case AlignmentOptions.BOTTOM_RIGHT: ((TMP_Text)_text).transform.localPosition = new Vector3(CONST_X, 0f - CONST_Y, 0f); ((TMP_Text)_text).alignment = (TextAlignmentOptions)1028; ((TMP_Text)_text).margin = new Vector4(-500f, -500f, XOffset.Value, YOffset.Value); break; case AlignmentOptions.BOTTOM_LEFT: ((TMP_Text)_text).transform.localPosition = new Vector3(0f - CONST_X, 0f - CONST_Y, 0f); ((TMP_Text)_text).alignment = (TextAlignmentOptions)1025; ((TMP_Text)_text).margin = new Vector4(XOffset.Value, -500f, -500f, YOffset.Value); break; case AlignmentOptions.TOP_LEFT: ((TMP_Text)_text).transform.localPosition = new Vector3(0f - CONST_X, CONST_Y - 5f, 0f); ((TMP_Text)_text).alignment = (TextAlignmentOptions)257; ((TMP_Text)_text).margin = new Vector4(XOffset.Value, YOffset.Value, -500f, -500f); break; case AlignmentOptions.TOP_RIGHT: ((TMP_Text)_text).transform.localPosition = new Vector3(CONST_X, CONST_Y - 5f, 0f); ((TMP_Text)_text).alignment = (TextAlignmentOptions)260; ((TMP_Text)_text).margin = new Vector4(-500f, YOffset.Value, XOffset.Value, -500f); break; } } } }