using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Coruscnium")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Warframe-style enemy highlight, outline, and target tint with configurable colors and intensity")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0.0")] [assembly: AssemblyProduct("EnemyHighlights")] [assembly: AssemblyTitle("EnemyHighlights")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EnemyHighlights { [BepInPlugin("enemyhighlights.mycopunk", "EnemyHighlights", "1.0.0.0")] [BepInProcess("Mycopunk.exe")] [MycoMod(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private static class HighlightOverlay { private static readonly HashSet _parts = new HashSet(); private static readonly List _iter = new List(); private static Material _overlayMat; private static RenderParams _renderParams; private static readonly int _LineRotation = Shader.PropertyToID("_LineRotation"); internal static void Register(EnemyPart part) { if (part != null) { _parts.Add(part); } } internal static void Render() { //IL_0037: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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) if (_highlightStrength <= 0f || _parts.Count == 0 || !EnsureMaterial()) { return; } Color val = _highlightColor * (1f + 0.6f * _highlightStrength); val.a = Mathf.Lerp(0.15f, 1f, _highlightStrength); _overlayMat.SetColor(Global._BaseColor, val); _iter.Clear(); _iter.AddRange(_parts); for (int i = 0; i < _iter.Count; i++) { EnemyPart val2 = _iter[i]; if (val2 == null || !Object.op_Implicit((Object)(object)val2)) { _parts.Remove(val2); } else { if (!((Behaviour)val2).isActiveAndEnabled) { continue; } EnemyBrain brain = val2.Brain; if (brain == null || brain.DigProgress > 0f) { continue; } List meshes = val2.Meshes; if (meshes == null) { continue; } for (int j = 0; j < meshes.Count; j++) { TargetMesh val3 = meshes[j]; if (val3 == null || val3.mesh == null) { continue; } Mesh sharedMesh = val3.mesh.sharedMesh; if (sharedMesh != null) { Matrix4x4 localToWorldMatrix = ((Component)val3.mesh).transform.localToWorldMatrix; int subMeshCount = sharedMesh.subMeshCount; for (int k = 0; k < subMeshCount; k++) { Graphics.RenderMesh(ref _renderParams, sharedMesh, k, localToWorldMatrix, (Matrix4x4?)null); } } } } } } private static bool EnsureMaterial() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown if (_overlayMat != null) { return true; } Shader val = Shader.Find("Universal Render Pipeline/Unlit"); if (val != null) { _overlayMat = new Material(val); _overlayMat.SetFloat("_Surface", 1f); _overlayMat.SetOverrideTag("RenderType", "Transparent"); _overlayMat.SetInt("_SrcBlend", 5); _overlayMat.SetInt("_DstBlend", 10); _overlayMat.SetInt("_ZWrite", 0); _overlayMat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); _overlayMat.renderQueue = 3000; Logger.LogInfo((object)"[highlight] overlay using URP/Unlit (depth-tested)"); } else { Highlighter val2 = default(Highlighter); if (!Highlighter.TryGetInstance(ref val2)) { return false; } Material highlightMaterial = val2.HighlightMaterial; if (highlightMaterial == null) { return false; } _overlayMat = new Material(highlightMaterial); _overlayMat.SetFloat(_LineRotation, 1f); if (!_overlayMat.HasProperty("_ZTest")) { Logger.LogError((object)("[highlight] URP/Unlit stripped from build and Highlighter shader '" + ((Object)highlightMaterial.shader).name + "' has no _ZTest property — overlay would draw through walls, DISABLING highlight")); _overlayMat = null; return false; } _overlayMat.SetInt("_ZTest", 4); Logger.LogInfo((object)("[highlight] overlay cloned from Highlighter ('" + ((Object)highlightMaterial.shader).name + "'), _ZTest forced to LessEqual")); } RenderParams renderParams = default(RenderParams); ((RenderParams)(ref renderParams))..ctor(_overlayMat); ((RenderParams)(ref renderParams)).layer = 0; ((RenderParams)(ref renderParams)).renderingLayerMask = 1u; _renderParams = renderParams; return true; } } private static class EnemyPartPatches { [HarmonyPatch(typeof(EnemyPart), "Initialize")] [HarmonyPostfix] private static void Initialize_Postfix(EnemyPart __instance) { HighlightOverlay.Register(__instance); } [HarmonyPatch(typeof(EnemyPart), "SetupRenderersOnAttach")] [HarmonyPostfix] private static void SetupRenderersOnAttach_Postfix(EnemyPart __instance) { HighlightOverlay.Register(__instance); } } private static class HighlighterPatches { private static readonly FieldInfo GradientField = AccessTools.Field(typeof(Highlighter), "highlightHealthColor"); private static readonly FieldInfo OpacityField = AccessTools.Field(typeof(Highlighter), "highlightOpacity"); private static Gradient _vanillaGradient; private static Range _vanillaOpacity; private static bool _captured; [HarmonyPatch(typeof(Highlighter), "Setup")] [HarmonyPostfix] private static void Setup_Postfix(Highlighter __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) _vanillaGradient = (Gradient)GradientField.GetValue(__instance); _vanillaOpacity = (Range)OpacityField.GetValue(__instance); _captured = true; ApplyTargetingOverride(); } internal static void ApplyTargetingOverride() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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) Highlighter obj = default(Highlighter); if (_captured && Highlighter.TryGetInstance(ref obj)) { if (_targetingStrength <= 0f) { GradientField.SetValue(obj, _vanillaGradient); OpacityField.SetValue(obj, _vanillaOpacity); return; } Gradient val = new Gradient(); val.colorKeys = (GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(_targetingColor, 0f), new GradientColorKey(_targetingColor, 1f) }; val.alphaKeys = (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }; Gradient value = val; GradientField.SetValue(obj, value); OpacityField.SetValue(obj, new Range(_targetingStrength, _targetingStrength)); } } } public const string PluginGUID = "enemyhighlights.mycopunk"; public const string PluginName = "EnemyHighlights"; public const string PluginVersion = "1.0.0.0"; internal static ManualLogSource Logger; private static ConfigEntry _highlightColorCfg; private static ConfigEntry _highlightIntensityCfg; private static ConfigEntry _targetingColorCfg; private static ConfigEntry _targetingIntensityCfg; private static Color _highlightColor = Color.red; private static float _highlightStrength; private static Color _targetingColor = Color.red; private static float _targetingStrength; private static FileSystemWatcher _configWatcher; private static volatile bool _pendingConfigReload; private void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; _highlightColorCfg = ((BaseUnityPlugin)this).Config.Bind("Highlight", "HighlightColor", "FF2A00", "Hex color (RRGGBB) for the whole-enemy overlay."); _highlightIntensityCfg = ((BaseUnityPlugin)this).Config.Bind("Highlight", "HighlightIntensity", 30, new ConfigDescription("0 disables (vanilla). 100 = solid, super-bright color coat.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); _targetingColorCfg = ((BaseUnityPlugin)this).Config.Bind("Targeting", "TargetingColor", "FF2A00", "Hex color (RRGGBB) for the pointed-at part overlay."); _targetingIntensityCfg = ((BaseUnityPlugin)this).Config.Bind("Targeting", "TargetingIntensity", 0, new ConfigDescription("0 disables (vanilla health-gradient overlay). 100 = fully opaque overlay.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged; ((BaseUnityPlugin)this).Config.Save(); try { _configWatcher = new FileSystemWatcher(Paths.ConfigPath, "enemyhighlights.mycopunk.cfg") { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), EnableRaisingEvents = true }; _configWatcher.Changed += OnConfigFileChanged; _configWatcher.Created += OnConfigFileChanged; _configWatcher.Renamed += OnConfigFileChanged; } catch (Exception ex) { Logger.LogWarning((object)("Could not start config file watcher: " + ex.Message)); } RefreshCachedValues(); Harmony val = new Harmony("enemyhighlights.mycopunk"); val.PatchAll(typeof(EnemyPartPatches)); val.PatchAll(typeof(HighlighterPatches)); Logger.LogInfo((object)"EnemyHighlights 1.0.0.0 loaded."); } private static void OnSettingChanged(object sender, SettingChangedEventArgs args) { RefreshCachedValues(); HighlighterPatches.ApplyTargetingOverride(); } private static void OnConfigFileChanged(object sender, FileSystemEventArgs e) { _pendingConfigReload = true; } private void Update() { if (_pendingConfigReload) { _pendingConfigReload = false; ((BaseUnityPlugin)this).Config.Reload(); } } private void LateUpdate() { HighlightOverlay.Render(); } private void OnDestroy() { if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = false; _configWatcher.Changed -= OnConfigFileChanged; _configWatcher.Created -= OnConfigFileChanged; _configWatcher.Renamed -= OnConfigFileChanged; _configWatcher.Dispose(); _configWatcher = null; } } private static void RefreshCachedValues() { //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_0015: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) _highlightColor = ParseHex(_highlightColorCfg.Value, Color.red); _highlightStrength = (float)Mathf.Clamp(_highlightIntensityCfg.Value, 0, 100) / 100f; _targetingColor = ParseHex(_targetingColorCfg.Value, Color.red); _targetingStrength = (float)Mathf.Clamp(_targetingIntensityCfg.Value, 0, 100) / 100f; } private static Color ParseHex(string hex, Color fallback) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0044: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(hex)) { return fallback; } string text = hex.Trim(); if (!text.StartsWith("#")) { text = "#" + text; } Color val = default(Color); return ColorUtility.TryParseHtmlString(text, ref val) ? val : fallback; } } }