Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CaptainDiabloTimer v0.1.4
plugins/CaptainDiabloTimer/CaptainDiabloTimer.dll
Decompiled 20 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using EntityStates; using EntityStates.Captain.Weapon; using Microsoft.CodeAnalysis; using On.EntityStates; using UnityEngine; [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("CaptainDiabloTimer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CaptainDiabloTimer")] [assembly: AssemblyTitle("CaptainDiabloTimer")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace CaptainDiabloTimer { [BepInPlugin("com.trynlord.captain-diablo-timer", "Captain Diablo Timer", "0.1.4")] public sealed class CaptainDiabloTimerPlugin : BaseUnityPlugin { private sealed class StrikeTimer { public float EndTime; public int LastBeepSecond = int.MaxValue; } public const string PluginGuid = "com.trynlord.captain-diablo-timer"; public const string PluginName = "Captain Diablo Timer"; public const string PluginVersion = "0.1.4"; private static CaptainDiabloTimerPlugin? _instance; private readonly List<StrikeTimer> _activeStrikes = new List<StrikeTimer>(); private readonly List<float> _remainingTimes = new List<float>(); private ConfigEntry<bool> _enabled; private ConfigEntry<float> _strikeDelaySeconds; private ConfigEntry<bool> _showCountdown; private ConfigEntry<bool> _showOnlyDuringWarning; private ConfigEntry<float> _warningStartsAtSeconds; private ConfigEntry<int> _maxVisibleTimers; private ConfigEntry<string> _labelText; private ConfigEntry<int> _fontSize; private ConfigEntry<float> _verticalPosition; private ConfigEntry<bool> _playBeeps; private ConfigEntry<bool> _playImpactBeep; private ConfigEntry<float> _beepVolume; private AudioSource? _audioSource; private AudioClip? _countdownBeep; private AudioClip? _impactBeep; private GUIStyle? _timerStyle; private void Awake() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown _instance = this; BindConfig(); CreateAudio(); AimThrowableBase.FireProjectile += new hook_FireProjectile(AimThrowableBase_FireProjectile); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Captain Diablo Timer 0.1.4 loaded (client-side only)."); } private void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown AimThrowableBase.FireProjectile -= new hook_FireProjectile(AimThrowableBase_FireProjectile); if ((Object)(object)_countdownBeep != (Object)null) { Object.Destroy((Object)(object)_countdownBeep); } if ((Object)(object)_impactBeep != (Object)null) { Object.Destroy((Object)(object)_impactBeep); } if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private static void AimThrowableBase_FireProjectile(orig_FireProjectile orig, AimThrowableBase self) { orig.Invoke(self); try { if ((Object)(object)_instance != (Object)null && self is CallAirstrikeAlt) { ((BaseUnityPlugin)_instance).Logger.LogInfo((object)"Diablo Strike confirmed; countdown started."); if (_instance._enabled.Value) { _instance.AddStrike(); } } } catch (Exception arg) { CaptainDiabloTimerPlugin? instance = _instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogError((object)$"Failed to start Diablo timer: {arg}"); } } } private void BindConfig() { _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the Diablo Strike countdown and warnings."); _strikeDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Timer", "StrikeDelaySeconds", 20f, "Seconds between confirming the Diablo Strike target and impact. Keep this at 20 for vanilla; change it only if another mod changes the delay."); _showCountdown = ((BaseUnityPlugin)this).Config.Bind<bool>("Timer", "ShowCountdown", true, "Show the on-screen countdown."); _showOnlyDuringWarning = ((BaseUnityPlugin)this).Config.Bind<bool>("Timer", "ShowOnlyDuringWarning", false, "Hide the timer until WarningStartsAtSeconds is reached."); _warningStartsAtSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Timer", "WarningStartsAtSeconds", 5f, "Timer turns red and countdown beeps begin at this many seconds."); _maxVisibleTimers = ((BaseUnityPlugin)this).Config.Bind<int>("Timer", "MaxVisibleTimers", 4, "Maximum simultaneous Diablo Strike timers shown on screen."); _labelText = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "Label", "DIABLO STRIKE", "Text shown before the remaining time."); _fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "FontSize", 34, "Countdown font size."); _verticalPosition = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "VerticalPosition", 0.16f, "Vertical screen position from 0 (top) to 1 (bottom)."); _playBeeps = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "PlayCountdownBeeps", true, "Play one short beep per second during the warning window."); _playImpactBeep = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "PlayImpactBeep", true, "Play a lower double-length beep when the timer reaches zero."); _beepVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "BeepVolume", 0.55f, "Beep volume from 0 to 1."); } private void CreateAudio() { _audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); _audioSource.playOnAwake = false; _audioSource.loop = false; _audioSource.spatialBlend = 0f; _countdownBeep = CreateTone("CaptainDiabloTimer_Countdown", 880f, 0.085f); _impactBeep = CreateTone("CaptainDiabloTimer_Impact", 440f, 0.17f); } private static AudioClip CreateTone(string name, float frequency, float duration) { int num = Mathf.Max(1, Mathf.CeilToInt(44100f * duration)); float[] array = new float[num]; for (int i = 0; i < num; i++) { float num2 = (float)i / 44100f; float num3 = Mathf.Sin(MathF.PI * (float)i / (float)num); array[i] = Mathf.Sin(MathF.PI * 2f * frequency * num2) * num3 * 0.35f; } AudioClip obj = AudioClip.Create(name, num, 1, 44100, false); obj.SetData(array, 0); return obj; } private void AddStrike() { float num = Mathf.Max(0.25f, _strikeDelaySeconds.Value); _activeStrikes.Add(new StrikeTimer { EndTime = Time.time + num }); ((BaseUnityPlugin)this).Logger.LogDebug((object)$"Local Diablo Strike timer started ({num:0.##}s)."); } private void Update() { if (!_enabled.Value) { _activeStrikes.Clear(); return; } int num = Mathf.Max(1, Mathf.CeilToInt(_warningStartsAtSeconds.Value)); for (int num2 = _activeStrikes.Count - 1; num2 >= 0; num2--) { StrikeTimer strikeTimer = _activeStrikes[num2]; float num3 = strikeTimer.EndTime - Time.time; if (num3 <= 0f) { if (_playImpactBeep.Value) { PlayClip(_impactBeep); } _activeStrikes.RemoveAt(num2); } else { int num4 = Mathf.CeilToInt(num3); if (_playBeeps.Value && num4 >= 1 && num4 <= num && num4 < strikeTimer.LastBeepSecond) { PlayClip(_countdownBeep); } strikeTimer.LastBeepSecond = num4; } } } private void PlayClip(AudioClip? clip) { if (!((Object)(object)_audioSource == (Object)null) && !((Object)(object)clip == (Object)null)) { _audioSource.PlayOneShot(clip, Mathf.Clamp01(_beepVolume.Value)); } } private void OnGUI() { //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) if (!_enabled.Value || !_showCountdown.Value || _activeStrikes.Count == 0) { return; } _remainingTimes.Clear(); float num = Mathf.Max(0f, _warningStartsAtSeconds.Value); foreach (StrikeTimer activeStrike in _activeStrikes) { float num2 = activeStrike.EndTime - Time.time; if (!(num2 <= 0f) && (!_showOnlyDuringWarning.Value || !(num2 > num))) { _remainingTimes.Add(num2); } } if (_remainingTimes.Count != 0) { _remainingTimes.Sort(); EnsureStyle(); int num3 = Mathf.Min(_remainingTimes.Count, Mathf.Clamp(_maxVisibleTimers.Value, 1, 10)); float num4 = Mathf.Max(34f, (float)_fontSize.Value + 10f); float num5 = (float)num3 * num4; float num6 = Mathf.Clamp01(_verticalPosition.Value) * (float)Screen.height - num5 * 0.5f; Rect rect = default(Rect); for (int i = 0; i < num3; i++) { float num7 = _remainingTimes[i]; string arg = ((_remainingTimes.Count > 1) ? $" {i + 1}" : string.Empty); string text = $"{_labelText.Value}{arg} — {num7:0.0}s"; ((Rect)(ref rect))..ctor(0f, num6 + (float)i * num4, (float)Screen.width, num4); bool num8 = num7 <= num; float num9 = (num8 ? (0.82f + Mathf.Sin(Time.time * 10f) * 0.18f) : 1f); Color foreground = (Color)(num8 ? new Color(1f, 0.23f * num9, 0.12f * num9, 1f) : Color.white); DrawOutlinedLabel(rect, text, foreground); } } } private void EnsureStyle() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) //IL_0032: Expected O, but got Unknown if (_timerStyle == null) { _timerStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1, richText = false }; } _timerStyle.fontSize = Mathf.Clamp(_fontSize.Value, 12, 96); } private void DrawOutlinedLabel(Rect rect, string text, Color foreground) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) if (_timerStyle != null) { Color textColor = _timerStyle.normal.textColor; _timerStyle.normal.textColor = new Color(0f, 0f, 0f, 0.85f); GUI.Label(new Rect(((Rect)(ref rect)).x - 2f, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, _timerStyle); GUI.Label(new Rect(((Rect)(ref rect)).x + 2f, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, _timerStyle); GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y - 2f, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, _timerStyle); GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 2f, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, _timerStyle); _timerStyle.normal.textColor = foreground; GUI.Label(rect, text, _timerStyle); _timerStyle.normal.textColor = textColor; } } } }