using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using Berserk; using Character_Stats; using HarmonyLib; using Improve; using Increase_Tumble_Damage; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("headclef")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1+60f46ab44e7fb2fc34543787492e3ce5904502a9")] [assembly: AssemblyProduct("UI")] [assembly: AssemblyTitle("UI")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 HeadclefUI { [BepInPlugin("headclef.UI", "UI", "1.3.1")] [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 HeadclefUI : BaseUnityPlugin { private const string PluginGuid = "headclef.UI"; private const string PluginName = "UI"; private const string PluginVersion = "1.3.1"; internal static HeadclefUI Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0049: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private void OnDestroy() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public static class MapValueTracker { private static float _lastRecalcTime; private const float RecalcInterval = 2f; public static float TotalValue { get; private set; } public static float InitialValue { get; private set; } public static void Reset() { TotalValue = 0f; InitialValue = 0f; _lastRecalcTime = 0f; } public static void Recalculate() { if ((Object)(object)RoundDirector.instance == (Object)null || Traverse.Create((object)RoundDirector.instance).Field("allExtractionPointsCompleted").GetValue()) { return; } TotalValue = 0f; ValuableObject[] array = Object.FindObjectsOfType(); ValuableObject[] array2 = array; foreach (ValuableObject val in array2) { if (val.dollarValueSet) { TotalValue += val.dollarValueCurrent; } } _lastRecalcTime = Time.time; } public static void UpdateIfNeeded() { if (Time.time - _lastRecalcTime >= 2f) { Recalculate(); } } [HarmonyPatch(typeof(LevelGenerator), "StartRoomGeneration")] [HarmonyPrefix] private static void OnGenerationStart() { Reset(); } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] [HarmonyPostfix] private static void OnGenerationDone() { Recalculate(); InitialValue = TotalValue; } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "BreakRPC")] [HarmonyPostfix] private static void OnBreak(float valueLost, bool _loseValue) { if (_loseValue) { TotalValue -= valueLost; } } [HarmonyPatch(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC")] [HarmonyPostfix] private static void OnDestroy(PhysGrabObject __instance) { if (SemiFunc.RunIsLevel()) { ValuableObject component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && component.dollarValueCurrent >= component.dollarValueOriginal * 0.15f) { TotalValue -= component.dollarValueCurrent; } } } [HarmonyPatch(typeof(RoundDirector), "ExtractionCompleted")] [HarmonyPostfix] private static void OnExtraction() { if (SemiFunc.RunIsLevel()) { Recalculate(); } } } [HarmonyPatch] public static class TabOverlay { private static GameObject? _overlayRoot; private static TextMeshProUGUI? _infoText; private static TextMeshProUGUI? _playerText; private static bool _depsChecked; private static bool _improveLoaded; private static bool _charStatsLoaded; private static bool _tumbleDamageLoaded; private static bool _berserkLoaded; private static ItemGun? _cachedFallbackGun; private static float _lastGunScanTime; private const float GunScanInterval = 0.25f; private static void EnsureDepsChecked() { if (!_depsChecked) { _depsChecked = true; Dictionary pluginInfos = Chainloader.PluginInfos; _improveLoaded = pluginInfos.ContainsKey("headclef.Improve"); _charStatsLoaded = pluginInfos.ContainsKey("headclef.CharacterStats"); _tumbleDamageLoaded = pluginInfos.ContainsKey("headclef.IncreaseTumbleDamage"); _berserkLoaded = pluginInfos.ContainsKey("headclef.Berserk"); } } [HarmonyPatch(typeof(RoundDirector), "Update")] [HarmonyPostfix] private static void RoundDirector_Update_Postfix() { if (!SemiFunc.RunIsLevel()) { return; } try { if ((Object)(object)_overlayRoot == (Object)null) { _overlayRoot = null; _infoText = null; _playerText = null; CreateOverlay(); if ((Object)(object)_overlayRoot == (Object)null) { return; } } bool flag = false; if ((Object)(object)MapToolController.instance != (Object)null) { flag = Traverse.Create((object)MapToolController.instance).Field("mapToggled").GetValue(); } bool flag2 = SemiFunc.InputHold((InputKey)8) || flag; _overlayRoot.SetActive(flag2); if (flag2) { UpdateContent(); } } catch (Exception ex) { HeadclefUI.Logger.LogError((object)("TabOverlay exception: " + ex.Message)); } } [HarmonyPatch(typeof(SemiFunc), "OnSceneSwitch")] [HarmonyPrefix] private static void OnSceneSwitch_Prefix() { if ((Object)(object)_overlayRoot != (Object)null) { Object.Destroy((Object)(object)_overlayRoot); _overlayRoot = null; _infoText = null; _playerText = null; } } private static void CreateOverlay() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("Game Hud"); if ((Object)(object)val == (Object)null) { HeadclefUI.Logger.LogWarning((object)"Tab overlay: 'Game Hud' not found."); return; } GameObject val2 = GameObject.Find("Tax Haul"); if ((Object)(object)val2 == (Object)null) { HeadclefUI.Logger.LogWarning((object)"Tab overlay: 'Tax Haul' not found."); return; } TMP_Text component = val2.GetComponent(); TMP_FontAsset val3 = ((component != null) ? component.font : null); if (val3 == null) { HeadclefUI.Logger.LogWarning((object)"Tab overlay: HUD font not found."); return; } _overlayRoot = new GameObject("Headclef Tab Overlay", new Type[1] { typeof(RectTransform) }); _overlayRoot.SetActive(false); _overlayRoot.transform.SetParent(val.transform, false); RectTransform val4 = (RectTransform)_overlayRoot.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; _infoText = CreateText("Info", val3, _overlayRoot.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-25f, -80f), (TextAlignmentOptions)260); _playerText = CreateText("Players", val3, _overlayRoot.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-25f, 40f), (TextAlignmentOptions)1028); } private static TextMeshProUGUI CreateText(string name, TMP_FontAsset? font, Transform parent, Vector2 anchor, Vector2 pivot, Vector2 anchoredPos, TextAlignmentOptions alignment) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).font = font; ((Graphic)val2).color = new Color(0.79f, 0.91f, 0.9f, 1f); ((TMP_Text)val2).fontSize = 15f; ((TMP_Text)val2).enableWordWrapping = true; ((TMP_Text)val2).alignment = alignment; RectTransform component = val.GetComponent(); component.anchorMin = anchor; component.anchorMax = anchor; component.pivot = pivot; component.sizeDelta = new Vector2(420f, 600f); component.anchoredPosition = anchoredPos; return val2; } private static void UpdateContent() { if ((Object)(object)_infoText == (Object)null || (Object)(object)_playerText == (Object)null) { return; } EnsureDepsChecked(); StringBuilder stringBuilder = new StringBuilder(); if (_berserkLoaded) { AppendBerserkInfo(stringBuilder); } if (_improveLoaded) { AppendImproveInfo(stringBuilder); } MapValueTracker.UpdateIfNeeded(); float totalValue = MapValueTracker.TotalValue; stringBuilder.AppendLine($"Map Value: ${totalValue:N0}"); AppendCombatInfo(stringBuilder); ((TMP_Text)_infoText).text = stringBuilder.ToString().TrimEnd(); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.AppendLine("Players"); List list = SemiFunc.PlayerGetAll(); if (list != null) { foreach (PlayerAvatar item in list) { if (!((Object)(object)item == (Object)null)) { string text = item.playerName ?? "Unknown"; string text2 = (item.deadSet ? "Dead" : "Alive"); string text3 = (item.deadSet ? "#ff5555" : "#55ff55"); stringBuilder2.AppendLine(" " + text + " — " + text2 + ""); } } } ((TMP_Text)_playerText).text = stringBuilder2.ToString().TrimEnd(); } private static void AppendBerserkInfo(StringBuilder sb) { try { if (Berserk.IsActive) { int activeStrengthBonus = Berserk.ActiveStrengthBonus; int activeLaunchBonus = Berserk.ActiveLaunchBonus; sb.AppendLine("BERSERK ACTIVE " + $"+{activeStrengthBonus} Strength, +{activeLaunchBonus} Launch"); } } catch (Exception ex) { HeadclefUI.Logger.LogWarning((object)("Berserk info unavailable: " + ex.Message)); } } private static void AppendImproveInfo(StringBuilder sb) { try { int num = SaveData.CurrentLevel(); sb.AppendLine($"Improve Level: {num}"); } catch (Exception ex) { HeadclefUI.Logger.LogWarning((object)("Improve info unavailable: " + ex.Message)); } } private static void AppendCombatInfo(StringBuilder sb) { ItemGun heldGun = GetHeldGun(); if ((Object)(object)heldGun != (Object)null) { int num = (((Object)(object)heldGun.itemBattery != (Object)null) ? heldGun.itemBattery.currentBars : 0); int num2 = (((Object)(object)heldGun.itemBattery != (Object)null) ? heldGun.itemBattery.batteryBars : 0); int gunDamage = GetGunDamage(heldGun); string arg = ((num > 0) ? "#55ff55" : "#ff5555"); sb.AppendLine(" Weapon: " + ((Object)((Component)heldGun).gameObject).name + ""); sb.AppendLine($" Ammo: {num} / {num2}"); sb.AppendLine($" Damage: {gunDamage}"); } else { int tumbleLaunchDamage = GetTumbleLaunchDamage(); if (tumbleLaunchDamage > 0) { sb.AppendLine($" Tumble Launch: {tumbleLaunchDamage} dmg"); } else { sb.AppendLine(" No weapon held"); } } } private static ItemGun? GetHeldGun() { try { PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance != (Object)null && instance.grabbed && (Object)(object)instance.grabbedPhysGrabObject != (Object)null) { PhysGrabObject grabbedPhysGrabObject = instance.grabbedPhysGrabObject; ItemGun val = ((Component)grabbedPhysGrabObject).GetComponent() ?? ((Component)grabbedPhysGrabObject).GetComponentInChildren(); if ((Object)(object)val != (Object)null) { return val; } } if (Time.time - _lastGunScanTime < 0.25f) { return _cachedFallbackGun; } _lastGunScanTime = Time.time; ItemGun[] array = Object.FindObjectsOfType(); foreach (ItemGun val2 in array) { PhysGrabObject val3 = ((Component)val2).GetComponent() ?? ((Component)val2).GetComponentInParent(); if ((Object)(object)val3 != (Object)null && val3.grabbedLocal) { _cachedFallbackGun = val2; return val2; } } _cachedFallbackGun = null; return null; } catch { return null; } } private static int GetGunDamage(ItemGun gun) { try { if ((Object)(object)gun.bulletPrefab != (Object)null) { ItemGunBullet component = gun.bulletPrefab.GetComponent(); if ((Object)(object)component != (Object)null && component.hasHurtCollider && (Object)(object)component.hurtCollider != (Object)null) { return component.hurtCollider.enemyDamage; } } ItemGunLaser val = ((Component)gun).GetComponent() ?? ((Component)gun).GetComponentInChildren(); if ((Object)(object)val != (Object)null && (Object)(object)val.semiLaser != (Object)null && (Object)(object)val.semiLaser.hurtCollider != (Object)null) { return val.semiLaser.hurtCollider.enemyDamage; } if ((Object)(object)gun.hurtCollider != (Object)null) { return gun.hurtCollider.enemyDamage; } } catch { } return 0; } private static int GetTumbleLaunchDamage() { try { if ((Object)(object)PlayerAvatar.instance == (Object)null) { return 0; } PlayerTumble tumble = PlayerAvatar.instance.tumble; if ((Object)(object)tumble == (Object)null) { return 0; } HurtCollider hurtCollider = tumble.hurtCollider; if ((Object)(object)hurtCollider == (Object)null) { return 0; } int num = hurtCollider.enemyDamage; if (num <= 0) { num = 12; } string steamId = SemiFunc.PlayerGetSteamID(PlayerAvatar.instance); int launchUpgradeLevel = GetLaunchUpgradeLevel(steamId); if (launchUpgradeLevel > 0 && _tumbleDamageLoaded) { int scaledTumbleDamage = GetScaledTumbleDamage(num, launchUpgradeLevel); if (scaledTumbleDamage > 0) { return scaledTumbleDamage; } } return num; } catch { return 0; } } private static int GetLaunchUpgradeLevel(string steamId) { if (_charStatsLoaded) { try { return GetLaunchLevelFromCharacterStats(steamId); } catch { } } if ((Object)(object)StatsManager.instance != (Object)null && StatsManager.instance.playerUpgradeLaunch.TryGetValue(steamId, out var value)) { return value; } return 0; } private static int GetLaunchLevelFromCharacterStats(string steamId) { return Character_Stats.GetUpgradeLevel(steamId, "Launch"); } private static int GetScaledTumbleDamage(int baseDmg, int upgrades) { if (!Increase_Tumble_Damage.EnableDamageOnEnemy.Value) { return 0; } float value = Increase_Tumble_Damage.MultiplierPerLevel.Value; float value2 = Increase_Tumble_Damage.MaxMultiplier.Value; float num = value * (float)upgrades; if (value2 > 0f) { num = Math.Min(num, value2); } if (num > 0f) { return Mathf.RoundToInt((float)baseDmg * num); } return 0; } } }