Decompiled source of DolyCards v1.5.0
plugins\RoundsDolyMods.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using ClassesManagerReborn; using ClassesManagerReborn.Util; using HarmonyLib; using InControl; using Microsoft.CodeAnalysis; using ModdingUtils.Utils; using Photon.Pun; using RarityLib.Utils; using RoundsDolyMods.Cards; using RoundsDolyMods.Effects; using RoundsDolyMods.Integrations; using RoundsDolyMods.Visuals; using SimulationChamber; using Sonigon; using TMPro; using TabInfo.Utils; using ToggleCardsCategories; using UnboundLib; using UnboundLib.Cards; using UnboundLib.GameModes; using UnboundLib.Utils.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RoundsDolyMods")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1ec54cdd2e17e7621f2746e89459b4b1f13c5560")] [assembly: AssemblyProduct("RoundsDolyMods")] [assembly: AssemblyTitle("RoundsDolyMods")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 RoundsDolyMods { internal static class CardStats { internal static CardInfoStat Positive(string stat, string amount) { return Build(stat, amount, positive: true); } internal static CardInfoStat Negative(string stat, string amount) { return Build(stat, amount, positive: false); } internal static CardInfoStat Neutral(string stat, string amount) { return Build(stat, amount, positive: true); } private static CardInfoStat Build(string stat, string amount, bool positive) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new CardInfoStat { positive = positive, stat = stat, amount = amount, simepleAmount = (SimpleAmount)0 }; } } internal static class ClassManagerBridge { internal static void RegisterEntry(CardInfo cardInfo, string className) { Register(cardInfo, className, (CardType)1, null, 1); EnsureClassBadge(cardInfo); } internal static void RegisterRequiredCard(CardInfo cardInfo, string className, CardInfo requiredCard) { Register(cardInfo, className, (CardType)16, requiredCard, (!cardInfo.allowMultiple) ? 1 : 99); } private static void Register(CardInfo cardInfo, string className, CardType cardType, CardInfo? requiredCard, int maxAllowed) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (requiredCard != null) { ClassesRegistry.Register(cardInfo, cardType, requiredCard, maxAllowed); } else { ClassesRegistry.Register(cardInfo, cardType, maxAllowed); } ((Component)cardInfo).gameObject.GetOrAddComponent<ClassNameMono>().className = className; } private static void EnsureClassBadge(CardInfo cardInfo) { if (((Component)cardInfo).gameObject.GetComponent<ClassCornerBadge>() == null) { ((Component)cardInfo).gameObject.AddComponent<ClassCornerBadge>(); } } } internal static class ComponentExtensions { internal static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component { T component = gameObject.GetComponent<T>(); if (component == null) { return gameObject.AddComponent<T>(); } return component; } internal static T GetOrAddComponent<T>(this Component component) where T : Component { return component.gameObject.GetOrAddComponent<T>(); } } internal static class DolyModSettings { private enum BindingSlot { KeyboardModifier, KeyboardUp, KeyboardRight, KeyboardDown, KeyboardLeft, ControllerModifier, ControllerUp, ControllerRight, ControllerDown, ControllerLeft } private sealed class HelldiverSettingsMenuController : MonoBehaviour { private readonly Dictionary<BindingSlot, GameObject> buttons = new Dictionary<BindingSlot, GameObject>(); private Slider? hudScaleSlider; private TextMeshProUGUI? summaryText; private TextMeshProUGUI? helpText; private BindingSlot? activeCapture; private bool initializedMenu; internal void Initialize(GameObject menu) { //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) if (initializedMenu) { Refresh(); return; } initializedMenu = true; TextMeshProUGUI text = default(TextMeshProUGUI); MenuHandler.CreateText("Doly Mod Settings", menu, ref text, 52, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureTextBlock(text, 50f, (TextAlignmentOptions)514); TextMeshProUGUI text2 = default(TextMeshProUGUI); MenuHandler.CreateText("HUD", menu, ref text2, 48, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureTextBlock(text2, 48f, (TextAlignmentOptions)514); float helldiverHudScale = GetHelldiverHudScale(); UnityAction<float> obj = delegate(float value) { SetHelldiverHudScale(value); }; TextAlignmentOptions? val = (TextAlignmentOptions)514; Slider val2 = default(Slider); GameObject sliderObject = MenuHandler.CreateSlider("Helldiver HUD scale", menu, 36, 0.5f, 2f, helldiverHudScale, obj, ref val2, false, (Color?)null, (Direction)0, false, (Color?)null, (TMP_FontAsset)null, (Material)null, val); hudScaleSlider = val2; ConfigureSliderBlock(sliderObject, (TextAlignmentOptions)514); MenuHandler.CreateText("HUD Prompt", menu, ref summaryText, 32, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureTextBlock(summaryText, 60f, (TextAlignmentOptions)514); TextMeshProUGUI text3 = default(TextMeshProUGUI); MenuHandler.CreateText("Keyboard", menu, ref text3, 48, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureTextBlock(text3, 48f, (TextAlignmentOptions)514); CreateBindingButton(menu, BindingSlot.KeyboardModifier); CreateBindingButton(menu, BindingSlot.KeyboardUp); CreateBindingButton(menu, BindingSlot.KeyboardRight); CreateBindingButton(menu, BindingSlot.KeyboardDown); CreateBindingButton(menu, BindingSlot.KeyboardLeft); TextMeshProUGUI text4 = default(TextMeshProUGUI); MenuHandler.CreateText("Controller", menu, ref text4, 48, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureTextBlock(text4, 48f, (TextAlignmentOptions)514); CreateBindingButton(menu, BindingSlot.ControllerModifier); CreateBindingButton(menu, BindingSlot.ControllerUp); CreateBindingButton(menu, BindingSlot.ControllerRight); CreateBindingButton(menu, BindingSlot.ControllerDown); CreateBindingButton(menu, BindingSlot.ControllerLeft); GameObject obj2 = MenuHandler.CreateButton("Reset Helldiver defaults", menu, (UnityAction)delegate { ResetDefaults(); activeCapture = null; Refresh(); }, 36, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureButtonLabel(obj2, (TextAlignmentOptions)514); TextMeshProUGUI componentInChildren = obj2.GetComponentInChildren<TextMeshProUGUI>(); if (componentInChildren != null) { ((Graphic)componentInChildren).color = new Color(1f, 0.86f, 0.68f, 1f); } MenuHandler.CreateText("", menu, ref helpText, 28, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureTextBlock(helpText, 70f, (TextAlignmentOptions)514); Refresh(); } private void Update() { if (!activeCapture.HasValue) { return; } if (Input.GetKeyDown((KeyCode)27)) { activeCapture = null; Refresh(); } else if (Input.GetKeyDown((KeyCode)8) || Input.GetKeyDown((KeyCode)127)) { ResetDefault(activeCapture.Value); activeCapture = null; Refresh(); } else if (IsKeyboardSlot(activeCapture.Value)) { if (TryCaptureKeyboard(activeCapture.Value)) { activeCapture = null; Refresh(); } } else if (TryCaptureController(activeCapture.Value)) { activeCapture = null; Refresh(); } } private void CreateBindingButton(GameObject menu, BindingSlot slot) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown GameObject val = null; val = MenuHandler.CreateButton(GetButtonLabel(slot), menu, (UnityAction)delegate { activeCapture = slot; Refresh(); }, 36, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ConfigureButtonLabel(val, (TextAlignmentOptions)514); buttons[slot] = val; } private bool TryCaptureKeyboard(BindingSlot slot) { //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_0017: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < KeyboardCaptureCandidates.Length; i++) { KeyCode val = KeyboardCaptureCandidates[i]; if (Input.GetKeyDown(val)) { if (slot == BindingSlot.KeyboardModifier) { SetKeyboardModifier(val); } else { SetKeyboardDirectionBinding(ToDirection(slot), ((object)(KeyCode)(ref val)).ToString()); } return true; } } return false; } private bool TryCaptureController(BindingSlot slot) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_003a: Unknown result type (might be due to invalid IL or missing references) ReadOnlyCollection<InputDevice> devices = InputManager.Devices; if (devices == null) { return false; } for (int i = 0; i < devices.Count; i++) { InputDevice val = devices[i]; if (val == null) { continue; } for (int j = 0; j < ControllerCaptureCandidates.Length; j++) { InputControlType val2 = ControllerCaptureCandidates[j]; if (((OneAxisInputControl)val.GetControl(val2)).WasPressed) { if (slot == BindingSlot.ControllerModifier) { SetControllerModifier(val2); } else { SetControllerDirectionBinding(ToDirection(slot), val2); } return true; } } } return false; } private void Refresh() { if (hudScaleSlider != null && !Mathf.Approximately(hudScaleSlider.value, GetHelldiverHudScale())) { hudScaleSlider.value = GetHelldiverHudScale(); } foreach (KeyValuePair<BindingSlot, GameObject> button in buttons) { TextMeshProUGUI componentInChildren = button.Value.GetComponentInChildren<TextMeshProUGUI>(); if (componentInChildren != null) { ((TMP_Text)componentInChildren).text = ((activeCapture == button.Key) ? ("> Press " + (IsKeyboardSlot(button.Key) ? "a key" : "a controller input") + " for " + GetCaptureLabel(button.Key) + " <") : GetButtonLabel(button.Key)); } } if (summaryText != null) { ((TMP_Text)summaryText).text = (TryGetHelldiverInputSummary(out string summary) ? ("HUD prompt: " + summary) : "HUD prompt: hidden for custom direction layouts"); } if (helpText != null) { ((TMP_Text)helpText).text = (activeCapture.HasValue ? ("Rebinding " + GetCaptureLabel(activeCapture.Value) + ". Press Escape to cancel or Backspace/Delete to restore the default binding.") : "Click any binding entry to rebind it."); } } private static string GetCaptureLabel(BindingSlot slot) { return slot switch { BindingSlot.KeyboardModifier => "Keyboard Input Button", BindingSlot.KeyboardUp => "Keyboard Up", BindingSlot.KeyboardRight => "Keyboard Right", BindingSlot.KeyboardDown => "Keyboard Down", BindingSlot.KeyboardLeft => "Keyboard Left", BindingSlot.ControllerModifier => "Controller Input Button", BindingSlot.ControllerUp => "Controller Up", BindingSlot.ControllerRight => "Controller Right", BindingSlot.ControllerDown => "Controller Down", BindingSlot.ControllerLeft => "Controller Left", _ => "Binding", }; } private static HelldiverInputDirection ToDirection(BindingSlot slot) { switch (slot) { case BindingSlot.KeyboardUp: case BindingSlot.ControllerUp: return HelldiverInputDirection.Up; case BindingSlot.KeyboardRight: case BindingSlot.ControllerRight: return HelldiverInputDirection.Right; case BindingSlot.KeyboardDown: case BindingSlot.ControllerDown: return HelldiverInputDirection.Down; case BindingSlot.KeyboardLeft: case BindingSlot.ControllerLeft: return HelldiverInputDirection.Left; default: return HelldiverInputDirection.Up; } } private static void ConfigureTextBlock(TextMeshProUGUI text, float preferredHeight, TextAlignmentOptions alignment) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)text).alignment = alignment; ((TMP_Text)text).enableWordWrapping = true; LayoutElement obj = ((Component)text).gameObject.GetComponent<LayoutElement>() ?? ((Component)text).gameObject.AddComponent<LayoutElement>(); obj.preferredHeight = preferredHeight; obj.minHeight = preferredHeight; } private static void ConfigureButtonLabel(GameObject buttonObject, TextAlignmentOptions alignment) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI componentInChildren = buttonObject.GetComponentInChildren<TextMeshProUGUI>(); if (componentInChildren != null) { ((TMP_Text)componentInChildren).alignment = alignment; } } private static void ConfigureSliderBlock(GameObject sliderObject, TextAlignmentOptions alignment) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI[] componentsInChildren = sliderObject.GetComponentsInChildren<TextMeshProUGUI>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((TMP_Text)componentsInChildren[i]).alignment = alignment; } } } private const string HelldiverHudSettingsCategory = "Helldiver HUD"; private const string HelldiverSettingsCategory = "Helldiver Keybinds"; private const string PlayerUpToken = "@PlayerUp"; private const string PlayerRightToken = "@PlayerRight"; private const string PlayerDownToken = "@PlayerDown"; private const string PlayerLeftToken = "@PlayerLeft"; private const float DefaultHelldiverHudScale = 1f; private const float MinHelldiverHudScale = 0.5f; private const float MaxHelldiverHudScale = 2f; private static readonly InputControlType[] ControllerCaptureCandidates; private static readonly KeyCode[] KeyboardCaptureCandidates; private static ConfigEntry<KeyCode>? helldiverKeyboardModifier; private static ConfigEntry<string>? helldiverKeyboardUp; private static ConfigEntry<string>? helldiverKeyboardRight; private static ConfigEntry<string>? helldiverKeyboardDown; private static ConfigEntry<string>? helldiverKeyboardLeft; private static ConfigEntry<float>? helldiverHudScale; private static ConfigEntry<InputControlType>? helldiverControllerModifier; private static ConfigEntry<InputControlType>? helldiverControllerUp; private static ConfigEntry<InputControlType>? helldiverControllerRight; private static ConfigEntry<InputControlType>? helldiverControllerDown; private static ConfigEntry<InputControlType>? helldiverControllerLeft; private static bool initialized; internal static void Initialize(ConfigFile config) { if (!initialized) { helldiverKeyboardModifier = config.Bind<KeyCode>("Helldiver Keybinds", "Keyboard Input Button", (KeyCode)306, "Modifier button held while entering Helldiver stratagem directions on keyboard."); helldiverKeyboardUp = BindKeyboardDirection(config, HelldiverInputDirection.Up, "@PlayerUp"); helldiverKeyboardRight = BindKeyboardDirection(config, HelldiverInputDirection.Right, "@PlayerRight"); helldiverKeyboardDown = BindKeyboardDirection(config, HelldiverInputDirection.Down, "@PlayerDown"); helldiverKeyboardLeft = BindKeyboardDirection(config, HelldiverInputDirection.Left, "@PlayerLeft"); helldiverHudScale = config.Bind<float>("Helldiver HUD", "HUD Scale", 1f, "Scales the Helldiver HUD uniformly. 1.0 is the default size."); helldiverControllerModifier = config.Bind<InputControlType>("Helldiver Keybinds", "Controller Input Button", (InputControlType)17, "Modifier button held while entering Helldiver stratagem directions on controller."); helldiverControllerUp = BindControllerDirection(config, HelldiverInputDirection.Up, (InputControlType)11); helldiverControllerRight = BindControllerDirection(config, HelldiverInputDirection.Right, (InputControlType)14); helldiverControllerDown = BindControllerDirection(config, HelldiverInputDirection.Down, (InputControlType)12); helldiverControllerLeft = BindControllerDirection(config, HelldiverInputDirection.Left, (InputControlType)13); Unbound.RegisterMenu("Doly Mod Settings", (UnityAction)null, (Action<GameObject>)BuildMenu, (GameObject)null, true); initialized = true; } } internal static bool IsHelldiverInputModifierHeld(PlayerActions? playerActions) { if (!IsKeyboardModifierHeld()) { return IsControllerModifierHeld(playerActions); } return true; } internal static bool TryReadHelldiverDirection(PlayerActions? playerActions, out HelldiverInputDirection direction) { if (TryReadKeyboardDirection(playerActions, out direction)) { return true; } return TryReadControllerDirection(playerActions, out direction); } internal static bool TryGetHelldiverInputSummary(out string summary) { List<string> list = new List<string>(2); if (TryGetKeyboardPromptPart(out string summary2)) { list.Add(summary2); } if (TryGetControllerPromptPart(out string summary3)) { list.Add(summary3); } summary = string.Join(" | ", list); return list.Count > 0; } internal static string GetHelldiverInputSummary() { if (!TryGetHelldiverInputSummary(out string summary)) { return string.Empty; } return summary; } internal static float GetHelldiverHudScale() { return Mathf.Clamp(helldiverHudScale?.Value ?? 1f, 0.5f, 2f); } private static ConfigEntry<string> BindKeyboardDirection(ConfigFile config, HelldiverInputDirection direction, string defaultValue) { return config.Bind<string>("Helldiver Keybinds", $"Keyboard {direction}", defaultValue, $"Keyboard button used for the Helldiver {direction} direction. Resetting restores the player's normal {direction} movement binding."); } private static ConfigEntry<InputControlType> BindControllerDirection(ConfigFile config, HelldiverInputDirection direction, InputControlType defaultValue) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) return config.Bind<InputControlType>("Helldiver Keybinds", $"Controller {direction}", defaultValue, $"Controller button used for the Helldiver {direction} direction."); } private static KeyCode[] BuildKeyboardCaptureCandidates() { //IL_0025: 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_002f: Unknown result type (might be due to invalid IL or missing references) KeyCode[] array = (KeyCode[])Enum.GetValues(typeof(KeyCode)); List<KeyCode> list = new List<KeyCode>(array.Length); foreach (KeyCode val in array) { if (IsSupportedKeyboardKey(val)) { list.Add(val); } } return list.ToArray(); } private static bool IsSupportedKeyboardKey(KeyCode keyCode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)keyCode == 0) { return false; } string text = ((object)(KeyCode)(ref keyCode)).ToString(); if (!text.StartsWith("Joystick", StringComparison.Ordinal)) { return !text.StartsWith("Mouse", StringComparison.Ordinal); } return false; } private static void BuildMenu(GameObject menu) { HelldiverSettingsMenuController helldiverSettingsMenuController = menu.GetComponent<HelldiverSettingsMenuController>(); if (helldiverSettingsMenuController == null) { helldiverSettingsMenuController = menu.AddComponent<HelldiverSettingsMenuController>(); } helldiverSettingsMenuController.Initialize(menu); } private static bool IsKeyboardModifierHeld() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) KeyCode keyboardModifier = GetKeyboardModifier(); if ((int)keyboardModifier != 0) { return Input.GetKey(keyboardModifier); } return false; } private static bool IsControllerModifierHeld(PlayerActions? playerActions) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InputDevice val = ((playerActions != null) ? ((PlayerActionSet)playerActions).Device : null); if (val != null) { return ((OneAxisInputControl)val.GetControl(GetControllerModifier())).IsPressed; } return false; } private static bool TryReadKeyboardDirection(PlayerActions? playerActions, out HelldiverInputDirection direction) { direction = HelldiverInputDirection.Up; if (!IsKeyboardModifierHeld()) { return false; } if (WasKeyboardDirectionPressed(playerActions, HelldiverInputDirection.Right)) { direction = HelldiverInputDirection.Right; return true; } if (WasKeyboardDirectionPressed(playerActions, HelldiverInputDirection.Down)) { direction = HelldiverInputDirection.Down; return true; } if (WasKeyboardDirectionPressed(playerActions, HelldiverInputDirection.Left)) { direction = HelldiverInputDirection.Left; return true; } if (WasKeyboardDirectionPressed(playerActions, HelldiverInputDirection.Up)) { direction = HelldiverInputDirection.Up; return true; } return false; } private static bool WasKeyboardDirectionPressed(PlayerActions? playerActions, HelldiverInputDirection direction) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) string keyboardDirectionBinding = GetKeyboardDirectionBinding(direction); if (TryGetPlayerActionDirection(keyboardDirectionBinding, out var direction2)) { return WasPlayerActionPressed(playerActions, direction2); } if (Enum.TryParse<KeyCode>(keyboardDirectionBinding, out KeyCode result)) { return Input.GetKeyDown(result); } return false; } private static bool WasPlayerActionPressed(PlayerActions? playerActions, HelldiverInputDirection direction) { if (playerActions == null) { return false; } return direction switch { HelldiverInputDirection.Up => ((OneAxisInputControl)playerActions.Up).WasPressed, HelldiverInputDirection.Right => ((OneAxisInputControl)playerActions.Right).WasPressed, HelldiverInputDirection.Down => ((OneAxisInputControl)playerActions.Down).WasPressed, HelldiverInputDirection.Left => ((OneAxisInputControl)playerActions.Left).WasPressed, _ => false, }; } private static bool TryReadControllerDirection(PlayerActions? playerActions, out HelldiverInputDirection direction) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) direction = HelldiverInputDirection.Up; InputDevice val = ((playerActions != null) ? ((PlayerActionSet)playerActions).Device : null); if (val == null || !((OneAxisInputControl)val.GetControl(GetControllerModifier())).IsPressed) { return false; } if (((OneAxisInputControl)val.GetControl(GetControllerDirectionBinding(HelldiverInputDirection.Right))).WasPressed) { direction = HelldiverInputDirection.Right; return true; } if (((OneAxisInputControl)val.GetControl(GetControllerDirectionBinding(HelldiverInputDirection.Down))).WasPressed) { direction = HelldiverInputDirection.Down; return true; } if (((OneAxisInputControl)val.GetControl(GetControllerDirectionBinding(HelldiverInputDirection.Left))).WasPressed) { direction = HelldiverInputDirection.Left; return true; } if (((OneAxisInputControl)val.GetControl(GetControllerDirectionBinding(HelldiverInputDirection.Up))).WasPressed) { direction = HelldiverInputDirection.Up; return true; } return false; } private static bool TryGetKeyboardPromptPart(out string summary) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) summary = string.Empty; if (!TryFormatRecognizedKeyboardModifier(GetKeyboardModifier(), out string label)) { return false; } if (!TryGetKeyboardDirectionLayoutLabel(out string label2)) { return false; } summary = label + " + " + label2; return true; } private static bool TryGetControllerPromptPart(out string summary) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) summary = string.Empty; if (!TryFormatRecognizedControllerModifier(GetControllerModifier(), out string label)) { return false; } if (!TryGetControllerDirectionLayoutLabel(out string label2)) { return false; } summary = label + " + " + label2; return true; } private static bool TryGetKeyboardDirectionLayoutLabel(out string label) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) if (MatchesKeyboardDirections("@PlayerUp", "@PlayerRight", "@PlayerDown", "@PlayerLeft")) { label = "MOVE"; return true; } KeyCode val = (KeyCode)119; string? up = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)100; string? right = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)115; string? down = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)97; if (MatchesKeyboardDirections(up, right, down, ((object)(KeyCode)(ref val)).ToString())) { label = "WASD"; return true; } val = (KeyCode)273; string? up2 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)275; string? right2 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)274; string? down2 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)276; if (MatchesKeyboardDirections(up2, right2, down2, ((object)(KeyCode)(ref val)).ToString())) { label = "ARROWS"; return true; } val = (KeyCode)105; string? up3 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)108; string? right3 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)107; string? down3 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)106; if (MatchesKeyboardDirections(up3, right3, down3, ((object)(KeyCode)(ref val)).ToString())) { label = "IJKL"; return true; } val = (KeyCode)264; string? up4 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)262; string? right4 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)261; string? down4 = ((object)(KeyCode)(ref val)).ToString(); val = (KeyCode)260; if (MatchesKeyboardDirections(up4, right4, down4, ((object)(KeyCode)(ref val)).ToString())) { label = "NUMPAD"; return true; } label = string.Empty; return false; } private static bool MatchesKeyboardDirections(string up, string right, string down, string left) { if (string.Equals(GetKeyboardDirectionBinding(HelldiverInputDirection.Up), up, StringComparison.Ordinal) && string.Equals(GetKeyboardDirectionBinding(HelldiverInputDirection.Right), right, StringComparison.Ordinal) && string.Equals(GetKeyboardDirectionBinding(HelldiverInputDirection.Down), down, StringComparison.Ordinal)) { return string.Equals(GetKeyboardDirectionBinding(HelldiverInputDirection.Left), left, StringComparison.Ordinal); } return false; } private static bool TryGetControllerDirectionLayoutLabel(out string label) { if (MatchesControllerDirections((InputControlType)11, (InputControlType)14, (InputControlType)12, (InputControlType)13)) { label = "DPAD"; return true; } if (MatchesControllerDirections((InputControlType)1, (InputControlType)4, (InputControlType)2, (InputControlType)3)) { label = "LSTICK"; return true; } if (MatchesControllerDirections((InputControlType)6, (InputControlType)9, (InputControlType)7, (InputControlType)8)) { label = "RSTICK"; return true; } if (MatchesControllerDirections((InputControlType)22, (InputControlType)20, (InputControlType)19, (InputControlType)21)) { label = "FACE"; return true; } label = string.Empty; return false; } private static bool MatchesControllerDirections(InputControlType up, InputControlType right, InputControlType down, InputControlType left) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (GetControllerDirectionBinding(HelldiverInputDirection.Up) == up && GetControllerDirectionBinding(HelldiverInputDirection.Right) == right && GetControllerDirectionBinding(HelldiverInputDirection.Down) == down) { return GetControllerDirectionBinding(HelldiverInputDirection.Left) == left; } return false; } private static bool TryFormatRecognizedKeyboardModifier(KeyCode keyCode, out string label) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown string text = (((int)keyCode == 9) ? "TAB" : ((keyCode - 301) switch { 5 => "LCTRL", 4 => "RCTRL", 3 => "LSHIFT", 2 => "RSHIFT", 7 => "LALT", 6 => "RALT", 0 => "CAPS", _ => string.Empty, })); label = text; return label.Length > 0; } private static bool TryFormatRecognizedControllerModifier(InputControlType controlType, out string label) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected I4, but got Unknown label = (controlType - 5) switch { 12 => "LB", 13 => "RB", 10 => "LT", 11 => "RT", 0 => "L3", 5 => "R3", 14 => "A", 15 => "B", 16 => "X", 17 => "Y", _ => string.Empty, }; return label.Length > 0; } private static bool TryGetPlayerActionDirection(string binding, out HelldiverInputDirection direction) { direction = binding switch { "@PlayerUp" => HelldiverInputDirection.Up, "@PlayerRight" => HelldiverInputDirection.Right, "@PlayerDown" => HelldiverInputDirection.Down, "@PlayerLeft" => HelldiverInputDirection.Left, _ => HelldiverInputDirection.Up, }; switch (binding) { default: return binding == "@PlayerLeft"; case "@PlayerUp": case "@PlayerRight": case "@PlayerDown": return true; } } private static KeyCode GetKeyboardModifier() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)helldiverKeyboardModifier?.Value) ?? 306); } private static string GetKeyboardDirectionBinding(HelldiverInputDirection direction) { return direction switch { HelldiverInputDirection.Up => helldiverKeyboardUp?.Value ?? "@PlayerUp", HelldiverInputDirection.Right => helldiverKeyboardRight?.Value ?? "@PlayerRight", HelldiverInputDirection.Down => helldiverKeyboardDown?.Value ?? "@PlayerDown", HelldiverInputDirection.Left => helldiverKeyboardLeft?.Value ?? "@PlayerLeft", _ => "@PlayerUp", }; } private static InputControlType GetControllerModifier() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (InputControlType)(((??)helldiverControllerModifier?.Value) ?? 17); } private static InputControlType GetControllerDirectionBinding(HelldiverInputDirection direction) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) switch (direction) { case HelldiverInputDirection.Up: { ConfigEntry<InputControlType>? obj3 = helldiverControllerUp; return (InputControlType)((obj3 == null) ? 11 : ((int)obj3.Value)); } case HelldiverInputDirection.Right: { ConfigEntry<InputControlType>? obj2 = helldiverControllerRight; return (InputControlType)((obj2 == null) ? 14 : ((int)obj2.Value)); } case HelldiverInputDirection.Down: { ConfigEntry<InputControlType>? obj4 = helldiverControllerDown; return (InputControlType)((obj4 == null) ? 12 : ((int)obj4.Value)); } case HelldiverInputDirection.Left: { ConfigEntry<InputControlType>? obj = helldiverControllerLeft; return (InputControlType)((obj == null) ? 13 : ((int)obj.Value)); } default: return (InputControlType)11; } } private static void SetKeyboardModifier(KeyCode keyCode) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) helldiverKeyboardModifier.Value = keyCode; } private static void SetKeyboardDirectionBinding(HelldiverInputDirection direction, string binding) { switch (direction) { case HelldiverInputDirection.Up: helldiverKeyboardUp.Value = binding; break; case HelldiverInputDirection.Right: helldiverKeyboardRight.Value = binding; break; case HelldiverInputDirection.Down: helldiverKeyboardDown.Value = binding; break; case HelldiverInputDirection.Left: helldiverKeyboardLeft.Value = binding; break; } } private static void SetControllerModifier(InputControlType controlType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) helldiverControllerModifier.Value = controlType; } private static void SetControllerDirectionBinding(HelldiverInputDirection direction, InputControlType controlType) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) switch (direction) { case HelldiverInputDirection.Up: helldiverControllerUp.Value = controlType; break; case HelldiverInputDirection.Right: helldiverControllerRight.Value = controlType; break; case HelldiverInputDirection.Down: helldiverControllerDown.Value = controlType; break; case HelldiverInputDirection.Left: helldiverControllerLeft.Value = controlType; break; } } private static void SetHelldiverHudScale(float scale) { helldiverHudScale.Value = Mathf.Clamp(scale, 0.5f, 2f); } private static void ResetDefaults() { helldiverKeyboardModifier.Value = (KeyCode)306; helldiverKeyboardUp.Value = "@PlayerUp"; helldiverKeyboardRight.Value = "@PlayerRight"; helldiverKeyboardDown.Value = "@PlayerDown"; helldiverKeyboardLeft.Value = "@PlayerLeft"; helldiverHudScale.Value = 1f; helldiverControllerModifier.Value = (InputControlType)17; helldiverControllerUp.Value = (InputControlType)11; helldiverControllerRight.Value = (InputControlType)14; helldiverControllerDown.Value = (InputControlType)12; helldiverControllerLeft.Value = (InputControlType)13; } private static void ResetDefault(BindingSlot slot) { switch (slot) { case BindingSlot.KeyboardModifier: SetKeyboardModifier((KeyCode)306); break; case BindingSlot.KeyboardUp: SetKeyboardDirectionBinding(HelldiverInputDirection.Up, "@PlayerUp"); break; case BindingSlot.KeyboardRight: SetKeyboardDirectionBinding(HelldiverInputDirection.Right, "@PlayerRight"); break; case BindingSlot.KeyboardDown: SetKeyboardDirectionBinding(HelldiverInputDirection.Down, "@PlayerDown"); break; case BindingSlot.KeyboardLeft: SetKeyboardDirectionBinding(HelldiverInputDirection.Left, "@PlayerLeft"); break; case BindingSlot.ControllerModifier: SetControllerModifier((InputControlType)17); break; case BindingSlot.ControllerUp: SetControllerDirectionBinding(HelldiverInputDirection.Up, (InputControlType)11); break; case BindingSlot.ControllerRight: SetControllerDirectionBinding(HelldiverInputDirection.Right, (InputControlType)14); break; case BindingSlot.ControllerDown: SetControllerDirectionBinding(HelldiverInputDirection.Down, (InputControlType)12); break; case BindingSlot.ControllerLeft: SetControllerDirectionBinding(HelldiverInputDirection.Left, (InputControlType)13); break; } } private static bool IsKeyboardSlot(BindingSlot slot) { if ((uint)slot <= 4u) { return true; } return false; } private static string GetButtonLabel(BindingSlot slot) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) return slot switch { BindingSlot.KeyboardModifier => "Keyboard input button: " + FormatKeyboardKey(GetKeyboardModifier()), BindingSlot.KeyboardUp => "Keyboard up: " + FormatKeyboardDirectionBinding(GetKeyboardDirectionBinding(HelldiverInputDirection.Up)), BindingSlot.KeyboardRight => "Keyboard right: " + FormatKeyboardDirectionBinding(GetKeyboardDirectionBinding(HelldiverInputDirection.Right)), BindingSlot.KeyboardDown => "Keyboard down: " + FormatKeyboardDirectionBinding(GetKeyboardDirectionBinding(HelldiverInputDirection.Down)), BindingSlot.KeyboardLeft => "Keyboard left: " + FormatKeyboardDirectionBinding(GetKeyboardDirectionBinding(HelldiverInputDirection.Left)), BindingSlot.ControllerModifier => "Controller input button: " + FormatControllerBinding(GetControllerModifier()), BindingSlot.ControllerUp => "Controller up: " + FormatControllerBinding(GetControllerDirectionBinding(HelldiverInputDirection.Up)), BindingSlot.ControllerRight => "Controller right: " + FormatControllerBinding(GetControllerDirectionBinding(HelldiverInputDirection.Right)), BindingSlot.ControllerDown => "Controller down: " + FormatControllerBinding(GetControllerDirectionBinding(HelldiverInputDirection.Down)), BindingSlot.ControllerLeft => "Controller left: " + FormatControllerBinding(GetControllerDirectionBinding(HelldiverInputDirection.Left)), _ => string.Empty, }; } private static string FormatKeyboardKey(KeyCode keyCode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected I4, but got Unknown return (keyCode - 256) switch { 0 => "Numpad 0", 1 => "Numpad 1", 2 => "Numpad 2", 3 => "Numpad 3", 4 => "Numpad 4", 5 => "Numpad 5", 6 => "Numpad 6", 7 => "Numpad 7", 8 => "Numpad 8", 9 => "Numpad 9", _ => (keyCode - 301) switch { 5 => "Left Ctrl", 4 => "Right Ctrl", 3 => "Left Shift", 2 => "Right Shift", 7 => "Left Alt", 6 => "Right Alt", 0 => "Caps Lock", _ => ((object)(KeyCode)(ref keyCode)).ToString(), }, }; } private static string FormatKeyboardDirectionBinding(string binding) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) switch (binding) { case "@PlayerUp": return "Player Up"; case "@PlayerRight": return "Player Right"; case "@PlayerDown": return "Player Down"; case "@PlayerLeft": return "Player Left"; default: { if (Enum.TryParse<KeyCode>(binding, out KeyCode result)) { return FormatKeyboardKey(result); } return binding; } } } private static string FormatControllerBinding(InputControlType controlType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected I4, but got Unknown return (controlType - 1) switch { 16 => "Left bumper", 17 => "Right bumper", 14 => "Left trigger", 15 => "Right trigger", 4 => "Left stick button", 9 => "Right stick button", 10 => "D-Pad Up", 13 => "D-Pad Right", 11 => "D-Pad Down", 12 => "D-Pad Left", 0 => "Left Stick Up", 3 => "Left Stick Right", 1 => "Left Stick Down", 2 => "Left Stick Left", 5 => "Right Stick Up", 8 => "Right Stick Right", 6 => "Right Stick Down", 7 => "Right Stick Left", 18 => "A", 19 => "B", 20 => "X", 21 => "Y", _ => ((object)(InputControlType)(ref controlType)).ToString(), }; } static DolyModSettings() { InputControlType[] array = new InputControlType[22]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); ControllerCaptureCandidates = (InputControlType[])(object)array; KeyboardCaptureCandidates = BuildKeyboardCaptureCandidates(); } } internal static class DolyRarityHelper { internal static Rarity Resolve(string rarityName, Rarity fallback) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(rarityName)) { return fallback; } try { return RarityUtils.GetRarity(rarityName); } catch { return fallback; } } } internal static class GamblecoreRegistry { internal static CardInfo? GamblecoreCardInfo { get; set; } internal static CardInfo? AwDangItCardInfo { get; set; } internal static CardInfo? ICantStopWinningCardInfo { get; set; } } internal static class HelldiverClassRegistry { internal const string ClassName = "Helldiver"; internal const float FallbackThrowSpeed = 22f; internal const float FallbackThrowGravity = 30f; internal const float BeaconRadius = 0.18f; internal const float MaxGroundAngleDegrees = 40f; internal const float InputChainTimeoutSeconds = 1.35f; internal const float SelfCollisionGraceSeconds = 0.18f; private static readonly IReadOnlyDictionary<HelldiverStratagemType, HelldiverStratagemDefinition> Definitions = new Dictionary<HelldiverStratagemType, HelldiverStratagemDefinition> { [HelldiverStratagemType.OrbitalPrecisionStrike] = new HelldiverStratagemDefinition(HelldiverStratagemType.OrbitalPrecisionStrike, "Orbital Precision Strike", new HelldiverInputDirection[3] { HelldiverInputDirection.Right, HelldiverInputDirection.Right, HelldiverInputDirection.Up }, 20f, 1.5f, 0, new Color(0.48f, 0.86f, 1f, 1f)), [HelldiverStratagemType.OrbitalGatlingBarrage] = new HelldiverStratagemDefinition(HelldiverStratagemType.OrbitalGatlingBarrage, "Orbital Gatling Barrage", new HelldiverInputDirection[5] { HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Left, HelldiverInputDirection.Up, HelldiverInputDirection.Up }, 25f, 1f, 0, new Color(1f, 0.74f, 0.22f, 1f)), [HelldiverStratagemType.OrbitalGasStrike] = new HelldiverStratagemDefinition(HelldiverStratagemType.OrbitalGasStrike, "Orbital Gas Strike", new HelldiverInputDirection[4] { HelldiverInputDirection.Right, HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Right }, 40f, 1f, 0, new Color(0.56f, 0.93f, 0.46f, 1f)), [HelldiverStratagemType.OrbitalEmsStrike] = new HelldiverStratagemDefinition(HelldiverStratagemType.OrbitalEmsStrike, "Orbital EMS Strike", new HelldiverInputDirection[4] { HelldiverInputDirection.Right, HelldiverInputDirection.Right, HelldiverInputDirection.Left, HelldiverInputDirection.Down }, 35f, 1f, 0, new Color(0.47f, 0.87f, 1f, 1f)), [HelldiverStratagemType.Orbital120mmHEBarrage] = new HelldiverStratagemDefinition(HelldiverStratagemType.Orbital120mmHEBarrage, "Orbital 120mm HE Barrage", new HelldiverInputDirection[6] { HelldiverInputDirection.Right, HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Left, HelldiverInputDirection.Right, HelldiverInputDirection.Down }, 30f, 1.5f, 0, new Color(1f, 0.66f, 0.28f, 1f)), [HelldiverStratagemType.Orbital380mmHEBarrage] = new HelldiverStratagemDefinition(HelldiverStratagemType.Orbital380mmHEBarrage, "Orbital 380mm HE Barrage", new HelldiverInputDirection[7] { HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Up, HelldiverInputDirection.Left, HelldiverInputDirection.Down, HelldiverInputDirection.Down }, 35f, 2f, 0, new Color(1f, 0.54f, 0.22f, 1f)), [HelldiverStratagemType.Eagle500kgBomb] = new HelldiverStratagemDefinition(HelldiverStratagemType.Eagle500kgBomb, "Eagle 500kg Bomb", new HelldiverInputDirection[5] { HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Down, HelldiverInputDirection.Down }, 8f, 1.5f, 1, new Color(1f, 0.5f, 0.25f, 1f)), [HelldiverStratagemType.EagleStrafingRun] = new HelldiverStratagemDefinition(HelldiverStratagemType.EagleStrafingRun, "Eagle Strafing Run", new HelldiverInputDirection[3] { HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Right }, 8f, 1.5f, 3, new Color(1f, 0.78f, 0.32f, 1f)), [HelldiverStratagemType.EagleAirstrike] = new HelldiverStratagemDefinition(HelldiverStratagemType.EagleAirstrike, "Eagle Airstrike", new HelldiverInputDirection[4] { HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Right }, 8f, 1.5f, 3, new Color(1f, 0.66f, 0.32f, 1f)), [HelldiverStratagemType.EagleClusterBomb] = new HelldiverStratagemDefinition(HelldiverStratagemType.EagleClusterBomb, "Eagle Cluster Bomb", new HelldiverInputDirection[5] { HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Down, HelldiverInputDirection.Right }, 8f, 0.8f, 3, new Color(1f, 0.5f, 0.25f, 1f)), [HelldiverStratagemType.EagleRearm] = new HelldiverStratagemDefinition(HelldiverStratagemType.EagleRearm, "Eagle Rearm", new HelldiverInputDirection[5] { HelldiverInputDirection.Up, HelldiverInputDirection.Up, HelldiverInputDirection.Left, HelldiverInputDirection.Up, HelldiverInputDirection.Right }, 25f, 0.3f, 0, new Color(1f, 0.5f, 0.25f, 1f)), [HelldiverStratagemType.MachineGunSentry] = new HelldiverStratagemDefinition(HelldiverStratagemType.MachineGunSentry, "A/MG-43 Machine Gun Sentry", new HelldiverInputDirection[5] { HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Right, HelldiverInputDirection.Up }, 40f, 2f, 0, new Color(1f, 0.5f, 0.25f, 1f)), [HelldiverStratagemType.RocketSentry] = new HelldiverStratagemDefinition(HelldiverStratagemType.RocketSentry, "A/MLS-4X Rocket Sentry", new HelldiverInputDirection[5] { HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Right, HelldiverInputDirection.Left }, 50f, 2f, 0, new Color(1f, 0.58f, 0.2f, 1f)), [HelldiverStratagemType.AutocannonSentry] = new HelldiverStratagemDefinition(HelldiverStratagemType.AutocannonSentry, "A/AC-8 Autocannon Sentry", new HelldiverInputDirection[6] { HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Up, HelldiverInputDirection.Left, HelldiverInputDirection.Up }, 55f, 2f, 0, new Color(1f, 0.66f, 0.28f, 1f)), [HelldiverStratagemType.GatlingSentry] = new HelldiverStratagemDefinition(HelldiverStratagemType.GatlingSentry, "A/G-16 Gatling Sentry", new HelldiverInputDirection[4] { HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Left }, 50f, 2f, 0, new Color(1f, 0.5f, 0.25f, 1f)), [HelldiverStratagemType.LaserSentry] = new HelldiverStratagemDefinition(HelldiverStratagemType.LaserSentry, "A/LAS-98 Laser Sentry", new HelldiverInputDirection[6] { HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Right, HelldiverInputDirection.Down, HelldiverInputDirection.Up, HelldiverInputDirection.Right }, 60f, 2f, 0, new Color(1f, 0.1f, 0.08f, 1f)) }; private const string UpArrowColor = "#FFD700"; private const string RightArrowColor = "#4FC3F7"; private const string DownArrowColor = "#81C784"; private const string LeftArrowColor = "#E57373"; internal static CardInfo? EntryCardInfo { get; set; } internal static IEnumerable<HelldiverStratagemType> AllStratagems => Definitions.Keys; internal static HelldiverStratagemDefinition GetDefinition(HelldiverStratagemType type) { return Definitions[type]; } internal static bool IsOrbitalStratagem(HelldiverStratagemType type) { if ((uint)(type - 1) <= 5u) { return true; } return false; } internal static bool IsEagleStratagem(HelldiverStratagemType type) { if ((uint)(type - 7) <= 4u) { return true; } return false; } internal static bool IsLimitedUseEagleStratagem(HelldiverStratagemType type) { if ((uint)(type - 7) <= 3u) { return true; } return false; } internal static bool IsSentryStratagem(HelldiverStratagemType type) { if ((uint)(type - 12) <= 4u) { return true; } return false; } internal static string FormatCode(IReadOnlyList<HelldiverInputDirection> code) { if (code.Count <= 0) { return "-"; } string[] array = new string[code.Count]; for (int i = 0; i < code.Count; i++) { string[] array2 = array; int num = i; array2[num] = code[i] switch { HelldiverInputDirection.Up => "<color=#FFD700><b>^</b></color>", HelldiverInputDirection.Right => "<color=#4FC3F7><b>></b></color>", HelldiverInputDirection.Down => "<color=#81C784><b>v</b></color>", HelldiverInputDirection.Left => "<color=#E57373><b><</b></color>", _ => "<color=#FF6B6B><b>?</b></color>", }; } return string.Join("-", array); } internal static bool IsPrefixOfAnyOwned(IReadOnlyList<HelldiverInputDirection> buffer, IEnumerable<HelldiverStratagemType> ownedTypes) { foreach (HelldiverStratagemType ownedType in ownedTypes) { IReadOnlyList<HelldiverInputDirection> code = GetDefinition(ownedType).Code; if (buffer.Count > code.Count) { continue; } bool flag = true; for (int i = 0; i < buffer.Count; i++) { if (buffer[i] != code[i]) { flag = false; break; } } if (flag) { return true; } } return false; } internal static bool TryResolveExactMatch(IReadOnlyList<HelldiverInputDirection> buffer, IEnumerable<HelldiverStratagemType> ownedTypes, out HelldiverStratagemType type) { foreach (HelldiverStratagemType ownedType in ownedTypes) { IReadOnlyList<HelldiverInputDirection> code = GetDefinition(ownedType).Code; if (buffer.Count != code.Count) { continue; } bool flag = true; for (int i = 0; i < buffer.Count; i++) { if (buffer[i] != code[i]) { flag = false; break; } } if (flag) { type = ownedType; return true; } } type = HelldiverStratagemType.None; return false; } } internal enum HelldiverStratagemType { None, OrbitalPrecisionStrike, OrbitalGatlingBarrage, OrbitalGasStrike, OrbitalEmsStrike, Orbital120mmHEBarrage, Orbital380mmHEBarrage, Eagle500kgBomb, EagleStrafingRun, EagleAirstrike, EagleClusterBomb, EagleRearm, MachineGunSentry, RocketSentry, AutocannonSentry, GatlingSentry, LaserSentry } internal enum HelldiverInputDirection { Up, Right, Down, Left } internal sealed class HelldiverStratagemDefinition { internal HelldiverStratagemType Type { get; } internal string DisplayName { get; } internal IReadOnlyList<HelldiverInputDirection> Code { get; } internal float CooldownSeconds { get; } internal float CallInTimeSeconds { get; } internal int UsesPerRound { get; } internal Color Color { get; } internal bool HasLimitedUses => UsesPerRound > 0; internal string CodeText => HelldiverClassRegistry.FormatCode(Code); internal HelldiverStratagemDefinition(HelldiverStratagemType type, string displayName, IReadOnlyList<HelldiverInputDirection> code, float cooldownSeconds, float callInTimeSeconds, int usesPerRound, Color color) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Type = type; DisplayName = displayName; Code = code; CooldownSeconds = cooldownSeconds; CallInTimeSeconds = callInTimeSeconds; UsesPerRound = usesPerRound; Color = color; } } internal static class HelldiverGameLifecycleHooks { internal static void Register() { GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)OnGameStart); GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)OnPointEnd); GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)OnRoundEnd); GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)OnPickStart); } private static IEnumerator OnGameStart(IGameModeHandler handler) { HelldiverPrecisionGunPool.Invalidate(); HelldiverGatlingGunPool.Invalidate(); HelldiverBombGunPool.Invalidate(); ResetAllPlayerEffects(roundOver: true); yield break; } private static IEnumerator OnPointEnd(IGameModeHandler handler) { ResetAllPlayerEffects(roundOver: false); yield break; } private static IEnumerator OnRoundEnd(IGameModeHandler handler) { ResetAllPlayerEffects(roundOver: true); yield break; } private static IEnumerator OnPickStart(IGameModeHandler handler) { ResetAllPlayerEffects(roundOver: true); yield break; } private static void ResetAllPlayerEffects(bool roundOver) { List<Player> list = PlayerManager.instance?.players; if (list != null) { foreach (Player item in list) { if (item != null) { HelldiverRuntime component = ((Component)item).gameObject.GetComponent<HelldiverRuntime>(); if (roundOver) { component?.HandleRoundOver(); } else { component?.HandlePointOver(); } } } } HelldiverWorldCleanup.CleanupPointObjects(); } } internal static class HolySmiteClassRegistry { internal const string ClassName = "Holy Smite"; internal static CardInfo? EntryCardInfo { get; set; } } internal static class HolySmiteGameLifecycleHooks { internal static void Register() { GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)ResetTemporaryEffects); GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)ResetTemporaryEffects); GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)ResetTemporaryEffects); } private static IEnumerator ResetTemporaryEffects(IGameModeHandler handler) { HolySmiteShrinkEffect.ResetAll(); yield break; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.dolyfin.rounds.dolymods", "Doly's Cards", "1.5.0")] [BepInProcess("Rounds.exe")] public sealed class RoundsDolyModsPlugin : BaseUnityPlugin { internal const string ModId = "com.dolyfin.rounds.dolymods"; internal const string ModName = "Doly's Cards"; internal const string ModInitials = "DOLY"; internal const string Version = "1.5.0"; private static readonly HashSet<string> HelldiverCardNames = new HashSet<string> { "Helldiver", "Democracy Protects", "Reinforcements", "Orbital Gatling Barrage", "Orbital EMS Strike", "Orbital 120mm HE Barrage", "Orbital 380mm HE Barrage", "Orbital Gas Strike", "Expanded Weapons Bay", "Targeting Software Upgrade", "Eagle 500kg Bomb", "Eagle Strafing Run", "Eagle Airstrike", "Eagle Cluster Bomb", "Eagle Rearm", "A/MG-43 Machine Gun Sentry", "A/MLS-4X Rocket Sentry", "A/AC-8 Autocannon Sentry", "A/G-16 Gatling Sentry", "A/LAS-98 Laser Sentry", "I NEED STIMS" }; internal static RoundsDolyModsPlugin? Instance { get; private set; } private void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Instance = this; new Harmony("com.dolyfin.rounds.dolymods").PatchAll(); } private void Start() { DolyModSettings.Initialize(((BaseUnityPlugin)this).Config); Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)IsCardAllowedForMatchConditions); ToggleCardsCategoriesManager.instance.RegisterCategories("DOLY"); DolyTabInfoIntegration.Register(); HelldiverGameLifecycleHooks.Register(); HolySmiteGameLifecycleHooks.Register(); CustomCard.BuildCard<HealthCharmCard>(); CustomCard.BuildCard<DamageCharmCard>(); CustomCard.BuildCard<GreaterHealthCharmCard>(); CustomCard.BuildCard<GreaterDamageCharmCard>(); CustomCard.BuildCard<SuperiorHealthCharmCard>(); CustomCard.BuildCard<SuperiorDamageCharmCard>(); CustomCard.BuildCard<SupremeHealthCharmCard>(); CustomCard.BuildCard<SupremeDamageCharmCard>(); CustomCard.BuildCard<MegaCard>(); CustomCard.BuildCard<GiantSlayerCard>(); CustomCard.BuildCard<BladeOfTheRuinedKingCard>(); CustomCard.BuildCard<GrievousWoundsCard>(); CustomCard.BuildCard<SuppressorCard>(); CustomCard.BuildCard<Makeshift2xScopeCard>(); CustomCard.BuildCard<Wobbly6xScopeCard>(); CustomCard.BuildCard<DuctTaped12xScopeCard>(); CustomCard.BuildCard<ScopiestScopeCard>(); CustomCard.BuildCard<AtchissonAa12Card>(); CustomCard.BuildCard<FriendliestOfFiresCard>(); CustomCard.BuildCard<ExtendedMagazineCard>(); CustomCard.BuildCard<DrumMagCard>(); CustomCard.BuildCard<CompressedAirCard>(); CustomCard.BuildCard<HydrogenBombCard>(); CustomCard.BuildCard<AtomicCard>(); CustomCard.BuildCard<DropMagCard>(); CustomCard.BuildCard<FlappyBirdCard>(); CustomCard.BuildCard<FullSteamAheadCard>(); CustomCard.BuildCard<TrapperCard>(); CustomCard.BuildCard<CoughingBabyCard>(); CustomCard.BuildCard<MoreBulletForYourBulletCard>(); CustomCard.BuildCard<BeepboopCard>(); CustomCard.BuildCard<BiodegradableBulletsCard>(); CustomCard.BuildCard<GamblecoreCard>((Action<CardInfo>)delegate(CardInfo cardInfo) { GamblecoreRegistry.GamblecoreCardInfo = cardInfo; }); CustomCard.BuildCard<AwDangItCard>((Action<CardInfo>)delegate(CardInfo cardInfo) { GamblecoreRegistry.AwDangItCardInfo = cardInfo; RegisterHiddenCard(cardInfo); }); CustomCard.BuildCard<ICantStopWinningCard>((Action<CardInfo>)delegate(CardInfo cardInfo) { GamblecoreRegistry.ICantStopWinningCardInfo = cardInfo; RegisterHiddenCard(cardInfo); }); CustomCard.BuildCard<HeresyCard>(); CustomCard.BuildCard<TackShooterCard>(); CustomCard.BuildCard<FasterShootingCard>(); CustomCard.BuildCard<EvenFasterShootingCard>(); CustomCard.BuildCard<HotShotsCard>(); CustomCard.BuildCard<LongRangeTacksCard>(); CustomCard.BuildCard<SuperRangeTacksCard>(); CustomCard.BuildCard<MoreTacksCard>(); CustomCard.BuildCard<EvenMoreTacksCard>(); CustomCard.BuildCard<TackSprayerCard>(); CustomCard.BuildCard<OverdriveCard>(); CustomCard.BuildCard<TheTackZoneCard>(); CustomCard.BuildCard<RingOfFireCard>(); CustomCard.BuildCard<HolySmiteCard>(); CustomCard.BuildCard<GreaterSmiteCard>(); CustomCard.BuildCard<ThunderingSmiteCard>(); CustomCard.BuildCard<MightySmiteCard>(); CustomCard.BuildCard<QuakingSmiteCard>(); CustomCard.BuildCard<GodlySmiteCard>(); CustomCard.BuildCard<StunningSmiteCard>(); CustomCard.BuildCard<DivineJudgmentCard>(); CustomCard.BuildCard<DiscoSmiteCard>(); CustomCard.BuildCard<RevelationSmiteCard>(); CustomCard.BuildCard<FlamingSmiteCard>(); CustomCard.BuildCard<VampiricSmiteCard>(); CustomCard.BuildCard<ZealotsBargainCard>(); CustomCard.BuildCard<ConfessionCard>(); CustomCard.BuildCard<SpeakOfTheDevilCard>(); CustomCard.BuildCard<DevilsMarkCard>(); CustomCard.BuildCard<AegisSmiteCard>(); CustomCard.BuildCard<RejuvenatingSmiteCard>(); CustomCard.BuildCard<ShrinkRayCard>(); CustomCard.BuildCard<OrbitalLaserCard>(); CustomCard.BuildCard<HelldiverCard>(); CustomCard.BuildCard<DemocracyProtectsCard>(); CustomCard.BuildCard<ReinforcementsCard>(); CustomCard.BuildCard<OrbitalGatlingBarrageCard>(); CustomCard.BuildCard<OrbitalEmsStrikeCard>(); CustomCard.BuildCard<Orbital120mmHEBarrageCard>(); CustomCard.BuildCard<Orbital380mmHEBarrageCard>(); CustomCard.BuildCard<OrbitalGasStrikeCard>(); CustomCard.BuildCard<ExpandedWeaponsBayCard>(); CustomCard.BuildCard<TargetingSoftwareUpgradeCard>(); CustomCard.BuildCard<Eagle500kgBombCard>(); CustomCard.BuildCard<EagleStrafingRunCard>(); CustomCard.BuildCard<EagleAirstrikeCard>(); CustomCard.BuildCard<EagleClusterBombCard>(); CustomCard.BuildCard<EagleRearmCard>(); CustomCard.BuildCard<MachineGunSentryCard>(); CustomCard.BuildCard<RocketSentryCard>(); CustomCard.BuildCard<AutocannonSentryCard>(); CustomCard.BuildCard<GatlingSentryCard>(); CustomCard.BuildCard<LaserSentryCard>(); CustomCard.BuildCard<HighQualityLubricantCard>(); CustomCard.BuildCard<ShockAbsorptionGelCard>(); CustomCard.BuildCard<AdvancedConstructionCard>(); CustomCard.BuildCard<StimsCard>(); } private static bool IsCardAllowedForMatchConditions(Player player, CardInfo card) { if (card == null) { return true; } if (HelldiverCardNames.Contains(card.cardName) && PlayerHasCard(player, card.cardName)) { return false; } if (card.cardName == "Heresy") { CardInfo holySmiteEntry = HolySmiteClassRegistry.EntryCardInfo; if (holySmiteEntry == null) { return false; } return EnemyHasCard(player, (CardInfo other) => other.cardName == holySmiteEntry.cardName); } if (card.cardName == "Coughing Baby") { return EnemyHasCard(player, (CardInfo other) => other.cardName == "Hydrogen Bomb"); } if (card.cardName == "Suppressor") { return HasEffectiveFireDelayBelow(player, 0.15f); } if (card.cardName == "Aw Dang It" || card.cardName == "I Can't Stop Winning") { return false; } if (card.cardName == "Expanded Weapons Bay") { if (TryGetHelldiverEffect(player, out HelldiverEffect effect) && effect.HasAnyOwnedLimitedUseEagleStratagem()) { return !PlayerHasCard(player, "Expanded Weapons Bay"); } return false; } if (card.cardName == "Targeting Software Upgrade") { if (TryGetHelldiverEffect(player, out HelldiverEffect effect2) && effect2.HasAnyOwnedOrbitalStratagem()) { return !PlayerHasCard(player, "Targeting Software Upgrade"); } return false; } if (card.cardName == "Eagle Rearm") { if (TryGetHelldiverEffect(player, out HelldiverEffect effect3) && effect3.HasAnyOwnedLimitedUseEagleStratagem()) { return !PlayerHasCard(player, "Eagle Rearm"); } return false; } if (card.cardName == "High-Quality Lubricant") { if (TryGetHelldiverEffect(player, out HelldiverEffect effect4)) { return effect4.HasAnyOwnedSentryStratagem(); } return false; } if (card.cardName == "Shock Absorption Gel") { if (TryGetHelldiverEffect(player, out HelldiverEffect effect5)) { return effect5.HasAnyOwnedSentryStratagem(); } return false; } if (card.cardName == "Advanced Construction") { if (TryGetHelldiverEffect(player, out HelldiverEffect effect6)) { return effect6.HasAnyOwnedSentryStratagem(); } return false; } return true; } private static bool HasEffectiveFireDelayBelow(Player player, float maximumDelaySeconds) { Gun val = player?.data?.weaponHandler?.gun; float valueOrDefault = (player?.data?.stats?.attackSpeedMultiplier).GetValueOrDefault(1f); if (val == null) { return false; } valueOrDefault = ((valueOrDefault <= 0f) ? 0.001f : valueOrDefault); return val.attackSpeed / valueOrDefault < maximumDelaySeconds; } private static bool EnemyHasCard(Player player, Predicate<CardInfo> match) { List<Player> list = PlayerManager.instance?.players; if (player == null || list == null) { return false; } foreach (Player item in list) { if (item == null || item.playerID == player.playerID || item.teamID == player.teamID) { continue; } List<CardInfo> list2 = item.data?.currentCards; if (list2 == null) { continue; } for (int i = 0; i < list2.Count; i++) { CardInfo val = list2[i]; if (val != null && match(val)) { return true; } } } return false; } private static bool PlayerHasCard(Player player, string cardName) { List<CardInfo> list = player?.data?.currentCards; if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { if (list[i]?.cardName == cardName) { return true; } } return false; } private static bool TryGetHelldiverEffect(Player player, out HelldiverEffect effect) { effect = ((Component)player).gameObject.GetComponent<HelldiverEffect>(); return effect != null; } private static void RegisterHiddenCard(CardInfo cardInfo) { if (cardInfo != null) { Cards.instance.AddHiddenCard(cardInfo); } } } internal static class TackShooterClassRegistry { internal const string ClassName = "Tack Shooter"; internal const float BaseTackSpeed = 32f; internal const float BaseTackRangeMultiplier = 1f; internal const float BaseTackDamageMultiplier = 0.5f; internal const float MinEffectiveFireDelay = 0.033f; internal static CardInfo? EntryCardInfo { get; set; } } } namespace RoundsDolyMods.Visuals { internal sealed class ClassCornerBadge : MonoBehaviour { private const string EdgePartName = "EdgePart (1)"; private const string BadgeObjectName = "DOLY_ClassCornerBadge"; private void Start() { //IL_0050: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) RectTransform val = ((IEnumerable<RectTransform>)((Component)this).GetComponentsInChildren<RectTransform>(true)).FirstOrDefault((Func<RectTransform, bool>)((RectTransform rect) => ((Object)((Component)rect).gameObject).name == "EdgePart (1)")); if (val != null && !HasExistingCornerText((Component)(object)val)) { GameObject val2 = new GameObject("DOLY_ClassCornerBadge", new Type[1] { typeof(TextMeshProUGUI) }); val2.transform.SetParent(((Component)val).transform, false); val2.transform.localEulerAngles = new Vector3(0f, 0f, 135f); val2.transform.localScale = Vector3.one; val2.transform.localPosition = new Vector3(-50f, -50f, 0f); TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = "Class"; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).alignment = (TextAlignmentOptions)1028; ((TMP_Text)component).alpha = 0.1f; ((TMP_Text)component).fontSize = 50f; } } private static bool HasExistingCornerText(Component edgePart) { return ((IEnumerable<TMP_Text>)edgePart.GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text text) => !string.IsNullOrWhiteSpace(text.text))) != null; } } } namespace RoundsDolyMods.Patches { [HarmonyPatch(typeof(Block), "TryBlock")] internal static class BlockTryBlockPatches { private static bool Prefix(Block __instance) { HelldiverEffect componentInParent = ((Component)__instance).GetComponentInParent<HelldiverEffect>(); if (componentInParent == null) { return true; } return !componentInParent.TryHijackBlock(); } } [HarmonyPatch(typeof(Block), "TryBlockMe")] internal static class BlockTryBlockMePatches { private static bool Prefix(Block __instance, GameObject toBlock, Vector3 forward, Vector3 hitPos, ref bool __result) { //IL_000f: 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) if (__instance.sinceBlock < 0.3f && BlockPatches.TryHandleSentryBlock(__instance, toBlock, forward, hitPos, playParticle: true)) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Block), "DoBlock")] internal static class BlockDoBlockPatches { private static bool Prefix(Block __instance, GameObject toBlock, Vector3 forward, Vector3 hitPos) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return !BlockPatches.TryHandleSentryBlock(__instance, toBlock, forward, hitPos, playParticle: true); } } [HarmonyPatch(typeof(Block), "blocked")] internal static class BlockPatches { private static bool Prefix(Block __instance, GameObject projectile, Vector3 forward, Vector3 hitPos) { //IL_000f: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (projectile == null) { return true; } if (projectile.GetComponentInParent<HelldiverSentryProjectileController>() != null && TryHandleSentryBlock(__instance, projectile, forward, hitPos, playParticle: false)) { return false; } HelldiverPrecisionProjectileController componentInParent = projectile.GetComponentInParent<HelldiverPrecisionProjectileController>(); if (componentInParent != null) { Player componentInParent2 = ((Component)__instance).GetComponentInParent<Player>(); if (componentInParent2 != null) { componentInParent.HandleBlocked(componentInParent2, Vector2.op_Implicit(hitPos), Vector2.op_Implicit(forward)); } } DisintegrateOnBlockProjectileEffect componentInParent3 = projectile.GetComponentInParent<DisintegrateOnBlockProjectileEffect>(); if (componentInParent3 == null) { return true; } ProjectileHit component = projectile.GetComponent<ProjectileHit>(); if (component != null) { component.RemoveOwnPlayerFromPlayersHit(); HealthHandler componentInParent4 = ((Component)__instance).GetComponentInParent<HealthHandler>(); if (componentInParent4 != null) { component.AddPlayerToHeld(componentInParent4); } } PlayBlockFeedback(__instance, forward, hitPos); RunBlockProjectileAction(__instance, projectile, forward, hitPos); componentInParent3.TryDisintegrate(); return false; } private static void Postfix(Block __instance, GameObject projectile) { if (projectile == null || projectile.GetComponentInParent<DisintegrateOnBlockProjectileEffect>() != null) { return; } HolySmiteProjectileTracker componentInParent = projectile.GetComponentInParent<HolySmiteProjectileTracker>(); if (componentInParent != null) { Player componentInParent2 = ((Component)__instance).GetComponentInParent<Player>(); if (componentInParent2 != null) { componentInParent.HandleBlocked(componentInParent2); } } } internal static bool TryHandleSentryBlock(Block block, GameObject projectile, Vector3 forward, Vector3 hitPos, bool playParticle) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (projectile == null) { return false; } HelldiverSentryProjectileController componentInParent = projectile.GetComponentInParent<HelldiverSentryProjectileController>(); if (componentInParent == null) { return false; } Player componentInParent2 = ((Component)block).GetComponentInParent<Player>(); if (componentInParent2 == null) { return false; } SoundManager.Instance.Play(block.soundBlockBlocked, ((Component)block).transform); componentInParent.HandleBlocked(componentInParent2, Vector2.op_Implicit(hitPos), Vector2.op_Implicit(forward)); PlayBlockFeedback(block, forward, hitPos); RunBlockProjectileAction(block, projectile, forward, hitPos); if (playParticle) { block.particle.Play(); } return true; } private static void PlayBlockFeedback(Block block, Vector3 forward, Vector3 hitPos) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) ((Component)block.blockedPart).transform.position = hitPos + ((Component)block).transform.forward * 5f; ((Component)block.blockedPart).transform.rotation = Quaternion.LookRotation(-forward * 1.5f); GamefeelManager.GameFeel(Vector2.op_Implicit(forward)); block.blockedPart.Play(); } private static void RunBlockProjectileAction(Block block, GameObject projectile, Vector3 forward, Vector3 hitPos) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) SpawnedAttack componentInParent = projectile.GetComponentInParent<SpawnedAttack>(); if ((!Object.op_Implicit((Object)(object)componentInParent) || !((Object)(object)((Component)componentInParent.spawner).gameObject == (Object)(object)((Component)((Component)block).transform.root).gameObject)) && block.BlockProjectileAction != null) { block.BlockProjectileAction(projectile, forward, hitPos); } } } [HarmonyPatch(typeof(GeneralInput), "Update")] internal static class GeneralInputPatches { [HarmonyPostfix] private static void SuppressMovementWhileEnteringStratagem(GeneralInput __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) PlayerActions playerActions = ((Component)__instance).GetComponentInParent<CharacterData>()?.playerActions; if (((Component)__instance).GetComponentInParent<HelldiverEffect>() != null && DolyModSettings.IsHelldiverInputModifierHeld(playerActions)) { __instance.direction = Vector3.zero; } } } [HarmonyPatch(typeof(HealthHandler), "Heal")] internal static class HealthHandlerPatches { private static bool Prefix(HealthHandler __instance) { HealBlockDebuff healBlockDebuff = ((Component)__instance).GetComponent<HealBlockDebuff>() ?? ((Component)__instance).GetComponentInParent<HealBlockDebuff>(); if (healBlockDebuff != null) { return !healBlockDebuff.IsActive; } return true; } } [HarmonyPatch(typeof(HealthHandler), "TakeDamage", new Type[] { typeof(Vector2), typeof(Vector2), typeof(GameObject), typeof(Player), typeof(bool), typeof(bool) })] [HarmonyPriority(300)] internal static class SelfDamagePatches { private static void Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer) { //IL_0038: 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_0048: Unknown result type (might be due to invalid IL or missing references) if (damagingPlayer == null) { return; } Player val = ((Component)__instance).GetComponent<Player>() ?? ((Component)__instance).GetComponentInParent<Player>(); if (val != null && !((Object)(object)val != (Object)(object)damagingPlayer)) { SelfDamageReductionEffect component = ((Component)val).GetComponent<SelfDamageReductionEffect>(); if (component != null && component.Stacks > 0) { damage *= component.GetMultiplier(); } } } } [HarmonyPatch(typeof(HealthHandler), "TakeDamage", new Type[] { typeof(Vector2), typeof(Vector2), typeof(GameObject), typeof(Player), typeof(bool), typeof(bool) })] internal static class GiantSlayerDamagePatches { private static void Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (damagingPlayer != null) { CharacterData val = ((Component)__instance).GetComponent<CharacterData>() ?? ((Component)__instance).GetComponentInParent<CharacterData>(); Player val2 = ((Component)__instance).GetComponent<Player>() ?? ((Component)__instance).GetComponentInParent<Player>(); GiantSlayerEffect component = ((Component)damagingPlayer).gameObject.GetComponent<GiantSlayerEffect>(); CharacterData data = damagingPlayer.data; if (val != null && val2 != null && component != null && data != null && component.Stacks > 0 && val2.playerID != damagingPlayer.playerID && val2.teamID != damagingPlayer.teamID && !(val.maxHealth <= data.maxHealth * 2f)) { damage *= 1f + (float)component.Stacks * 2f; } } } } [HarmonyPatch(typeof(HealthHandler), "TakeDamage", new Type[] { typeof(Vector2), typeof(Vector2), typeof(GameObject), typeof(Player), typeof(bool), typeof(bool) })] internal static class GrievousWoundsDamagePatches { private sealed class GrievousHitState { internal CharacterData? TargetData; internal int StackCount; internal float HealthBeforeHit; } private static void Prefix(HealthHandler __instance, Player damagingPlayer, out GrievousHitState? __state) { __state = null; if (damagingPlayer != null) { GrievousWoundsEffect component = ((Component)damagingPlayer).gameObject.GetComponent<GrievousWoundsEffect>(); CharacterData val = ((Component)__instance).GetComponent<CharacterData>() ?? ((Component)__instance).GetComponentInParent<CharacterData>(); if (component != null && component.Stacks > 0 && val != null) { __state = new GrievousHitState { TargetData = val, StackCount = component.Stacks, HealthBeforeHit = val.health }; } } } private static void Postfix(HealthHandler __instance, GrievousHitState? __state) { if (__state?.TargetData != null && (__state.TargetData.dead || !(__state.TargetData.health >= __state.HealthBeforeHit - 0.0001f))) { HealBlockDebuff healBlockDebuff = ((Component)__instance).GetComponent<HealBlockDebuff>() ?? ((Component)__instance).GetComponentInParent<HealBlockDebuff>(); if (healBlockDebuff == null) { healBlockDebuff = ((Component)__state.TargetData).gameObject.GetOrAddComponent<HealBlockDebuff>(); } healBlockDebuff.Apply(4f * (float)__state.StackCount); } } } [HarmonyPatch(typeof(HealthHandler), "TakeDamage", new Type[] { typeof(Vector2), typeof(Vector2), typeof(GameObject), typeof(Player), typeof(bool), typeof(bool) })] [HarmonyPriority(400)] internal static class HolySmiteAegisPatches { private static void Prefix(HealthHandler __instance, ref Vector2 damage) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) Player obj = ((Component)__instance).GetComponent<Player>() ?? ((Component)__instance).GetComponentInParent<Player>(); HolySmiteEffect holySmiteEffect = ((obj != null) ? ((Component)obj).gameObject.GetComponent<HolySmiteEffect>() : null); if (holySmiteEffect != null && holySmiteEffect.EntryCount > 0 && !holySmiteEffect.IsSmiteReady && !Mathf.Approximately(holySmiteEffect.DamageTakenMultiplierWhenNotReady, 1f)) { damage *= holySmiteEffect.DamageTakenMultiplierWhenNotReady; } } } [HarmonyPatch(typeof(HealthHandler), "TakeDamage", new Type[] { typeof(Vector2), typeof(Vector2), typeof(GameObject), typeof(Player), typeof(bool), typeof(bool) })] [HarmonyPriority(600)] internal static class HolySmiteMarkPatches { private sealed class MarkHitState { internal HolySmiteMarkEffect? MarkEffect; internal int DamagingPlayerId; internal float HealthBeforeHit; } private static void Prefix(HealthHandler __instance, ref Vector2 damage, Player damagingPlayer, out MarkHitState? __state) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) __state = null; if (damagingPlayer == null) { return; } Player val = ((Component)__instance).GetComponent<Player>() ?? ((Component)__instance).GetComponentInParent<Player>(); CharacterData val2 = ((Component)__instance).GetComponent<CharacterData>() ?? ((Component)__instance).GetComponentInParent<CharacterData>(); if (val != null && val2 != null) { HolySmiteMarkEffect component = ((Component)val).gameObject.GetComponent<HolySmiteMarkEffect>(); if (component != null && component.TryGetDamageMultiplier(damagingPlayer.playerID, out var damageMultiplier)) { damage *= damageMultiplier; __state = new MarkHitState { MarkEffect = component, DamagingPlayerId = damagingPlayer.playerID, HealthBeforeHit = val2.health }; } } } private static void Postfix(HealthHandler __instance, MarkHitState? __state) { if (__state?.MarkEffect != null) { CharacterData val = ((Component)__instance).GetComponent<CharacterData>() ?? ((Component)__instance).GetComponentInParent<CharacterData>(); if (val == null) { __state.MarkEffect.ConsumeMark(__state.DamagingPlayerId); } else if (val.dead || val.health < __state.HealthBeforeHit - 0.0001f) { __state.MarkEffect.ConsumeMark(__state.DamagingPlayerId); } } } } [HarmonyPatch(typeof(HealthHandler), "DoDamage", new Type[] { typeof(Vector2), typeof(Vector2), typeof(Color), typeof(GameObject), typeof(Player), typeof(bool), typeof(bool), typeof(bool) })] internal static class DemocracyProtectsPatches { private static bool Prefix(HealthHandler __instance, Vector2 damage, ref bool lethal, bool healthRemoval) { if (healthRemoval) { return true; } DemocracyProtectsEffect democracyProtectsEffect = ((Component)__instance).GetComponent<DemocracyProtectsEffect>() ?? ((Component)__instance).GetComponentInParent<DemocracyProtectsEffect>(); if (democracyProtectsEffect != null && democracyProtectsEffect.Stacks > 0 && democracyProtectsEffect.IsImmune) { lethal = false; return false; } if (!lethal) { return true; } CharacterData val = ((Component)__instance).GetComponent<CharacterData>() ?? ((Component)__instance).GetComponentInParent<CharacterData>(); if (val == null) { return true; } if (val.health - ((Vector2)(ref damage)).magnitude >= 0f) { return true; } if (democracyProtectsEffect == null || democracyProtectsEffect.Stacks <= 0) { return true; } if (!PhotonNetwork.OfflineMode && val.view != null && !val.view.IsMine) { val.health = Mathf.Clamp(val.health - ((Vector2)(ref damage)).magnitude, 1f, val.maxHealth); lethal = false; return false; } if (democracyProtectsEffect.ShouldPreventLethalDamage()) { lethal = false; } return true; } } [HarmonyPatch(typeof(Player), "Start")] internal static class HelldiverPlayerRuntimePatches { [HarmonyPostfix] private static void EnsureRuntime(Player __instance) { if (__instance != null) { HelldiverRuntime.GetOrAdd(__instance); } } } [HarmonyPatch(typeof(ProjectileCollision), "HitSurface")] internal static class ProjectileCollisionPatches { private static bool Prefix(ProjectileCollision __instance, GameObject projectile, ref HasToStop __result) { if (!TrapperProjectileCollisionHelper.ShouldIgnoreTrapperProjectileHit(((Component)__instance).gameObject, projectile)) { return true; } __result = (HasToStop)1; return false; } } [HarmonyPatch(typeof(ProjectileHit), "Hit")] internal static class ProjectileHitPatches { [HarmonyPrefix] private static bool HandleProjectileHit(ProjectileHit __instance, HitInfo hit, bool forceCall) { HelldiverHellpodDamageable.TryHandleProjectileHit(__instance, hit, forceCall); HelldiverSentryDamageable.TryHandleProjectileHit(__instance, hit, forceCall); GameObject gameObject = ((Component)__instance).gameObject; Collider2D collider = hit.collider; object obj = ((collider != null) ? ((Component)collider).gameObject : null); if (obj == null) { Transform transform = hit.transform; obj = ((transform != null) ? ((Component)transform).gameObject : null); } return !TrapperProjectileCollisionHelper.ShouldIgnoreTrapperProjectileHit(gameObject, (GameObject?)obj); } } internal static class TrapperProjectileCollisionHelper { internal static bool ShouldIgnoreTrapperProjectileHit(GameObject? currentObject, GameObject? otherObject) { TrapperProjectileTag? trapperTag = GetTrapperTag(currentObject); TrapperProjectileTag trapperTag2 = GetTrapperTag(otherObject); if (trapperTag != null) { return trapperTag2 != null; } return false; } private static TrapperProjectileTag? GetTrapperTag(GameObject? gameObject) { if (gameObject == null) { return null; } return gameObject.GetComponentInParent<TrapperProjectileTag>(); } } } namespace RoundsDolyMods.Integrations { internal static class DolyTabInfoIntegration { private static bool registered; internal static void Register() { if (!registered) { registered = true; RegisterTackShooterStats(); RegisterHolySmiteStats(); RegisterHelldiverStats(); } } private static void RegisterTackShooterStats() { StatCategory obj = TabInfoManager.RegisterCategory("DOLY Tack Shooter", 20); TabInfoManager.RegisterStat(obj, "Tacks", (Func<Player, bool>)((Player player) => TryGetTackEffect(player, out TackShooterEffect _)), (Func<Player, string>)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect11)) ? "-" : effect11.TackCount.ToString())); TabInfoManager.RegisterStat(obj, "Tack range", (Func<Player, bool>)((Player player) => TryGetTackEffect(player, out TackShooterEffect _)), (Func<Player, string>)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect9)) ? "-" : effect9.TackRange.ToString("F0"))); TabInfoManager.RegisterStat(obj, "Tack DMG", (Func<Player, bool>)((Player player) => TryGetTackEffect(player, out TackShooterEffect _)), (Func<Player, string>)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect7)) ? "-" : $"{Mathf.RoundToInt(0.5f * effect7.TackDamageMultiplier * 100f)}%")); TabInfoManager.RegisterStat(obj, "Hot Shots", (Func<Player, bool>)((Player player) => TryGetTackEffect(player, out TackShooterEffect effect6) && effect6.UnblockableStacks > 0), (Func<Player, string>)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect5) || effect5.UnblockableStacks <= 0) ? "-" : $"Yes x{effect5.UnblockableStacks}")); TabInfoManager.RegisterStat(obj, "Ring of Fire", (Func<Player, bool>)((Player player) => TryGetTackEffect(player, out TackShooterEffect effect4) && effect4.RingOfFireStacks > 0), (Func<Player, string>)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect3) || effect3.RingOfFireStacks <= 0) ? "-" : $"Yes x{effect3.RingOfFireStacks}")); TabInfoManager.RegisterStat(obj, "Ring HP DMG", (Func<Player, bool>)((Player player) => TryGetTackEffect(player, out TackShooterEffect effect2) && effect2.ResolvedRingOfFirePercentDamage > 0f), (Func<Player, string>)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect) || !(effect.ResolvedRingOfFirePercentDamage > 0f)) ? "-" : $"{effect.ResolvedRingOfFirePercentDamage * 100f:F1}%")); } private static void RegisterHolySmiteStats() { StatCategory obj = TabInfoManager.RegisterCategory("DOLY Holy Smite", 21); TabInfoManager.RegisterStat(obj, "Smite DMG", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect19)) ? "-" : $"{Mathf.RoundToInt(effect19.ResolvedDamageRatio * 100f)}% bullet + {effect19.ResolvedFlatDamage:F0}")); TabInfoManager.RegisterStat(obj, "Smite cooldown", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect17)) ? "-" : $"{effect17.ResolvedCooldown:F2}s")); TabInfoManager.RegisterStat(obj, "Smite delay", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect15)) ? "-" : $"{effect15.ResolvedDelay:F2}s")); TabInfoManager.RegisterStat(obj, "Smite size", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect13)) ? "-" : $"{effect13.ResolvedSize:F2}")); TabInfoManager.RegisterStat(obj, "Bounce smite chance", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect12) && effect12.QuakingBounceChance > 0f), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect11) || !(effect11.QuakingBounceChance > 0f)) ? "-" : $"{Mathf.RoundToInt(effect11.QuakingBounceChance * 100f)}%")); TabInfoManager.RegisterStat(obj, "Additional smites", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect10) && effect10.ResolvedAdditionalSmites > 0), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect9)) ? "-" : effect9.ResolvedAdditionalSmites.ToString())); TabInfoManager.RegisterStat(obj, "Smite life steal", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect8) && effect8.LifeStealFraction > 0f), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect7)) ? "-" : $"{Mathf.RoundToInt(effect7.LifeStealFraction * 100f)}%")); TabInfoManager.RegisterStat(obj, "Stun", (Func<Player, bool>)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect6) && effect6.StunDuration > 0f), (Func<Player, string>)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect5)) ? "-" : $"{effect5.StunDuration:F2}s")); TabInfoManager.RegisterStat(obj,