using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using SpawnStats.UI; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SpawnStats")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SpawnStats")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("42bcfad8-6e0d-4c8e-889f-2cb81eba095e")] [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 SpawnStats { [BepInPlugin("nachariah.whiteknuckle.spawnstats", "SpawnStats", "1.1.1")] [BepInProcess("White Knuckle.exe")] public class Plugin : BaseUnityPlugin { public const string GUID = "nachariah.whiteknuckle.spawnstats"; public Plugin instance; private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown instance = this; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[SpawnStats] Patching..."); Harmony val = new Harmony("nachariah.whiteknuckle.spawnstats"); val.PatchAll(); SceneManager.sceneLoaded += OnSceneLoaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[SpawnStats] Loaded"); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "Game-Main") { CommandConsole.hasCheated = true; CL_GameManager.gamemode.allowAchievements = false; CL_GameManager.gamemode.allowCheatedScores = false; Debug.Log((object)"[SpawnStats] Leaderboard Disabled"); } } public static void LabelSpawnEntityByID(UT_SpawnEntityByID instance) { SpawnSettings spawnSettings = instance.spawnSettings; if (spawnSettings == null) { return; } float effectiveSpawnChance = spawnSettings.GetEffectiveSpawnChance(); if (Mathf.Approximately(effectiveSpawnChance, 1f)) { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject(instance.idToSpawn, instance.customDatabase); if ((Object)(object)assetGameObject != (Object)null && (Object)(object)assetGameObject.GetComponentInChildren() != (Object)null) { return; } } string displayText = "Spawner\nID: " + instance.idToSpawn + $"\nChance: {effectiveSpawnChance:P1}"; TagGO(((Component)instance).gameObject, GetModText(displayText, spawnSettings)); } public static void ForceSpawnAndLabel(UT_SpawnChance __instance) { SpawnSettings spawnSettings = __instance.spawnSettings; if (spawnSettings == null) { return; } ((Component)__instance).gameObject.SetActive(true); float effectiveSpawnChance = spawnSettings.GetEffectiveSpawnChance(); float spawnChance = spawnSettings.spawnChance; UT_SpawnEntityByID componentInParent = ((Component)__instance).GetComponentInParent(); if (Mathf.Approximately(effectiveSpawnChance, 1f) && (Object)(object)componentInParent != (Object)null) { float effectiveSpawnChance2 = componentInParent.spawnSettings.GetEffectiveSpawnChance(); if (!Mathf.Approximately(effectiveSpawnChance2, 1f)) { return; } } string text = ((Object)((Component)__instance).gameObject).name + $"\nBase Chance: {spawnChance:P1}"; if (effectiveSpawnChance != spawnChance) { text += $"\nEffective Chance: {effectiveSpawnChance:P1}"; } TagGO(((Component)__instance).gameObject, GetModText(text, spawnSettings)); } public static void TagGO(GameObject gameObject, string displayText) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown SpawnLabelTag spawnLabelTag = gameObject.GetComponent(); if ((Object)(object)spawnLabelTag == (Object)null) { spawnLabelTag = gameObject.AddComponent(); } if ((Object)(object)spawnLabelTag.label == (Object)null) { GameObject val = new GameObject("SpawnChanceLabel"); ChanceLabel chanceLabel = val.AddComponent(); chanceLabel.Init(gameObject.transform, displayText); spawnLabelTag.label = val; } else { ChanceLabel component = spawnLabelTag.label.GetComponent(); if ((Object)(object)component != (Object)null) { component.SetText(displayText); } } } public static string GetModText(string displayText, SpawnSettings settings) { List list = new List(); float num = settings.spawnChance; if (settings.forceIfUnlockAll && (CL_GameManager.GetCurrentGamemode().IsCompetitive() || SettingsManager.settings.unlockAll)) { list.Add("ForceUnlockAll"); return displayText + "\nMODIFIERS:\n" + string.Join(", ", list); } if (settings.useProgressionUnlock && !CL_ProgressionManager.HasProgressionUnlock(settings.unlockName)) { list.Add("Progression✗"); } if (settings.useFlags) { bool flag = false; foreach (string item in settings.flagBlacklist) { if (CL_GameManager.HasActiveFlag(item, false)) { flag = true; break; } } if (flag) { list.Add("FlagBlocked"); } else if (settings.flagWhitelist != null && settings.flagWhitelist.Count > 0) { bool flag2 = false; foreach (string item2 in settings.flagWhitelist) { if (CL_GameManager.HasActiveFlag(item2, settings.flagUsesUnlockAll)) { flag2 = true; break; } } if (!flag2) { list.Add("Whitelist✗"); } } } if (settings.useDifficulty) { float num2 = num; float num3 = Mathf.Clamp01((CL_GameManager.currentDifficulty - settings.difficultyMin) / (settings.difficultyMax - settings.difficultyMin)); num *= num3; if (!Mathf.Approximately(num2, num)) { list.Add($"Difficulty x{num3:F2}"); } } if (settings.useStats) { float num2 = num; float num4 = Mathf.Clamp01(((float)StatManager.GetStatisticInt(StatManager.sessionStats, settings.sessionStat) - settings.sessionStatMin) / (settings.sessionStatMax - settings.sessionStatMin)); float num5 = settings.sessionStatModifier.Evaluate(num4); num *= num5; if (!Mathf.Approximately(num2, num)) { list.Add($"Stats x{num5:F2}"); } } if (settings.useHardMode) { bool flag3 = CL_GameManager.IsHardmode(); if (settings.hardModeOnly && !flag3) { list.Add("HardOnly✗"); } if (flag3) { float num2 = num; num *= settings.hardModeMult; if (!Mathf.Approximately(num2, num)) { list.Add($"Hard x{settings.hardModeMult:F2}"); } } } if (settings.checkStatList && settings.statCheckers != null && settings.statCheckers.Count > 0) { list.Add($"StatChecks({settings.statCheckers.Count})"); } if (settings.useAscent) { float num2 = num; float num6 = Mathf.Clamp01((CL_GameManager.gMan.GetPlayerBestTravelDistance() - settings.ascentMin) / (settings.ascentMax - settings.ascentMin)); float num7 = settings.ascentSpawnModifier.Evaluate(num6); num *= num7; if (!Mathf.Approximately(num2, num)) { list.Add($"Ascent x{num7:F2}"); } } if (settings.settingModules != null && settings.settingModules.Count > 0) { float num8 = num; foreach (SpawnSettingModule settingModule in settings.settingModules) { num *= settingModule.Check(); } if (!Mathf.Approximately(num8, num)) { list.Add($"Modules({settings.settingModules.Count})"); } } if (CL_GameManager.IsHardmode() && settings.hardModeMin > 0f) { float num9 = num; num = Mathf.Max(num, settings.hardModeMin); if (!Mathf.Approximately(num9, num)) { list.Add($"HardMin {settings.hardModeMin:P0}"); } } if (list.Count > 0) { displayText += "\nMODIFIERS:"; displayText = displayText + "\n" + string.Join(", ", list); } return displayText; } } } namespace SpawnStats.Patchers { [HarmonyPatch(typeof(UT_SpawnChance), "Start")] public static class UT_SpawnChance_Start_Patcher { [HarmonyPrefix] public static bool Prefix(UT_SpawnChance __instance) { Plugin.ForceSpawnAndLabel(__instance); return false; } } [HarmonyPatch(typeof(UT_SpawnChance), "Check")] public static class UT_SpawnChance_Check_Patcher { [HarmonyPrefix] public static bool Prefix(UT_SpawnChance __instance) { Plugin.ForceSpawnAndLabel(__instance); return false; } } [HarmonyPatch(typeof(UT_SpawnEntityByID), "Spawn")] public static class UT_SpawnEntityByID_SpawnPatch { [HarmonyPrefix] public static bool Prefix(UT_SpawnEntityByID __instance) { Plugin.LabelSpawnEntityByID(__instance); __instance.SpawnCustom(__instance.idToSpawn); return false; } } [HarmonyPatch(typeof(DEN_Bloodbug), "FixedUpdate")] public static class DEN_Bloodbug_FixedUpdate_Patcher { [HarmonyPrefix] public static bool Prefix(DEN_Bloodbug __instance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown FieldInfo field = typeof(DEN_Bloodbug).GetField("rigid", BindingFlags.Instance | BindingFlags.NonPublic); Rigidbody val = (Rigidbody)field.GetValue(__instance); val.useGravity = false; return false; } } [HarmonyPatch(typeof(DEN_Gasbag), "FixedUpdate")] public static class DEN_Gasbag_FixedUpdate_Patcher { [HarmonyPrefix] public static bool Prefix(DEN_Gasbag __instance) { return false; } } } namespace SpawnStats.UI { public class SpawnLabelTag : MonoBehaviour { public GameObject label; private void OnDestroy() { if ((Object)(object)label != (Object)null) { Object.Destroy((Object)(object)label); } } } public class ChanceLabel : MonoBehaviour { private Transform target; private TextMesh textMesh; private LineRenderer line; private float hoverOffset = 0.5f; private static Transform overlayRoot; private static Transform OverlayRoot { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)overlayRoot == (Object)null) { GameObject val = new GameObject("SpawnChanceOverlayRoot"); overlayRoot = val.transform; Object.DontDestroyOnLoad((Object)(object)val); } return overlayRoot; } } public void Init(Transform targetTransform, string labelText) { //IL_0077: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) target = targetTransform; ((Component)this).transform.SetParent(OverlayRoot, false); textMesh = ((Component)this).gameObject.AddComponent(); textMesh.text = labelText; textMesh.fontSize = 64; textMesh.anchor = (TextAnchor)4; textMesh.alignment = (TextAlignment)1; textMesh.characterSize = 0.015f; textMesh.color = Color.yellow; line = ((Component)this).gameObject.AddComponent(); line.positionCount = 2; line.useWorldSpace = true; line.widthCurve = AnimationCurve.Constant(0f, 1f, 0.01f); line.numCapVertices = 4; Material val = new Material(Shader.Find("Sprites/Default")); if ((Object)(object)val != (Object)null) { val.SetInt("_SrcBlend", 5); val.SetInt("_DstBlend", 10); val.SetInt("_ZWrite", 0); val.DisableKeyword("_ALPHATEST_ON"); val.EnableKeyword("_ALPHABLEND_ON"); val.DisableKeyword("_ALPHAPREMULTIPLY_ON"); val.SetInt("_ZTest", 8); val.renderQueue = 3001; } ((Renderer)line).material = val; line.startColor = new Color(1f, 0.9f, 0.2f, 1f); line.endColor = new Color(1f, 0.9f, 0.2f, 0.6f); } private void LateUpdate() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Collider component = ((Component)target).GetComponent(); Vector3 position = default(Vector3); if ((Object)(object)component != (Object)null) { Bounds bounds = component.bounds; ((Vector3)(ref position))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + hoverOffset, ((Bounds)(ref bounds)).center.z); } else { position = target.position + Vector3.up * (1.5f + hoverOffset); } ((Component)this).transform.position = position; if ((Object)(object)Camera.main != (Object)null) { Vector3 val = ((Component)Camera.main).transform.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Component)this).transform.rotation = Quaternion.LookRotation(val, Vector3.up); ((Component)this).transform.Rotate(0f, 180f, 0f); } } Vector3 position2 = default(Vector3); if ((Object)(object)component != (Object)null) { Bounds bounds2 = component.bounds; ((Vector3)(ref position2))..ctor(((Bounds)(ref bounds2)).center.x, ((Bounds)(ref bounds2)).min.y + 0.05f, ((Bounds)(ref bounds2)).center.z); } else { position2 = target.position; } if ((Object)(object)line != (Object)null) { line.SetPosition(0, ((Component)this).transform.position); line.SetPosition(1, position2); } } public void SetText(string t) { if ((Object)(object)textMesh != (Object)null) { textMesh.text = t; } } } public class Billboard : MonoBehaviour { private void LateUpdate() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Camera.main == (Object)null)) { ((Component)this).transform.LookAt(((Component)Camera.main).transform, Vector3.up); } } } }